ConcurrentModificationException?

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

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

    ImSxYN

    I have fixed the last errors and now I am getting these errors whenever a player clicks a block in the banned list or breaks a block in the banned list.

    Code:
    2015-06-21 17:24:03 [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:42)
    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
    2015-06-21 17:24:04 [SEVERE] Could not pass event PlayerInteractEvent 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.callPlayerInteractEvent(CraftEventFactory.java:217)
    at net.minecraft.item.ItemInWorldManager.func_73078_a(ItemInWorldManager.java:482)
    at net.minecraft.network.NetServerHandler.func_72472_a(NetServerHandler.java:896)
    at net.minecraft.network.packet.Packet15Place.func_73279_a(Packet15Place.java:79)
    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.onPlayerInteract(BlockBreakListener.java:68)
    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)
    ... 17 more
    Here is the java code associated with the errors. I see that the errors are on my ArrayLists but I'm not sure what to do about them:

    Code:
    package me.woofyy.guicloser;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    
    import org.bukkit.Bukkit;
    import org.bukkit.Material;
    import org.bukkit.block.Block;
    import org.bukkit.entity.HumanEntity;
    import org.bukkit.entity.Player;
    import org.bukkit.event.EventException;
    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.inventory.InventoryOpenEvent;
    import org.bukkit.event.player.PlayerInteractEvent;
    import org.bukkit.inventory.Inventory;
    
    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 (Player player: players) {
                if (GuiCloser.blockInfo.contains(eventblock.toString())) {
                    guiClose(player, 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)){
                        dataMap.remove(eplayer);
                        players.remove(eplayer);
                    }
                }
                for (Player player: players) {
                    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() == 1 && isPlayerCrouched(eplayer) && !(GuiCloser.blockInfo.contains(eventblock.toString()))){
                        guiClose(player, item);
                    }
                }
            }
    
        }
      
        public void guiClose(Player player, Block block){
            if(dataMap.containsKey(player) && dataMap.get(player).equals(block)){
                player.closeInventory();
                dataMap.remove(player);
                players.remove(player);
            }
        }
      
        public boolean isPlayerCrouched(Player player){
            return player.isSneaking();
        }
    }
    
    Ignore the marked out part. I don't actually use it. It's just there in case I feel like it

    --

    Ive heard that you can use Iterators to fix this but im unsure how toi use them in this code. Can anyone help me?


    {{Posts merged by Myrathi}}
     
    Last edited by a moderator: Jun 20, 2015
  2. Offline

    Totom3

    @ImSxYN The error is caused because an element was removed from the list while you were iterating on it.

    Code:
    for (Player player : players) {
        if ([...]) {
            guiClose(player, item);
        }
    }
    In the first line, an iterator is internally created so you can iterate over the elements of players. If the condition passes, guiClose() is called. Problem is that guiClose() removes the given player from players. If we then come back to the loop, the iterator notices an element was removed from the collection, and throws an exception.

    How to fix: it is possible to remove elements from a collection while iterating over it by using the iterator's remove() method. Instead of making a call to guiClose(), do the same checks in the method and use the iterator's remove method. You will also need to use an iterator loop instead of a for-each loop.
     
  3. Offline

    teej107

    You can still use for-each loops with Iterators.
    Code:
    for(Iterator itr = <someIterator>; itr.hasNext();)
    {}......
     
  4. Offline

    Totom3

    @teej107 That is not a for-each loop though
     
  5. Offline

    teej107

    Derp me of course
     
    Totom3 likes this.
Thread Status:
Not open for further replies.

Share This Page