Patch-module with dynamic layer creating.

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Patch-module with dynamic layer creating.

Alex Sviridov
Hi all,

I create ModuleLayer this way

ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
ModuleLayer parent = ModuleLayer.boot();
Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
Class<?> c = layer.findLoader("myapp").loadClass("app.Main");

And I need for newly created layer make the following:
-patch-module java.xml.ws.annotation=jsr305-3.0.2.jar

Could anyone say, how I can do it, taking into consideration that when I start JVM I don't
know what layers I will create and what patch module I will need to use, so
I can not use for it JVM parameters.

--
Best regards, Alex Sviridov
Reply | Threaded
Open this post in threaded view
|

Re: Patch-module with dynamic layer creating.

Alan Bateman
On 11/10/2018 10:57, Alex Sviridov wrote:

> Hi all,
>
> I create ModuleLayer this way
>
> ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
> ModuleLayer parent = ModuleLayer.boot();
> Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
> ClassLoader scl = ClassLoader.getSystemClassLoader();
> ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
> Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
>
> And I need for newly created layer make the following:
> -patch-module java.xml.ws.annotation=jsr305-3.0.2.jar
>
> Could anyone say, how I can do it, taking into consideration that when I start JVM I don't
> know what layers I will create and what patch module I will need to use, so
> I can not use for it JVM parameters.
>
The --patch-module option is for patching modules in the boot layer,
there is no API support for patching modules when creating module layers
with the API. If you want to patch modules in custom module layers then
you need a create a ModuleFinder that will find the patched module -
it's not too hard to do, it's essentially scanning the patch locations
to find additional packages and then pre-pending the patch so that
resources are found in the patch before looking in the unpatched module.

-Alan
Reply | Threaded
Open this post in threaded view
|

Re[2]: Patch-module with dynamic layer creating.

Alex Sviridov
Hi Alan

Maybe it is necessary to add possibility to have equal control for boot layer and
other layers. Because layers are graph but at this moment we can do for boot layer
more then for others -> if we work with non boot layers we must use another
solutions -> different solutions within one technology is not good.

For example we could pass something like String[] args when we create custom layer.

Alex


>Четверг, 11 октября 2018, 14:27 +03:00 от Alan Bateman <[hidden email]>:
>
>On 11/10/2018 10:57, Alex Sviridov wrote:
>> Hi all,
>>
>> I create ModuleLayer this way
>>
>> ModuleFinder finder = ModuleFinder.of(dir1, dir2, dir3);
>> ModuleLayer parent = ModuleLayer.boot();
>> Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("myapp"));
>> ClassLoader scl = ClassLoader.getSystemClassLoader();
>> ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);
>> Class<?> c = layer.findLoader("myapp").loadClass("app.Main");
>>
>> And I need for newly created layer make the following:
>> -patch-module java.xml.ws.annotation=jsr305-3.0.2.jar
>>
>> Could anyone say, how I can do it, taking into consideration that when I start JVM I don't
>> know what layers I will create and what patch module I will need to use, so
>> I can not use for it JVM parameters.
>>
>The --patch-module option is for patching modules in the boot layer,
>there is no API support for patching modules when creating module layers
>with the API. If you want to patch modules in custom module layers then
>you need a create a ModuleFinder that will find the patched module -
>it's not too hard to do, it's essentially scanning the patch locations
>to find additional packages and then pre-pending the patch so that
>resources are found in the patch before looking in the unpatched module.
>
>-Alan


--
Alex Sviridov
Reply | Threaded
Open this post in threaded view
|

Re: Patch-module with dynamic layer creating.

Alan Bateman
On 12/10/2018 13:16, Alex Sviridov wrote:
> Hi Alan
>
> Maybe it is necessary to add possibility to have equal control for boot layer and
> other layers. Because layers are graph but at this moment we can do for boot layer
> more then for others -> if we work with non boot layers we must use another
> solutions -> different solutions within one technology is not good.
>
> For example we could pass something like String[] args when we create custom layer.
>
I don't know if that is really feasible as you would somehow need to
identify the layer and then somehow interpose on the ModuleFinders that
the container creates. Instead, I think it needs the container to create
a ModuleFinder that finds the patched modules. Yes, this means doing
something similar to patch support that the JDK does for the modules in
the boot layer but it would be under the control of the container. It
shouldn't be a lot of code to this do.

-Alan
Reply | Threaded
Open this post in threaded view
|

Re[2]: Patch-module with dynamic layer creating.

Alex Sviridov
I am speaking not only about patch-module but about all possible options:
--add-exports, --add-opens, --patch-module, --add-modules, --add-reads etc.

Agree that "custom" support for them is not a good way.

Alex



>Пятница, 12 октября 2018, 17:50 +03:00 от Alan Bateman <[hidden email]>:
>
>On 12/10/2018 13:16, Alex Sviridov wrote:
>> Hi Alan
>>
>> Maybe it is necessary to add possibility to have equal control for boot layer and
>> other layers. Because layers are graph but at this moment we can do for boot layer
>> more then for others -> if we work with non boot layers we must use another
>> solutions -> different solutions within one technology is not good.
>>
>> For example we could pass something like String[] args when we create custom layer.
>>
>I don't know if that is really feasible as you would somehow need to
>identify the layer and then somehow interpose on the ModuleFinders that
>the container creates. Instead, I think it needs the container to create
>a ModuleFinder that finds the patched modules. Yes, this means doing
>something similar to patch support that the JDK does for the modules in
>the boot layer but it would be under the control of the container. It
>shouldn't be a lot of code to this do.
>
>-Alan


--
Alex Sviridov
Reply | Threaded
Open this post in threaded view
|

Re: Patch-module with dynamic layer creating.

Alan Bateman
On 12/10/2018 16:00, Alex Sviridov wrote:
> I am speaking not only about patch-module but about all possible options:
> --add-exports, --add-opens, --patch-module, --add-modules, --add-reads etc.
>
ModuleLayer defines static variants of the defineModuleXXX methods that
return a Controller object that you can use to do the equivalent of
--add-reads or --add-exports/-add-opens to export/open a package to
specific modules. The equivalent of --add-modules is to add module name
to the set of modules to resolve.

For patching then it does mean writing code and creating your own
ModuleFinder but it shouldn't be too difficult.

-Alan.
Reply | Threaded
Open this post in threaded view
|

Re[2]: Patch-module with dynamic layer creating.

Alex Sviridov

Hi Alan,

Thank you for detailed explanation. It is great that we have API that allows to implement
such features. However, what I suggest is a little different. I am speaking about using
existing code for such features.

I think this way - firstly, we can do write the same code many times. We can, but we
don't want. Secondly if we pass parameters to JPMS via JVM options to configure boot
layer, it would be great if we had possibility to pass the same parameters to configure a
custom layer without writing a line of code and use existing JDK code.

Of course this is my person opinion. It is interesting to hear what other developers think.

>Пятница, 12 октября 2018, 19:24 +03:00 от Alan Bateman <[hidden email]>:
>
>On 12/10/2018 16:00, Alex Sviridov wrote:
>> I am speaking not only about patch-module but about all possible options:
>> --add-exports, --add-opens, --patch-module, --add-modules, --add-reads etc.
>>
>ModuleLayer defines static variants of the defineModuleXXX methods that
>return a Controller object that you can use to do the equivalent of
>--add-reads or --add-exports/-add-opens to export/open a package to
>specific modules. The equivalent of --add-modules is to add module name
>to the set of modules to resolve.
>
>For patching then it does mean writing code and creating your own
>ModuleFinder but it shouldn't be too difficult.
>
>-Alan.


--
Alex Sviridov
Reply | Threaded
Open this post in threaded view
|

Re: Patch-module with dynamic layer creating.

Alan Bateman
On 12/10/2018 21:57, Alex Sviridov wrote:

> Hi Alan,
>
> Thank you for detailed explanation. It is great that we have API that allows to implement
> such features. However, what I suggest is a little different. I am speaking about using
> existing code for such features.
>
> I think this way - firstly, we can do write the same code many times. We can, but we
> don't want. Secondly if we pass parameters to JPMS via JVM options to configure boot
> layer, it would be great if we had possibility to pass the same parameters to configure a
> custom layer without writing a line of code and use existing JDK code.
>
> Of course this is my person opinion. It is interesting to hear what other developers think.
>
I'm skeptical on both the feasibility and desirability of going there.
If a container is creating module layers at runtime then it is arranging
which modules are observable, e.g. it may choose one version of JAX-RS
for one configuration/layer, and another version for another
configuration/layer. In your scenario it may want to patch or augment
one of these modules. I don't think you can easily express this on the
command line as there isn't anything to identify the layer than you want
to adjust. Also module names may not be sufficient in the face of a
container wanting to make available different versions. It's also
possible that a container would want to opt out from this as it would
want full control of which modules to resolve.

-Alan
Reply | Threaded
Open this post in threaded view
|

Re[2]: Patch-module with dynamic layer creating.

Alex Sviridov
Суббота, 13 октября 2018, 10:43 +03:00 от Alan Bateman <[hidden email]>:

>
>On 12/10/2018 21:57, Alex Sviridov wrote:
>> Hi Alan,
>>
>> Thank you for detailed explanation. It is great that we have API that allows to implement
>> such features. However, what I suggest is a little different. I am speaking about using
>> existing code for such features.
>>
>> I think this way - firstly, we can do write the same code many times. We can, but we
>> don't want. Secondly if we pass parameters to JPMS via JVM options to configure boot
>> layer, it would be great if we had possibility to pass the same parameters to configure a
>> custom layer without writing a line of code and use existing JDK code.
>>
>> Of course this is my person opinion. It is interesting to hear what other developers think.
>>
>I'm skeptical on both the feasibility and desirability of going there.
>If a container is creating module layers at runtime then it is arranging
>which modules are observable, e.g. it may choose one version of JAX-RS
>for one configuration/layer, and another version for another
>configuration/layer. In your scenario it may want to patch or augment
>one of these modules. I don't think you can easily express this on the
>command line as there isn't anything to identify the layer than you want
>to adjust.
I am sorry, maybe I didn't express this very clear: I mean something like this:
 ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl, args); Where args are for example String[] and we pass the same --add-exports, --add-opens, --patch-module,
--add-modules, --add-reads etc that we pass to configure boot layer. The disadvantage of such way
is using String. However, there are two main advantages: 1) no line of code 2) use the same parameters
that we use to configure boot layer - one solution within one technology.

--
Alex Sviridov
Reply | Threaded
Open this post in threaded view
|

Re: Patch-module with dynamic layer creating.

Alan Bateman
On 13/10/2018 08:54, Alex Sviridov wrote:
> :
> I am sorry, maybe I didn't express this very clear: I mean something like this:
>   ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl, args); Where args are for example String[] and we pass the same --add-exports, --add-opens, --patch-module,
> --add-modules, --add-reads etc that we pass to configure boot layer. The disadvantage of such way
> is using String. However, there are two main advantages: 1) no line of code 2) use the same parameters
> that we use to configure boot layer - one solution within one technology.
>
I don't think this is the right approach either. It would mean
standardizing what is currently JDK specific command line options. In
addition it impacts Configuration resolve and resolveAndBind because
--add-modules adds to the set of root modules to resolve (also you need
the patched modules to be observable at this time too).

If it helps, I think this is what you need to do:

--add-modules
Add the names of the modules to the root set that you specify to
Configuration resolve and resolveAndBind.

--patch-module
Provide a ModuleFinder that interposes on the unpatched module to
override or augment its resources. This should be the only case where
you need to write a lot of code (mundane rather than hard). There may be
an opportunity to develop this as its own project in the event that
there is wider interest in patching modules.

--add-reads, --add-exports, --add-opens
Are you sure you need these? If you then use the static
ModuleLayer.defineModulesWithOneLoader method to specify the parent
layer as a parameter rather than the receiver. This will return you a
ModuleLayer.Controller object that you can use to do the equivalent of
these CLI options, at least for the cases where the target is a specific
module.

-Alan.