> On 16 Dec 2024, at 17:17, David Lloyd <david.ll...@redhat.com> wrote:
> 
> The model I'm working with is such that we are loading every single module 
> (whether they are within our container or the user's application) into a 
> separate layer, as has been previously recommended as the way to meet 
> requirements like ours, with our class loaders handling all inter-module 
> linkage concerns. Everything works exactly as we want in this scenario: 
> modules are able to be lazily loaded and linked (just like classes); our 
> integrity constraints are enforced locally per module on demand, rather than 
> globally across the whole layer (again, just like classes); and, we get our 
> nice stack traces and encapsulation behaviors. However there is one 
> exception, and that is that service loading does not work for any module, 
> since no modules can find their implementations, regardless of what we do 
> with class loading. This is what I'm trying to address.

Ok, thank you! Indeed, if a dynamic container is designed to load every module 
in a separate layer then ServiceLoaders in libraries may not work unless the 
container is able to put a library’s service providers in the same layer as the 
library. 

Now, if you’re not interested in Alan’s suggestion, then there’s not much I can 
add.

I can say that I’ve seen similar problems arise with virtual threads. Some 
projects wanted to get the benefit of virtual threads under the condition that 
nothing else in their architecture, algorithms, or deployment would have to 
change, and that’s just not possible sometimes (e.g. to get the benefit of 
virtual threads you need high concurrency, and if the rest of your system is 
designed and deployed to ensure that every server only ever experiences low 
concurrency then you won’t enjoy the benefits of virtual threads). Similarly, 
modules were not designed to match every possible non-modular design (e.g. they 
also forbid circular dependencies), especially every elaborate dynamic loading 
design. That wasn’t the intent.

As another side note, I will also say that not a single invariant written in 
Java can have integrity without modules’ strong encapsulation. Even properties 
such as “strings are immutable” cannot be trusted, let alone “this private 
method is never called unless some precondition holds”. In particular, class 
loader isolation only offers encapsulation in a very approximate and rather 
weak sense.

In short, I’m not discounting the difficulty you’ve encountered, but if you 
want to enjoy modules’ capabilities as they currently work, you may want to 
consider a different design.

Is Quarkus also experiencing that difficulty?

— Ron

Reply via email to