Post by Milen Dyankov
So am I right to assume that any application server like software is
expected to always run on top of all standard JDK modules that export
"java.*" packages? I mean, say there is an application server that runs on
top of "minimal" JPMS created with jlink. If the base layer of that
application server does not have "java.sql" for example, there is
essentially no way for it to load it dynamically, when a JAR or WAR that
needs it is deployed, correct?
One thing to say is the restriction on the java.* class name space is
rooted in security and has been in the Java SE API specification for
many releases. The VM enforcement around this goes back to JDK 1.2 at
least. The specification was relaxed in Java SE 9 to allow java.*
classes be defined to the platform class loader but going further, to
allow java.* classes be defined by other class loaders, would require
Aside from java.base, there are 7 modules in Java SE with java.* APIs:
The long standing specified restriction on the java.* class name space
and the matching restrictions in the ModuleLayer API, mean that you
cannot load (or override) these 7 modules in a child layer created by
In your case, the main application (container / app server) doesn't
transitively require java.sql so this module is not in the boot layer.
It can't dynamically load it (because it contains a java.* classes) so
it has ensure that the above 7 modules are in the boot layer in order to
support dynamically loading of application modules that might require
one or more of these modules. In JEP 261 we document --add-modules
ALL-DEFAULT for this purpose:
"As a special case at run time, if <module> is ALL-DEFAULT then the
default set of root modules for the unnamed module, as defined above, is
added to the root set. This is useful when the application is a
container that hosts other applications which can, in turn, depend upon
modules not required by the container itself."
Could you use that?