----- Mail original ----- > De: "Neil Bartlett" <njbartl...@gmail.com> > À: "Malachi de Ælfweald" <malac...@gmail.com> > Cc: "Remi Forax" <fo...@univ-mlv.fr>, "ZML-OpenJDK-Jigsaw-Developers" > <jigsaw-dev@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 <malac...@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 <fo...@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" <pbened...@apache.org> >>>> À: "ZML-OpenJDK-Jigsaw-Developers" <jigsaw-dev@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