Alvin-LB / NameTagChanger

Library to be shaded into Bukkit Plugins to allow for modification of player name tags.
MIT License
31 stars 10 forks source link

Prevent ConcurrentModificationEx. in disable() #4

Closed Xesau closed 6 years ago

Xesau commented 6 years ago

ConcurrentModificationExceptions can occur when a HashMap is modified while being iterated through. By first wrapping the gameProfiles.keySet() in an ArrayList, the HashMap is not modified while iterating through it. I'm not sure if this is the perfect solution, but it should do the job just fine.

Alvin-LB commented 6 years ago

You are right. It is probably wise to do something like this, even though it seems to work without it. Have you found any instances where a ConcurrentModificationException is actually thrown?

Xesau commented 6 years ago

Yes, a few times.

Alvin-LB commented 6 years ago

Can you give an example of when? A stacktrace perhaps? It would be good if I could reproduce it.

AxeVillager commented 6 years ago

A ConcurrentModificationException occurs when the plugin RolePlayName (the plugin that uses NameTagChanger v1.1-SNAPSHOT) disables (reload/shutdown) and there are two or more players online that have changed their nametag.

Plugins installed: RolePlayName and ProtocolLib version 4.4.0-SNAPSHOT-b399.

[11:54:00 WARN]: java.util.ConcurrentModificationException
[11:54:00 WARN]:        at java.util.HashMap$HashIterator.nextNode(Unknown Source)
[11:54:00 WARN]:        at java.util.HashMap$KeyIterator.next(Unknown Source)
[11:54:00 WARN]:        at com.bringholm.nametagchanger.NameTagChanger.disable(NameTagChanger.java:331)
[11:54:00 WARN]:        at com.axevillager.roleplayname.Main.disableNameTagChanger(Main.java:75)
[11:54:00 WARN]:        at com.axevillager.roleplayname.Main.onDisable(Main.java:42)
[11:54:00 WARN]:        at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:266)
[11:54:00 WARN]:        at org.bukkit.plugin.java.JavaPluginLoader.disablePlugin(JavaPluginLoader.java:361)
[11:54:00 WARN]:        at org.bukkit.plugin.SimplePluginManager.disablePlugin(SimplePluginManager.java:422)
[11:54:00 WARN]:        at org.bukkit.plugin.SimplePluginManager.disablePlugins(SimplePluginManager.java:415)
[11:54:00 WARN]:        at org.bukkit.plugin.SimplePluginManager.clearPlugins(SimplePluginManager.java:456)
[11:54:00 WARN]:        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.reload(CraftServer.java:720)
[11:54:00 WARN]:        at org.bukkit.Bukkit.reload(Bukkit.java:525)
[11:54:00 WARN]:        at org.bukkit.command.defaults.ReloadCommand.execute(ReloadCommand.java:27)
[11:54:00 WARN]:        at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141)
[11:54:00 WARN]:        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.dispatchCommand(CraftServer.java:649)
[11:54:00 WARN]:        at org.bukkit.craftbukkit.v1_12_R1.CraftServer.dispatchServerCommand(CraftServer.java:635)
[11:54:00 WARN]:        at net.minecraft.server.v1_12_R1.DedicatedServer.aP(DedicatedServer.java:444)
[11:54:00 WARN]:        at net.minecraft.server.v1_12_R1.DedicatedServer.D(DedicatedServer.java:407)
[11:54:00 WARN]:        at net.minecraft.server.v1_12_R1.MinecraftServer.C(MinecraftServer.java:679)
[11:54:00 WARN]:        at net.minecraft.server.v1_12_R1.MinecraftServer.run(MinecraftServer.java:577)
[11:54:00 WARN]:        at java.lang.Thread.run(Unknown Source)
Alvin-LB commented 6 years ago

Okay thank you, I managed to replicate the issue myself now (the issue doesn't occur if you only test with one player).

Having adjusted some formatting, I'll merge this now.