Can a parent layer use a child layer?
Johannes Spangenberg
johannes.spangenberg at hotmail.de
Sun Oct 27 11:45:53 UTC 2024
Hi Pavel, if I understand you correctly, your problem is that with the
JPMS, you have no way to control which modules can be accessed by the
child layers.
> After some consideration, I realized the core issue: JPMS doesn’t
> allow to hide (or make "private") modules within a layer
It has been some years since I have last worked on code setting up
module layers. So I might miss something, but I think it would makes
sense to have more control here. However, note that I am just a fellow
subscriber to this mailing list.
For example if you create a plugin API, you may not want to expose all
the (internal) modules of your application to the plugins. It is also
not really viable to require all of your internal modules to only use
qualified exports. Using qualified imports for this purpose also seems
like a violation of Separation of Concerns. If you are using a library,
it should not be the concern of the library whether you are providing a
plugin API.
> All child layers [...] should not have any access to the engine or its
> jars (classes).
How important is the enforcement during runtime? Before you go to great
length to change the architecture of your application code, this is
something you may want to think about. Consider that even if you prevent
access to these modules, child layers may still cause havoc by calling
System.exit(int) or other Java-methods with significant site effects.
If you need to enforce this at runtime, an alternative solution might be
to verify the modules in the child layers before loading them. I guess
this might be done after resolving the Configuration. For named modules,
it might be enough to look at ResolvedModule.reads(). However, I doubt
that this will not work for automatic or unnamed modules in the child layer.
For a third potential solution, the JPMS still allows you to use custom
class loaders which I imagine could filter out classes from internal
modules. However, if I remember correctly, the JPMS doesn't make it easy
to build your own class loaders for a module layer. You might need to
re-implement some JDK-internal code.
> To achieve this, I want to place all jars related to the engine in a
> child layer, thereby hiding these jars and their classes from other
> child layers. However, I’m concerned that this setup results in the
> boot layer depending on a child layer, which seems to go against JPMS
> principles,
While I am not entirely convinced by the maintainability of your idea
based on your brief description, you can have a parent layer depending
on a child layer. You just need to ensure that the API between both
layers is defined in the parent (or some other common layer).
More information about the jigsaw-dev
mailing list