ConcurrentModificationException when not actually modifying O.o

Discussion in 'Plugin Development' started by Digi, Sep 7, 2012.

Thread Status:
Not open for further replies.
  1. Someone reported this stacktrace:
    Code:
    2012-09-06 15:53:16 [WARNING] [RecipeManager] Task #2681 for RecipeManager v1.26b generated an exception
    java.util.ConcurrentModificationException
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
        at java.util.HashMap$EntryIterator.next(HashMap.java:847)
        at java.util.HashMap$EntryIterator.next(HashMap.java:845)
        at digi.recipeManager.FurnacesTask.run(FurnacesTask.java:37)
        at org.bukkit.craftbukkit.scheduler.CraftTask.run(CraftTask.java:52)
        at org.bukkit.craftbukkit.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:316)
        at net.minecraft.server.MinecraftServer.q(MinecraftServer.java:537)
        at net.minecraft.server.DedicatedServer.q(DedicatedServer.java:245)
        at net.minecraft.server.MinecraftServer.p(MinecraftServer.java:501)
        at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:419)
        at net.minecraft.server.ThreadServerApplication.run(SourceFile:539)
    In my digi.recipeManager.FurnacesTask line 37 on the version he's using, there's this:
    Code:
    	@Override
    	public void run()
    	{
    		Iterator<Entry<String, MutableDouble>> iterator = RecipeManager.recipes.furnaceSmelting.entrySet().iterator();
    		
    		Entry<String, MutableDouble> entry;
    		Furnace furnace;
    		FurnaceInventory inventory;
    		ItemStack smelt;
    		ItemStack result;
    		Item recipeResult;
    		Smelt recipe;
    		double time;
    		
    		while(iterator.hasNext())
    		{
    			entry = iterator.next(); // <<-------------------== line 37
    			
    			if((furnace = Recipes.stringToFurnace(entry.getKey())) == null)
    			{
    				iterator.remove();
    				continue;
    			}
    			
    			inventory = furnace.getInventory();
    			smelt = inventory.getSmelting();
    (Entire class: https://github.com/THDigi/RecipeManager/blob/master/digi/recipeManager/FurnacesTask.java )

    I thought that ConcurentModificationException only triggers when you actually modify a collection that's looped through by another iterator... so what's up with this ? :confused:
    I am not using anything else than iterator.remove() to remove entries and that task is sync.
     
  2. Offline

    andf54

    I don't use iterators, so there is a good chance that I'm wrong.

    Im guessing that .entrySet().iterator(); still leaves the the iterator in hands of something else.
     
  3. Offline

    nisovin

    This is likely caused by some other block of code adding or removing items. It's probably called (either directly or indirectly) from within this iterator while loop.
     
  4. Offline

    Courier

    Is this running as an async task?
     
  5. Offline

    Giant

    Your issue is on line 40, because you are removing IN the iterator, it goes apeshit kinda...
    Code:
    iterator.remove();
    
    Edit:
    Courier looking at line 590 in Recipes.java, it seems to be a sync task.
     
  6. Offline

    Courier

    No. That is fine. That is how you are supposed to remove during iteration. That is the reason iterators have a remove() method.

    I'm guessing that this is running as an async task, and he happened to remove while something else (the server) was looping through the furnace recipes.
     
  7. Offline

    Courier

    You're right. He even said it was sync in his original post... my bad :p.

    That is pretty strange then. Maybe the user had another plugin that was asynchronously looping through the furnace recipes. That seems unlikely, but I can't think of anything else.
     
  8. Hmm, the reporter said he used it with Dwarf Forge plugin, altough I am not sure what the problem is tough.
     
  9. Offline

    Courier

    Hmm. This does do a lot with furnaces and their inventories, so it might be involved somehow. However, the only place I found them doing anything off the main thread was in their Metrics... but it looks like it is all done properly, and doesn't deal with furnaces anyway.


    I don't know, this is an odd one.
     
  10. Hmm... the stack trace ends here:
    Code:
        at java.util.HashMap$HashIterator.nextEntry(HashMap.java:806)
    And there is the manual error trigger:
    Code:
      804           final Entry<K,V> nextEntry() {
      805               if (modCount != expectedModCount)
      806                   throw new ConcurrentModificationException();
      807               Entry<K,V> e = next;
      808               if (e == null)
      809                   throw new NoSuchElementException();
      810   
      811               if ((next = e.next) == null) {
      812                   Entry[] t = table;
      813                   while (index < t.length && (next = t[index++]) == null)
      814                       ;
      815               }
      816               current = e;
      817               return e;
      818           }
    (From http://www.docjar.com/html/api/java/util/HashMap.java.html)

    So yeah... size doesn't match...
     
Thread Status:
Not open for further replies.

Share This Page