Adding modules from a child layer

Simone Bordet simone.bordet at gmail.com
Fri Mar 14 10:54:54 UTC 2025


Hi,

I'm working on improving JPMS support in Jetty.

Jetty 12 has a set of core modules that do not depend on Jakarta EE,
and then has "environments" such as ee9, ee10, etc. so it is possible
to deploy on the same server both an EE9 web application and an EE10
web application: Jetty isolates the jakarta.servlet-api-5.0.0.jar (for
EE9) from the jakarta.servlet-api-6.0.0.jar (for EE10).

Previously, this was done using ClassLoaders only.

Now I am trying to use ModuleLayers, with the following setup.

- server ModuleLayer
    + jetty-util-12.1.0.jar (plus a bunch of other Jetty core jars)

  - ee10 ModuleLayer (child of the server ModuleLayer)
    + jakarta.servlet-api-6.0.0.jar
    + jetty-ee10-webapp-12.1.0.jar (plus a bunch of other Jetty ee10 jars)

The server ModuleLayer is created by the JVM at startup, via command
line (i.e. java -p jetty-util-12.1.0.jar:... -m ...).
The ee10 ModuleLayer is created at runtime by the Jetty code (reading
command line arguments).

Now, it happens that jetty-ee10-webapp.jar requires java.instrument
(declared in the jetty-ee10-webapp's module-info).

Running in this setup yields:

Exception in thread "main" java.lang.module.FindException: Module
java.instrument not found
    at java.base/java.lang.module.Resolver.findFail(Resolver.java:893)
    at java.base/java.lang.module.Resolver.resolve(Resolver.java:129)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:421)
    at java.base/java.lang.module.Configuration.resolve(Configuration.java:255)

My interpretation of this error is that the ee10 ModuleLayer tries to
resolve the jetty-ee10-webapp dependencies; obviously the
java.instrument module is not in the ee10 ModuleLayer, so it delegates
to the server ModuleLayer.
The server ModuleLayer has modules, but none depend on
java.instrument, and there is no explicit --add-modules
java.instrument directive (as it is not necessary for the server
ModuleLayer), so the java.instrument module is not in the module
graph, and hence the error.

If I manually add the --add-modules java.instrument directive to the
server ModuleLayer, the error is gone.

The question is whether there is a way for a child ModuleLayer to
perform the equivalent of "--add-modules", but programmatically at
runtime, that would add the module to the graph?

As a side question, I was wondering what is the benefit of using
ModuleLayers versus just using ClassLoaders.
I can think of earlier error detection: if the ModuleLayer is not
setup correctly (as above) I get an early error, which I would only
get much later at runtime if I was using ClassLoaders.
Isolation is provided by the ClassLoaders anyway.
Anything else I could not think of?

Thanks!
-- 
Simone Bordet
---
Finally, no matter how good the architecture and design are,
to deliver bug-free software with optimal performance and reliability,
the implementation technique must be flawless.   Victoria Livschitz


More information about the jigsaw-dev mailing list