Re: jlink images and module layers

2021-02-11 Thread Alan Bateman

On 10/02/2021 21:44, Gunnar Morling wrote:

Hi Alan,

Thanks for your thoughtful reply. The use case I'd see for layers
within jlink images is isolation of different (transitive) dependency
versions within an application. While this isn't present (and I
understand it'd add a fair share of complexity), we can work around
this by putting the modules of different layers into a separate
directory and use this as source for the layers running on top of the
JDK modules from the image. We might envision some tooling support for
creating such "extended" jlink image.
It would need a lot of consideration and exploration before going there. 
One reason for having different versions of a module in the run-time 
image might be to support different initial modules, say a run-time 
image containing two distinct applications or tools. Both would run with 
in flat name space but for whatever reason can't use the same version of 
some module. At the other extreme might be launching an application that 
is magically started with several layers and different versions of 
modules in each layer. Somewhere in the middle is a container in the 
boot layer and at run-time it uses the APIs to create module layers. The 
set of observable modules that it uses when creating the configurations 
for these modules layer is some subset of the modules in the run-time 
image that include modules that weren't observable at startup when 
creating the boot layer.






Btw. when exploring dynamic plug-in layers and their interaction with
services, we noticed that you'll also get services provided by parent
layers. This leads to code patterns like shown here:

 
https://urldefense.com/v3/__https://github.com/moditect/layrry-examples/blob/master/modular-tiles/core/modular-tiles-core/src/main/java/org/kordamp/tiles/core/TilePluginLifecycleListener.java*L41-L43__;Iw!!GqivPVa7Brio!L0YyyA2bQu9Mr2QdbMC3mK-U7Vkt8WmI3LIlw_FmwS58Iqo42j9JN77ETD7lxI-Q-Q$

I.e. you need to filter out all those service implementations from
parent layers. It would be nice if there was a flavour of load()
(perhaps just a boolean flag "includeParentLayers"), which would make
this a bit simpler. Also, IIUC, the code using the service loader
needs to have awareness of the fact that it runs within layers, as the
traditional load() methods wouldn't find any implementations from
parent layers, which might present a migration obstacle when moving
existing libraries to layered architectures.
The load(ModuleLayer, service) is specified to load service providers in 
the given layer and its ancestors. That is consistent with the load 
method that takes a ClassLoader as that has always been specified to use 
the class loaders that are reachable via parent delegation.


The stream() method might be useful for the example as you could use a 
filter to selects providers in the desired layer.


What parent class loader do you specify to defineModules when you 
are creating the module layers? I'm asking because the traditional 
ServiceLoader.load will locate providers in named modules when the class 
loader specified to the method has modules in a module layer. This goes 
for class loaders that are reachable via parent delegation too. When 
Layrry creates a layer with defineModules then it must specify the 
parent class loader for the resulting class loaders. If you choose one 
of the class loaders from the layer parent (any of them will do) then it 
might get more of the traditional usages of ServiceLoader.load working.


-Alan




Re: jlink images and module layers

2021-02-10 Thread Gunnar Morling
Hi Alan,

Thanks for your thoughtful reply. The use case I'd see for layers
within jlink images is isolation of different (transitive) dependency
versions within an application. While this isn't present (and I
understand it'd add a fair share of complexity), we can work around
this by putting the modules of different layers into a separate
directory and use this as source for the layers running on top of the
JDK modules from the image. We might envision some tooling support for
creating such "extended" jlink image.

Btw. when exploring dynamic plug-in layers and their interaction with
services, we noticed that you'll also get services provided by parent
layers. This leads to code patterns like shown here:


https://github.com/moditect/layrry-examples/blob/master/modular-tiles/core/modular-tiles-core/src/main/java/org/kordamp/tiles/core/TilePluginLifecycleListener.java#L41-L43

I.e. you need to filter out all those service implementations from
parent layers. It would be nice if there was a flavour of load()
(perhaps just a boolean flag "includeParentLayers"), which would make
this a bit simpler. Also, IIUC, the code using the service loader
needs to have awareness of the fact that it runs within layers, as the
traditional load() methods wouldn't find any implementations from
parent layers, which might present a migration obstacle when moving
existing libraries to layered architectures.

Best,

--Gunnar


Am Sa., 6. Feb. 2021 um 17:56 Uhr schrieb Alan Bateman
:
>
> On 05/02/2021 15:39, Gunnar Morling wrote:
> > Hi all,
> >
> > While working on Layrry [1] [2] [3], a launcher and runtime for
> > layered Java applications, I've come to wonder whether there's a way
> > for sourcing multiple module layers from a custom runtime image
> > created via jlink?
> >
> > I couldn't find a way so far, as a) it seems not possible to add
> > multiple versions of a module to a runtime image (one of the use cases
> > for layered applications), and b) it's not clear how the module finder
> > API would address modules in an image. If this is not supported atm.,
> > are there any plans to do so?
> >
> > To give some context on Layrry, it's an exploration for providing a
> > framework that allows the creation of modularized applications based
> > on the module system and its notion of layers, addressing the
> > multi-version issue of (transitive) dependences, provisioning modules
> > based on their Maven coordinates, supporting the dynamic
> > addition/removal of layers at runtime ("plug-ins"), and more.
> >
> No, there isn't any support for this.
>
> As things stand, the universe of observable modules at startup includes
> all modules in the run-time image. If a run-time image were to include
> modules only intended for module layers created at run-time then there
> would need to be configuration or something to support the partitioning,
> also maybe APIs to expose enough at run-time to reconstitute the
> configuration. There would be restrictions on the content of these
> modules, e.g. modules intended only for child layers couldn't contribute
> command-line launchers for the bin directory. The container format used
> for classes and resources would need to be rev'ed to support more
> complex addressing (this is something we explored a bit in JDK 9 but
> didn't go too far), or the run-time image structure would need to be
> updated to support directories of observable modules for each
> configuration. A lot of complexity would be heaped on jlink as it would
> have to create the configuration for each of the layers at link time,
> maybe even a training run to map the modules to class loaders to
> identity consistency issues at link-time. Overall I think it would add a
> lot of complexity in many areas.
>
> Module layers are great for containers that launch applications that use
> different versions of components, it's also great for plugins and
> dynamic behavior (the "Finding Plug-In Implementations ..." section in
> your blog is good). I'm less sure about trying to bring it to the link
> phase where it's about static configuration and link-time optimizations.
>
> -Alan
>


Re: jlink images and module layers

2021-02-06 Thread Alan Bateman

On 05/02/2021 15:39, Gunnar Morling wrote:

Hi all,

While working on Layrry [1] [2] [3], a launcher and runtime for
layered Java applications, I've come to wonder whether there's a way
for sourcing multiple module layers from a custom runtime image
created via jlink?

I couldn't find a way so far, as a) it seems not possible to add
multiple versions of a module to a runtime image (one of the use cases
for layered applications), and b) it's not clear how the module finder
API would address modules in an image. If this is not supported atm.,
are there any plans to do so?

To give some context on Layrry, it's an exploration for providing a
framework that allows the creation of modularized applications based
on the module system and its notion of layers, addressing the
multi-version issue of (transitive) dependences, provisioning modules
based on their Maven coordinates, supporting the dynamic
addition/removal of layers at runtime ("plug-ins"), and more.


No, there isn't any support for this.

As things stand, the universe of observable modules at startup includes 
all modules in the run-time image. If a run-time image were to include 
modules only intended for module layers created at run-time then there 
would need to be configuration or something to support the partitioning, 
also maybe APIs to expose enough at run-time to reconstitute the 
configuration. There would be restrictions on the content of these 
modules, e.g. modules intended only for child layers couldn't contribute 
command-line launchers for the bin directory. The container format used 
for classes and resources would need to be rev'ed to support more 
complex addressing (this is something we explored a bit in JDK 9 but 
didn't go too far), or the run-time image structure would need to be 
updated to support directories of observable modules for each 
configuration. A lot of complexity would be heaped on jlink as it would 
have to create the configuration for each of the layers at link time, 
maybe even a training run to map the modules to class loaders to 
identity consistency issues at link-time. Overall I think it would add a 
lot of complexity in many areas.


Module layers are great for containers that launch applications that use 
different versions of components, it's also great for plugins and 
dynamic behavior (the "Finding Plug-In Implementations ..." section in 
your blog is good). I'm less sure about trying to bring it to the link 
phase where it's about static configuration and link-time optimizations.


-Alan



jlink images and module layers

2021-02-05 Thread Gunnar Morling
Hi all,

While working on Layrry [1] [2] [3], a launcher and runtime for
layered Java applications, I've come to wonder whether there's a way
for sourcing multiple module layers from a custom runtime image
created via jlink?

I couldn't find a way so far, as a) it seems not possible to add
multiple versions of a module to a runtime image (one of the use cases
for layered applications), and b) it's not clear how the module finder
API would address modules in an image. If this is not supported atm.,
are there any plans to do so?

To give some context on Layrry, it's an exploration for providing a
framework that allows the creation of modularized applications based
on the module system and its notion of layers, addressing the
multi-version issue of (transitive) dependences, provisioning modules
based on their Maven coordinates, supporting the dynamic
addition/removal of layers at runtime ("plug-ins"), and more.

Thanks,

--Gunnar

[1] https://github.com/moditect/layrry/
[2] 
https://www.morling.dev/blog/plugin-architectures-with-layrry-and-the-java-module-system/
[3] http://andresalmiray.com/layrry-1-0-0-alpha1-has-been-released/