Solved Issue returning instance of class from static method?

Discussion in 'Spigot Plugin Development' started by Qruet, Jul 20, 2018.

  1. Not quite sure why this is occurring but I'm getting an ArrayOutOfBoundsException without any details from where exactly it's coming from. I'm creating a new instance from within a static method within the same class and I made sure to add debug messages. It should broadcast a message before creating the instance and should broadcast a message the second the constructor is called before the constructor does anything else. I get the first message, but nothing happens after it. I'm not sure why this is happening? Any help would be most appreciated.

    Code (Text):

        private TitleUser(Player player) {
            Bukkit.broadcastMessage("1"); //this never broadcasts
            this.player = player;
            Bukkit.broadcastMessage("2");
            update();
            Bukkit.broadcastMessage("3");
            StoredUsers.add(this);
        }


    public static TitleUser getTitleUser(Player player){
            for(TitleUser user : StoredUsers){
                if(user.getPlayer().getUniqueId() == player.getUniqueId()){
                    return user;
                }
            }
            Bukkit.broadcastMessage("Returning new instance of TitleUser!"); //this does broadcast
            return new TitleUser(player);
        }

     

    Code (Text):
    [22:09:03] [Server thread/INFO]: geekles issued server command: /rankup
    [22:09:03] [Server thread/INFO]: Returning new instance of TitleUser!
    [22:09:03] [Server thread/ERROR]: null
    org.bukkit.command.CommandException: Unhandled exception executing command 'rankup' in plugin PyrixTitles v0.0.8-ALPHA
        at org.bukkit.command.PluginCommand.execute(PluginCommand.java:46) ~[spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) ~[spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.dispatchCommand(CraftServer.java:651) ~[spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.PlayerConnection.handleCommand(PlayerConnection.java:1392) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.PlayerConnection.a(PlayerConnection.java:1227) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:45) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.PacketPlayInChat.a(PacketPlayInChat.java:1) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.PlayerConnectionUtils$1.run(SourceFile:13) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [?:1.8.0_171]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [?:1.8.0_171]
        at net.minecraft.server.v1_12_R1.SystemUtils.a(SourceFile:46) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.MinecraftServer.D(MinecraftServer.java:748) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:406) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577) [spigot-1.12.2-R0.1-SNAPSHOT.jar:git-Spigot-93e20b3-31d3159]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_171]
    Caused by: java.lang.ArrayIndexOutOfBoundsException
     
  2. ScarabCoder

    ScarabCoder Retired Resource Staff
    Retired

    Can you put the exception in a hastebin? It's difficult to read as it's written now, plus it looks like it may not be full.
     
  3. Nope I guarantee it is full. I went through the logs just to be sure. I too was confused why it would just print the ArrayOutOfBoundsException without referencing a class within my plugin. Also the stacktrace looks fine on my end, unless you read it when I first posted the thread, I updated it several minutes ago with a formatted version. Here you go though just incase, http://hatebin.com/kibhpvnies.
     
  4. You might want to go over your code line by line in debug mode (Eclipse or IntelliJ) to see what really happens
     
    • Informative Informative x 1
  5. ScarabCoder

    ScarabCoder Retired Resource Staff
    Retired

    ^ Try enabling the break on exception feature. It allows you to step backwards, frame by frame, to find out where the error originated.
     
  6. Perhaps what I'm doing is actually causing something with spigot to break and not directly being caused by my plugin? I'm not using any runnables, therefore the only code being run at that moment in my plugin is from calling the constructor. The stack trace referes to issues with the classes located within spigot. That would be my only guess, and to be sure that would probably result in me having to debug those classes as well which isn't something I can necessarily do, at least as far as I know. Adding debug messages to the spigot jar and then building the jar back is a lengthy process that I've attempted before in which resulted in my IDE (IntelliJ & Eclipse) running out of memory. The code I have displayed is the only code that would be running from my plugin around the time when the issue occurs. My listeners currently are only listening for "/rankup" command and InventoryClick, therefore I doubt it originates from there as well. (I'll debug just to be sure though I suppose).
    EDIT: The only other classes (listeners) that might be at all in use during the course of the activity are not being used, except for the class that handles the rankup command of course which is only called once before the error occurs ofc.
     
    #6 Qruet, Jul 20, 2018
    Last edited: Jul 20, 2018
  7. Can we see the update method and the StoredUsers class?

    Edit: Try moving the update() and StoredUsers#add(this) out of the constructor into the factory method. Regardless of the cause, it’s unsafe to publish a reference in a constructor.
     
    #7 PanteLegacy, Jul 20, 2018
    Last edited: Jul 20, 2018
  8. I'll post it asap since I'm not currently at my computer however I do not see the reason since that method isnt called since the debug messages in the constructor themselves arent run, and the first thing that should run when the constructor is called is the debug message which doesnt occur. So something appears to occur after the constructor is called and before the first line of code is actually run within the constructor. Let me remind you no runnable, no async thread is being used in my plugin.
     
  9. electronicboy

    IRC Staff

    Add this to your JVM flags:
    Code (Text):

    -XX:-OmitStackTraceInFastThrow
     
    Java likes to optimize stuff, that includes optimizing out the process of actually generating a proper stack trace...
     
  10. Mmmm, maybe I can see why storing the instance of the class within its constructor can be a bit iffy, however I don't see why I shouldn't use the update method within the constructor? This simply allows me to update/store values within the private local variables within the class?
     
  11. I gave what you said a try. I'm not even sure if I did it correctly tbh, perhaps something I changed in the code might've changed something but in the end I did manage to get a more detailed stacktrace which helped resolve the issue. One of the private variables wasn't instantiating correctly. It was trying to read the last value of an array that had a length of zero. Not sure how I overlooked that, but the issue is resolved.