Solved NullPointerException with getConfig

Discussion in 'Spigot Plugin Help' started by abstractionAlpha, Sep 4, 2020.

  1. In a non-main class, I'm trying to access the config as a field to reduce some clutter in my code. Whenever the getConfig line tries to execute, though, I get a NullPointerException as shown above. Here's...

    The class:
    Code (Text):
    public class FillChests  {


        private static ConfigurationSection chest;
        private static Integer x;
        private static Integer y;
        private static Integer z;
        private static String tier;

        private static Plugin plugin = ChestRandomizer.getPlugin();
        private static Configuration config = plugin.getConfig();

        /**
         * Method that finds chest to fill.
         *
         * @param chestName Name of chest being filled.
         */
        public static void fill(String chestName) {
            try {
                chest = config.getConfigurationSection("chests." + chestName);
            } catch (Exception e) {
                e.printStackTrace();
            }
    }
    The stack trace:
    Code (Text):
    [21:48:02 ERROR]: Could not load 'plugins/ChestRandomizer-1.0-SNAPSHOT.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidPluginException: java.lang.ExceptionInInitializerError
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:141) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:397) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:305) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.craftbukkit.v1_16_R2.CraftServer.loadPlugins(CraftServer.java:387) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.craftbukkit.v1_16_R2.CraftServer.reload(CraftServer.java:936) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.Bukkit.reload(Bukkit.java:699) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:54) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:159) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.craftbukkit.v1_16_R2.CraftServer.dispatchCommand(CraftServer.java:800) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.craftbukkit.v1_16_R2.CraftServer.dispatchServerCommand(CraftServer.java:762) ~[patched_1.16.2.jar:git-Paper-179]
        at net.minecraft.server.v1_16_R2.DedicatedServer.handleCommandQueue(DedicatedServer.java:409) ~[patched_1.16.2.jar:git-Paper-179]
        at net.minecraft.server.v1_16_R2.DedicatedServer.b(DedicatedServer.java:376) ~[patched_1.16.2.jar:git-Paper-179]
        at net.minecraft.server.v1_16_R2.MinecraftServer.a(MinecraftServer.java:1211) ~[patched_1.16.2.jar:git-Paper-179]
        at net.minecraft.server.v1_16_R2.MinecraftServer.w(MinecraftServer.java:999) ~[patched_1.16.2.jar:git-Paper-179]
        at net.minecraft.server.v1_16_R2.MinecraftServer.lambda$a$0(MinecraftServer.java:177) ~[patched_1.16.2.jar:git-Paper-179]
        at java.lang.Thread.run(Thread.java:832) [?:?]
    Caused by: java.lang.ExceptionInInitializerError
        at com.abstractionalpha.minecraft.plugins.chestrandomizer.ChestRandomizer.<init>(ChestRandomizer.java:22) ~[?:?]
        at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
        at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[?:?]
        at java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:124) ~[?:?]
        at jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:346) ~[?:?]
        at java.lang.Class.newInstance(Class.java:604) ~[?:?]
        at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:80) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:137) ~[patched_1.16.2.jar:git-Paper-179]
        ... 15 more
    Caused by: java.lang.NullPointerException
        at com.abstractionalpha.minecraft.plugins.chestrandomizer.FillChests.<clinit>(FillChests.java:34) ~[?:?]
        at com.abstractionalpha.minecraft.plugins.chestrandomizer.ChestRandomizer.<init>(ChestRandomizer.java:22) ~[?:?]
        at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
        at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[?:?]
        at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
        at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:500) ~[?:?]
        at java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:124) ~[?:?]
        at jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:346) ~[?:?]
        at java.lang.Class.newInstance(Class.java:604) ~[?:?]
        at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:80) ~[patched_1.16.2.jar:git-Paper-179]
        at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:137) ~[patched_1.16.2.jar:git-Paper-179]
        ... 15 more
    KEY: Caused by: java.lang.NullPointerException at com.abstractionalpha.minecraft.plugins.chestrandomizer.FillChests.<clinit>(FillChests.java:34) ~[?:?]

    I've withheld the methods as they are irrelevant to this issue, but please let me know if there's anything I should provide.
     
  2. Use FileConfiguration instead of Configuration for your variable config.
     
  3. Please use dependency injection. Static abuse results into this issue in your case and many other ones.

    At the time the class is loaded the plugin instance is not present. With dependency injection you can ensure that the stuff will be present in your lifecycle of the plugin.
     
    • Agree Agree x 1
  4. Hey, thanks for the input. I'm relatively new to Spigot and haven't used dependency injection before, so I'm trying to follow this tutorial. When I try and compile after creating my SimpleBinderModule class, I receive this compiler error Error:(9,41) java: cannot find symbol. This error points to AbstractModule.

    Would you mind explaining to me how to fix this, or point me to a better tutorial in the case that this one's outdated? I can't find any documentation for AbstractModule. Github link here and SimpleBinderModule class located at src/main/java/com/abstractionalpha/minecraft/plugins/chestrandomizer/SimpleBinderModule.java.

    Sorry for asking you of finer details; I am still learning.

    EDIT: Added more detail where helpful
     
    #4 abstractionAlpha, Sep 4, 2020
    Last edited: Sep 4, 2020
  5. Just use dependency injection. Do not use a framework for that.

    https://www.journaldev.com/2394/java-dependency-injection-design-pattern-example-tutorial
     
  6. bro...
    Code (Java):
    public class FillChests  {
        private final FileConfiguration config;

        public FillChests(FileConfiguration config){
            this.config = config;
        }
    }
    you just have to pass the necessary dependencies as parameters of the class constructor.
     
    • Agree Agree x 1
  7. Strahan

    Benefactor

    Yea, you're over complicating matters. At a basic level, all you really need to do is:
    Code (Text):
    public class MyPlugin extends JavaPlugin {
      onEnable {
        getServer().getPluginManager().registerEvents(MyEventClass(this), this);
      }
    }

    public MyEventClass implements Listener {
      private final MyPlugin plugin;

      public MyEventClass(MyPlugin plugin) {
        this.plugin = plugin;
      }
     
    The key is passing the instance of the primary class to other classes.
     
  8. bro, is exactly what I put above, besides because pass the instance of the main class being that only the guy needs the File Configuration class
     
  9. Hey - tried to implement this and got error Error:(46,21) java: non-static variable config cannot be referenced from a static context pointing to my private final FileConfiguration config;. How to resolve? Still struggling to navigate source on dependency injection. Updated code in git here.
     
  10. oh, in that case add the word static to the variable
    Code (Text):
    private static final FileConfiguration config;
     
    #10 joshy23, Sep 4, 2020
    Last edited: Sep 4, 2020
  11. Resolved. Thanks!

    EDIT: However, not that two access modifiers can't be used on FileConfiguration definition, so just use of static appropriate here
     
    #11 abstractionAlpha, Sep 4, 2020
    Last edited: Sep 4, 2020
    • Like Like x 1
  12. Strahan

    Benefactor

    I prefer having the main class passed because then you get everything. That aside...

    [​IMG]
    Check things like timestamps before you go whining about shit like that :p
     
  13. Sorry, I didn't look at the timestamp. As for the parameter, why pass an object that contains the object you need and others, being that you can pass the reference to that object you need.
     
  14. Strahan

    Benefactor

    Just habit. It costs no extra resources, and if down the road I decide I want to throw something on the logger or perform some other functionality that isn't accessible in my event, I'll already have the main instance there and ready for me.
     
  15. Hi, Strahan:

    I tried to implement your suggestions as follows:

    Main class:
    Code (Java):
    public final class ChestRandomizer extends JavaPlugin {

        IdTools id = new IdTools();

        FillChests fillChests = new FillChests(this);

        EmptyChests emptyChests;

        private static Plugin plugin;

        /**
         * Plugin start-up logic.
         */

        @Override
        public void onEnable() {
            getServer().getPluginManager().registerEvents(FillChests(this), this);
            getServer().getPluginManager().registerEvents(EmptyChests(this), this);
            saveDefaultConfig();
        }
    Dependant class 1:
    Code (Java):
    public class FillChests implements Listener {
        private final ChestRandomizer chestRandomizer;

        public FillChests(ChestRandomizer chestRandomizer) {
            this.chestRandomizer = chestRandomizer;
        }
    Dependant class 2:
    Code (Java):
    public class EmptyChests implements Listener {
        private final ChestRandomizer chestRandomizer;

        public EmptyChests(ChestRandomizer chestRandomizer) {
            this.chestRandomizer = chestRandomizer;
        }
    But on build, I get the compiler error Error:(33,55) java: cannot find symbol pointing to FillChests(this) in the main class. What am I doing wrong?
     
  16. Strahan

    Benefactor

    Close. You should be doing the new FillChests(this) in your event declaration, not up as a class scope variable. Well, that or use the class variable you created in the event registration instead of a class reference. Though as there is no need for a class variable for the event in the main class, I prefer to create it right there in the event registration. If you put "new" in the event registration, that error should go away.

    Also no need to make a static plugin variable if you are going to use dependency injection, that's kinda of the point - to avoid making static stuff everywhere ;)

    EDIT: Oh snap, my bad. I just realized I wrote the initial example wrong, d'oh!
     
    • Winner Winner x 1