[SPIGOT-6419] Bukkit's wierd class loading logic Created: 09/Apr/21  Updated: 14/May/21  Resolved: 14/May/21

Status: Resolved
Project: Spigot
Component/s: None
Affects Version/s: None
Fix Version/s: None

Type: Bug Priority: Minor
Reporter: Yz Ren Assignee: Unassigned
Resolution: Fixed Votes: 0
Labels: None
Environment:

Windows 10 x64

 


Version: None
Guidelines Read: Yes

 Description   

The Bukkit class loader usually does fine and doesn't need to care, but the issue comes when two plugins contain the same lib (or two classes with exactly same name), the PluginClassLoader will attempt to load class from the previously loaded plugin if no cached class found, then load it from it's belonging plugin's file. If these two classes have different content, then the plugin would crash.

Normally this wouldn't happen, and two plugins shouldn't have classes with the same full name. But it is weird that class loader preferred to load classes from another jar rather than its own.

So this issue is mainly caused by logic in PluginClassLoader::findClass, it will try to find cached class from JavaPluginLoader and other PluginClassLoader first, then find bytecode file in its own jar. But finding class through all other plugins just for a cache doesn't seem to be more efficient than finding its own.

Another thing about PluginClassLoader is that it's the only option to load plugin, adding an option to allow developers to specify a custom class loader for their own plugin would be better. 

 

For example in Plugin A:

public class Test

{     public static void test() \{System.out.println("Test plugin A loaded!");}

}

public final class TestPluginA extends JavaPlugin

{ public void onEnable() \{System.out.println("Loading plugin A!");Test.test();}

}

 

And Plugin B:

public class Test

{     public static void test() \{System.out.println("Test plugin B loaded!");}

}

public final class TestPluginB extends JavaPlugin

{ public void onEnable() \{System.out.println("Loading plugin B!");Test.test();}

}

 

The two classes named Test are in the package com.example in two different plugin.

 

There're always a plugin that can print "Loading plugin A following" with "Test plugin A loaded".

Then another plugin will print "Loading plugin B following" with a Bukkit dependency warning and "Test plugin A loaded".

 

 

 



 Comments   
Comment by md_5 [ 14/May/21 ]

Should be resolved by the library support changes which have now been added

Comment by md_5 [ 11/Apr/21 ]

Yes this is known behaviour which results from plugins not being isolated from each other. There is slow work to improve this, for example since last year the plugin classloader will print a warning if it loads a class from a plugin which is not a (soft)depend.

Soon we are also adding the ability to load isolated plugins from Maven central. My current draft of this change actually more or less unintentionally fixes your issue of other plugin classes being preferred, but I need to think about the implications of this further now.

Generated at Tue Apr 22 06:38:51 UTC 2025 using Jira 10.3.5#10030005-sha1:190c783f2bd6c69cd5accdb70f97e48812a78d14.