[Semi-Solved] StackOverflowError with Hopper inventories?

Discussion in 'Plugin Development' started by ipodtouch0218, Sep 22, 2016.

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

    ipodtouch0218

    I'm creating a plugin where it uses the Hopper's inventory to create a "private bank" of sorts.

    It seems that sometimes a StackOverflowError occurs when interacting with hoppers. The only inventory event I have is InventoryCloseEvent to save the bank itself. The items teleport back to where they were before you moved them when the error pops up.

    Maybe it has something to do with the Hopper inv having only 5 slots? It likes to spam:
    Code:
    at net.minecraft.server.v1_10_R1.Container.a(Container.java:470)
    at net.minecraft.server.v1_10_R1.Container.a(Container.java:268)
    And the stacktrace that I was able to find amongst 1000's of Container errors.
    Code:
    [Server thread/FATAL]: Error executing task
    java.util.concurrent.ExecutionException: java.lang.StackOverflowError
        at java.util.concurrent.FutureTask.report(Unknown Source) ~[?:1.8.0_91]
        at java.util.concurrent.FutureTask.get(Unknown Source) ~[?:1.8.0_91]
        at net.minecraft.server.v1_10_R1.SystemUtils.a(SourceFile:46) [spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at net.minecraft.server.v1_10_R1.MinecraftServer.D(MinecraftServer.java:737) [spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at net.minecraft.server.v1_10_R1.DedicatedServer.D(DedicatedServer.java:399) [spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at net.minecraft.server.v1_10_R1.MinecraftServer.C(MinecraftServer.java:673) [spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at net.minecraft.server.v1_10_R1.MinecraftServer.run(MinecraftServer.java:572) [spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at java.lang.Thread.run(Unknown Source) [?:1.8.0_91]
    Caused by: java.lang.StackOverflowError
        at java.util.HashMap.putVal(Unknown Source) ~[?:1.8.0_91]
        at java.util.HashMap.put(Unknown Source) ~[?:1.8.0_91]
        at net.minecraft.server.v1_10_R1.NBTTagCompound.setString(SourceFile:134) ~[spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at net.minecraft.server.v1_10_R1.ItemStack.save(ItemStack.java:258) ~[spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at net.minecraft.server.v1_10_R1.ItemStack.<init>(ItemStack.java:68) ~[spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
        at net.minecraft.server.v1_10_R1.ItemStack.cloneItemStack(ItemStack.java:450) ~[spigot-1.10.jar:git-Spigot-a9631d2-67b2424]
    Which is strange, since I only save the items to a HashMap when the inventory closes.

    Source: http://pastebin.com/fLazE6k1

    Thanks in advance.
     
  2. Offline

    Tecno_Wizard

    @ipodtouch0218 That's not the whole stack trace. I need all that spam too. It may not seem important but it is with this exception.
     
  3. Offline

    ipodtouch0218

    @Tecno_Wizard
    No, it is not. I can't paste the whole stacktrace into Pastebin, it goes over the 50kb limit inside of Pastebin by 600kbs.

    EDIT: Turns out the same error repeated itself many times. Deleted those, and just left one. http://pastebin.com/u8v5Fkzj
     
  4. Offline

    Tecno_Wizard

    @ipodtouch0218 okay then... It shouldn't be. Can you link your latest server log file? You can find that in the log folder of the server.

    EDIT: it's named latest.log
     
  5. Offline

    I Al Istannen

    @ipodtouch0218
    Additional to that:
    Code:java
    1. Reader defConfigStream = null;
    2. try {
    3. defConfigStream = new InputStreamReader(this.getResource(str + ".yml"), "UTF8");
    4. e.printStackTrace();
    5. }
    6. if (defConfigStream != null) {
    7. YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
    8. fileConfig.setDefaults(defConfig);
    9. }

    Close the reader! I would advice the use of a try-with-resource statement, they were made for exactly this:
    Code:java
    1. try (Reader streamReader = new InputStreamReader(stream)) {
    2.  
    3. Load it here
    4. } catch( The exceptions ) {
    5. // do something
    6. }

    And you may want to wrap the reader in a buffered reader, to increase efficiency. Not sure if it makes a great impact though, or what the load method does with it.

    And:
    • Make your variables private
    • Make the methods private
    • Code:java
      1. new File(this.getDataFolder()+"/Banks.yml");

      You can use the correct method "new File(getDataFolder(), "Banks.yml");" for that.
    • Code:java
      1. List<UUID> confirm = new ArrayList<UUID>();

      You can declare that a Collection<UUID> and change it to a HashSet to make it faster and allow no duplicates.
    • You may want to remove the player form "confirm", if they wrote the command again and you deleted everything.
    • You may want to restructure the on command to return on failure, to avoid the deep if nesting.
     
  6. Offline

    ipodtouch0218

    @Tecno_Wizard
    Here's a dropbox link to the latest.log: https://www.dropbox.com/s/4kaaetanq38uzz0/latest.log?dl=0

    @I Al Istannen
    Thanks, like it says in my signature I'm open to suggestions. I'll send the updated code when I'm finished changing everything you mentioned.

    EDIT: Does this look better?
    Code:
        private void reloadCustomConfig(FileConfiguration fileConfig, File file, String str) {
            if (file == null) {
                file = new File(getDataFolder(), str + ".yml");
            }
            fileConfig = YamlConfiguration.loadConfiguration(file);
            try (BufferedReader defConfigStream = new BufferedReader(InputStreamReader(getResource(str + ".yml"), "UTF8"))) {
                YamlConfiguration defConfig = YamlConfiguration.loadConfiguration(defConfigStream);
                fileConfig.setDefaults(defConfig);
                defConfigStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
     
    Last edited: Sep 22, 2016
  7. Offline

    I Al Istannen

    @ipodtouch0218
    Define the InputStreamReader first and then the BufferedReader. I think this way the InputStreamReader will be closed, even if the BufferedReader can't be initialized.

    And you don't need to call close, the try-with-resource statement does that for you. That is its function ;)

    But otherwise, yes :)
     
  8. Offline

    ipodtouch0218

    @I Al Istannen
    Wait... so initialize the InputStreamReader first then the BufferedReader?
    When will the BufferedReader not be able to be initialized?
     
  9. Offline

    I Al Istannen

    @ipodtouch0218
    Better be safe than sorry :p
    try(InputStreamReader inReader = ... ;
    BufferedReader reader = new BufferedReader(inReader)) {
    }
     
  10. Offline

    Tecno_Wizard

    @ipodtouch0218, that's being caused by an item failing to clone properly.

    I think one of the itemstacks in your "private bank" is messed up in some way that it cannot be read properly when it is being copied, or more likely, there's a backend server issue that you've found.

    This is likely an issue on Spigot or Mojang's side more than your own fault. I'd try the Spigot bug reporter first. If it ends up being an MC issue, they'll probably report it to them.

    EDIT: Looking at decompiled source. It appears to be an infinite recursion error within Mojang's code that Bukkit/Spigot patched.

    EDIT2: Confirmed infinite recursion bug within the Bukkit edited mojang code. Report this to spigot when you get the chance.

    This is called (a is the constructor here)
    Code:
    protected void a(int i, int j, boolean flag, EntityHuman entityhuman) {
        a(i, j, InventoryClickType.QUICK_MOVE, entityhuman);
      }
    And the constructor eventually leads to here. Voila! You've got yourself infinite recursion.
    Code:
    a(i, j, true, entityhuman);
     
    Last edited: Sep 22, 2016
    ipodtouch0218 likes this.
  11. Offline

    ipodtouch0218

    @Tecno_Wizard
    It seems to happen randomly. I can create a new ItemStack, it works fine, and then randomly it fails to copy. I don't know where it's copying because it still shows up on my cursor, it just teleports back once I place it down inside another ItemStack.

    I'll try updating my Spigot to the newest one and maybe that'll work.
     
  12. Offline

    Tecno_Wizard

    @ipodtouch0218 if it doesn't, make a bug report to spigot. This isn't your fault.
     
  13. Offline

    mythbusterma

    @ipodtouch0218

    I would recommend avoiding what you're doing. @Tecno_Wizard While it isn't his fault, he still needs to work around it.
     
  14. Offline

    JanTuck

    This is a plugin request he is filling do he cant avoid it. Have you tried base64?

    Sent from Tapatalk
     
  15. Offline

    Tecno_Wizard

    I thought that was a given. XD
     
    ipodtouch0218 likes this.
Thread Status:
Not open for further replies.

Share This Page