ConcurrentModificationException on Disable

Discussion in 'Plugin Development' started by xYourFreindx, Jun 12, 2014.

Thread Status:
Not open for further replies.
  1. Before disabling my plugin, I need to be able to kick everyone out of cameramode, and set them back to their previous state.​
    For obvious reasons.​
    But every time I run the below code, WHILE a player is in cameramode, it throws an exception.​
    As far as I can tell, it doesn't seem to effect what I'm trying to do, and it still gets done.​
    So I just catch the error.​
    But I'd like to know if I could avoid it all together, instead of hiding it.​
    If you can see something, I'm unable to, in here, please let me know.​
    Code:java
    1.  
    2. try{
    3. for (String se : main.flyplayers){
    4. UUID blah = UUID.fromString(se);
    5. Player p = main.getServer().getPlayer(blah);
    6. if(main.flyplayers.contains(p.getUniqueId().toString()) && p.getGameMode() == (GameMode.SURVIVAL)) {
    7. p.setAllowFlight(false);
    8. Location loc = main.locations.get(p.getUniqueId().toString());
    9. p.teleport(new Location (loc.getWorld(),loc.getX(),loc.getY(),loc.getZ(),loc.getYaw(),loc.getPitch()));
    10. main.flyplayers.remove(p.getUniqueId().toString());
    11. p.addPotionEffects(main.effects.get(p.getUniqueId().toString()));
    12. p.sendMessage(ChatColor.RED + "You are no longer in CameraMode!");
    13. int Fireup = main.fireticks.get(p.getUniqueId().toString()).intValue();
    14. p.setFireTicks(Fireup);
    15. p.setFallDistance(main.falldistance.get(p.getUniqueId().toString()));
    16. int air = main.breath.get(p.getUniqueId().toString()).intValue();
    17. p.setRemainingAir(air);
    18. p.setVelocity(main.vel.get(p.getUniqueId().toString()));
    19. for (Player pl : Bukkit.getServer().getOnlinePlayers()) {
    20. pl.showPlayer(p);
    21. }
    22. }else if (main.flyplayers.contains(p.getUniqueId().toString()) && p.getGameMode() == (GameMode.CREATIVE)) {
    23. main.flyplayers.remove(p.getUniqueId().toString());
    24. int Fireup = main.fireticks.get(p.getUniqueId().toString()).intValue();
    25. p.setFireTicks(Fireup);
    26. int air = main.breath.get(p.getUniqueId().toString()).intValue();
    27. p.setRemainingAir(air);
    28. Location loc = main.locations.get(p.getUniqueId().toString());
    29. p.setFallDistance(main.falldistance.get(p.getUniqueId().toString()));
    30. p.teleport(new Location (loc.getWorld(),loc.getX(),loc.getY(),loc.getZ(),loc.getYaw(),loc.getPitch()));
    31. p.setVelocity(main.vel.get(p.getUniqueId().toString()));
    32. p.sendMessage(ChatColor.RED + "You are no longer in CameraMode!");
    33. p.addPotionEffects(main.effects.get(p.getUniqueId().toString()));
    34. for (Player pl : Bukkit.getServer().getOnlinePlayers()) {
    35. pl.showPlayer(p);
    36. }
    37. }
    38. }
    39. main.getLogger().severe("Plugin Disabled With Players In CameraMode... Fixing...");
    40. }
     
  2. Offline

    xTigerRebornx

    xYourFreindx The error is thrown because you are trying to remove an element from a list while you are iterating over it. It doesn't hurt to use Google once in awhile, you know :p
    Simply remove the element after you are done iterating
     
  3. Offline

    Tzeentchful

    Like xTigerRebornx said you are trying to remove an element form the collection while you are looping over it. If you want to remove an element from a collection while iterating over it you will want to use an iterator since it has a .remove() method to remove the current item.

    Here is an example i wrote up quickly.
    Code:java
    1. List<String> flyingPlayers = new ArrayList<Stirng>();
    2. flyingPlayers.add("Dinnerbone");
    3. flyingPlayers.add("Notch");
    4.  
    5. Iterator<String> iterator = flyingPlayers.iterator();
    6. while (iterator.hasNext()) {
    7. String player = iterator.next();
    8.  
    9. if (player.equalsIgnoreCase("Notch")) {
    10. iterator.remove();
    11. }
    12. }
     
  4. Offline

    Garris0n

    You can just store the UUIDs, you don't need to store them as strings.
     
  5. Garris0n
    I realize that.
    I realized that when I first started doing that.
    Yes, it's one more method I have to call... For every time I use the arraylist/hashmap.
    But when I first learned how to make them, I had run into a problem that required I use strings. And I've just started using it ever since, to avoid that problem again, should it have the opportunity to come up.
    Now that I'm "slightly" smarter with java, I realize that the problem I was having probably could have been solved in one simple casting, instead of creating all my plugins with the extra method. But now that they are all founded like that, and that I've been using them so long... It's hard to revert. A bad habit.

    xTigerRebornx I actually do use google. And I don't know why 1/2 the time, when someone asks a question that's obvious to the answerer, they automatically assume that the asker did no research. But, in this instance.. This guy did. Only, the conclusion I had come to after reading multilple forums, was that my plugin was calling for things to happen, even after it's been disabled. So I just assumed it probably couldn't be fixed (seing as I need those to be called), that's when I decided to add the try/ catch statement.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
  6. Offline

    Garris0n

    Every time you make any sort of collection, don't use a String in place of a UUID. Seems rather simple. It didn't take me any sort of conscious battle to switch from usernames to UUIDs...
     
    xYourFreindx likes this.
  7. Tzeentchful This is the first time I've heard of iterators like that.
    I'm not sure how to incorporate it into what I already have.
    So before I go and do what I think I should be doing.

    Would you suggest I delete the entire for loop and replace it with the while loop and the iterator?
    And how does the iterator interact with the arraylist itself? Would removing the object from the iterator also remove it from the arraylist, or vice versa? Or would I need to remove them both separately?


    I know... I'm an idiot.
    I just can't stand having half of my plugin use strings and the other half use UUIDs.
    The whole thing is a way of thought for me, and having to swap ways of thinking every time I use an arraylist or hashmap is scary to me. 0_o
    I'd like to just not have to think about what I'm doing, and get it done.
    Next time I begin a plugin, I'll begin it without using strings in place of uuids.
    Till then, or until I get enough time to clean up my mess... That's the way it's gunna look.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: Jun 8, 2016
  8. Offline

    Garris0n

    Fix the half that uses Strings.
     
  9.  
  10. Offline

    Tzeentchful

    xYourFreindx You can keep all your code you will just need to make a variable to replace the one in the for loop.
    So change
    Code:java
    1. for (String se : main.flyplayers) {

    To
    Code:java
    1. Iterator<String> iterator = main.flyplayers.iterator();
    2. while (iterator.hasNext()) {
    3. String se = iterator.next();
    4. ...


    Then just do:
    iterator.remove();
    When you want to remove the item.
     
  11. Code:java
    1.  
    2. @EventHandler
    3. public void onPluginDisable(PluginDisableEvent e){
    4. Iterator <String> iterator = main.flyplayers.iterator();
    5. while(iterator.hasNext()){
    6. UUID blah = UUID.fromString(iterator.next());
    7. Player p = main.getServer().getPlayer(blah);
    8. if(main.flyplayers.contains(p.getUniqueId().toString()) && p.getGameMode() == (GameMode.SURVIVAL)) {
    9. p.setAllowFlight(false);
    10. Location loc = main.locations.get(p.getUniqueId().toString());
    11. p.teleport(new Location (loc.getWorld(),loc.getX(),loc.getY(),loc.getZ(),loc.getYaw(),loc.getPitch()));
    12. p.addPotionEffects(main.effects.get(p.getUniqueId().toString()));
    13. p.sendMessage(ChatColor.RED + "You are no longer in CameraMode!");
    14. int Fireup = main.fireticks.get(p.getUniqueId().toString()).intValue();
    15. p.setFireTicks(Fireup);
    16. p.setFallDistance(main.falldistance.get(p.getUniqueId().toString()));
    17. int air = main.breath.get(p.getUniqueId().toString()).intValue();
    18. p.setRemainingAir(air);
    19. p.setVelocity(main.vel.get(p.getUniqueId().toString()));
    20. for (Player pl : Bukkit.getServer().getOnlinePlayers()) {
    21. pl.showPlayer(p);
    22. }
    23. }else if (main.flyplayers.contains(p.getUniqueId().toString()) && p.getGameMode() == (GameMode.CREATIVE)) {
    24. int Fireup = main.fireticks.get(p.getUniqueId().toString()).intValue();
    25. p.setFireTicks(Fireup);
    26. int air = main.breath.get(p.getUniqueId().toString()).intValue();
    27. p.setRemainingAir(air);
    28. Location loc = main.locations.get(p.getUniqueId().toString());
    29. p.setFallDistance(main.falldistance.get(p.getUniqueId().toString()));
    30. p.teleport(new Location (loc.getWorld(),loc.getX(),loc.getY(),loc.getZ(),loc.getYaw(),loc.getPitch()));
    31. p.setVelocity(main.vel.get(p.getUniqueId().toString()));
    32. p.sendMessage(ChatColor.RED + "You are no longer in CameraMode!");
    33. p.addPotionEffects(main.effects.get(p.getUniqueId().toString()));
    34. for (Player pl : Bukkit.getServer().getOnlinePlayers()) {
    35. pl.showPlayer(p);
    36. }
    37. }
    38. iterator.remove();
    39. }
    40. }



    This "seems" to work.
    Do you see any problems with how I've set it up? ​
     
  12. Offline

    xize

    xYourFreindx
    sorry to ask this but could I ask how the List is instanced? I'm not seeing a stacktrace nor which line this error is throwing, it could or by iterating or by something else.

    are you trying to modificate the List from a other thread or is your instance maybe called final in a way it cannot be modified but is called in a anonymous way such like static?, I don't really know but ive once gotten a ConcurentModificationException just by using a final field but I guess it also count I was using it in a static context which I may did wrong.
     
  13. Offline

    Tzeentchful

    xYourFreindx Yeah that looks fine let me know if it doen't work.
     
Thread Status:
Not open for further replies.

Share This Page