Question about java.system.class.loader and the module system
Volker Simonis
volker.simonis at gmail.com
Wed Mar 3 10:43:19 UTC 2021
Hi,
I have a question about how changing the system class loader by
setting "java.system.class.loader" interacts with the module system. I
couldn't find a lot of information on this topic but if it has been
discussed before please point me to the corresponding place.
Traditionally, setting "java.system.class.loader" to the name of a
class loader will instruct the JVM to use that class loader as the
system class loader which will be used to load the application main
class. But this class loader has to be loaded itself by a class
loader. So the JVM defines its own "default system class loader" which
will be used to load the custom system class loader and which will act
as delegation parent for it [1]. By writing a custom class loader
which intercepts calls to loadClass() and defining it as the system
class loader by setting "java.system.class.loader" it can be easily
verified that the JVM will load the applications main class with that
custom class loader.
This behaviour changes however if we use the new module syntax "-m
<module>/<class>" to start an application. In that case, the main
application class will always be loaded by the default system class
loader, no matter if we define "java.system.class.loader" or not.
>From what I've found by looking into the sources, this is because the
application module will be added to the boot layer and associated with
the default system class loader early in the JVM boot process (i.e.
"initPhase2") when only classes from java.base can be loaded and the
custom class loader is therefore not available. The system class
loader is only initialized later in "initiPhase3" at which it seems to
be already to late to associate it with the application module (is
this really the case?).
My question now is if this is an inherent property of the module
system or merely an implementation detail? I.e. would it be possible
to put the application module into its own layer and initialize that
only later when the custom system class loader will be available? I
think this would be relatively easy if the custom class loader can be
found on the class path. If the custom class loader is in a module
itself, that module would have to be in the boot layer to make it
accessible to the default system class loader.
The current API documentation of the system class loader [1] mentions
that the system class loader "is typically the class loader used to
start the application". Shouldn't that be updated to mention that this
will not be the case for modular applications?
Thank you and best regards,
Volker
[1] https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/ClassLoader.html#getSystemClassLoader()
More information about the core-libs-dev
mailing list