Uploaded image for project: 'Spigot'
  1. Spigot
  2. SPIGOT-3734

CLONE - Exception due to call ClassLoader.definePackage in PluginClassLoader

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: Major Major
    • None
    • None
    • None
    • Spigot 1.12.2

      Hi!

      Spigot 1.12.2

      "name": "1485",
      "description": "Jenkins build 1485",
      "BuildData": "a9c4523879abc011821f06283dd468c67c3b0097",
      "Bukkit": "07afa3d58b1869147b5e6b44e1227001512a68d1",
      "CraftBukkit": "e40c9ef4b981612e94e3ea4b980060cb442d630c",
      "Spigot": "325fbc7f164aeab1f169e47374a9bdd0d67cc8ba"
      "toolsVersion": 47

       

      Sometimes getServer().getPluginManager().registerEvents throws exception
      java.lang.IllegalArgumentException: me.myplugin.mypackage

      I think this is due to concurrent call ClassLoder.definePackage in PluginClassLoader.findClass

      Details:

      My plugin class:
      public class MyPlugin extends JavaPlugin implements Listener { ...

      function: public void onEnable() { ...

      I call: getServer().getPluginManager().registerEvents(this, this);

      But before this I start new thread which access static member in some class (let's name it "ClassA" in package "me.myplugin.mypackage")
      public class ClassA { public static List LIST = new ArrayList(); }

      So, PluginClassLoader.findClass in main thread calls definePackage simultaneously with implicitly defining package in new thread

      My code in onEnable looks like:

       

      new Thread(new Runnable() { @Override public void run() { 
         while(something) ChunkCache.LIST.doSomething(); 
      }}).start();
      getServer().getPluginManager().registerEvents(this, this);
      

      PluginClassLoader.findClass line 130

       

       

      if (getPackage(pkgName) == null) {
        if (manifest != null) {
          definePackage(pkgName, manifest, url);
        } else {
          definePackage(pkgName, null, null, null, null, null, null, null);
        }
      }
      

      What happens:
      1. getPackage(pkgName) returns null - ok, no package has been define yet
      2. At this moment my new thread calls ChunkCache.LIST.size() and java implicitly defines package as it has not been initialized yet (first time to access class in program)
      3. PluginClassLoader.findClass calls definePackage(...) and "IllegalArgumentException" is occured, because package is already defined!

      To prevent this error I have made a stub:

      // workaround concurrent ClassLoader.definePackage due to registerEvents (just do something with class)
      ChunkCache.LIST.size(); 
      
      new Thread(new Runnable() { @Override public void run() { 
          while(something) ChunkCache.LIST.doSomething(); 
      }}).start();
      getServer().getPluginManager().registerEvents(this, this);
      

      But this is not solution. It is a stub

      May be do in PluginClassLoader.findClass something like:

      try{ definePackage(...); } catch(IllegalArgumentException ignore){} ?  

      Thanks that you have read until this line 

            Unassigned Unassigned
            serjproch Serj
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: