Weakness of "requires public"

forax at univ-mlv.fr forax at univ-mlv.fr
Tue Jul 26 22:24:57 UTC 2016


----- Mail original -----
> De: "Neil Bartlett" <njbartlett at gmail.com>
> À: "Malachi de Ælfweald" <malachid at gmail.com>
> Cc: "Remi Forax" <forax at univ-mlv.fr>, "ZML-OpenJDK-Jigsaw-Developers" <jigsaw-dev at openjdk.java.net>
> Envoyé: Mardi 26 Juillet 2016 23:54:06
> Objet: Re: Weakness of "requires public"

> 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.

yes,
like when you change a method public to be private.
Changing 'require public' to 'require' is not a backward compatible change.

> 
> 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.

Inheritance in Java 8 doesn't ask for visibility of the full hierarchy,
by example, you can hide an abstract class (like java.lang.AbstractStringBuilder) easily without much trouble.

and yes, inheritance creates a strong coupling between a super class and a subclass to the point it makes it useless to use it across packages or modules.

> 
> Regards,
> Neil

Rémi

> 
> 
> 
>> 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