NullPointerException

Discussion in 'Spigot Plugin Development' started by Waldxn, Apr 24, 2017.

  1. So what the code is supposed to do is break glass whenever someone shoots it with an arrow. Whenever you shoot an Entity with an arrow I am getting a NullPointerException. So I added code to where if the ProjectileHitEvent was NOT equal to Material#GLASS, then it would just return. Still getting a NullPointerExepction though.

    Code (Text):
       @EventHandler
        public void onArrowHit(ProjectileHitEvent phe) {

            if (this.plugin.getConfig().getBoolean("plugin-enabled")) {

                Projectile p = phe.getEntity();

                if (phe.getHitBlock().getType().toString() != Material.GLASS.toString()){

                    return;

                }
     
  2. WAS

    WAS

    Don't check strings, and also check to see if it's not null.

    Code (Java):
        if (phe.getHitBlock() != null && !(phe.getHitBlock().getType().equals(Material.GLASS))){
    It helps to know where the NPE is actually occurring as well. Is your config boolean null? You don't specify a default value
    Code (Java):
    this.plugin.getConfig().getBoolean("plugin-enabled", true)
     
  3. dont use .toString() to compare if its Material.GLASS.toString()
     
  4. Choco

    Moderator

    1. The only thing that can be null in this situation is your "plugin" field, or the block that was hit (which may instead be an Entity). Though, we haven't seen where your plugin field is initialized, nor any specific line where the error is occurring... thus we're only capable of taking wild guesses.
    2. You cannot compare String contents with == (or !=. Same thing)
    3. There's no reason to compare the String representation of Materials. They are constants for a reason. Compare constants with the == operator
    Code (Java):
    Block block = phe.getHitBlock();
    if (block == null || block.getType() != Material.GLASS) return;
     
    • Informative Informative x 1
  5. In the config.yml it automatically starts off set as true.

    Here is the error

    Code (Text):
     Could not pass event ProjectileHitEvent to BreakableGlass v1.0.0
    org.bukkit.event.EventException
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.craftbukkit.v1_11_R1.event.CraftEventFactory.callProjectileHitEvent(CraftEventFactory.java:792) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.EntityArrow.a(EntityArrow.java:259) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.EntityArrow.A_(EntityArrow.java:194) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.EntityTippedArrow.A_(EntityTippedArrow.java:86) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.World.entityJoinedWorld(World.java:1631) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.World.h(World.java:1606) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.World.tickEntities(World.java:1432) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.WorldServer.tickEntities(WorldServer.java:618) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:814) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:399) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:678) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:576) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_121]
    Caused by: java.lang.NullPointerException
            at com.waldxn.breakableGlass.events.BowAndArrow.onArrowHit(BowAndArrow.java:31) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_121]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_121]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_121]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:302) ~[spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            ... 16 more
    Here is the new code.

    Code (Text):
     if (phe.getHitBlock().getType() != null && !(phe.getHitBlock().getType() == Material.GLASS)){

                    return;
                   
                }
     
  6. Choco

    Moderator

    It's not the type that can be null, but rather the block. See my reply above
     
  7. What is the correct way to compare strings?
     
  8. Choco

    Moderator

    The contents of Strings should be compared using #equals(), though the memory address of a String can be compared with == much like any other object. I suggest reading up on the comparative operators
     
  9. After changing the code to this:
    Code (Text):
                if (phe.getHitBlock() != null && !(phe.getHitBlock().getType() == Material.GLASS)){

                    return;

                }
    I am still getting this error:

    Code (Text):
    Could not pass event ProjectileHitEvent to BreakableGlass v1.0.0
    org.bukkit.event.EventException
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:306) ~[spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62) ~[spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:502) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:487) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at org.bukkit.craftbukkit.v1_11_R1.event.CraftEventFactory.callProjectileHitEvent(CraftEventFactory.java:792) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.EntityArrow.a(EntityArrow.java:259) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.EntityArrow.A_(EntityArrow.java:194) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.EntityTippedArrow.A_(EntityTippedArrow.java:86) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.World.entityJoinedWorld(World.java:1631) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.World.h(World.java:1606) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.World.tickEntities(World.java:1432) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.WorldServer.tickEntities(WorldServer.java:618) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.MinecraftServer.D(MinecraftServer.java:814) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.DedicatedServer.D(DedicatedServer.java:399) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.MinecraftServer.C(MinecraftServer.java:678) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at net.minecraft.server.v1_11_R1.MinecraftServer.run(MinecraftServer.java:576) [spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_121]
    Caused by: java.lang.NullPointerException
            at com.waldxn.breakableGlass.events.BowAndArrow.onArrowHit(BowAndArrow.java:37) ~[?:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.8.0_121]
            at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_121]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[?:1.8.0_121]
            at java.lang.reflect.Method.invoke(Unknown Source) ~[?:1.8.0_121]
            at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:302) ~[spigot-1.11.2-R0.1-SNAPSHOT.jar:git-Spigot-54ec0b8-e04a179]
            ... 16 more
    EDIT: Here is line 37

    Code (Text):
              if (phe.getHitBlock().getType() == Material.GLASS) {
     
  10. WAS

    WAS

    I use equals for constants, and most things as well, as equals is first going to fire off a '==' comparison.

    Again

    Code (Java):
        if ( phe.getHitBlock() != null && ! ( phe.getHitBlock().getType().equals(Material.GLASS) ) ) {
    This is checking if the hit block is not null, and doesn't equal Material.GLASS
     
  11. These are the lines the error is referring to now

    Code (Text):
     if (phe.getHitBlock().getType() == Material.GLASS) {

                    if (p.toString().equals("CraftArrow")) {

                        phe.getHitBlock().breakNaturally();
                        p.remove();
                        phe.getHitBlock().getWorld().playSound(phe.getHitBlock().getLocation(), Sound.BLOCK_GLASS_BREAK, 1, 1);

                        if (this.plugin.getConfig().getBoolean("glass-return")) {

                            ItemStack g = new ItemStack(Material.GLASS, 1);
                            ProjectileSource en = p.getShooter();

                            if (en instanceof Player) {

                                Player pl = (Player) en;
                                pl.getInventory().addItem(g);

                            }
                        }
                    }
                }
     
  12. WAS

    WAS

    You need to use what we have given you and fix the remainder of your code. Mainly the to string bits.
     
  13. Did I not already change the if statement???
     
  14. This has literally not helped at all. Thanks for the help but I've used your advice and there's been no success.
     
  15. Choco

    Moderator

    The first line of the code you sent has not been changed. You are still not checking if the block returned from #getHitBlock() is null or not. We can't help you if you aren't changing your code...

    #equals() is prone to NullPointerExceptions, and often not necessary due to its default implementation of comparing with ==. Primitive data types (int, boolean, float, short, long, etc.) and enumeration constants should be compared with == as it's generally good practice. Just an extra method invocation that shouldn't really be needed.

    It helps to figure out the difference between #equals() and == in order to understand when and when not to use them in which situation. In the case of enumeration constants such as Material, the operator is better.
     
  16. I did change the code. I got a NEW error on line 37 instead of line 31. That's why I posted those new lines of code.

    EDIT:

    I was having issues with this:
    Code (Text):
     if (phe.getHitBlock() != null && !(phe.getHitBlock().getType() == Material.GLASS)){

                    return;

                }
    Now I'm having issues with this:
    Code (Text):
    if (phe.getHitBlock().getType() == Material.GLASS) {

                    if (p.toString().equals("CraftArrow")) {

                        phe.getHitBlock().breakNaturally();
                        p.remove();
                        phe.getHitBlock().getWorld().playSound(phe.getHitBlock().getLocation(), Sound.BLOCK_GLASS_BREAK, 1, 1);

                        if (this.plugin.getConfig().getBoolean("glass-return")) {

                            ItemStack g = new ItemStack(Material.GLASS, 1);
                            ProjectileSource en = p.getShooter();

                            if (en instanceof Player) {

                                Player pl = (Player) en;
                                pl.getInventory().addItem(g);

                            }
                        }
                    }
                }
     
  17. Choco

    Moderator

    That NEW line is throwing an exception for the exact same reason. You should take a bit to read up on Stacktraces and learning to debug your code. This is an essential skill of any Java developer, and it would help you a lot along the way if you read up a bit more on this topic. Trust me, it's worth reading about
     
  18. I feel like a fucking idiot man. Sorry to waste your time
     
  19. Choco

    Moderator

    We all had to learn at one point or another. We've all written Hello World programs before, and we've all had our moments where we didn't know what public / private even meant. The difference between a programmer and a good programmer, is that a good programmer will learn from their mistakes and improve upon their existing code. Be that good developer and learn ^-^
     
    • Useful Useful x 1
  20. WAS

    WAS

    I would take a look at something like this http://stackoverflow.com/questions/1750435/comparing-java-enum-members-or-equals

    Spigot enums are constants. They are predefined. It's better to use #equals(), actually. It's also a good fallback measure for the class itself.