1.15.2 NullPointerException - Can't Locate

Discussion in 'Spigot Plugin Development' started by Nitecell, Mar 29, 2020.

  1. I have been working on a punishments plugin that (so far) just kicks someone and logs the kick into a punishments.yml file. For the last hour I have been attempting to solve this NullPointerException issue but I've had no luck. I feel like I am missing something that is a simple mistake. Some advice will also be appreciated!

    Code (Java):
    package me.nitecell.nitepunishments;

    import me.nitecell.nitepunishments.commands.KickCommand;
    import me.nitecell.nitepunishments.managers.ConfigManager;
    import org.bukkit.ChatColor;
    import org.bukkit.plugin.java.JavaPlugin;

    public final class NitePunishments extends JavaPlugin {

        private ConfigManager config;
        private static NitePunishments instance;
        public static NitePunishments getInstance() { return instance; }

        [USER=32110]@Override[/USER]
        public void onEnable() {
            instance = this;

            registerCommands();
            registerListeners();
            loadConfig();

            System.out.println(ChatColor.GREEN + "[NitePunishments] has been enabled.");
        }

        [USER=32110]@Override[/USER]
        public void onDisable() {
            instance = null;
            System.out.println(ChatColor.RED + "[NitePunishments] has been disabled.");
        }

        private void registerCommands() {
            getCommand("kick").setExecutor(new KickCommand());
        }

        public void loadConfig () {
            getConfig().options().copyDefaults(true);
            saveConfig();
        }

    }

    Code (Java):
    package me.nitecell.nitepunishments.commands;

    import me.nitecell.nitepunishments.managers.ConfigManager;
    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandExecutor;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;

    import java.util.Date;

    public class KickCommand implements CommandExecutor {

        ConfigManager punishments = ConfigManager.getInstance();
        ConfigManager config = ConfigManager.getInstance();

        @Override
        public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
            int kickid = 0;

            if (args.length == 0) {
                sender.sendMessage(ChatColor.RED + "Not enough arguments.");
                return true;
            }
            Player target = Bukkit.getPlayer(args[0]);
            if (target == null) {
                sender.sendMessage(ChatColor.RED + "Specified user could not be found.");
                return true;
            } else {
                String targetuuid = target.getUniqueId().toString();
                kickid = newKickID();
                Date date = new Date();

                punishments.getPunishments().set("punishments." + targetuuid + ".username", target.getName());
                punishments.getPunishments().set("punishments." + targetuuid + ".kicks." + kickid + ".reason", getReason(args));
                punishments.getPunishments().set("punishments." + targetuuid + ".kicks." + kickid + ".time", date);
                punishments.getPunishments().set("punishments." + targetuuid + ".kicks." + kickid + ".location.x", target.getLocation().getX());
                punishments.getPunishments().set("punishments." + targetuuid + ".kicks." + kickid + ".location.y", target.getLocation().getY());
                punishments.getPunishments().set("punishments." + targetuuid + ".kicks." + kickid + ".location.z", target.getLocation().getZ());
                punishments.getPunishments().set("punishments." + targetuuid + ".kicks." + kickid + ".punisher", sender.getName());
                punishments.savePunishments();
                target.kickPlayer(config.getConfig().getString("default-kick-message"));
                return true;
            }
        }

        public int newKickID() {
            int newid = config.getConfig().getInt("total-kicks") + 1;
            punishments.getConfig().set("total-kicks", newid);
            return newid;
        }

        public String getReason(String[] args) {
            if (args.length == 1) {
                return config.getConfig().getString("default-kick-reason");
            }
            StringBuilder str = new StringBuilder();
            for (int i = 1; i < args.length; i++) {
                str.append(args[i]).append(" ");
            } return str.toString();
        }
    }

    Code (Java):
    package me.nitecell.nitepunishments.managers;

    import org.bukkit.Bukkit;
    import org.bukkit.ChatColor;
    import org.bukkit.configuration.file.FileConfiguration;
    import org.bukkit.configuration.file.YamlConfiguration;
    import org.bukkit.plugin.Plugin;

    import java.io.File;
    import java.io.IOException;
    import java.text.SimpleDateFormat;

    public class ConfigManager {

        private ConfigManager() { }
        static ConfigManager instance = new ConfigManager();
        public static ConfigManager getInstance() { return instance; }

        public FileConfiguration config;
        public File cfile;

        public FileConfiguration punishments;
        public File pfile;

        public void setup(Plugin p) {
            if (!(p.getDataFolder().exists())) {
                p.getDataFolder().mkdir();
                Bukkit.getServer().getLogger().fine("Data Folder did not exist, creating one!");
            }

            cfile = new File(p.getDataFolder(), "config.yml");

            if (!cfile.exists()) {
                try {
                    cfile.createNewFile();
                } catch (IOException e) {
                    Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "[NitePunishments] Could not create the config.yml file");
                }
            }

            pfile = new File(p.getDataFolder(), "punishments.yml");

            if (!pfile.exists()) {
                try {
                    pfile.createNewFile();
                } catch (IOException e) {
                    Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "[NitePunishments] Could not create the punishments.yml file");
                }
            }

            punishments = YamlConfiguration.loadConfiguration(pfile);

        }

        public FileConfiguration getConfig() { return config; }
        public void saveConfig() {
            try {
                punishments.save(cfile);
            } catch (IOException e) {
                Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "[NitePunishments] Could not save the config.yml");
            }
        }
        public void reloadConfig() { punishments = YamlConfiguration.loadConfiguration(cfile); }

        public FileConfiguration getPunishments() { return punishments; }
        public void savePunishments() {
            try {
                punishments.save(pfile);
            } catch (IOException e) {
                Bukkit.getServer().getConsoleSender().sendMessage(ChatColor.RED + "[NitePunishments] Could not save the punishments.yml");
            }
        }
        public void reloadPunishments() { punishments = YamlConfiguration.loadConfiguration(pfile); }

    }

    Code (YAML):
    default-kick-message: You have been kicked from the server.
    default-kick-reason
    : The boot has spoken!

    Code (YAML):
    name: NitePunishments
    version
    : ${project.version}
    main
    : me.nitecell.nitepunishments.NitePunishments
    api-version
    : 1.13
    authors
    : [Nitecell]
    description
    : NitePunishments

    commands
    :
      kick
    :
        usage
    : /<command>
        aliases
    : [boot]
        description
    : Kick Command

    Stacktrace
    Code (Text):
    [18:37:45] [Server thread/INFO]: Nitecell issued server command: /kick Nitecell

    [18:37:45] [Server thread/ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'kick' in plugin NitePunishments v1.0-SNAPSHOT
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:47) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:149) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at org.bukkit.craftbukkit.v1_15_R1.CraftServer.dispatchCommand(CraftServer.java:723) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.PlayerConnection.handleCommand(PlayerConnection.java:1658) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.PlayerConnection.a(PlayerConnection.java:1498) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.PacketPlayInChat.a(PacketPlayInChat.java:47) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.PlayerConnectionUtils.lambda$0(PlayerConnectionUtils.java:19) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.TickTask.run(SourceFile:18) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeTask(SourceFile:144) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandlerReentrant.executeTask(SourceFile:23) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.executeNext(SourceFile:118) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.MinecraftServer.ba(MinecraftServer.java:918) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.MinecraftServer.executeNext(MinecraftServer.java:911) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.IAsyncTaskHandler.awaitTasks(SourceFile:127) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.MinecraftServer.sleepForTick(MinecraftServer.java:895) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at net.minecraft.server.v1_15_R1.MinecraftServer.run(MinecraftServer.java:828) [spigot.jar:git-Spigot-a03b1fd-fc318cc]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_241]
    Caused by: java.lang.NullPointerException
        at me.nitecell.nitepunishments.commands.KickCommand.newKickID(KickCommand.java:49) ~[?:?]
        at me.nitecell.nitepunishments.commands.KickCommand.onCommand(KickCommand.java:32) ~[?:?]
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:45) ~[spigot.jar:git-Spigot-a03b1fd-fc318cc]
        ... 17 more
    NOTE:
    I have investigated newKickID, removed it, changed it, etc. and the problem still exists. I think I might have messed up something with the configuration file but I have re-done that again as well. Help will be appreciated <3.
     
  2. What's the point of this? You're getting the same instance.
    Can't assure, but maybe that's the reason - pretty weird singleton design. Try to debug punishments in your KickCommand class - check if it's null and print some message.
     
  3. I can’t confirm fully as using a phone but it looks like your referencing something in the config (“total-kicks”) that as per your config.yml isn’t defined.

    I can’t see if you are storing that value in the other config but if so you would need to get it from the other config (getPunishments) not getConfig().
     
  4. While the singleton pattern here is itself sound and not the problem, the config manager is still an issue. You created a nice setup inside it but then ... never call it?
     
  5. Why do you have to fields that hold the same instance?

    Edit: just noticed the first post on this thread already adresses this issue.