Weakness of "requires public"

Malachi de Ælfweald malachid at gmail.com
Tue Jul 26 22:19:11 UTC 2016


> Hopefully this will be rare. Subclassing creates a very tightly coupled
dependency and it really shouldn’t be done across module boundaries.

While I agree that subclassing is more tightly coupled than say ECS - most
subclasses are of 3rd party classes...?



Malachi de Ælfweald
http://www.google.com/profiles/malachid

On Tue, Jul 26, 2016 at 2:54 PM, Neil Bartlett <njbartlett at gmail.com> wrote:

> 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