[SPIGOT-461] getOfflinePlayer(String) is blocking yet not thread-safe Created: 22/Jan/15 Updated: 07/Jun/15 Resolved: 07/Jun/15 |
|
Status: | Resolved |
Project: | Spigot |
Component/s: | None |
Affects Version/s: | None |
Fix Version/s: | None |
Type: | Bug | Priority: | Minor |
Reporter: | Matt Harris | Assignee: | md_5 |
Resolution: | Fixed | Votes: | 4 |
Labels: | craftbukkit |
Issue Links: |
|
Description |
Spoke to md_5 on IRC about getOfflinePlayer(String) not being thread-safe. If a method is blocking, it is supposed to be thread-safe otherwise he says it is considered to be a bug. I wrote a simple plugin to observe failed attempts to invoke getOfflinePlayer() from multiple async tasks: GetOfflinePlayerAsyncTest.java package net.minelink.gopat; import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.plugin.java.JavaPlugin; import java.util.UUID; public class GetOfflinePlayerAsyncTest extends JavaPlugin { @Override public boolean onCommand(final CommandSender sender, Command command, String label, String[] args) { for (int i = 0; i < 3; ++i) { Bukkit.getScheduler().runTaskLaterAsynchronously(this, new Runnable() { @Override public void run() { Bukkit.getOfflinePlayer(UUID.randomUUID().toString().substring(0, 15)); } }, 1); } return true; } } Invoking the above code will produce one of three outcomes:
The stack traces observed in the console are as follows: ConcurrentModificationException [23:55:17 WARN]: Exception in thread "Craft Scheduler Thread - 0" [23:55:17 WARN]: org.apache.commons.lang.UnhandledException: Plugin GetOfflinePlayerAsyncTest v0.0.1-SNAPSHOT generated an exception while executing task 28 at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:56) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: java.util.ConcurrentModificationException at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:953) at java.util.LinkedList$ListItr.next(LinkedList.java:886) at com.google.common.collect.Iterators$9.next(Iterators.java:939) at com.google.common.collect.Iterators.addAll(Iterators.java:357) at com.google.common.collect.Lists.newArrayList(Lists.java:147) at net.minecraft.server.v1_8_R1.UserCache.a(UserCache.java:213) at net.minecraft.server.v1_8_R1.UserCache.c(UserCache.java:194) at net.minecraft.server.v1_8_R1.UserCache.getProfile(UserCache.java:123) at org.bukkit.craftbukkit.v1_8_R1.CraftServer.getOfflinePlayer(CraftServer.java:1288) at org.bukkit.Bukkit.getOfflinePlayer(Bukkit.java:741) at net.minelink.gopat.GetOfflinePlayerAsyncTest$1.run(GetOfflinePlayerAsyncTest.java:19) at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftTask.run(CraftTask.java:71) at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:53) NullPointerException [23:55:22 WARN]: Exception in thread "Craft Scheduler Thread - 3" [23:55:22 WARN]: org.apache.commons.lang.UnhandledException: Plugin GetOfflinePlayerAsyncTest v0.0.1-SNAPSHOT generated an exception while executing task 35 at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:56) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) at java.lang.Thread.run(Thread.java:745) Caused by: java.lang.NullPointerException at java.util.LinkedList$ListItr.next(LinkedList.java:891) at com.google.common.collect.Iterators$9.next(Iterators.java:939) at com.google.common.collect.Iterators.addAll(Iterators.java:357) at com.google.common.collect.Lists.newArrayList(Lists.java:147) at net.minecraft.server.v1_8_R1.UserCache.a(UserCache.java:213) at net.minecraft.server.v1_8_R1.UserCache.c(UserCache.java:194) at net.minecraft.server.v1_8_R1.UserCache.getProfile(UserCache.java:123) at org.bukkit.craftbukkit.v1_8_R1.CraftServer.getOfflinePlayer(CraftServer.java:1288) at org.bukkit.Bukkit.getOfflinePlayer(Bukkit.java:741) at net.minelink.gopat.GetOfflinePlayerAsyncTest$1.run(GetOfflinePlayerAsyncTest.java:19) at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftTask.run(CraftTask.java:71) at org.bukkit.craftbukkit.v1_8_R1.scheduler.CraftAsyncTask.run(CraftAsyncTask.java:53) |
Comments |
Comment by mibby mibster [ 26/May/15 ] |
Any update to this? Still an on-going issue with 1.8.6. Spigot 1.8.6 git-Spigot-6a6b839-b0e81a4 [23:10:18] [Server thread/INFO]: [ChestShop] Enabling ChestShop v3.8.8 [23:10:18] [Server thread/ERROR]: Error occurred while enabling ChestShop v3.8.8 (Is it up to date?) java.util.ConcurrentModificationException at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966) ~[?:1.8.0_45] at java.util.LinkedList$ListItr.next(LinkedList.java:888) ~[?:1.8.0_45] at com.google.common.collect.Iterators$9.next(Iterators.java:939) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at com.google.common.collect.Iterators.addAll(Iterators.java:357) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at com.google.common.collect.Lists.newArrayList(Lists.java:147) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.UserCache.a(UserCache.java:235) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.UserCache.c(UserCache.java:216) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.UserCache.getProfile(UserCache.java:152) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at org.bukkit.craftbukkit.v1_8_R3.CraftServer.getOfflinePlayer(CraftServer.java:1304) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at org.bukkit.Bukkit.getOfflinePlayer(Bukkit.java:741) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at com.Acrobot.ChestShop.UUIDs.NameManager.load(NameManager.java:234) ~[?:?] at com.Acrobot.ChestShop.ChestShop.onEnable(ChestShop.java:95) ~[?:?] at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:321) ~[spigot.jar:git-Spigot-6a6b839-b0e81a4] at org.bukkit.plugin.java.JavaPluginLoader.enablePlugin(JavaPluginLoader.java:340) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at org.bukkit.plugin.SimplePluginManager.enablePlugin(SimplePluginManager.java:405) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at org.bukkit.craftbukkit.v1_8_R3.CraftServer.loadPlugin(CraftServer.java:356) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at org.bukkit.craftbukkit.v1_8_R3.CraftServer.enablePlugins(CraftServer.java:316) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.MinecraftServer.s(MinecraftServer.java:418) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.MinecraftServer.k(MinecraftServer.java:382) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.MinecraftServer.a(MinecraftServer.java:337) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.DedicatedServer.init(DedicatedServer.java:256) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at net.minecraft.server.v1_8_R3.MinecraftServer.run(MinecraftServer.java:528) [spigot.jar:git-Spigot-6a6b839-b0e81a4] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_45] Also occasionally occurs with EnjinMinecraftPlugin v2.7.2 at startup. [19:30:44] [Server thread/WARN]: [EnjinMinecraftPlugin] Task #79 for EnjinMinecraftPlugin v2.7.2-bukkit generated an exception java.util.ConcurrentModificationException at java.util.LinkedList$ListItr.checkForComodification(LinkedList.java:966) ~[?:1.8.0_40] at java.util.LinkedList$ListItr.next(LinkedList.java:888) ~[?:1.8.0_40] at com.google.common.collect.Iterators$9.next(Iterators.java:939) ~[spigot.jar:git-Spigot-c136710-350cb99] at com.google.common.collect.Iterators.addAll(Iterators.java:357) ~[spigot.jar:git-Spigot-c136710-350cb99] at com.google.common.collect.Lists.newArrayList(Lists.java:147) ~[spigot.jar:git-Spigot-c136710-350cb99] at net.minecraft.server.v1_8_R2.UserCache.a(UserCache.java:243) ~[spigot.jar:git-Spigot-c136710-350cb99] at net.minecraft.server.v1_8_R2.UserCache.c(UserCache.java:224) ~[spigot.jar:git-Spigot-c136710-350cb99] at net.minecraft.server.v1_8_R2.UserCache.getProfile(UserCache.java:153) ~[spigot.jar:git-Spigot-c136710-350cb99] at org.bukkit.craftbukkit.v1_8_R2.CraftServer.getOfflinePlayer(CraftServer.java:1304) ~[spigot.jar:git-Spigot-c136710-350cb99] at org.bukkit.Bukkit.getOfflinePlayer(Bukkit.java:741) ~[spigot.jar:git-Spigot-c136710-350cb99] at com.enjin.officialplugin.EnjinMinecraftPlugin$1.run(EnjinMinecraftPlugin.java:862) ~[?:?] at org.bukkit.craftbukkit.v1_8_R2.scheduler.CraftTask.run(CraftTask.java:71) ~[spigot.jar:git-Spigot-c136710-350cb99] at org.bukkit.craftbukkit.v1_8_R2.scheduler.CraftScheduler.mainThreadHeartbeat(CraftScheduler.java:350) [spigot.jar:git-Spigot-c136710-350cb99] at net.minecraft.server.v1_8_R2.MinecraftServer.A(MinecraftServer.java:718) [spigot.jar:git-Spigot-c136710-350cb99] at net.minecraft.server.v1_8_R2.DedicatedServer.A(DedicatedServer.java:368) [spigot.jar:git-Spigot-c136710-350cb99] at net.minecraft.server.v1_8_R2.MinecraftServer.z(MinecraftServer.java:651) [spigot.jar:git-Spigot-c136710-350cb99] at net.minecraft.server.v1_8_R2.MinecraftServer.run(MinecraftServer.java:554) [spigot.jar:git-Spigot-c136710-350cb99] at java.lang.Thread.run(Thread.java:745) [?:1.8.0_40] |
Comment by mibby mibster [ 14/Mar/15 ] |
Would very much greatly appreciate getOfflinePlayer check becoming async and thread safe to prevent ConcurrentModificationExceptions on server startup. As I'm still experiencing this issue myself with Spigot 1.8.3 (git-Spigot-ea179b3-6e0120a) and ChestShops 3.8.5. |
Comment by mibby mibster [ 09/Mar/15 ] |
Any update to making this thread-safe? |