Plugin is Null and i don't know why.

Discussion in 'Plugin Development' started by dipwr, Oct 27, 2021.

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

    dipwr

    Main (open)
    I have been developing a plugin for the last week and i am almost done but the code gives me a plugin null error, help will be much appreciated.
    I know the plugin is null because in the console it creates a NullPointerException on my "plugin" variable.
    Main Class:
    Main (open)

    Code:
    package me.dipwr.accessories;
    import org.bukkit.Bukkit;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public final class Main extends JavaPlugin {
        //Imports other classes
        CraftingRecipes craftingRecipes = new CraftingRecipes();
        Base64Encoding_Decoding base64Encoding_decoding = new Base64Encoding_Decoding();
        Accessories accessories = new Accessories();
    
        //Main variables
        public static Main plugin; //Null Error
        FileConfiguration config = getConfig();
    
        @Override
        public void saveConfig() {
            super.saveConfig();
        }
    
        @Override
        public void onEnable() {
            // Plugin startup logic
            plugin = this;
            getServer().getPluginManager().registerEvents(new Accessories(), this);
            getServer().getPluginCommand("accessories").setExecutor(new AccessoriesCommand());
    
            Bukkit.getLogger().info("test");
    
            //Here starts config.yml code
            getConfig().options().copyDefaults();
            saveDefaultConfig();
            if (!(config.getString("inventory") == "")){
                accessories.accessories = getInv();
                Bukkit.getLogger().info("Inv loaded");
            }
            //here ends config.yml code
    
    
    
    
            craftingRecipes.CreateRecipes();
        }
    
        @Override
        public void onDisable() {
            // Plugin shutdown logic
            saveConfig();
        }
    
        public Inventory getInv() {
            return base64Encoding_decoding.fromBase64(config.getString("inventory"));
        }
    }


    Config Class:
    Config (open)

    Code:
    package me.dipwr.accessories;
    
    import org.bukkit.Bukkit;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.inventory.Inventory;
    
    public class Config {
        FileConfiguration configuration = Main.plugin.config;
    
        public void setInv(Inventory inventory){
            Base64Encoding_Decoding base64Encoding_decoding = new Base64Encoding_Decoding();
            String string = base64Encoding_decoding.toBase64(inventory);
            configuration.set("inventory",string);
            Main.plugin.saveConfig();
            Bukkit.getLogger().info("Saved Config");
        }
    
    }

    Base64 Class:
    Base64 (open)

    Code:
    package me.dipwr.accessories;
    
    import org.bukkit.Bukkit;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.util.io.BukkitObjectInputStream;
    import org.bukkit.util.io.BukkitObjectOutputStream;
    
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.util.Base64;
    
    public class Base64Encoding_Decoding {
        public static String toBase64(Inventory inventory) {
            try {
                ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                BukkitObjectOutputStream data = new BukkitObjectOutputStream(outputStream);
                data.writeInt(inventory.getSize());
                data.writeObject("Accessories");
                for (int i = 0; i < inventory.getSize(); i++) {
                    data.writeObject(inventory.getItem(i));
                }
                data.close();
    
                return Base64.getEncoder().encodeToString(outputStream.toByteArray());
            } catch (Exception e) {
                e.printStackTrace();
            }
            return "";
        }
        public static Inventory fromBase64(String base64) {
            try {
                ByteArrayInputStream stream = new ByteArrayInputStream(Base64.getDecoder().decode(base64));
                BukkitObjectInputStream data = new BukkitObjectInputStream(stream);
                int size = data.readInt();
                if (size % 9 != 0) return null;
    
                Inventory inventory = Bukkit.createInventory(null, size, data.readObject().toString());
    
                for (int i = 0; i < inventory.getSize(); i++) {
                    inventory.setItem(i, (ItemStack) data.readObject());
                }
                data.close();
    
                return inventory;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
    
    
    }

    Accesories Class:
    Accesories (open)

    Code:
    package me.dipwr.accessories;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.inventory.*;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.inventory.ItemStack;
    
    public class Accessories implements Listener {
        public Inventory accessories = Bukkit.createInventory(null, InventoryType.CHEST, ChatColor.BLUE + "Accessories");
        public void openNewGui(Player p) {
            p.openInventory(accessories);
        }
        public ItemStack lightCrystal = CraftingRecipes.lightCrystalResult;
    
        Config configClass = new Config();
    
        @EventHandler
        public void invCloseEvent(InventoryCloseEvent inv) {
    
            if (inv.getInventory() == accessories) {
    
                if (inv.getInventory().contains(lightCrystal)) {
                    inv.getPlayer().sendMessage(ChatColor.GREEN + "You became invisible!");
                    inv.getPlayer().setInvisible(true);
                }else {
                    inv.getPlayer().setInvisible(false);
                    inv.getPlayer().sendMessage(ChatColor.RED + "You became visible!");
                }
                configClass.setInv(inv.getInventory());
            }
        }
    
    
        @EventHandler
        public void openGuiEvent(AccessoriesEvent e){
            openNewGui(e.getPlayer());
    
        }
    
    }

    Crafting Receipe Class:
    CraftingReceipe (open)

    Code:
    package me.dipwr.accessories;
    
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.Material;
    import org.bukkit.NamespacedKey;
    import org.bukkit.inventory.ItemStack;
    import org.bukkit.inventory.ShapedRecipe;
    import org.bukkit.inventory.meta.ItemMeta;
    
    import java.util.Arrays;
    
    public class CraftingRecipes {
    
        public static ItemStack lightCrystalResult = new ItemStack(Material.NETHER_STAR);
    
        public void CreateRecipes(){
            ItemMeta lightCrystalMeta = lightCrystalResult.getItemMeta();
    
            lightCrystalMeta.setDisplayName(ChatColor.YELLOW + "Light Crystal");
            lightCrystalMeta.setLore(Arrays.asList(ChatColor.GREEN + "Makes you Invisible!" ," ",ChatColor.LIGHT_PURPLE + "A crystal which was forged from all four eternal lights"));
    
            lightCrystalResult.setItemMeta(lightCrystalMeta);
    
            NamespacedKey key = new NamespacedKey(Main.plugin, "light_crystal");
            ShapedRecipe recipe = new ShapedRecipe(key, lightCrystalResult);
    
            recipe.shape(
                    "ADA",
                    "DED",
                    "ADA"
            );
            recipe.setIngredient('A', Material.AMETHYST_SHARD);
            recipe.setIngredient('D', Material.DIAMOND);
            recipe.setIngredient('E', Material.ENDER_EYE);
    
            Bukkit.addRecipe(recipe);
    
    
        }
    
    
    
    
    }

    AccessoriesCommand Class:
    AccesoriesCommand (open)

    Code:
    package me.dipwr.accessories;
    
    import org.bukkit.Bukkit;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    
    public class AccessoriesCommand implements CommandExecutor {
    
    
        @Override
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
            if (sender instanceof Player){
                Bukkit.getServer().getPluginManager().callEvent(new AccessoriesEvent((Player) sender));
                return true;
    
            }else {
                Bukkit.getLogger().info("You must be a player to run this command!");
    
            }
    
            return false;
        }
    }
    

    AccessoriesEvent Class:
    AccesoriesEvent (open)

    Code:
    package me.dipwr.accessories;
    
    import org.bukkit.entity.Player;
    import org.bukkit.event.Event;
    import org.bukkit.event.HandlerList;
    
    public class AccessoriesEvent extends Event {
    
        private final static HandlerList HANDLERS = new HandlerList();
    
        Player player;
    
        public AccessoriesEvent(Player player){
            this.player = player;
        }
        public Player getPlayer(){
            return player;
        }
    
    
        @Override
        public HandlerList getHandlers() {
    
    
    
            return HANDLERS;
        }
    
        public static HandlerList getHandlerList() {
    
    
            return HANDLERS;
        }
    
    }

    Error:
    Error (open)

    Code:
    [22:12:51 ERROR]: Could not load 'plugins\Accessories-1.0.jar' in folder 'plugins'
    org.bukkit.plugin.InvalidPluginException: java.lang.NullPointerException: Cannot read field "config" because "me.dipwr.accessories.Main.plugin" is null
            at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:157) ~[patched_1.17.1.jar:git-Paper-327]
            at org.bukkit.plugin.SimplePluginManager.loadPlugin(SimplePluginManager.java:416) ~[patched_1.17.1.jar:git-Paper-327]
            at org.bukkit.plugin.SimplePluginManager.loadPlugins(SimplePluginManager.java:324) ~[patched_1.17.1.jar:git-Paper-327]
            at org.bukkit.craftbukkit.v1_17_R1.CraftServer.loadPlugins(CraftServer.java:419) ~[patched_1.17.1.jar:git-Paper-327]
            at net.minecraft.server.dedicated.DedicatedServer.initServer(DedicatedServer.java:287) ~[patched_1.17.1.jar:git-Paper-327]
            at net.minecraft.server.MinecraftServer.runServer(MinecraftServer.java:1212) ~[patched_1.17.1.jar:git-Paper-327]        at net.minecraft.server.MinecraftServer.lambda$spin$0(MinecraftServer.java:319) ~[patched_1.17.1.jar:git-Paper-327]
            at java.lang.Thread.run(Thread.java:831) ~[?:?]
    Caused by: java.lang.NullPointerException: Cannot read field "config" because "me.dipwr.accessories.Main.plugin" is null        at me.dipwr.accessories.Config.<init>(Config.java:8) ~[Accessories-1.0.jar:?]
            at me.dipwr.accessories.Accessories.<init>(Accessories.java:19) ~[Accessories-1.0.jar:?]
            at me.dipwr.accessories.Main.<init>(Main.java:15) ~[Accessories-1.0.jar:?]
            at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[?:?]
            at jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:78) ~[?:?]
            at jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[?:?]
            at java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499) ~[?:?]
            at java.lang.reflect.ReflectAccess.newInstance(ReflectAccess.java:128) ~[?:?]
            at jdk.internal.reflect.ReflectionFactory.newInstance(ReflectionFactory.java:350) ~[?:?]
            at java.lang.Class.newInstance(Class.java:642) ~[?:?]
            at org.bukkit.plugin.java.PluginClassLoader.<init>(PluginClassLoader.java:83) ~[patched_1.17.1.jar:git-Paper-327]
            at org.bukkit.plugin.java.JavaPluginLoader.loadPlugin(JavaPluginLoader.java:153) ~[patched_1.17.1.jar:git-Paper-327]
            ... 7 more


    General Inprovements also welcome!
     
    Last edited by a moderator: Oct 27, 2021
  2. Offline

    timtower Administrator Administrator Moderator

    @dipwr You are making the CraftingRecipes class before your onEnable is called, at that time plugin is still null.
    Please use constructors to pass the main instance along to the classes that need it.
     
  3. Offline

    359Cube

    You should make your Main class like this
    Code:
    package me.dipwr.accessories;
    import org.bukkit.Bukkit;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.inventory.Inventory;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public final class Main extends JavaPlugin {
        //Imports other classes
        CraftingRecipes craftingRecipes = new CraftingRecipes();
        Base64Encoding_Decoding base64Encoding_decoding = new Base64Encoding_Decoding();
        Accessories accessories = new Accessories();
    
        //Main variables
        public static Main plugin = new Main(); //It should work
        FileConfiguration config = getConfig();
    
        @Override
        public void saveConfig() {
            super.saveConfig();
        }
    
        @Override
        public void onEnable() {
            // Plugin startup logic
        getServer().getPluginManager().registerEvents(new Accessories(), this);
            getServer().getPluginCommand("accessories").setExecutor(new AccessoriesCommand());
    
            Bukkit.getLogger().info("test");
    
            //Here starts config.yml code
            getConfig().options().copyDefaults();
            saveDefaultConfig();
            if (!(config.getString("inventory") == "")){
                accessories.accessories = getInv();
                Bukkit.getLogger().info("Inv loaded");
            }
            //here ends config.yml code
    
    
    
    
            craftingRecipes.CreateRecipes();
        }
    
        @Override
        public void onDisable() {
            // Plugin shutdown logic
            saveConfig();
        }
    
        public Inventory getInv() {
            return base64Encoding_decoding.fromBase64(config.getString("inventory"));
        }
    }
     
  4. Offline

    timtower Administrator Administrator Moderator

    @359Cube
    public static Main plugin = new Main(); //It should work

    That will never work.
     
    Strahan likes this.
  5. Offline

    Strahan

    Yea, you really shouldn't suggest code that you haven't tested. At least, I prefer not to. Guessing isn't good when you suggest something that will crash the plugin with an IllegalStateException.

    Code:
    if (!(config.getString("inventory") == "")){
    getString() returns a null if the value isn't present, not an empty string. You can make it return empty string though by passing that as the default after the path.
     
  6. Offline

    KarimAKL

    I feel like it should also be mentioned that strings in Java are compared with #equals, not ==.
     
  7. Offline

    Strahan

    Good point, I didn't even notice that.
     
Thread Status:
Not open for further replies.

Share This Page