Solved ConcurrentModificationException even while using an Iterator?

Discussion in 'Plugin Development' started by ImSxYN, Jun 21, 2015.

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

    ImSxYN

    I have had a concurrentmodificationexception error for a while and after looking around some I saw that you should use iterators. I have changed my code to use them But I am still getting the error. What am I doing wrong?

    Here is the code:
    Code:
    package me.woofyy.guicloser;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventHandler;
    import org.bukkit.event.Listener;
    import org.bukkit.event.block.Action;
    import org.bukkit.event.block.BlockBreakEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    
    public class BlockBreakListener implements Listener {
        ArrayList < Player > players = new ArrayList < Player > ();
        private static final HashMap < Player, Block > dataMap = new HashMap < Player, Block > ();
    
        /**
        @
        EventHandler
        public void onInventoryOpen(InventoryOpenEvent iEvent) {
            String player = iEvent.getPlayer().getName();
            HumanEntity eplayer = iEvent.getPlayer();
            Inventory item = iEvent.getInventory();
            if (!(dataMap.containsKey(player) && !(dataMap.containsValue(item)))) {
                dataMap.put(player, item);
            }
            if (!(players.contains(eplayer)))
                players.add(eplayer);
        }
        **/
        @
        EventHandler
        public void onBlockBreak(BlockBreakEvent event) {
            Player eplayer = event.getPlayer();
            Block item = event.getBlock();
            ItemData eventblock = new ItemData(item.getTypeId(), item.getData());
            for (Iterator<Player> iterator = players.iterator(); iterator.hasNext(); ) {
                Player p = iterator.next();
                if (GuiCloser.blockInfo.contains(eventblock.toString())) {
                    guiClose(p, item);
                }
            }
        }
    
        @
        EventHandler
        public void onBlockInteract(PlayerInteractEvent event){
            Player eplayer = event.getPlayer();
            Block item = event.getClickedBlock();
            if(item != null){
            ItemData eventblock = new ItemData(item.getTypeId(), item.getData());
                if(event.getAction() == Action.RIGHT_CLICK_BLOCK && GuiCloser.blockInfo.contains(eventblock.toString())){
                    if(!players.contains(eplayer)){
                        dataMap.put(eplayer, item);
                        players.add(eplayer);
                    }
                }else if(event.getAction() == Action.RIGHT_CLICK_BLOCK && GuiCloser.blockInfo2.contains(eventblock.toString())){
                    if(!players.contains(eplayer)){
                        dataMap.put(eplayer, item);
                        players.add(eplayer);
                    }
                }else{
                    if(players.contains(eplayer)){
                        remove(eplayer);
                    }
                }
                for (Iterator<Player> iterator = players.iterator(); iterator.hasNext(); ) {
                    Player p = iterator.next();
                    if (eplayer.getItemInHand().getType() == Material.AIR || eplayer.getItemInHand() == null) return;
                    if (!(eplayer.getItemInHand().hasItemMeta() && eplayer.getItemInHand().getItemMeta().hasDisplayName())) return;
                    if(event.getAction() == Action.RIGHT_CLICK_BLOCK && eplayer.getItemInHand().getTypeId() == 5397 && isPlayerCrouched(eplayer) && !(GuiCloser.blockInfo.contains(eventblock.toString()))){
                        guiClose(p, item);
                    }
                }
            }
    
        }
       
        public void guiClose(Player player, Block block){
            if(dataMap.containsKey(player) && dataMap.get(player).equals(block)){
                player.closeInventory();
                remove(player);
            }
        }
       
        public boolean isPlayerCrouched(Player player){
            return player.isSneaking();
        }
       
        public void remove(Player player){
            for (Iterator<Player> iterator = players.iterator(); iterator.hasNext(); ) {
                Player p = iterator.next();
                if(player.equals(p)){
                    iterator.remove();
                    dataMap.remove(p);
                }
            }
        }
    }
    
    And here is the error:
    Code:
    2015-06-22 14:53:30 [SEVERE] Could not pass event BlockBreakEvent to GuiCloser v1.0
    org.bukkit.event.EventException
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:437)
    at org.bukkit.plugin.RegisteredListener.callEvent(RegisteredListener.java:62)
    at org.bukkit.plugin.TimedRegisteredListener.callEvent(TimedRegisteredListener.java:31)
    at org.bukkit.plugin.SimplePluginManager.fireEvent(SimplePluginManager.java:479)
    at org.bukkit.plugin.SimplePluginManager.callEvent(SimplePluginManager.java:464)
    at org.bukkit.craftbukkit.v1_6_R3.event.CraftEventFactory.callBlockBreakEvent(CraftEventFactory.java:807)
    at net.minecraftforge.event.world.BlockEvent$BreakEvent.<init>(BlockEvent.java:77)
    at net.minecraftforge.common.ForgeHooks.onBlockBreakEvent(ForgeHooks.java:472)
    at net.minecraft.item.ItemInWorldManager.func_73084_b(ItemInWorldManager.java:361)
    at net.minecraft.item.ItemInWorldManager.func_73074_a(ItemInWorldManager.java:200)
    at net.minecraft.network.NetServerHandler.func_72510_a(NetServerHandler.java:771)
    at net.minecraft.network.packet.Packet14BlockDig.func_73279_a(Packet14BlockDig.java:67)
    at net.minecraft.network.TcpConnection.func_74428_b(TcpConnection.java:470)
    at net.minecraft.network.NetServerHandler.func_72570_d(NetServerHandler.java:233)
    at net.minecraft.network.NetworkListenThread.func_71747_b(NetworkListenThread.java:54)
    at net.minecraft.server.dedicated.DedicatedServerListenThread.func_71747_b(DedicatedServerListenThread.java:34)
    at net.minecraft.server.MinecraftServer.func_71190_q(MinecraftServer.java:910)
    at net.minecraft.server.dedicated.DedicatedServer.func_71190_q(DedicatedServer.java:330)
    at net.minecraft.server.MinecraftServer.func_71217_p(MinecraftServer.java:777)
    at net.minecraft.server.MinecraftServer.run(MinecraftServer.java:659)
    at net.minecraft.server.ThreadMinecraftServer.run(ThreadMinecraftServer.java:16)
    Caused by: java.util.ConcurrentModificationException
    at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
    at java.util.ArrayList$Itr.next(Unknown Source)
    at me.woofyy.guicloser.BlockBreakListener.onBlockBreak(BlockBreakListener.java:41)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at org.bukkit.plugin.java.JavaPluginLoader$1.execute(JavaPluginLoader.java:435)
    ... 20 more
     
  2. What I think will help is to instead using an iterator, use a for loop with an int that counts from 0 to the size of the list, and just use the get(int) method in the list. Another thing is that you store the Player class in the list. This is not recommended, and a better way is to save the uuid (getUniqueId()) in the list, and use Bukkit.getPlayer(uuid) to get the player.
     
  3. Offline

    Konato_K

    @ImSxYN An iterator allows you to remove an element from the collection (if supported) from the same iterator, in your case, you're calling guiClose, which then calls remove(Player), which gets another iterator and removes, but the iterator in the block break event is still trying to iterate, then something disappears to it and it complains.

    Basically, stop trying to remove the element in a different iterator.


    @Bram0101 There is no reason to use a for loop.
     
  4. Offline

    ImSxYN

    Thank you for the help. I ended up figuring it out after I got some sleep xD But I really appreciate it!
     
Thread Status:
Not open for further replies.

Share This Page