We have a plugin system with multiple module layers:
The PluginLoader
module inside the boot layer instantiates a custom ModuleLayer
for each Module
at runtime with ModuleLayer::defineModulesWithOneLoader
.
We now have a set of non-modular plugins that need access to the modular plugins inside the custom layers. They will be loaded after the custom layers have been instantiated. How can this be achieved?
Simply putting them on the classpath doesn't work, since the modular classes will be loaded a second time instead of using the (already loaded) classes from the modular plugins.
Our next try was creating a dummy plugin and loading it last inside a layer that has all other layers (and therefore modular plugins) as parents. It doesn't seem to be possible to add URLs to the class loader generated by the defineModulesWithOneLoader
method. Instead we created a custom URLClassLoader as a parent of this class loader and added the non-modular JARs via URLClassLoader::addURL
.
This works for the non-modular plugin classes. However, if a class already loaded in one of the modular plugins is referenced from such a class, it will also attempt to load the class with our custom URLClassLoader
(which fails, since the parent is null
) instead of the module's internal class loader, which delegates to parent layers. Is there a way to load our non-modular plugin's classes inside the unnamed module of a class loader that behaves like the JPMS' default class loader (search parent layers first) but still loads the classes inside the non-modular JAR, if they aren't found in the parent layers?
It is possible to solve this by using automatic modules, but we want to avoid this for now since it leads to a slew of other necessary changes (e.g. resolve split packages) which we currently don't have the resources for.