Solved Material becomes null when turned into an ItemStack

Discussion in 'Plugin Development' started by Reflxction, Aug 16, 2017.

Thread Status:
Not open for further replies.
  1. Offline

    Reflxction

    Hello guys,
    sorry for asking a lot of questions lately, I've been trying for hours, still not solved.
    So, my problem is, when I take a material from the config, I use it in an ItemStack. I printed out the value of the material and it said null. I've tried a lot of things but it still is not .
    Config:
    Code:
    item: DIAMOND
    Code:
    Code:
    Material item = Material.getMaterial(getConfig().getString("item").toUpperCase());
    ItemStack diamond = new ItemStack(item);
    inv.setItem(0, diamond);
    Player p = (Player) sender
    p.openInventory(inv);
    When I execute the command, it says an internal error occured blablabla, then it prints stacktraces saying that there is a NullPointerException at the line where I get the material from the config. I've tried loads of things yet it's not working. Any help would be much appreciated. Thanks
     
  2. Offline

    timtower Administrator Administrator Moderator

    @xTechno_ Could you post the entire method?
    getMaterial returns null when not found, should check if that is the case.
     
  3. Offline

    Reflxction

    @timtower
    Code:
        @Override
        public boolean onCommand(CommandSender sender, org.bukkit.command.Command cmd, String lbl, String[] args) {
            if (!(sender instanceof Player)) {
                sender.sendMessage(ChatColor.RED + "This command is for players only!");
            }
            if (sender instanceof Player) {
               
                if (cmd.getName().equalsIgnoreCase("shop")) {
                    Inventory inv = Bukkit.createInventory(null, 9);
                    Material item = Material.getMaterial(Main.instance().getConfig().getString("item").toUpperCase());
                    ItemStack diamond = new ItemStack(item);
                    inv.setItem(0, diamond);
                    Player p = (Player) sender;
                    p.openInventory(inv);
    
                }
            }
            return false;
        }
     
  4. Offline

    timtower Administrator Administrator Moderator

    @xTechno_ I am going for Main.instance() returning null.
    Use constructors, not public static.
     
  5. @timtower @xTechno_
    Actually - in this case having a static getter method for the plugin instance isn't that bad. I would say that one of the few times it is okay to use static is when having a getter method for the instance, but only as long as that's the only static you use.

    There are of course further use cases where statics make more sense than having objects, but those are rare in Bukkit, because you almost always have to support multiple instances of players anyway. There is also the obvious downside of having to keep track of when stuff loads and unloads, and it is easy to get that wrong. My recommendation is tokeep away from statics unless you are absolutely sure you know what you're doing.

    Also, Main is not the best of names for your plugin's Main class. What if you depend on 10 other libs which also have the name Main for their main class? Then you have 10 different Main classes. It is recommended that you instead use the name of your plugin as the main class.
     
    Reflxction likes this.
  6. Offline

    timtower Administrator Administrator Moderator

    @AlvinB Depends on how it is getting used. How it is used here is better then all the public static variables, this seems like a decent singleton (for how far that is possible for a plugin)
    I prefer passing instances using constructors though, certainly in Bukkit.
     
  7. @timtower
    Well, it's very hard to misuse a getter for a plugin instance, since the plugin instance is still used elsewhere in code for as long as the plugin is running. Only potential memory leak is between the calling of onDisable() and either shut down or reenable in the case of reloads, it's very minor. It could also easily be fixed by setting the instance to null in the onDisable() method.

    There is actually advantages to having a static getter method. What if you have a bunch of objects and 10 instances down contained in the various objects you just need to log a message? If you use constructors, you'd need to pass the instances all the way through the 10 objects constructors, just for that one log message. In that case, having a static getter method might just be easier.

    But as I said, for anything other than plugin instances, I recommend keeping away from statics as it is very easy to cause memory leaks, unless you are sure you know what you're doing.
     
    timtower likes this.
  8. Offline

    Reflxction

    @AlvinB @timtower I don't usually use constructors since you have to create every single object in it. I do realize that using public statics will cause memory leaks every time the server is reloaded, however it is already mentioned that the /reload command is not supported and any problems that occur should be the sender's fault. And what @AlvinB mentioned about setting the instance to null in the onDisable() method can be very efficient, so I don't really have to worry about the statics, but I'll refrain from using them in the future. And I usually name my main class with "Main" because, for example, I am making a super power's ability plugin. The plugin name would be "Abilities". I would have an enumeration named "Ability". If I had to deal with some events, I name a class "Listeners". This would confuse me a bit, but yeah I'll do that. Thanks

    On a side note, I doubt that the instance is what returning null. Any other ideas?
     
  9. Offline

    timtower Administrator Administrator Moderator

    @xTechno_ Regarding naming: one of the reasons that pretty much all my plugins end with "LikeMe"

    Could you post the related classes?
     
  10. @xTechno_
    Well, the only things it can be are Main.instance() or .getConfig().getString("item").

    Posting the stacktrace you're getting might also help a bit with the diagnosis.
     
  11. Offline

    Reflxction

    @timtower I have Main class (registering commands, events, etc), GUIManager for creating GUIs and managing the InventoryClickEvent, and the Command class for the command.


    @AlvinB Stack-traces point to "
    Material item = Material.getMaterial(Main.instance().getConfig().getString("item").toUpperCase());", a NullPointerException.
     
  12. Offline

    timtower Administrator Administrator Moderator

    @xTechno_ Could you post the code for the main class and for this class?
     
  13. Offline

    Reflxction

    @timtower
    Code:
    package net.xtechno.shops;
    
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class Main extends JavaPlugin {
    
        static Main plugin;
    
        @Override
        public void onEnable() {
            this.getConfig();
            saveDefaultConfig();
            getCommand("shop").setExecutor(new Command());
            getServer().getPluginManager().registerEvents(new GUIManager(), this);
        }
    
        @Override
        public void onDisable() {
    
        }
    
        public static Main instance() {
            return plugin;
        }
    }
    
     
  14. Offline

    timtower Administrator Administrator Moderator

    @xTechno_ And you never set plugin.
    Which you should make private btw, you never unset it either.
     
  15. Offline

    Reflxction

    @timtower Sorry I forgot about that. However still not working :/
     
  16. Offline

    timtower Administrator Administrator Moderator

    @xTechno_ Then you should have a new log with a new error.
     
  17. Offline

    Reflxction

    @timtower Nope, still the same errors and the same stacktraces
     
  18. Offline

    timtower Administrator Administrator Moderator

    @xTechno_ That is impressive.
    Then could you narrow the error down to a specific method call?
    Checking return values on null etc.
     
  19. Offline

    Reflxction

    @timtower I've commented some lines out and checked, and the problem just seems to be when the material is grabbed from the config from a non-main class. Should I move it to the main class and check if there is any difference?

    //Edit: Sorry for all this, it was just a typo in the config file, I had an underscore instead of "-". I guess the problem is solved xD
     
  20. Offline

    timtower Administrator Administrator Moderator

Thread Status:
Not open for further replies.

Share This Page