[FIXED] Null pointer error, help?

Discussion in 'Spigot Plugin Development' started by ParkaBoi, Jun 23, 2015.

  1. Hey guys, I am trying to create a plugin where you can type the command "/report <problem>". The purpose of this is to report a problem on the server and notify all staff members about the problem.
    This is the error I've been getting, (error happens in Report.java at line 74) :
    Code (Text):
    [01:47:37 INFO]: iParkaBoi issued server command: /report chees
    [01:47:37 ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'repo
    rt' in plugin FactionNerdsReport v1.0
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spi
    got-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:14
    1) ~[spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at org.bukkit.craftbukkit.v1_8_R3.CraftServer.dispatchCommand(CraftServe
    r.java:642) ~[spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.PlayerConnection.handleCommand(PlayerCon
    nection.java:1135) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.PlayerConnection.a(PlayerConnection.java
    :970) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java
    :45) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.PacketPlayInChat.a(PacketPlayInChat.java
    :1) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.PlayerConnectionUtils$1.run(SourceFile:1
    3) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source) [
    ?:1.8.0_45]
            at java.util.concurrent.FutureTask.run(Unknown Source) [?:1.8.0_45]
            at net.minecraft.server.v1_8_R3.SystemUtils.a(SystemUtils.java:19) [spig
    ot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.MinecraftServer.B(MinecraftServer.java:7
    18) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.DedicatedServer.B(DedicatedServer.java:3
    67) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.MinecraftServer.A(MinecraftServer.java:6
    57) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java
    :560) [spigot-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            at java.lang.Thread.run(Unknown Source) [?:1.8.0_45]
    Caused by: java.lang.NullPointerException
            at com.factionnerds.report.Report.onCommand(Report.java:74) ~[?:?]
            at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) ~[spi
    got-1.8.7.jar:git-Spigot-d2856ae-8f0f4ed]
            ... 15 more
    This is my Report.java
    Code (Text):
    package com.factionnerds.report;

    import java.util.List;

    import org.bukkit.ChatColor;
    import org.bukkit.command.Command;
    import org.bukkit.command.CommandSender;
    import org.bukkit.entity.Player;
    import org.bukkit.plugin.PluginManager;
    import org.bukkit.plugin.java.JavaPlugin;

    import Utilities.StaffListChecker;

    public class Report extends JavaPlugin
    {
        private List<String> staff;
        private PluginManager pm = getServer().getPluginManager();
        private StaffListChecker checker = new StaffListChecker();
       
        @Override
        public void onEnable()
        {
            pm.registerEvents(new JoinListener(this), this);
            pm.registerEvents(new LeaveListener(this), this);
            fillStaffList();
        }
       
        // Fills the staff list with the online staff players' names
        private void fillStaffList()
        {
            for(Player player : getServer().getOnlinePlayers())
            {
                if(checker.checkIfStaff(player.getName()))
                {
                    staff.add(player.getName());
                }
            }
        }
       
        public List<String> getStaff()
        {
            return staff;
        }
       
        public void addStaffName(String name)
        {
            staff.add(name);
        }
       
        public void removeStaffName(String name)
        {
            staff.remove(name);
        }
       
        @Override
        public boolean onCommand(CommandSender sender, Command cmd, String label, String args[])
        {
            if(cmd.getName().equalsIgnoreCase("report"))
            {
                if(!(sender instanceof Player))
                {
                    sender.sendMessage("Lol are you retarded, a player has to use this. Idiot.");
                    return false;
                }
                Player senderplayerobject = (Player) sender;
                if(args.length == 0) // Check if bad syntax...
                {
                    senderplayerobject.sendMessage("Incorrect syntax! use /report <problem>");
                    return false;
                }
                else // It is correct syntax, now go.
                {
                    senderplayerobject.sendMessage("You sent a report! Faction Nerds Staff will respond accordingly.");
                    for(String staffname : staff)
                    {
                        Player staffplayerobject = getServer().getPlayer(staffname);
                        staffplayerobject.sendMessage("REPORT:[" + senderplayerobject.getName() + "]" + " > " + ChatColor.DARK_RED + args);
                    }
                }
                return true;
            }
            return false;
        }

    }
    And this is my StaffListChecker.java
    Code (Text):
    package Utilities;

    import ru.tehkode.permissions.PermissionUser;
    import ru.tehkode.permissions.bukkit.PermissionsEx;

    public class StaffListChecker
    {
        @SuppressWarnings("deprecation")
        public boolean checkIfStaff(String name)
        {
            PermissionUser puser = PermissionsEx.getUser(name);
            for(String group : puser.getGroupsNames())
            {
                if(group == "rootadmin" || group == "superadmin" || group == "admin")
                {
                    return true;
                }
            }
            return false;
        }
    }
     
    This error happens when I enter "/report chees" in chat... can anyone see my problem? Thanks
     
  2. You create the staff list during the onEnable() -- and you cycle through that same list during the /report command. Odds are, some of the staff listed during the onEnable are no longer online when the /report command is used. I would first make sure that (getServer().getPlayer(staffname) != null) -- and then you might need to check that the staff member is online too with Player.isOnline() method.
     
  3. If you wanted to ping all online staff, you could cycle through all online players to sort for staff each time the command is used. If you wanted to keep a record system of reports, you could get creative with file IO or databases.
     
  4. I would say:
    Code (Text):
    OfflinePlayer p = Bukkit.getOfflinePlayer(staffname);
    if (p.isOnline()) {
    Player ponline = Bukkit.getPlayer(staffname);
    }
     
    Then you won't get an error because it checks if the Player is online.
    Please like if I could help.
     
  5. Nevermind, I found the problem, it was that the list was null since it wasn't instantiated (interface, you can't instantiate it). I just used an arraylist instead. Thanks for trying to help though. Guess I'm cut out for my low level C style arrays.
     
  6. Also strings aren't comparable with ==.

    Instead:
    group.equals("rootadmin")
    Or
    group.equalsIgnoreCase("rootadmin")

    Your plugin won't through errors with ==, but it will always be false. String is a object unlike int or char.
     
  7. Well, they're comparable, but == compares the object reference, not the value.
     
  8. Which is clearly gonna return false when you compare to quoted strings due to it being a whole new string
     
  9. Code (Java):
    System.out.println("butts" == "butts"); //prints true
     
  10. I think it's supposed to be like this (don't quote me on this)

    Player target = Bukkit.getServer().getPlayer("name");

    if(target == null) {
    //something
    }else{
    //something else
     
  11. It may compile in eclipse and what not, but it will not work reliably, the actual java emulator will not run it correctly. It will compare objects instead of the CHARs

    PROOF:
    [​IMG]

    Additionally, you should use UUID's where you can to get players.
     
  12. It will absolutely work reliably, because it compares the references. Strings are interned, which means comparing a literal or interned string with a string of the same value is always true.

    == is a valid comparison operator and it works exactly as intended for strings, or any other object: It compares the value of the reference. Comparison of the object's value (for any object) should be deferred to #equals.

    I'd recommend not learning from someone/someplace that just says "this is bad/never do this" rather than what something does.

    On a different and completely unrelated note, eclipse is garbage.
     
  13. It doesn't matter what IDE you use, string is not a literal. String is a object, not a primitive such as int or boolean. It is a wrapper class for char arrays that is automatically included in java. This is why it has methods while int and char do not. You have to call their objective class such as Integer or Character if you want to use method for them.
     
  14. That's called Autoboxing, and String is not an Autoboxed class. A string literal is this:

    Code (Java):
    String myLiteral = "Hello world";
    Whereas a string that isn't a literal could be:

    Code (Java):
    String myNonLiteral = new String("Hello world");
    if you did this:

    Code (Java):
    System.out.println(myLiteral == myNonLiteral); //prints false
    System.out.println(myLiteral == myNonLiteral.intern()); //prints true
    I'm aware String is an object, just as I stated in my previous post. You're a bit mislead on it being a "wrapper", though that's down to terminology. It does contain a char array internally, however strings are Immutable, not something to use as a wrapper.
     
  15. [​IMG] And the way strings are passed into onCommand, they're unreliable to use == on.
     
  16. Well, if you want to be sneaky, you could intern them yourself:

    Code (Java):
    if (cmd.getName().intern() == "myCmd") { //...
    But that'd be less efficient than just comparing the value in the first place. And since you're comparing value, you would use #equals anyhow (as I stated 3 posts ago).
     
  17. Than what was your whole point in arguing that I pointed out to him/her to use #equals? To waste time arguing over a point just to come back to saying s/he should use #equals which is what I pointed out initially! You shouldn't have even replied with anything... Unless your whole point of trying to seem like you know what you are talking about is to just get post counts up. All you did is work to confuse him/her. All s/he needed to know is that to have proper code with spigot is that s/he needed to use #equals or #equalsIgnoreCase to compare strings with the purpose s/he has.
     
  18. Well, I posted because you posted numerous amounts of misinformation as if they were fact:

     
  19. 1. I said strings aren't comparable with == because you can't compare the string, just the object. So that is technically correct.
    2. A string itself is not a literal. Int and Char are literals. If int x = 5 and int c = 5 they both = 5. They represent a byte/number of bytes. A string represents an object or a cluster of bytes to say.
    3. It pretty much is a wrapper class by theory. It wraps around a char array and manipulates it to make the string object manipulatable. You can recreate the String class using a char array, and a compiler plugin that will let you set how the compiler reads object == object. IE You have method isEqual in your custom string class, you have the compiler read String b == String a as b.Equal(a)

    Nothing I said was "misinformation". Instead of attacking the people actually helping someone, how about you simply answer their question. You have the right to post on the internet what you wish, but that doesn't mean any of us care to listen to it. Great words of advice for you.
     
  20. I feel like maybe there's a language barrier here...

    int/char/etc are all primitives, the only time something in code is a literal is when you specify the value outright:

    Code (Java):
    5
    42L
    3.14D
    "butts"
    1e2
    As far as "representing bytes", that's down to assembly's word/halfword/byte and ML, so not really a java concept.

    By theory's standards, it wouldn't be one, because it doesn't extend the functionality/behavior of the char array.

    There's more misinformation here: Strings are never manipulatable/mutable, they're immutable by definition. If you call methods on a string that return a new value, it will be an entirely new string object.

    I'm not even sure where you're going with the last part. Custom string class?

    Well between the 20,000 posts combined of me answering people's questions on internet forums, I think I can say I've done that.

    And at any given rate, by the time I had posted, the OP already solved their problem.
     
    • Winner Winner x 2