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).

Reply via email to