ConcurrentModificationException in Iterator

Discussion in 'Plugin Development' started by thebiologist13, Jul 31, 2012.

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

    thebiologist13

    Hi Everyone!

    I have been having the following error in my plugin when I try to remove integers from an array list and then remove mobs with those ids from the world.

    Code:
    2012-07-31 10:43:16 [SEVERE] java.util.ConcurrentModificationException
    2012-07-31 10:43:16 [SEVERE]    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    2012-07-31 10:43:16 [SEVERE]    at java.util.ArrayList$Itr.remove(Unknown Source)
    2012-07-31 10:43:16 [SEVERE]    at com.github.thebiologist13.CustomSpawners.removeMobs(CustomSpawners.java:689)
    2012-07-31 10:43:16 [SEVERE]    at com.github.thebiologist13.commands.spawners.RemoveMobsCommand.run(RemoveMobsCommand.java:123)
    2012-07-31 10:43:16 [SEVERE]    at com.github.thebiologist13.SpawnerExecutor.onCommand(SpawnerExecutor.java:275)
    2012-07-31 10:43:16 [SEVERE]    at org.bukkit.command.PluginCommand.execute(PluginCommand.java:40)
    2012-07-31 10:43:16 [SEVERE]    at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:166)
    2012-07-31 10:43:16 [SEVERE]    at org.bukkit.craftbukkit.CraftServer.dispatchCommand(CraftServer.java:479)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.NetServerHandler.handleCommand(NetServerHandler.java:821)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.NetServerHandler.chat(NetServerHandler.java:781)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:764)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.Packet3Chat.handle(Packet3Chat.java:34)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.NetworkManager.b(NetworkManager.java:229)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.NetServerHandler.a(NetServerHandler.java:113)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.NetworkListenThread.a(NetworkListenThread.java:78)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.MinecraftServer.w(MinecraftServer.java:567)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:459)
    2012-07-31 10:43:16 [SEVERE]    at net.minecraft.server.ThreadServerApplication.run(SourceFile:492)
    Here is the method that is throwing the error:

    Code:
    public synchronized void removeMobs(final Spawner s) {
        Iterator<Integer> mobs = s.getMobs().iterator();
        Iterator<LivingEntity> entities = s.getLoc().getWorld().getLivingEntities().iterator();
        int removeIndex = 0;
     
        while(mobs.hasNext()) {
            int spawnerMobId = (Integer) mobs.next();
     
            while(entities.hasNext()) {
                LivingEntity l = entities.next();
                int entityId = l.getEntityId();
     
                if(spawnerMobId == entityId) {
                    l.remove();
                    s.getMobs().remove(removeIndex);
                }
     
                entities.remove();
            }
     
            removeIndex++;
     
            mobs.remove();
        }
    }
    Things I have tried:
    • Using separate sync thread.
    • Wrapping the code in the method in a synchronized block.
    • Using and not using iterators.
    Other info:
    • Other tasks in my plugin are handled by a separate async thread. It also uses the same instances of Spawners.
    • Spawner does not refer to a vanilla mob spawner.
    • And when I use getMobs() it returns an ArrayList of mob IDs.
    • Furthermore, line 689 from the stack trace above is "mobs.remove()"
    Thanks in advance! :D

    EDIT: I have also looked at this thread: http://forums.bukkit.org/threads/solved-caused-by-java-util-concurrentmodificationexception.84419/
     
  2. Offline

    nisovin

    You need to use the remove() method on the Iterator to remove an item from the collection you're iterating over. You can't use the remove() method from the collection itself while iterating over it.
     
    thebiologist13 likes this.
  3. Offline

    thebiologist13

    Thanks so much! It works completely now.:D

    EDIT: New Code
    Code:
    public synchronized void removeMobs(final Spawner s) {
            Iterator<Integer> mobs = s.getMobs().iterator();
     
            while(mobs.hasNext()) {
                int spawnerMobId = mobs.next();
                Iterator<LivingEntity> livingEntities = s.getLoc().getWorld().getLivingEntities().iterator();
               
                while(livingEntities.hasNext()) {
                    LivingEntity l = livingEntities.next();
                   
                    int entityId = l.getEntityId();
     
                    if(spawnerMobId == entityId) {
                        l.remove();
                        mobs.remove();
                    }
                   
                }
               
            }
           
        }
     
Thread Status:
Not open for further replies.

Share This Page