excluding transitive module

Alex Buckley alex.buckley at oracle.com
Wed Apr 15 18:01:11 UTC 2020


On 4/15/2020 12:00 AM, Jochen Theodorou wrote:
> On 14.04.20 19:38, Alex Buckley wrote:
> [...]
>> It's fine for
>> Library1 to require SharedApi, and for Library2 to require
>> SharedApiImpl, but if the exported packages overlap, then it's not fine
>> for Project to require, indirectly, both SharedApi (via Library1) and
>> SharedApiImpl (via Library2). That is, SharedApi and SharedApiImpl are
>> not composable.
> 
> And what do you do when you are in that situation?
> 
>> If you had put them both on the classpath in JDK 8, then
>> you would have had a broken system. If you want to compose an
>> application that includes both, then one of them has to change.
>> There is no need to speak of "transitive" modules because `requires
>> transitive` has not entered the picture.
> 
> Without the module system I can just exclude one and be fine. With
> module system I get into a split package problem adn have not found a
> real solution yet

In the JDK 8 world:  If SharedApi and SharedApiImpl have different 
names, then (as you implied to Remi) Maven is going to treat them 
independently and put both on the classpath. Yes, you can realize that 
their content overlaps and exclude one of them in your POM, but *every* 
*single* *user* has to travel that road independently! If a user doesn't 
realize, and doesn't exclude, then their classpath has split packages 
and their application is broken. I think it's outrageous that the 
developers of SharedApi and SharedApiImpl imposed this tax on *every* 
*single* *user* and no-one held them to account.

Post JDK 8:  Only when SharedApi and SharedApiImpl are modularized does 
the presence of overlapping exports become clear, and prevent an 
application from being composed unsafely.

There is nothing you can do in the module-info.java of your application 
to express that its module graph indirectly requires the uncomposable 
modules M,N,O and that any `requires M` and `requires N` clauses should 
be overridden with `requires O`. This would be a maintenance nightmare. 
Mail their developers and tell them what they've done. Every library 
including its own copy of a standard API is a bug, not a feature.

(If a library is explicitly written to be loaded in its own class 
loader, such as in the OSGi environment, then things are different: 
private copies of APIs are OK, up to a point. However, the libraries you 
are using are plainly from the JDK 8 classpath era and have been lightly 
modularized -- enough for each vendor to let their module be required 
and jlinked, but not enough to address the bigger architectural issue of 
reuse / composability.)

Alex


More information about the jigsaw-dev mailing list