Java extensibility and JPMS (ServiceLoader)

Alex Buckley alex.buckley at oracle.com
Tue Jan 23 01:35:40 UTC 2024


Tomas,

I realize that you want to allow your modular JARs to be deployed on the 
classpath and still enjoy some degree of encapsulation.

However, mapping packages 1:1 to modules isn't the right way to use the 
module system. You get to formalize the system structure, and will be 
forced to break any legacy cycles between packages, but every module 
will export 100% of its packages, so there's no real information hiding. 
The maintainer of a module in one subsystem can freely require a module 
in another subsystem and access the exported-but-not-really-supported 
package of that other subsystem, so over time, a ball of mud will re-emerge.

Having "internal" packages is a _feature_ of modules, not a problem. 
It's only a problem if those modules are deployed on the classpath, and 
we don't recommend doing that.

On point 3: The requirement that a provider class must be public with a 
public ctor comes from the original design of ServiceLoader. This 
resulted in providers that were "too public", so we used the module 
system to solve that problem: you can take existing providers, "hide" 
them in unexported/internal packages of modules, and service consumers 
are not impacted at all.

Except for the small addition of "provider methods" as an alternative to 
public ctors, we took ServiceLoader in Java 9 as we found it. Evolving 
ServiceLoader in Java 23+ to allow providers with very limited 
accessibility -- package-access classes / ctors / provider methods -- is 
not incompatible with anything in the module system. In fact, keeping 
the circle of code that can instantiate providers as tight as possible 
is a good thing. However, we haven't heard the request for 
package-access providers from many people, and working on that feature 
would mean not working on something else, so it's unlikely that the 
feature will appear in the foreseeable future.

Alex

On 1/22/2024 3:30 PM, Tomas Langer wrote:
> We have a single module/single package approach, so all internal classes 
> are hidden by visibility (package local) and not by package (as that 
> cannot be enforced on classpath.
> Using more than one package usually results in internal packages and in 
> requirement to have some methods public, so classes in other packages of 
> your module can access them (where we can live with package local only...)
> 
> Tomas
> 
> Zasláno z Outlooku pro Android <https://aka.ms/AAb9ysg>
> ------------------------------------------------------------------------
> *From:* jigsaw-dev <jigsaw-dev-retn at openjdk.org> on behalf of Alex 
> Buckley <alex.buckley at oracle.com>
> *Sent:* Monday, January 22, 2024 9:13:39 PM
> *To:* jigsaw-dev at openjdk.org <jigsaw-dev at openjdk.org>
> *Subject:* Re: Java extensibility and JPMS (ServiceLoader)
> Tomas,
> 
> A clarification for point 3:
> 
> On 1/19/2024 5:02 AM, Tomas Langer wrote:
>> *Ad 3 - Provider implementation must be public with public constructor*
>> -------------------------------------
>> Details:
>> Provider implementations are not supposed to be visible to users - they 
>> are not public API of my module (the fact that I provide a service is 
>> part of my public API).
>> Right now there is only one option to work around this, and it only 
>> works in JPMS, and in my opinion it brings in even more problems - put 
>> the provider implementation in an un-exported package.
>> The problem with this approach is that now the provider implementation 
>> MUST use only public methods of my module, thus creating even more 
>> public APIs, where if I just put it in my exported package, I can use 
>> package private methods of my other classes to implement the service (so 
>> I pay the price of having one public class with one public constructor 
>> agains multiple public classes and public methods). Also the "hiding" in 
>> unexported package is lost when on classpath anyway...
> 
> I don't understand what you mean by "the provider implementation MUST
> use only public methods of my module". You have an arrangement of
> modules and packages in mind that I simply cannot see -- please share it.
> 
> Alex


More information about the jigsaw-dev mailing list