1.15.2 NoClassDefFound for org.bukkit.event.Listener when configuring the spring context

Discussion in 'Spigot Plugin Development' started by cc007, Mar 12, 2020.

  1. I am using mcspring-boot so that I am able to use spring in my spigot plugin, however this seems to break in the latest versions, giving me a ClassDefNotFounfException for org.bukkit.event.Listener.

    I explained here that it only happens in 1.15.1 and later. (I was told there to create my own post, so that's why I am making this one). Here is the code I used:

    Code (Text):
    public class HeadsPlugin extends JavaPlugin {

       ...

        @Override
        public void onLoad() {
            springClassLoaders = new ArrayList<>();
            getLogger().info("Added class loader to HeadsPlugin springClassLoaders");
            springClassLoaders.add(getClassLoader());
        }

        @Override
        public void onEnable() {
            // configure the class loader and run the spring application
            defaultClassLoader = Thread.currentThread().getContextClassLoader();
            ClassLoader classLoader = new CompoundClassLoader(springClassLoaders);
            Thread.currentThread().setContextClassLoader(classLoader);
            ResourceLoader loader = new DefaultResourceLoader(classLoader);
            SpringApplication application = new SpringApplication(loader, Application.class);
            application.addInitializers(new SpringSpigotInitializer(this));
            springContext = application.run();
        }

        ...

    }
    This code works fine in 1.13.2, 1.14.4 and 1.15, but in 1.15.1 and 1.15.2 it consistently fails.

    The other thread also contains info about someone else who has what I think is the same issue after setting the classloader of a spring context.
     
    #1 cc007, Mar 12, 2020
    Last edited: Mar 12, 2020
  2. I found a solution to the problem, but I don't know yet why this solution was only needed in 1.15.1 and newer.
    What I did was also add
    Code (Text):
    Thread.currentThread().getContextClassLoader();
    to the springClassLoaders. Apparently something changed in the PluginClassLoader so that it doesn't default to this current thread context class loader anymore if it can't find the class.

    This is a regression. I might add an issue to the issue tracker later, unless an spigot dev replies that they already are going to look into this.