Inconsistency with service loading by layer or by class loader

David Lloyd david.lloyd at redhat.com
Sat Dec 14 00:02:02 UTC 2024


On Fri, Dec 13, 2024 at 3:09 AM Alan Bateman <alan.bateman at oracle.com>
wrote:

> On 12/12/2024 14:35, David Lloyd wrote:
>
> On Thu, Dec 12, 2024 at 7:27 AM Alan Bateman <alan.bateman at oracle.com>
> wrote:
>
>> If ServiceLoader.load is invoked with a ClassLoader then it lazily
>> iterates through the class loader delegation chain. If ServiceLoader.load
>> is invoked with a ModuleLayer then it iterates through the module layers.
>> The former has deliberately limited support for cases where a class loader
>> is used by a module layer but doing what you propose is adding more
>> complexity for what seems like a really niche usage. I would worry that
>> changing it along the lines you propose would result in something that only
>> a few people could understand.
>>
>> Have you looked at changing these frameworks to work with modules and
>> specify a module layer to ServiceLoader.load?
>>
>
> The problem is that 100% of these frameworks are required to work on the
> class path as well (and some are not yet being tested on the module path,
> or even defining an automatic module name, though I've been working to
> improve that for a couple years now). So, we'd need some kind of
> non-trivial fallback logic to try both the correct layer (if any) or the
> correct class loader (since the unnamed module has no layer). Also note
> that "correct" depends on the framework: some are using the caller, some
> are using the TCCL, some are using their own class loader, some are using a
> configured class loader, etc. It also would likely involve deduplication of
> returned services along with coping with ordering, which is sometimes
> significant. I think it's unlikely that we would be able to settle on a
> preferred pattern for this, and even more unlikely that we would be able to
> successfully push these changes to *all* Jakarta, Microprofile, etc. spec
> APIs in addition to non-spec APIs (even the ones that Red Hat "controls"
> would probably give resistance unless the change was really clean/simple).
>
> This comes across as a soup of complexity. I can't help thinking it would
> be much simpler to use module layers as originally envisaged, meaning each
> configuration/layer layer is a graph of modules with a single parent.
> Whether the modules are mapped to a single class loader or different class
> loaders should just work. Existing code that uses ServiceLoader with a
> class loader would have a much better chance of working in that scenario.
>

The problem with having one (or a few) broad layer for all named modules is
twofold: first, that every module that *might* be needed for an application
must be found and loaded before *any* module is able to be loaded. This
works in some simpler packaging scenarios but is too startup-heavy in cases
with very large numbers of modules. The "--add-modules" switch on the Java
launcher is a direct result of forbidding late binding of modules. From a
usability perspective, this is already far from ideal, and if you start
talking about hundreds or thousands of modules, it becomes completely
unworkable. The second problem is that it makes it very difficult to
support any kind of dynamicity (for example adding additional
plugins/service implementations at run time) since an outsized amount of
static analysis must be done to categorize the layers, whereas lazily
loading layers solves the problem easily and elegantly.

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


More information about the jigsaw-dev mailing list