Class loader layer registration (8346946)

David Lloyd david.lloyd at redhat.com
Thu Jan 9 14:29:08 UTC 2025


If I have a module layer A containing module X that is registered to some
class loader L, *or* a class within the unnamed module of L, and I create a
new layer B contains module Y which is also registered to L, and B contains
modules which provide services, then once this layer is created, loading
services from class loader L will begin to find all service providers in B
(even those not in Y) in addition to those in A. This happens dynamically
at the time the new layer is created, even if B and A are sibling/cousin
layers. This behavior exists today.

Sometimes it is desirable to load a plugin (for example) where the
module(s) in the plugin provide services but the plugin should be loaded
into a layer that is isolated from (i.e. a sibling to) the
service-consuming layer, which is generally a private implementation layer
or a peer plugin. Note that the service type would be in a parent layer or
otherwise findable by both layers.

Thanks to the above behavior, this can be accomplished (poorly) today by
dynamically generating a layer with a "holder" module, containing one
generated class per service provider defined in B which is declared to
provide the corresponding service type. Each generated class would contain
a `provider` method which accesses the corresponding "real" service
provider and instantiates it according to the service loader specification.
The "holder" module is then mapped to class loader L, allowing L to then
indirectly load the service implementations in the sibling layer.

Sometimes it is possible to use a simpler approach where layer B contains a
"bogus" empty module which is registered with A. This works when B is
defined after A. But this would not generally be the case.

This is all unwieldy. The purpose of 8346946 [1] is to allow a simpler way
to directly register a layer with a custom class loader for service
loading, without defining an extra bogus module or a fake bridge layer.
There might be other ways to make this possible than the approach proposed
in the current version of the PR [2]. For example, in order to ensure that
I control both the class loader and the module layer in question, the
protected method on `ClassLoader` could accept a `ModuleLayer.Controller`,
ensuring that callers have control over both objects. Other solutions may
be possible as well.

[1] https://bugs.openjdk.org/browse/JDK-8346946
[2] https://github.com/openjdk/jdk/pull/22905

-- 
- DML • he/him
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/jigsaw-dev/attachments/20250109/f5aa17d3/attachment.htm>


More information about the jigsaw-dev mailing list