Ano-Tech-Computers / TelePlugin

Basic teleport commands
MIT License
0 stars 0 forks source link

1.94: onDisable() crash #4

Closed FloydATC closed 9 years ago

FloydATC commented 9 years ago

plugman unload TelePlugin [19:06:58 INFO]: [TelePlugin] Disabling TelePlugin v1.94 [19:06:58 ERROR]: Error occurred while disabling TelePlugin v1.94 (Is it up to date?) java.lang.NoSuchMethodError: java.util.concurrent.ConcurrentHashMap.keySet()Ljava/util/concurrent/ConcurrentHashMap$KeySetView; at no.atc.floyd.bukkit.tele.TelePlugin.onDisable(TelePlugin.java:63) ~[?:?] at org.bukkit.plugin.java.JavaPlugin.setEnabled(JavaPlugin.java:323) ~[spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at org.bukkit.plugin.java.JavaPluginLoader.disablePlugin(JavaPluginLoader.java:359) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at org.bukkit.plugin.SimplePluginManager.disablePlugin(SimplePluginManager.java:424) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at com.ryanclancy000.plugman.utilities.Utilities.unloadPlugin(Utilities.java:366) [PlugMan.jar:?] at com.ryanclancy000.plugman.utilities.Utilities.unloadCommand(Utilities.java:313) [PlugMan.jar:?] at com.ryanclancy000.plugman.PlugManCommands.onCommand(PlugManCommands.java:70) [PlugMan.jar:?] at org.bukkit.command.PluginCommand.execute(PluginCommand.java:44) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at org.bukkit.command.SimpleCommandMap.dispatch(SimpleCommandMap.java:141) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at org.bukkit.craftbukkit.v1_8_R1.CraftServer.dispatchCommand(CraftServer.java:645) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at org.bukkit.craftbukkit.v1_8_R1.CraftServer.dispatchServerCommand(CraftServer.java:631) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at net.minecraft.server.v1_8_R1.DedicatedServer.aM(DedicatedServer.java:353) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at net.minecraft.server.v1_8_R1.DedicatedServer.z(DedicatedServer.java:317) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at net.minecraft.server.v1_8_R1.MinecraftServer.y(MinecraftServer.java:623) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at net.minecraft.server.v1_8_R1.MinecraftServer.run(MinecraftServer.java:526) [spigot-1.8.jar:git-Spigot-081dfa5-5e6c347] at java.lang.Thread.run(Thread.java:744) [?:1.7.0_51]

osvein commented 9 years ago

What JRE are you using?

I suspect a faulty build. Did you build it yourself?

osvein commented 9 years ago

@FloydATC, why are we using concurrent hash maps anyway?

FloydATC commented 9 years ago

Both the test and production servers run java-1.7.0-openjdk-1.7.0.51-2.4.5.5.el7.x86_64 Just downloaded the plugin, no recompile. ConcurrentHashMap is necessary because of multithreading, it takes care of all the nasty semaphore/locking stuff so we won't have to.

osvein commented 9 years ago

If I remember correctly, v1.94 was built using Oracle's JDK. Does the problem persist if you build using the JDK corresponding to your JRE?

In what other threads are the hash maps accessed?

osvein commented 9 years ago

A quick comparison of the Java SE 8 and 7 javadocs reveals the cause of the problem: The return type of ConcurrentHashMap<K, V>.keySet() has changed from Set<K> in version 7 to ConcurrentHashMap.KeySetView<K, V> in version 8. This should be a compatible change though. However, v1.94 was built using JDK 8 for JRE 7. See link.

FloydATC commented 9 years ago

In Minecraft there are two threads per player; one to handle networking and one dealing with in-game events such as combat, block interaction etc. These threads make callbacks into the various plugins, meaning that two or more players may run plugin code simultaneously. Because of this, all plugins must be thread-safe. Plugins that utilize non-thread-safe classes (such as HashMap instead of ConcurrentHashMap) will crash immediately if accessed simultaneously by more than one thread (=player).

I use a JDK7 environment for all plugin related work, because I couldn't get the code to compile on JDK8. Looks like you found one of the main reasons. I don't know if changing the syntax and building on JDK8 will cause issues on JRE7, my guess is it will work just fine. Why they would go and change a perfectly good syntax is beyond me.

osvein commented 9 years ago

The interface wasn't changed, it was extended. Thus the code written for JDK 7 will also compile on JDK 8. The new return type is derived from the old one.

FloydATC commented 9 years ago

No, it was changed. In the most evil way possible. The code will compile using JDK8 but crashes spectacularly when executed in a JRE7 environment because .keySet() no longer returns an iterable "Set" object but rather a "ConcurrentHashMap.keySetView" object which doesn't have the method needed for JRE7 to iterate through the set. https://bz.apache.org/bugzilla/show_bug.cgi?id=55554 Seems I'm not the only one stumped by this record breaking stupidity which seems so integral to everything Java related. Meanwhile, I have no idea how to solve this so I'll go back to building on my Linux laptop with JDK7.

FloydATC commented 9 years ago

Problem solved. JDK8 can be used but you must set "compliance level 1.7" and then install and select JRE7 to be used when compiling. The procedure has been tested successfully and is described here: http://forums.atc.no/index.php?topic=1868.0 Case closed.