Random Error, But plugin still works

Discussion in 'Plugin Development' started by Laserhog, Nov 10, 2011.

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

    Laserhog

    I'm making a simple plugin for someone and it all works fine except i get this error when it runs
    Show Spoiler

    Code:
    21:34:34 [SEVERE] Could not pass event PLAYER_INTERACT to NoBoatsOnLand
    java.lang.NullPointerException
            at me.laserhog.NoBoatsOnLand.NoBoatsOnLandPlayerListener.onPlayerInterac
    t(NoBoatsOnLandPlayerListener.java:13)
            at org.bukkit.plugin.java.JavaPluginLoader$11.execute(JavaPluginLoader.j
    ava:330)
            at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.jav
    a:58)
            at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.j
    ava:339)
            at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEven
    t(CraftEventFactory.java:171)
            at org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEven
    t(CraftEventFactory.java:142)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:560)
            at net.minecraft.server.Packet15Place.a(SourceFile:57)
            at net.minecraft.server.NetworkManager.b(NetworkManager.java:226)
            at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:92)
            at net.minecraft.server.NetworkListenThread.a(SourceFile:108)
            at net.minecraft.server.MinecraftServer.h(MinecraftServer.java:471)
            at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:374)
            at net.minecraft.server.ThreadServerApplication.run(SourceFile:417)


    My main class is
    Show Spoiler

    Code:
    package me.laserhog.NoBoatsOnLand;
    
    import java.util.logging.Logger;
    
    import org.bukkit.event.Event;
    import org.bukkit.plugin.PluginDescriptionFile;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;
    
    public class NoBoatsOnLand extends JavaPlugin
    {
        public final Logger logger = Logger.getLogger("Minecraft");
        NoBoatsOnLandPlayerListener playerListener = new NoBoatsOnLandPlayerListener();
    
    @Override
        public void onEnable()
        {
        PluginManager pm = this.getServer().getPluginManager();
        pm.registerEvent(Event.Type.PLAYER_INTERACT, playerListener, Event.Priority.Normal, this);
    
        PluginDescriptionFile pdfFile = this.getDescription();
        this.logger.info(pdfFile.getName() +" Version " + pdfFile.getVersion() + " is Enabled");
        }
    
    @Override
        public void onDisable()
        {
        }
    }


    My playerListener is
    Show Spoiler

    Code:
    package me.laserhog.NoBoatsOnLand;
    
    import org.bukkit.entity.Player;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.event.player.PlayerListener;
    
    public class NoBoatsOnLandPlayerListener extends PlayerListener
    {
        public void onPlayerInteract(PlayerInteractEvent event)
        {
            Player player = event.getPlayer();
    
            Boolean liquidCheck = event.getClickedBlock().isLiquid();
    
            Integer inHand = player.getItemInHand().getType().getId();
    
            if(inHand == 333)
            {
                if(liquidCheck == false)
                {
                    event.setCancelled(true);
                }
            }
        }
    
    }


    It all works fine still, i'm just confused about why its throwing an error about that line.
    Any help or information is greatly appreciated :D
     
  2. Offline

    DrBowe

    "Boolean" should be lowercase, and Integer should be int--use the primitives, not the objects. (technically speaking, though, that's not the problem here)

    The issue is that you're setting liquidCheck to event.getClickedBlock().isLiquid().
    You need to check if they're actually clicking a block first, before you go ahead and assume that they are.
     
  3. Offline

    halley

    The error is on or near line 13, according to the dump. If I count your lines properly, line 13 is:

    Code:
    Boolean liquidCheck = event.getClickedBlock().isLiquid();
    As DrBoweNur said, you should be using 'boolean', not 'Boolean'. There is a class type called Boolean (which wraps a non-object boolean for data structures that need objects); this may be causing the confusion here, but the Java compiler may be converting this for you.

    In general, if you have a NullPointerException, you need to just decide each of the possible pointers in your expression, and see what might be null. On that line, you have:

    • event (probably can't be null, since it was used successfully on line above)
    • event.getClickedBlock() (can this be null in a PlayerInteractEvent situation?)

    Check these out with log.info() statements to see if they have the values you want, or if they may be null when you least expect.

    As an aside, it is really bad form to use magic constants like "333" in code. I'm guessing that's a boat, but who knows? Please use the appropriate Material enumerated constant name. It makes your code much more clear to understand what you're talking about later (for us, and for yourself in a few weeks time). Source code is for humans to read, not just compilers, so make your source code more readable.

    Code:
    Material inHand = player.getItemInHand().getType();
    if (inHand == Material.BOAT) { ... }
    
    or

    Code:
    ItemStack inHand = player.getItemInHand();
    if (inHand.getType() == Material.BOAT) { ... }
    
    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 21, 2016
  4. Offline

    Zaros

    Wouldn't they still be clicking air if they hit a mob or clicking in the air? Hitting a switch or button would return those items? Not sure if you could get a NPE from it.
     
  5. Offline

    halley

    I wasn't sure if it's possible in today's Bukkit, but it's often better to code defensively regardless. One could say that it's slightly less efficient to put in extra checks, but a single if/null check on any user interaction is not going to be noticeable... there are FAR worse inefficiencies all over Minecraft.

    Code:
    Block clicked = event.getClickedBlock();
    if (clicked != null && clicked.isLiquid() { ... }
    
     
  6. Offline

    Laserhog

    Thanks so much. This worked although
    Code:
    if (clicked != null && clicked.isLiquid() { ... }
    should be
    Code:
    if (clicked != null && clicked.isLiquid() == false) { ... }
    :p
     
  7. Offline

    halley

    Sure. I'd phrase that as !clicked.isLiquid() as it reads better, but good catch. Didn't mean to ruin the logic.
     
  8. if (!(event.hasBlock())) {
    return;
    }
     
  9. Offline

    nisovin

    The clicked block is the one that's highlighted in the client. If there is no highlighted block in the client, then the clicked block will be null. It doesn't return air.
     
Thread Status:
Not open for further replies.

Share This Page