From 2f1a8059319834f98072ea7988feae14fbb6bc7d Mon Sep 17 00:00:00 2001 From: Bukkit/Spigot Date: Wed, 26 Dec 2018 08:00:00 +1100 Subject: [PATCH] Ease ClassLoader Deadlocks Where Possible With Java 7 we can register the classloader as parallel capable to prevent deadlocks caused by certain scenarios. Due to the nature of PluginClassLoader this isn't completely safe, but we can make it safer by switching to concurrency focused collections. Either way this is far better than crashing the server. By: md_5 --- .../java/org/bukkit/plugin/java/JavaPluginLoader.java | 3 ++- .../java/org/bukkit/plugin/java/PluginClassLoader.java | 8 ++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java index 8d54297fa5..9589014ab8 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java @@ -12,6 +12,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.jar.JarEntry; import java.util.jar.JarFile; @@ -48,7 +49,7 @@ import org.yaml.snakeyaml.error.YAMLException; public final class JavaPluginLoader implements PluginLoader { final Server server; private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), }; - private final Map> classes = new HashMap>(); + private final Map> classes = new ConcurrentHashMap>(); private final List loaders = new CopyOnWriteArrayList(); /** diff --git a/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java b/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java index 154481af1f..7a8abe75ad 100644 --- a/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java +++ b/paper-api/src/main/java/org/bukkit/plugin/java/PluginClassLoader.java @@ -9,9 +9,9 @@ import java.net.URL; import java.net.URLClassLoader; import java.security.CodeSigner; import java.security.CodeSource; -import java.util.HashMap; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.Manifest; @@ -25,7 +25,7 @@ import org.bukkit.plugin.PluginDescriptionFile; */ final class PluginClassLoader extends URLClassLoader { private final JavaPluginLoader loader; - private final Map> classes = new HashMap>(); + private final Map> classes = new ConcurrentHashMap>(); private final PluginDescriptionFile description; private final File dataFolder; private final File file; @@ -36,6 +36,10 @@ final class PluginClassLoader extends URLClassLoader { private JavaPlugin pluginInit; private IllegalStateException pluginState; + static { + ClassLoader.registerAsParallelCapable(); + } + PluginClassLoader(final JavaPluginLoader loader, final ClassLoader parent, final PluginDescriptionFile description, final File dataFolder, final File file) throws IOException, InvalidPluginException, MalformedURLException { super(new URL[] {file.toURI().toURL()}, parent); Validate.notNull(loader, "Loader cannot be null");