Skip to content
This repository has been archived by the owner on Dec 28, 2021. It is now read-only.

Commit

Permalink
Ease ClassLoader Deadlocks Where Possible
Browse files Browse the repository at this point in the history
When on 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.
  • Loading branch information
md-5 authored and SpigotMC committed Jul 19, 2014
1 parent 28093f9 commit 0cd44c5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 2 deletions.
2 changes: 1 addition & 1 deletion src/main/java/org/bukkit/plugin/java/JavaPluginLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
public final class JavaPluginLoader implements PluginLoader {
final Server server;
private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), };
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
private final Map<String, Class<?>> classes = new java.util.concurrent.ConcurrentHashMap<String, Class<?>>(); // Spigot
private final Map<String, PluginClassLoader> loaders = new LinkedHashMap<String, PluginClassLoader>();
public static final CustomTimingsHandler pluginParentTimer = new CustomTimingsHandler("** Plugins"); // Spigot

Expand Down
23 changes: 22 additions & 1 deletion src/main/java/org/bukkit/plugin/java/PluginClassLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,35 @@
*/
final class PluginClassLoader extends URLClassLoader {
private final JavaPluginLoader loader;
private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>();
private final Map<String, Class<?>> classes = new java.util.concurrent.ConcurrentHashMap<String, Class<?>>(); // Spigot
private final PluginDescriptionFile description;
private final File dataFolder;
private final File file;
final JavaPlugin plugin;
private JavaPlugin pluginInit;
private IllegalStateException pluginState;

// Spigot Start
static
{
try
{
java.lang.reflect.Method method = ClassLoader.class.getDeclaredMethod( "registerAsParallelCapable" );
if ( method != null )
{
boolean oldAccessible = method.isAccessible();
method.setAccessible( true );
method.invoke( null );
method.setAccessible( oldAccessible );
org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.INFO, "Set PluginClassLoader as parallel capable" );
}
} catch ( Exception ex )
{
org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.WARNING, "Error setting PluginClassLoader as parallel capable", ex );
}
}
// Spigot End

PluginClassLoader(final JavaPluginLoader loader, final ClassLoader parent, final PluginDescriptionFile description, final File dataFolder, final File file) throws InvalidPluginException, MalformedURLException {
super(new URL[] {file.toURI().toURL()}, parent);
Validate.notNull(loader, "Loader cannot be null");
Expand Down

0 comments on commit 0cd44c5

Please sign in to comment.