Weakness of "requires public"

Neil Bartlett njbartlett at gmail.com
Tue Jul 26 21:54:06 UTC 2016


If you have client code that depends on Animal and calls the eat(Organism) method, then your code has a direct dependency on Organism. Now you have a choice between:

1. explicitly declaring requirements for all the types that you actually use (i.e. Animal and Organism)
2. explicitly declaring requirements for a subset of the types you actually use (Animal) but not others (Organism).

You are essentially arguing for the latter, and while this is clearly less typing I’m not sure that it’s any simpler.

What happens if the module that exposes Animal is refactored and no longer uses “require public” for Organism? In the former case your module continues to work but in the latter it stops working.

You also raise the question of inheritance. Using a type that extends from Animal has always required visibility of the full type hierarchy, so this means you should depend on the base class module also. Hopefully this will be rare. Subclassing creates a very tightly coupled dependency and it really shouldn’t be done across module boundaries.

Regards,
Neil



> On 26 Jul 2016, at 22:40, Malachi de Ælfweald <malachid at gmail.com> wrote:
> 
> I admit I came late to the discussion, so I am probably missing something
> obvious.
> 
> To try to better understand the discussion, I replaced the abritrary
> A/B/C/M1/M2/M3 with concrete names...
> 
> package world;
> public class Organism{...}
> 
> package fauna;
> public class Animal {
>    public void eat(Organism organism){...}
> }
> 
> package canine;
> public class Dog extends Animal {
> }
> 
> So looking at this... If I were to depend on the canine package/module, I
> would assume that eat(Organism) would still work which would mean that both
> fauna and world were included as well.
> I agree that this seems more like a build tool issue - but if I were to be
> writing the canine module, I should not be expected to know/maintain what
> is inside the fauna black box.  That's done by someone else.
> 
> 
> 
> 
> Malachi de Ælfweald
> http://www.google.com/profiles/malachid
> 
> On Tue, Jul 26, 2016 at 2:16 PM, Remi Forax <forax at univ-mlv.fr> wrote:
> 
>> Hi Paul,
>> suppose you have a module M1 that declare a class A in an exported package,
>> 
>> module M1 {
>>  exports m1;
>> }
>> 
>> package m1;
>> public class A { ... }
>> 
>> now suppose i have a second module M2 that use B as a type of one
>> parameter of a public method
>> 
>> module M2 {
>>  requires M1;
>> 
>>  exports m2;
>> }
>> 
>> package m2;
>> public class B {
>>  public void m(A a) { ... }
>> }
>> 
>> now i am in a third module M3 and i want to extends m2.B,
>> if i write
>> module M3 {
>>  requires M2;
>> }
>> 
>> package m3;
>> public class C extends B {
>>  ...
>> }
>> 
>> here i have an issue because while i can see B (the module-info requires
>> M2), i can not see m(A) because the module-info doesn't requires m1 which
>> contains A.
>> 
>> So you can modify M3 to requires both M1 and M2, i see no problem with
>> that.
>> But from the user point of view, a user just want to use an exported class
>> of M2 so a user may want to only require M2, and because a class of an
>> exported package of M1 is part of the public 'interface' of a class of an
>> exported package of M2, M1 is declared as 'require public' in the
>> module-info of M2.
>> 
>> The 'requires public' can be calculated automatically by the IDE (or any
>> other tools that take a look to the classes that are parts of the API) and
>> i'm pretty sure all IDEs will support that sooner than later.
>> 
>> Currently, a Maven POM has no feature likes 'require public', should that
>> feature be introduced or should Maven stick with requiring all modules and
>> it's transitive dependencies that are part of the API, i don't know, but i
>> fail to see why it has an impact on the java platform module spec. It's up
>> to the Maven guys to decide what is better for Maven and the community
>> around.
>> 
>> regards,
>> Rémi
>> 
>> ----- Mail original -----
>>> De: "Paul Benedict" <pbenedict at apache.org>
>>> À: "ZML-OpenJDK-Jigsaw-Developers" <jigsaw-dev at openjdk.java.net>
>>> Envoyé: Mardi 26 Juillet 2016 20:35:05
>>> Objet: Weakness of "requires public"
>> 
>>> In a modularized world, I don't see "requires public" delivering the
>> value
>>> it should.
>>> 
>>> Let's take this example:
>>> module java.sql {
>>>   requires public java.logging;
>>>   requires public java.xml;
>>>   exports java.sql;
>>>   exports javax.sql;
>>>   exports javax.transaction.xa;
>>> }
>>> 
>>> Given a theoretical Maven POM representing the "java.sql" module, the POM
>>> would have to list out the other two modules so that my project compiles
>>> against all declared modules. It is considered bad practice to compile
>>> against artifacts I did not declare in my POM. There are three artifacts
>>> here.
>>> 
>>> Would any Maven experts here disagree? I see the positive of "requires
>>> public" to be negated in build systems. Given what I just found, I do not
>>> like the idea of public transitive dependencies in the Module Descriptor.
>>> For developers using build systems, I believe "requires public" should be
>>> avoided.
>>> 
>>> Cheers,
>>> Paul
>> 



More information about the jigsaw-dev mailing list