Java Platform Module System

Alex Buckley alex.buckley at
Mon May 1 20:06:08 UTC 2017

On 4/30/2017 4:10 AM, Stephan Herrmann wrote:
> No. (B) may be true for your example, but it is not for the following
> (which is similar to examples we had in our January thread):
> //-- M/
> module M { exports pm; }
> //-- M/impl/
> package impl;
> public class Other { }
> //-- M/pm/
> package pm;
> import impl.Other;
> public class C1 extends Other {
>      public void m1(Other o) {}
> }
> //--
> //-- O/
> module O { requires M; }
> //-- O/impl/
> package impl;
> public class Other { }
> //-- O/po/
> package po;
> import pm.C1;
> public class Client {
>      void test1(C1 one) {
>          one.m1(one);
>      }
> }
> //--
> Looking at O, and trying to determine whether the method invocation
> one.m1(one)
> is legal, M's type impl.Other is *relevant*, because analysis must ...
> - detect that the type reference "Other" in the signature of m1 refers
> to the
>    type defined in M, not to the same-named type in O.
> - similarly detect that the type reference in C1's class header (or
> superclass
>    classfile attribute) refers to M's impl.Other.
> - conclude from the above, that C1 is compatible to m1's parameter.
> Ergo, the set of types relevant from the perspective of O contains two
> same-named types.

Per 7.3, it's true that when compiling any observable ordinary 
compilation units associated with O (such as O/po/, the host 
system must limit the ordinary compilation units that would otherwise be 
observable, to only those that are visible to O. Since O requires M, and 
since M/impl/ is an observable ordinary compilation unit 
associated with M, we have that M/impl/ is visible to O.

Then, by 6.3, the scope of M's top-level impl package is all observable 
compilation units in O.

Then, we get the difficulty in, because two top-level packages 
called impl are visible to code in O.

I specified package visibility in 7.3 in the way I did -- not 
considering exports -- in order to encourage compilers to take a "wide 
view" of what packages are physically present in required modules, even 
if a package isn't exported (M's package impl) and thus its types won't 
be accessible (M's type impl.Other isn't accessible to code in O).

For example, if M's author forgets to export impl (quite possible when M 
is first declared), I'd like a tool processing O to have the words to 
say: "impl is /visible/ in M, but not exported, so none of its types -- 
not even its 'public' types -- can be accessed".

> If Java 9 permits this situation, it not only hugely increases the
> complexity
> of all tools that need to "understand" this program, it also wastes a
> unique
> opportunity that JPMS has, which existing module systems did not have:
> Java 9 could make "API leaks" either illegal or ineffective and thus
> rule out
> an entire category of ill-formed programs, which to-date must unfortunately
> be accepted by module-unaware compilers:
>    (A) Java 9 has the opportunity to say that the declaration of m1 is
> illegal,
>    because it publicly exposes a non-accessible type, which is broken in
>    every regard.
>    (B) Alternatively, Java 9 has the opportunity to say that any attempt to
>    invoke m1 from outside M is illegal, because clients would need to know
>    about an inaccessible type.

Understood, but we didn't take those directions. More here:


More information about the jigsaw-dev mailing list