Hello Alan,
Thank you for such detailed answer. I read it with attention, but still don’t
know how to solve my situation.
Maybe may question didn’t provide all details, so here they are.
I want to create the following layer structure:
+++++++++++
+ Boot Layer +
+++++++++++
|
+++++++++++++++++
+ Web Server Layer +
+++++++++++++++++
|
++++++++++++++++++++
+ Web Application Layer +
++++++++++++++++++++
So, we have always one boot layer (it’s clear), one web server layer, and
multiple web application layers. At
the same time all web application layers have one parent — web server layer.
Boot layer doesn’t know and mustn’t know
about any child layer modules!!!! So it is impossible to add all modules to
boot layer!
In web server layer I have servlet container (Jetty) and rest implementation
(Jersey). When I create web server layer
Configuration cf = parentLayer.configuration().resolveAndBind(moduleFinder,
ModuleFinder.of(), moduleNames);
ModuleLayer layer = parentLayer.defineModulesWithOneLoader(cf,
parentClassLoader);
I add to it all modules of jetty, jersey and their dependencies. At the same
time jetty knows nothing about jersey. When web server layer is created one of
its modules starts Jetty.
So, when does jersey start? It starts only when web application layer is
created with .war file that has web.xml with jersey servlet. For example:
<servlet>
<servlet-name>JerseyServlet</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
</servlet>
So, in such configuration, when web server layer is created no one can know if
jersey will be used.
What what does JPMS do? It ignores all jersey modules including all its
dependencies (including API). So, the question.
How to ask JPMS not to ignore modules that it must add to layer?
--
Best regards, Alex Orlov
>Понедельник, 16 ноября 2020, 11:20 +03:00 от Alan Bateman
><alan.bate...@oracle.com>:
>
>On 15/11/2020 19:16, Alex Orlov wrote:
>> Hi all,
>>
>> I create JPMS layer this way:
>>
>> Configuration cf = parentLayer.configuration().resolveAndBind(moduleFinder,
>> ModuleFinder.of(), moduleNames);
>> ModuleLayer layer = parentLayer.defineModulesWithOneLoader(cf,
>> parentClassLoader);
>>
>> And I have a problem with adding implementation modules. These
>> implementation modules are ignored by JPMS because classes from these
>> modules are not used anywhere (it is clear, that classes from API modules
>> are used). So, JPMS doesn't add these modules to layer.
>>
>> As I understand, if I spoke about implementation modules on boot layer, I
>> could use --add-modules jvm argument. However, I couldn't find any
>> information how to force JPMS load my module (even if its classes are not
>> used) for dynamically created layers.
>>
>> Could anyone say how to do it? It would be useful if you could give an
>> example of "implementation
>module". I can't tell if you mean a jdk.* module, a service provider
>module that doesn't export an API, or something else.
>
>In any case, I think the picture you are describing is a module that is
>observable, either in the run-time image or on module path. The module
>is not resolved at startup (and so is not in the boot layer) because the
>initial module that you specify with `java -m` doesn't transitively
>require it and it doesn't provide an implementation of a service that
>any of the other resolved modules use.
>
>The summary is a module layer is immutable and there isn't any way to
>add modules to a module layer once it has been created. For what you are
>doing then maybe `--add-modules ALL-SYSTEM` can be used as workaround.
>This will ensure that all system/platform modules are in the boot layer
>as these modules cannot be loaded into a child layer (Johannes's suggest
>to specify the module name to resolveAndBind will not work for java.*
>modules as they cannot be loaded into child layers, his suggestion may
>work for other modules).
>
>One other point to mention is that the original set of requirement
>envisaged some means to augment the set of platform modules at run-time.
>We didn't get to that requirement except for the limited scenario that
>is tools loading the JMX agent or a java agent into a running VM. These
>limited scenario involve loading the jdk.management.agent or
>java.instrument modules and that is some with a special child layer
>rather than augmenting the boot layer. This partial solution, along with
>`--add-modules ALL-SYSTEM`as a workaround for the general cases, has
>been sufficient to date.
>
>-Alan