Checking for Enchantments causes NPE?

Discussion in 'Spigot Plugin Development' started by JordanOsterberg, May 16, 2015.

  1. I have found an NPE by using this code:
    PHP:
    public String getType()
        {
            String type = "";
           
            for(int x = 0; x<8; x++)
            {
                if(inv.getItem(x).getItemMeta().hasEnchants()) // error here
                {
                    // no enchantments
                }
                else
                {
                    ItemMeta im = inv.getItem(x).getItemMeta();
                    type = im.getDisplayName();
                }
            }
            type=type.substring(0,type.length()-1);
            return type;
        }
    and if(inv.getItem(x).getItemMeta().hasEnchants()) is creating an NPE.
     
  2. getItem() is returning null.
     
  3. Make sure there's an item in that slot and that it has ItemMeta. You can make sure by inserting null checks.
     
  4. @Skionz @ReadySetPawn Added these null checks, still getting an NPE.
    Code:
    PHP:
    public String getType()
        {
            String type = "";
           
            for(int x = 0; x<8; x++)
            {

                if (inv.getItem(x).getItemMeta() != null && inv.getItem(x) != null){
                    if(!inv.getItem(x).getItemMeta().hasEnchants())
                    {
                        // no enchantments
                    }
                    else
                    {
                        ItemMeta im = inv.getItem(x).getItemMeta();
                        type = im.getDisplayName();
                    }
                }
               
               
            }
            type=type.substring(0,type.length()-1);
            return type;
        }
    Error at: if (inv.getItem(x).getItemMeta() != null && inv.getItem(x) != null){
     
  5.  
  6. @Skionz
    if(inv.getItem(x).getItemMeta()!=null&& inv.getItem(x)!=null){
     
  7. Conditional expressions such as that one are evaluated left to right (the order is important because of short-circuit evaluation), so it crashes with a NPE on the first condition before it actually checks getItem(x) != null. Switch the order of the two conditions and it will work.
     
  8. This results in the same error.
     
  9. I find that hard to believe unless 'inv' itself is null. Post your updated code.
     
  10. PHP:
    public String getType()
        {
            String type = "";
           
            for(int x = 0; x<8; x++)
            {

                if (inv.getItem(x) != null && inv.getItem(x).getItemMeta() != null){
                    if(!inv.getItem(x).getItemMeta().hasEnchants())
                    {
                        // no enchantments
                    }
                    else
                    {
                        ItemMeta im = inv.getItem(x).getItemMeta();
                        type = im.getDisplayName();
                    }
                }
               
               
            }
            type=type.substring(0,type.length()-1);
            return type;
        }
     
  11. So where does the NPE occur?
     
  12. Post your entire class. My guess is 'inv' is null.
     
  13. 'inv' isn't null:
    PHP:
    inv = Bukkit.createInventory(null, 54, "§c§nPrizes Won");
     
  14. full class
     
  15. Line 177 in the PrizesWonInv class.
    PHP:

    if (inv.getItem(x) != null && inv.getItem(x).getItemMeta() != null){
     
     
  16. PHP:
    Core plugin = Core.getCore();
         Inventory inv;

        public void inv(Player p){
            ArrayList<Integer> tempList = plugin.getPrizes().readPrizes(p, getPath(getType(),getRarity()));
            List<String> pathList = (List<String>) Core.getCore().getConfig().getList(getPath(getType(),getRarity()));
           
            inv = Bukkit.createInventory(null, 54, "§c§nPrizes Won");
           
            ItemStack bow = new ItemStack(Material.BOW);
            ItemStack prefix = new ItemStack(Material.NAME_TAG);
            ItemStack hat = new ItemStack(Material.GLASS);
           
            ItemStack winMessage = new ItemStack(Material.PAPER);
            ItemStack deathMessage = new ItemStack(Material.PAPER);
            ItemStack taunt = new ItemStack(Material.PAPER);
           
            ItemStack backArrow = new ItemStack(Material.ARROW);
            ItemStack common = new ItemStack(Material.WOOL,1,DyeColor.GREEN.getData());
            ItemStack rare = new ItemStack(Material.WOOL,1,DyeColor.CYAN.getData());
            ItemStack chest = new ItemStack(Material.CHEST);
            ItemStack mythical = new ItemStack(Material.WOOL,1,DyeColor.PURPLE.getData());
            ItemStack legendary = new ItemStack(Material.WOOL,1,DyeColor.YELLOW.getData());
            ItemStack nextArrow = new ItemStack(Material.ARROW);

       
            ItemMeta bowMeta = bow.getItemMeta();
            ItemMeta prefixMeta = prefix.getItemMeta();
            ItemMeta hatMeta = hat.getItemMeta();
           
            ItemMeta winMessageMeta = winMessage.getItemMeta();
            ItemMeta deathMessageMeta = deathMessage.getItemMeta();
            ItemMeta tauntMeta = taunt.getItemMeta();
           
            ItemMeta backArrowMeta = backArrow.getItemMeta();
            ItemMeta commonMeta = common.getItemMeta();
            ItemMeta rareMeta = rare.getItemMeta();
            ItemMeta chestMeta = chest.getItemMeta();
            ItemMeta mythicalMeta = mythical.getItemMeta();
            ItemMeta legendaryMeta = legendary.getItemMeta();
            ItemMeta nextArrowMeta = nextArrow.getItemMeta();
           
           
            bowMeta.setDisplayName(ChatColor.DARK_GREEN + "?");
            prefixMeta.setDisplayName(ChatColor.DARK_GREEN + "Prefixs");
            hatMeta.setDisplayName(ChatColor.GREEN + "Hats");
           
            winMessageMeta.setDisplayName(ChatColor.BLUE + "Win Messages");
            deathMessageMeta.setDisplayName(ChatColor.DARK_AQUA + "Death Messages");
            tauntMeta.setDisplayName(ChatColor.AQUA + "Taunts");
           
            backArrowMeta.setDisplayName(ChatColor.GREEN + "Go Back");
            commonMeta.setDisplayName(ChatColor.GREEN + "Common Rarity");
            rareMeta.setDisplayName(ChatColor.AQUA + "Rare Rarity");
            chestMeta.setDisplayName(ChatColor.RED + "Items");
            mythicalMeta.setDisplayName(ChatColor.DARK_PURPLE + "Mythical Rarity");
            legendaryMeta.setDisplayName(ChatColor.GOLD + "Legendary Rarity");
            nextArrowMeta.setDisplayName(ChatColor.GREEN + "Go Next");

           
            bowMeta.setLore(Arrays.asList(ChatColor.GRAY + "Your ?."));
            prefixMeta.setLore(Arrays.asList(ChatColor.GRAY + "Your Prefixs."));
            hatMeta.setLore(Arrays.asList(ChatColor.GRAY + "your Hats."));
           
            winMessageMeta.setLore(Arrays.asList(ChatColor.GRAY + "your Win Messages."));
            deathMessageMeta.setLore(Arrays.asList(ChatColor.GRAY + "your Death Messages."));
            tauntMeta.setLore(Arrays.asList(ChatColor.GRAY + "Your Taunts."));

            backArrowMeta.setLore(Arrays.asList(ChatColor.GRAY + "a page."));
            commonMeta.setLore(Arrays.asList(ChatColor.GRAY + "Your Common Items."));
            rareMeta.setLore(Arrays.asList(ChatColor.GRAY + "Your Rare Items."));
            chestMeta.setLore(Arrays.asList(ChatColor.GRAY + "a page."));
            mythicalMeta.setLore(Arrays.asList(ChatColor.GRAY + "Your Mythical Items."));
            legendaryMeta.setLore(Arrays.asList(ChatColor.GRAY + "Your Legendary Items."));
            nextArrowMeta.setLore(Arrays.asList(ChatColor.GRAY + "a page."));

           
            bow.setItemMeta(bowMeta);
            prefix.setItemMeta(prefixMeta);
            hat.setItemMeta(hatMeta);
           
            winMessage.setItemMeta(winMessageMeta);
            deathMessage.setItemMeta(deathMessageMeta);
            taunt.setItemMeta(tauntMeta);

            backArrow.setItemMeta(backArrowMeta);
            common.setItemMeta(commonMeta);
            rare.setItemMeta(rareMeta);
            chest.setItemMeta(chestMeta);
            mythical.setItemMeta(mythicalMeta);
            legendary.setItemMeta(legendaryMeta);
            nextArrow.setItemMeta(nextArrowMeta);

           
            inv.setItem(1, bow);
            inv.setItem(2, prefix);
            inv.setItem(3, hat);
           
            inv.setItem(5, winMessage);
            inv.setItem(6, deathMessage);
            inv.setItem(7, taunt);
           
            if(tempList.size()>0)
            {
                for(int x = 0; x<36; x++)
                {
                    if(x<tempList.size())
                    {
                        ItemStack temp = getItemTypeData(getPath(getType(),getRarity()),tempList.get(x));
                        ItemMeta tempMeta = temp.getItemMeta();
                        tempMeta.setDisplayName(getRarityColor(getRarity()) + "" + ChatColor.BOLD + getRarity() + " " + getType() + ChatColor.RESET + getRarityColor(getRarity()) + ": " + pathList.get(tempList.get(x)));
                        temp.setItemMeta(tempMeta);
                        inv.setItem(x+9, temp);
                    }
                }
            }
           
            inv.setItem(45, backArrow);
            inv.setItem(47, common);
            inv.setItem(48, rare);
            inv.setItem(49, chest);
            inv.setItem(50, mythical);
            inv.setItem(51, legendary);
            inv.setItem(53, nextArrow);

           
            p.openInventory(inv);
        }
       
        public String getRarity()
        {
            String rarity = "";
           
            for(int x = 45; x<53; x++)
            {
                if (inv.getItem(x) != null && inv.getItem(x).getItemMeta() != null){
                    if(!inv.getItem(x).getItemMeta().hasEnchants()){
                    // no enchantments
                }
                else
                {
                    ItemMeta im = inv.getItem(x).getItemMeta();
                    rarity = im.getDisplayName();
                }
            }}
            rarity.replace(" ", "");
            rarity.replace("Rarity", "");
            return rarity;
        }
       
        public String getType()
        {
            String type = "";
           
            for(int x = 0; x<8; x++)
            {

                if (inv.getItem(x) != null && inv.getItem(x).getItemMeta() != null){
                    if(!inv.getItem(x).getItemMeta().hasEnchants())
                    {
                        // no enchantments
                    }
                    else
                    {
                        ItemMeta im = inv.getItem(x).getItemMeta();
                        type = im.getDisplayName();
                    }
                }
               
               
            }
            type=type.substring(0,type.length()-1);
            return type;
        }
       
        public String getPath(String type, String rarity)
        {
            type.replace(" ", "");
            type.substring(0,1).toLowerCase();
           
            rarity.toLowerCase();
           
            return "prizeBox." + type + "." + rarity;
        }
       
        public ItemStack getItemTypeData(String path, int randVal)
        {
            if(path.substring(9,12).equals("hat"))
            {
                return translateMaterial(path, randVal);
            }
            else if(path.substring(9,15).equals("prefix"))
            {
                return new ItemStack(Material.NAME_TAG,1);
            }
            else
            {
                return new ItemStack(Material.PAPER,1);
            }
        }
       
        public ChatColor getRarityColor(String rarity)
        {
            if(rarity.equals("Common"))
            {
                return ChatColor.GREEN;
            }
            else if(rarity.equals("Rare"))
            {
                return ChatColor.AQUA;
            }
            else if(rarity.equals("Mythical"))
            {
                return ChatColor.DARK_PURPLE;
            }
            else
            {
                return ChatColor.GOLD;
            }
        }
       
        public void removeSelectedType()
        {
            for(int x = 0; x<8; x++)
            {
                if(inv.getItem(x).getItemMeta().hasEnchants())
                {
                    // no enchantments
                }
                else
                {
                    ItemMeta im = inv.getItem(x).getItemMeta();
                    im.removeEnchant(Enchantment.SILK_TOUCH);
                }
            }
        }
       
        public void removeSelectedRarity()
        {
            for(int x = 45; x<53; x++)
            {
                if (inv.getItem(x).hasItemMeta()){
                    if(inv.getItem(x).getItemMeta().hasEnchants())
                {
                    // no enchantments
                }
                else
                {
                    ItemMeta im = inv.getItem(x).getItemMeta();
                    im.removeEnchant(Enchantment.SILK_TOUCH);
                }
            }}
        }
       
        public ItemStack translateMaterial(String path, int randVal)
        {
            List<String> tempList = (List<String>) Core.getCore().getConfig().getList(path);
            String toMaterial=tempList.get(randVal);
            toMaterial.toLowerCase().replace(" ", "");
            Material m = Material.matchMaterial(toMaterial);
            return new ItemStack(m,1);
        }
    }
     
  17. Have you checked whether inv itself is null?

    Edit: Heed ReadySetPawn's advice, that's most likely the problem you're having.
     
    #17 dxdy, May 16, 2015
    Last edited: May 16, 2015
  18. Change "&&" to "||". Because it only takes one of those getters to be null in order to throw an NPE.
     
  19. If the ItemStack isn't air, the ItemMeta will not be null.
     
  20. Changed this, NPE is still there.