Solved NPE Giving me a headache

Discussion in 'Plugin Development' started by ColaCraft, Dec 25, 2014.

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

    ColaCraft

    I am using a listener class and an API class (both separate from the main class) to do this. All I want to do is send a player into spectate mode when they die, but I am getting an NPE when I am calling my method.

    Code:
    @EventHandler
        public void onPlayerDeath(PlayerDeathEvent e){
           
            Player a =  e.getEntity();
           
            a.setHealth(20);
           
            api.setSpectating(a);
           
            if(a.getKiller() instanceof Player){
           
            e.setDeathMessage(ChatColor.DARK_RED + "Player " + ChatColor.GOLD + a.getName() + ChatColor.DARK_RED + " has fallen to " + ChatColor.GOLD + a.getKiller().getName());
           
            }
        }
    That is my listener class, it works fine, the NPE is thrown at my method right here:

    Code:
        public void setSpectating(Player p){
    
            if(p != null){
            if(spectating.size() < 10){
               
                plugin.chat.put(p.getName(), "spectate"); //NPE HERE
                p.sendMessage(plugin.tag + ChatColor.AQUA + "You are now spectating."); //NPE HERE IF LINE ABOVE IS REMOVED
                p.getInventory().clear();
               
                spectating.add(p.getName());
               
                p.setGameMode(GameMode.SPECTATOR);
            }else{
               
                for(Player s : Bukkit.getServer().getOnlinePlayers()){
                    p.getInventory().clear();
                    s.kickPlayer(ChatColor.DARK_RED + "Game over! " + ChatColor.GOLD + p.getName() + ChatColor.DARK_RED + " has won!");
                    gameOver();
                }
            }
               
            }
           
        }
    The odd thing is that it makes it past the null check-- I have a player, I just cant do anything with it.

    I already tried initiating the variable, but that didn't work at all. NPE's suck.

    Oh, and I reference my API class with the api.whatever

    Code:
    MortalAPI api = new MortalAPI(plugin);
     
  2. Offline

    nverdier

    @ColaCraft Possible that it's "plugin" that's null.
     
  3. Offline

    ColaCraft

    Code:
    Main plugin;
    
        public MortalListener(Main plugin) {
            this.plugin = plugin;
        }
     
  4. Offline

    Konato_K

    Why don't you give the stacktrace and the line of code the stacktrace points?

    Also, just for the record Player#getKiller always returns a Player, so you can just check if it's null instead of checking instance.
     
  5. Offline

    ColaCraft

    instanceof does the same thing? I know I could do that.

    Also, I have the line marked where the NPE is thrown, if you really want to read the stacktrace, here it is, it is just going to say the same thing :p

    Code:
    [18:22:23] [Server thread/INFO]: PorterK issued server command: /kill
    [18:22:23] [Server thread/ERROR]: Could not pass event PlayerDeathEvent to MortalGames v1.0
    org.bukkit.event.EventException
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:297) ~[craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:501) [craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:486) [craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.craftbukkit.v1_8_R1.event.CraftEventFactory.callPlayerDeathEvent(CraftEventFactory.java:364) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.EntityPlayer.die(EntityPlayer.java:392) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.EntityLiving.damageEntity(EntityLiving.java:765) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.EntityHuman.damageEntity(EntityHuman.java:795) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.EntityPlayer.damageEntity(EntityPlayer.java:471) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.EntityLiving.G(EntityLiving.java:86) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.CommandKill.execute(SourceFile:29) [craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.craftbukkit.v1_8_R1.command.VanillaCommandWrapper.dispatchVanillaCommand(VanillaCommandWrapper.java:91) [craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.craftbukkit.v1_8_R1.command.VanillaCommandWrapper.execute(VanillaCommandWrapper.java:42) [craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:140) [craftbukkit.jar:git-Bukkit-f233e7d]
        at org.bukkit.craftbukkit.v1_8_R1.CraftServer.dispatchCommand(CraftServer.java:624) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.PlayerConnection.handleCommand(PlayerConnection.java:1058) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.PlayerConnection.a(PlayerConnection.java:919) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(SourceFile:37) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.PacketPlayInChat.a(SourceFile:9) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.PacketHandleTask.run(SourceFile:13) [craftbukkit.jar:git-Bukkit-f233e7d]
        at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [?:1.8.0_25]
        at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_25]
        at net.minecraft.server.v1_8_R1.MinecraftServer.z(MinecraftServer.java:643) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:284) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:598) [craftbukkit.jar:git-Bukkit-f233e7d]
        at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:506) [craftbukkit.jar:git-Bukkit-f233e7d]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_25]
    Caused by: java.lang.NullPointerException
        at me.porterk.mg.MortalAPI.setSpectating(MortalAPI.java:513) ~[?:?]
        at me.porterk.mg.MortalListener.onPlayerDeath(MortalListener.java:157) ~[?:?]
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_25]
        at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_25]
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_25]
        at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_25]
        at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:295) ~[craftbukkit.jar:git-Bukkit-f233e7d]
        ... 26 more
    [18:22:23] [Server thread/INFO]: PorterK fell out of the world
    [18:22:23] [Server thread/INFO]: [PorterK: Killed PorterK]
    
    
    Line 513:

    Code:
    plugin.chat.put(p.getName(), "spectate");
    Line 157:

    Code:
    api.setSpectating(a);
     
    Last edited: Dec 25, 2014
  6. Offline

    Totom3

    @ColaCraft If it's not plugin that is null, it must be plugin.chat. Do you initialize it as the plugin is enabled?
     
  7. Offline

    SuperOriginal

    Did you instantiate the (incorrectly public) hashmap? With NPE's it's probably better to post full classes.
     
  8. Offline

    ColaCraft

    What is null is Player p, or whatever, even though it passes my null check. If I take out that line, I still get a NPE, just for the next time I try to do p.anything
     
  9. Offline

    SuperOriginal

    @ColaCraft Even if Java magically made the mistake of letting a null object through a check, it is impossible for p to even be null in the situation it is called in, as a player from PlayerDeathEvent is never null...

    Be more thorough with your debugging.
     
    Last edited: Dec 25, 2014
  10. Offline

    ColaCraft

    Sigh... if I remove the line with the plugin chat, the NPE is at p.sendMessage("");

    Call it magical or impossible, but it is a reality that I am living with :/
     
  11. Offline

    Totom3

    @ColaCraft I'm not so sure about that. Nothing can magically pass through a null check. I'm now fairly certain that plugin is actually null because the next time you invoke a method on the player object is this line:
    Code:
    p.sendMessage(plugin.tag+ ChatColor.AQUA+"You are now spectating.");
    You are also trying to get plugin.tag, which also might be the cause of your NPE. Add something like this and check the console :
    Code:
    System.out.println("Plugin equals "+plugin+", and player equals "+p); 
    This will reveal which one is null.
     
  12. Offline

    ColaCraft

    o.o this is a clear sign that I have been looking at this NPE for far too long.....

    @Totom3 but
    Code:
    Main plugin;
    
        public MortalAPI(Main plugin) {
            this.plugin = plugin;
        }
    And I use the plugin tag at least 100 other times in that same class

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Nov 17, 2016
    Totom3 likes this.
  13. Offline

    Totom3

    @ColaCraft Nothing prevents you to pass a null argument to a constructor either. What does the console say with the debug message I posted?
     
  14. Offline

    ColaCraft

    Plugin is null -.-













    ...cri
     
  15. Offline

    nverdier

    Then don't pass a null value into the constructor...
     
  16. Offline

    ColaCraft

    Thanks for the advice... :p

    I fixed it with this:

    Code:
        public void setSpectating(Player p, Main plugin){
           
            this.plugin = plugin;
    
            if(p != null){
            if(spectating.size() < 10){
               
                plugin.chat.put(p.getName(), "spectate");
                p.sendMessage(plugin.tag + ChatColor.AQUA + "You are now spectating.");
                p.getInventory().clear();
               
                spectating.add(p.getName());
               
                p.setGameMode(GameMode.SPECTATOR);
            }else{
               
                for(Player s : Bukkit.getServer().getOnlinePlayers()){
                    p.getInventory().clear();
                    s.kickPlayer(ChatColor.DARK_RED + "Game over! " + ChatColor.GOLD + p.getName() + ChatColor.DARK_RED + " has won!");
                    gameOver();
                }
            }
               
            }
           
        }
     
  17. Offline

    nverdier

    Yup that's what you do :p
     
  18. Offline

    Totom3

    @ColaCraft If that works then that's cool but if you later want to expand your plugin and don't fix the real issue... you'll end up passing the plugin on each method. It's not necessary, but if I was you, I'd fix this right away
     
    nverdier likes this.
  19. Offline

    ColaCraft

    What exactly is the real issue? I'm sure I could figure it out if I sat down and looked for long enough, but I am sitting on like 6 hours looking at plugin today, I am starting to miss things or see things that aren't there :eek:

    I realize that "plugin" is null there, but I'm not sure why exactly is is null only there.
     
  20. Offline

    mythbusterma

    @ColaCraft

    The issue is that you never set the member variable, or are using an instance that wasn't built with the constructor.
     
  21. Offline

    Totom3

    @ColaCraft We'd need the full class(es) to help you track down the issue. I guess that this can either be caused by passing a null object to the constructor, or as @mythbusterma said, using another instance.
     
  22. Offline

    ColaCraft

  23. Offline

    nverdier

Thread Status:
Not open for further replies.

Share This Page