On 09/04/2020 19:23, Eirik Bjørsnøs wrote:

Alan,

    If I read your mail correctly, you are creating "multi-module JAR
    files"
    where the modules are "exploded" under /META-INF/modules in
    ${NAME}-${VERSION} directories.


Correct.
Do they need to be "exploded"? If the dependences are automatic modules then I assume putting the JAR files (without unpacking) into META-INF/modules should just work without needing a new ModuleFinder implementation or implementing the exploded equivalent of multi-module JAR files (or modular multi-release JAR files).

(The reason it should work is that the built-in implementation can work with paths to locations in virtual file systems. It handles this by copying the JAR files from the virtual file system to the default file system so that it can be opened with the JarFile API. It does this in order to support signed JARs as the zip file system provider doesn't have any support for validating signatures. It's possible this approach isn't very efficient, also we haven't looked into interactions with the cron jobs that clean tmpfs so there may be a bit more work needed here).


To achieve this, I had to copy / replicate quite a bit of code from the ModulePath class which is not accessible outside java.base.

It wasn't all that hard, I just wasn't happy with the amount of classes / methods I had to copy from java.base only to slightly modify them

This includes:

Code to create / build the ModuleDescriptor (stolen from deriveModuleDescriptor) Code to clean the artifactId used to produce the automatic name (Stolen from cleanModuleName, Patterns and Checks)
Duplication of ExplodedModuleReader which also dragged in Resources.
Understood although you probably don't need a deep copy of everything as there is a lot in exploded module reader related to potential security and traversal on the default file system that is less interesting in JAR files.


:

The runtime loads a graph of module layers, each containing one or more modules. Layers may depend on other layers, forming a DAG with corresponding class loader delegation.

When the runtime detects that a module needs to be redeployed, the transitive closure of depending layers is removed from the graph and new module layers are created and added to the graph.

Services are bound using dependency injection, so there's also a DAG of service dependencies. This allows restarting services which are affected by the redeploy, either because they are provided from updated modules or because they consume services from updated modules.

So not really hot-deploying in the JVM sense, but still pretty fast and developer-friendly.

My demo has a module which provides a JAX-RS resource which is consumed by a Jersey module which provides an HttpServlet which is again consumed by a Jetty module which deploys the servlet in a servlet context.

Redeploying the module containing the JAX-RS resource takes something like 50ms IIRC.

This sounds very interesting. I'm sure there are several people here that would be interesting in seeing a write-up or demo of this. I'm curious if the service wiring make use of the existing uses/provides or something else. I'm also curious if you've run into any issues with multi-parent configurations as that is an area that might need attention some day.

-Alan



Reply via email to