Java Platform Module System

classic Classic list List threaded Threaded
37 messages Options
12
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Java Platform Module System

Jayaprakash Artanareeswaran
Hello everyone,


The JLS makes references to the "Java Platform Module System" in several places but we are not sure where this is specified. The Eclipse JDT team has been making do with whatever informal documents we can get our hands on such as "State of the Module System", Javac etc. It would be really nice to get some update on this as this would give us the much needed confidence that we (JDT) are indeed going in the right direction.


Regards,

Jay
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

mark.reinhold
2017/4/24 9:14:31 -0700, [hidden email]:
> The JLS makes references to the "Java Platform Module System" in
> several places but we are not sure where this is specified. The
> Eclipse JDT team has been making do with whatever informal documents
> we can get our hands on such as "State of the Module System", Javac
> etc. It would be really nice to get some update on this as this would
> give us the much needed confidence that we (JDT) are indeed going in
> the right direction.

JSR 376 home page: http://openjdk.java.net/projects/jigsaw/spec/

Current draft specification, linked from that page:
http://cr.openjdk.java.net/~mr/jigsaw/spec/

- Mark
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
On 24.04.2017 18:18, [hidden email] wrote:

> 2017/4/24 9:14:31 -0700, [hidden email]:
>> The JLS makes references to the "Java Platform Module System" in
>> several places but we are not sure where this is specified. The
>> Eclipse JDT team has been making do with whatever informal documents
>> we can get our hands on such as "State of the Module System", Javac
>> etc. It would be really nice to get some update on this as this would
>> give us the much needed confidence that we (JDT) are indeed going in
>> the right direction.
>
> JSR 376 home page: http://openjdk.java.net/projects/jigsaw/spec/
>
> Current draft specification, linked from that page:
> http://cr.openjdk.java.net/~mr/jigsaw/spec/
>
> - Mark
>

Thanks. Unfortunately, these links, which we've been using all along, don't
provide the answers we were hoping for.


As of today your references seem to point to the same version as submitted for
Public Review:
   "Java Platform Module System Public Review (updated 14 April 2017)"

The main index.html surely states
   "This specification defines the Java Platform Module System"

Obviously, defining JPMS is not done in index.html itself but delegated
to individual documents.

One of the linked documents is a version of JLS with changes on behalf of JSR 376.

Jay's question was triggered by the observation that this exact version of JLS
contains references like these:
  - "the host system must use the Java Platform Module System to determine ..."
  - "A 'dependency' is the module resolved by the Java Platform Module System
    for a given requires directive."
  - "The Java programming language does not distinguish between named modules
    specified explicitly in module declarations versus named modules specified by the
    Java Platform Module System when it detects a JAR file on the modulepath
    ('automatic modules')"

This creates the impression that for implementing a compiler for JPMS another
document must be consulted in addition to JLS, but the reference "specified by the JPMS"
gives no clue were to look, as it appears inside the specification of JPMS.

We could happily brush these question aside - as a curiosity in JLS wording -
iff JLS would unambiguously tell us how to implement the compiler in a way
that guarantees equivalence to javac. Unfortunately, we don't see how the
current draft of JLS could fulfill this task. That's why we were hoping for
some additional document that might have escaped our attention.

Stephan

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
On 4/24/2017 5:22 PM, Stephan Herrmann wrote:

> Obviously, defining JPMS is not done in index.html itself but delegated
> to individual documents.
>
> One of the linked documents is a version of JLS with changes on behalf
> of JSR 376.
>
> Jay's question was triggered by the observation that this exact version
> of JLS contains references like these:
>   - "the host system must use the Java Platform Module System to
> determine ..."
>   - "A 'dependency' is the module resolved by the Java Platform Module
> System
>     for a given requires directive."
>   - "The Java programming language does not distinguish between named
> modules
>     specified explicitly in module declarations versus named modules
> specified by the
>     Java Platform Module System when it detects a JAR file on the
> modulepath
>     ('automatic modules')"
>
> This creates the impression that for implementing a compiler for JPMS
> another document must be consulted in addition to JLS, but the
> reference "specified by the JPMS" gives no clue were to look, as it
> appears inside the specification ofJPMS.

Dependency resolution in JPMS is accomplished by the static 'resolve'
method of java.lang.module.Configuration.

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
On 25.04.2017 03:50, Alex Buckley wrote:

> On 4/24/2017 5:22 PM, Stephan Herrmann wrote:
>> Obviously, defining JPMS is not done in index.html itself but delegated
>> to individual documents.
>>
>> One of the linked documents is a version of JLS with changes on behalf
>> of JSR 376.
>>
>> Jay's question was triggered by the observation that this exact version
>> of JLS contains references like these:
>>   - "the host system must use the Java Platform Module System to
>> determine ..."
>>   - "A 'dependency' is the module resolved by the Java Platform Module
>> System
>>     for a given requires directive."
>>   - "The Java programming language does not distinguish between named
>> modules
>>     specified explicitly in module declarations versus named modules
>> specified by the
>>     Java Platform Module System when it detects a JAR file on the
>> modulepath
>>     ('automatic modules')"
>>
>> This creates the impression that for implementing a compiler for JPMS
>> another document must be consulted in addition to JLS, but the
>> reference "specified by the JPMS" gives no clue were to look, as it
>> appears inside the specification ofJPMS.
>
> Dependency resolution in JPMS is accomplished by the static 'resolve' method of java.lang.module.Configuration.
>
> Alex

Interesting.
Are you saying the semantics of JPMS depends on the implementation
of one or more methods in java.lang.module.Configuration and friends?
Are all mentions of JPMS inside JLS intended as references into JDK API?
How are compiler engineers expected to use this information?

Stephan
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
On 4/25/2017 1:20 AM, Stephan Herrmann wrote:
> On 25.04.2017 03:50, Alex Buckley wrote:
>> Dependency resolution in JPMS is accomplished by the static 'resolve'
>> method of java.lang.module.Configuration.
>
> Interesting.
> Are you saying the semantics of JPMS depends on the implementation
> of one or more methods in java.lang.module.Configuration and friends?
> Are all mentions of JPMS inside JLS intended as references into JDK API?
> How are compiler engineers expected to use this information?

JPMS semantics (notably, dependency resolution) are defined by the API
specification (not the implementation) of java.lang.module.Configuration
and friends. JLS references to JPMS are references to this Java SE API.

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
On 25.04.2017 19:02, Alex Buckley wrote:

> On 4/25/2017 1:20 AM, Stephan Herrmann wrote:
>> On 25.04.2017 03:50, Alex Buckley wrote:
>>> Dependency resolution in JPMS is accomplished by the static 'resolve'
>>> method of java.lang.module.Configuration.
>>
>> Interesting.
>> Are you saying the semantics of JPMS depends on the implementation
>> of one or more methods in java.lang.module.Configuration and friends?
>> Are all mentions of JPMS inside JLS intended as references into JDK API?
>> How are compiler engineers expected to use this information?
>
> JPMS semantics (notably, dependency resolution) are defined by the API specification (not the implementation) of
> java.lang.module.Configuration and friends. JLS references to JPMS are references to this Java SE API.
>
> Alex

Got it. Since now JLS is no longer self-contained it would tremendously
help if we could get a list of which parts of the API specification are
expected to be considered at compile time. I understand that we need to
apply the naming rules for automatic modules. Is there more that should
be respected / validated / enforced at compile time?



Let me add a friendly reminder, that we are still waiting for a
specification that unambiguously tells us which module system to implement.
For illustration:

(A) Is JPMS a module system that keeps the semantics of qualified names as
they are in Java 8 and only superimposes encapsulation boundaries?
(i.e., each type is globally uniquely identified by its qualified name).

(B) Is JPMS a module system that maintains the assumption that from the
perspective of each module all relevant types can be distinguished using
their qualified name?
(i.e. admitting identical qualified names as long as no compilation of one
module will ever encounter several candidates at once).

(C) Is JPMS a module system that establishes a separate namespace for each
module, where types with identical qualified name - but defined in different
modules - need to be distinguished?
(i.e., uniqueness is primarily required for module-prefixed qualified names).


Despite some efforts I fail to find a definite answer in JLS (and Alex
mentioned that some of this is still being discussed). Still JLS as of today
sounds mostly like (A). To me (B) sounds like the natural choice, but I
understood Alex as saying it *should* be (C). I don't see, however, how the
conceptual framework of JLS could possibly support such design.


Stephan

PS: I'm also having hard times to imagine, how those parts of the
specification, that are focused on compilation units, can possibly define
aspects like accessibility when looking at .class files, not compilation
units - but hopefully, this is just a technicality in how the spec is worded,
not a conceptual problem.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
On 4/27/2017 12:38 PM, Stephan Herrmann wrote:

> On 25.04.2017 19:02, Alex Buckley wrote:
>> JPMS semantics (notably, dependency resolution) are defined by the API
>> specification (not the implementation) of
>> java.lang.module.Configuration and friends. JLS references to JPMS are
>> references to this Java SE API.
>
> Got it. Since now JLS is no longer self-contained it would tremendously
> help if we could get a list of which parts of the API specification are
> expected to be considered at compile time. I understand that we need to
> apply the naming rules for automatic modules. Is there more that should
> be respected / validated / enforced at compile time?

The JLS was never self-contained as it always referenced a variety of
java.lang and java.io types (and more recently java.lang.annotation and
java.lang.invoke types). I have changed 7.3 to state:

"The host system must use the Java Platform Module System (as if by
execution of the 'resolve' method of java.lang.module.Configuration) to
determine which modules are read by M (§7.7.1). It is a compile-time
error if the Java Platform Module System is unable to determine which
modules are read by M."

That is, if a compiler processes a module declaration mentioning
"requires X;", and the "as if" JPMS resolution fails because no module
called "X" is found (whether an explicitly declared module with that
name, or an implicitly declared i.e. automatic module with that name),
then compilation fails too. The mapping from a JAR filename to an
implicitly declared i.e. automatic module name is part of JPMS
resolution. And even if a module called "X" is found, there are other
reasons why JPMS resolution (and hence compilation) can fail, e.g. the
module requiring X also requires Y and both X and Y export the same
package. The JLS, as is traditional, allows a compiler to be as helpful
or as terse as it likes w.r.t. the content of the compile-time error
message.

> Let me add a friendly reminder, that we are still waiting for a
> specification that unambiguously tells us which module system to implement.
> For illustration:
>
> (A) Is JPMS a module system that keeps the semantics of qualified names as
> they are in Java 8 and only superimposes encapsulation boundaries?
> (i.e., each type is globally uniquely identified by its qualified name).
>
> (B) Is JPMS a module system that maintains the assumption that from the
> perspective of each module all relevant types can be distinguished using
> their qualified name?
> (i.e. admitting identical qualified names as long as no compilation of one
> module will ever encounter several candidates at once).
>
> (C) Is JPMS a module system that establishes a separate namespace for each
> module, where types with identical qualified name - but defined in
> different modules - need to be distinguished?
> (i.e., uniqueness is primarily required for module-prefixed qualified
> names).
>
> Despite some efforts I fail to find a definite answer in JLS (and Alex
> mentioned that some of this is still being discussed). Still JLS as of
> today sounds mostly like (A). To me (B) sounds like the natural choice, but I
> understood Alex as saying it *should* be (C). I don't see, however, how the
> conceptual framework of JLS could possibly support such design.

(B) and (C) are not mutually exclusive because (B) was worded from the
perspective of each module while (C) was not.

(B) is true. Assume two modules M and N each contain the type P.C, but
neither module exports P (or, M exports P and N doesn't, or, N exports P
and M doesn't). Then, a third module O can require M and N. If code in
any module refers statically to a type P.C, then JPMS resolution
guarantees that P.C is either defined by that module or is exported to
the module by exactly one other module which the module reads.

At run time, when 'java' is run with M+N+O on the modulepath, the system
will stop -- M+N+O will pass resolution (i.e. a Configuration will be
constructed) but they can't all be mapped to the application class
loader. javac will produce a lint warning to this effect. However, M and
N and O are by no means "bad" modules, either individually or jointly,
as M+N+O will work if mapped to a multi-loader layer. So, (C) is true too.

The JLS, as is traditional with classes and packages, does not restrict
the modules which can be given as input for an invocation of a compiler.
A compiler is assumed to be able to process multiple modules at once. In
the case of M and N, a compiler will encounter P.C in M and P.C in N,
and is expected to distinguish them -- code in M refers to P.C in M
while code in N refers to P.C in N. This (C)-style property is now
expressed in 4.3.4:

"Two reference types are the same compile-time type if they are declared
in compilation units associated with the same module (§7.3), and they
have the same binary name (§13.1), and their type arguments, if any, are
the same, applying this definition recursively."

> PS: I'm also having hard times to imagine, how those parts of the
> specification, that are focused on compilation units, can possibly define
> aspects like accessibility when looking at .class files, not compilation
> units - but hopefully, this is just a technicality in how the spec is
> worded, not a conceptual problem.

The JLS has never said how a compiler should process a mix of
compilation units and .class files, yet compilers have figured it out.
Everything in 7.3 about the host system associating compilation units
with modules is applicable to associating class files with modules.

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
On 29.04.2017 01:25, Alex Buckley wrote:
> On 4/27/2017 12:38 PM, Stephan Herrmann wrote:
>> Got it. Since now JLS is no longer self-contained it would tremendously
>> help if we could get a list of which parts of the API specification are
>> expected to be considered at compile time. I understand that we need to
>> apply the naming rules for automatic modules. Is there more that should
>> be respected / validated / enforced at compile time?
>
> The JLS was never self-contained as it always referenced a variety of java.lang and java.io types (and more recently
> java.lang.annotation and java.lang.invoke types).

You're right. Still the degree of dependence has changed.

> I have changed 7.3 to state:
>
> "The host system must use the Java Platform Module System (as if by execution of the 'resolve' method of
> java.lang.module.Configuration) to determine which modules are read by M (§7.7.1). It is a compile-time error if the Java Platform
> Module System is unable to determine which modules are read by M."

Thanks, this looks like a good start.

For the question at hand, this is what we learn from that improved reference:
   "A readability graph is constructed"

Now we only need a link to the specification that *defines* what is a
readability graph and what is the meaning of "m1 reads m2".
I assume, you want to add a further reference to the "Resolution"
section of the package specification for java.lang.module?


     BTW: while pondering if the given package specification is sufficient,
     I wonder if "requires transitive" should work through multiple levels:
       M1
       M2 requires transitive M1
       M3 requires transitive M2
       M4 requires M3
     Does M4 read M1?
     Looking at 7.7.1:
       "The requires keyword may be followed by the modifier transitive. This causes
        any module which depends on the current module to have an implicitly declared
        dependence on the module specified by the requires transitive directive."
     Am I right in assuming that "depends" should cover explicitly and implicitly
     declared dependences? Taking into consideration the subtlety about dependence
     vs. dependency, may I suggest adding s.t. like
       "A module M1 is said to depend on another module M2, if it has an explicitly
        or implicitly declared dependence on M2."
     (this also makes "depends" a technical term rather than the general (fuzzy)
      English word).


 > The JLS, as is traditional, allows a compiler to be as helpful or as terse as it likes w.r.t. the content of the compile-time
error message.

That's totally fine.


Revisiting other references to "Java Platform Module System" inside JLS,
what about the two occurrences in the body of 7.7:

- One reference is used to discriminate "dependence" from "dependency":
   From a quick scan, I believe this sentence:
     "Generally, the  rules  of  the  Java  programming  language  are
      more  interested  in  dependences  than dependencies."
   can probably be made stronger:
     "The rules of the Java programming language are not interested in
      dependencies, only in dependences.".
   Or perhaps the paragraph about dependencies could be removed entirely.
   If this interpretation is wrong, another reference to detailed specification
   would be needed. Perhaps it is only JLS, that is agnostic to dependencies,
   whereas the API specification part indeed uses this concept?

- Another reference links "automatic modules" into JLS and will probably
   link to ModuleFinder.of(Path...), right?


best,
Stephan


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
In reply to this post by Alex Buckley
On 29.04.2017 01:25, Alex Buckley wrote:

> On 4/27/2017 12:38 PM, Stephan Herrmann wrote:
>> For illustration:
>>
>> (A) Is JPMS a module system that keeps the semantics of qualified names as
>> they are in Java 8 and only superimposes encapsulation boundaries?
>> (i.e., each type is globally uniquely identified by its qualified name).
>>
>> (B) Is JPMS a module system that maintains the assumption that from the
>> perspective of each module all relevant types can be distinguished using
>> their qualified name?
>> (i.e. admitting identical qualified names as long as no compilation of one
>> module will ever encounter several candidates at once).
>>
>> (C) Is JPMS a module system that establishes a separate namespace for each
>> module, where types with identical qualified name - but defined in
>> different modules - need to be distinguished?
>> (i.e., uniqueness is primarily required for module-prefixed qualified
>> names).
>>
>> Despite some efforts I fail to find a definite answer in JLS (and Alex
>> mentioned that some of this is still being discussed). Still JLS as of
>> today sounds mostly like (A). To me (B) sounds like the natural choice, but I
>> understood Alex as saying it *should* be (C). I don't see, however, how the
>> conceptual framework of JLS could possibly support such design.
>
> (B) and (C) are not mutually exclusive because (B) was worded from the perspective of each module while (C) was not.
>
> (B) is true.

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-info.java
module M { exports pm; }

//-- M/impl/Other.java
package impl;
public class Other { }

//-- M/pm/C1.java
package pm;
import impl.Other;
public class C1 extends Other {
        public void m1(Other o) {}
}
//--
//-- O/module-info.java
module O { requires M; }

//-- O/impl/Other.java
package impl;
public class Other { }

//-- O/po/Client.java
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.


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.


For comparison note, that the following is already illegal:


//-- M/module-info.java
module M { exports pm; }

//-- M/impl/Func.java
package impl;
public interface Func {
        void show(Object o);
}

//-- M/pm/C1.java
package pm;
import impl.Func;
public class C1 {
        public void m2(Func f) {}
}
//--
//-- O/module-info.java
module O { requires M; }

//-- O/po/Client.java
package po;
import pm.C1;
public class Client {
        void test2(C1 one) {
                one.m2(a -> {}); // javac: error: Func is not visible
        }
}
//--

Interestingly, Client is now rejected due to an attempt to "implicitly
access" an inaccessible type, which is backed by 15.27.3 saying:
   "It is a compile-time error if any class or interface mentioned by either
    U or the function type of U is not accessible (§6.6) from the class or
    interface in which the lambda expression appears."

The same reasoning should also apply to the attempt to invoke m1 above.

Otherwise, add type inference to the mix, and open a can of inconsistencies,
giving abundant material for lots of confused discussions on StackOverflow.

Stephan

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alan Bateman
On 30/04/2017 12:10, Stephan Herrmann wrote:

> :
>
> 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.
FWIW, this is -Xlint:exports when using javac, e.g: public class in a
non-exported package:

src/m/p/C1.java:4: warning: [exports] class C2 in module m is not exported
     public q.C2 hello() { return null; }
             ^
1 warning

or a non-public class in an exported package:

src/m/p/C1.java:4: warning: [exports] class C2 in module m is not
accessible to clients that require this module
     public C2 hello() { return null; }
            ^
1 warning

-Alan


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
On 30.04.2017 17:47, Alan Bateman wrote:

> On 30/04/2017 12:10, Stephan Herrmann wrote:
>
>> :
>>
>> 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.
> FWIW, this is -Xlint:exports when using javac, e.g: public class in a non-exported package:
>
> src/m/p/C1.java:4: warning: [exports] class C2 in module m is not exported
>     public q.C2 hello() { return null; }
>             ^
> 1 warning
>
> or a non-public class in an exported package:
>
> src/m/p/C1.java:4: warning: [exports] class C2 in module m is not accessible to clients that require this module
>     public C2 hello() { return null; }
>            ^
> 1 warning
>
> -Alan

Thanks for the hint.

My obvious question: Is this specified (where?), or javac's own deliberation?
Even if the latter, it would be great to see a list of jigsaw related lints.

This is a step in the direction I was hoping for, but by issuing just a warning
and still accepted the program, this does not help to avoid the extra complexity
in language & tools.

best,
Stephan

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
In reply to this post by Stephan Herrmann
On 4/30/2017 3:25 AM, Stephan Herrmann wrote:
> For the question at hand, this is what we learn from that improved
> reference:
>    "A readability graph is constructed"
>
> Now we only need a link to the specification that *defines* what is a
> readability graph and what is the meaning of "m1 reads m2".
> I assume, you want to add a further reference to the "Resolution"
> section of the package specification for java.lang.module?

Yes, the API spec for java.lang.module will be updated to define the
readability relation. But instead of waiting for that, I recommend you
watch https://youtu.be/Vxfd3ehdAZc?t=18m15s because readability has been
stable for a long time.

>      BTW: while pondering if the given package specification is sufficient,
>      I wonder if "requires transitive" should work through multiple levels:
>        M1
>        M2 requires transitive M1
>        M3 requires transitive M2
>        M4 requires M3
>      Does M4 read M1?

It does work through multiple levels, in order to support arbitrary
amounts of refactoring: once you've released a module that someone else
reuses (via 'requires'), then you've committed to your module's name and
API but are free to refactor its content into deeper modules which your
original module "reuses" (via 'requires transitive') for the benefit of
consumers. There is no "re-exporting", just modules being made to read
one another.

So, going top down (because resolution starts from a set of root
modules) :- M4 requires and thus reads M3, and M3 requires transitive
M2, so M4 reads M2. Since M4 reads M2, and M2 requires transitive M1, we
have M4 reads M1.

>      Looking at 7.7.1:
>        "The requires keyword may be followed by the modifier transitive.
> This causes
>         any module which depends on the current module to have an
> implicitly declared
>         dependence on the module specified by the requires transitive
> directive."
>      Am I right in assuming that "depends" should cover explicitly and
> implicitly
>      declared dependences? Taking into consideration the subtlety about
> dependence
>      vs. dependency, may I suggest adding s.t. like
>        "A module M1 is said to depend on another module M2, if it has an
> explicitly
>         or implicitly declared dependence on M2."
>      (this also makes "depends" a technical term rather than the general
> (fuzzy)
>       English word).

I understand the point; when we clarify the API spec for readability,
I'll make sure the JLS usage of "depends" is explicitly aligned.

> Revisiting other references to "Java Platform Module System" inside JLS,
> what about the two occurrences in the body of 7.7:
>
> - One reference is used to discriminate "dependence" from "dependency":
>    From a quick scan, I believe this sentence:
>      "Generally, the  rules  of  the  Java  programming  language  are
>       more  interested  in  dependences  than dependencies."
>    can probably be made stronger:
>      "The rules of the Java programming language are not interested in
>       dependencies, only in dependences.".
>    Or perhaps the paragraph about dependencies could be removed entirely.
>    If this interpretation is wrong, another reference to detailed
> specification
>    would be needed. Perhaps it is only JLS, that is agnostic to
> dependencies,
>    whereas the API specification part indeed uses this concept?

This text is an informative note distinguishing the "dependence"
expressed rather statically in the Language, from the "dependency"
module determined rather dynamically by the JPMS. I see no reason to
change it.

> - Another reference links "automatic modules" into JLS and will probably
>    link to ModuleFinder.of(Path...), right?

This text is also an informative note. Automatic modules are discovered
through ModuleFinder.of, sure, and they appear in other places in the
java.lang.module API too -- but none of that is the point of the note.
The point of the note is that the developer doesn't specify 'requires'
any differently for an automatic module than for an explicit module.

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
In reply to this post by Alex Buckley
On 29.04.2017 01:25, Alex Buckley wrote:

> On 4/27/2017 12:38 PM, Stephan Herrmann wrote:
>> Let me add a friendly reminder, that we are still waiting for a
>> specification that unambiguously tells us which module system to implement.
>> For illustration:
>>
>> (A) Is JPMS a module system that keeps the semantics of qualified names as
>> they are in Java 8 and only superimposes encapsulation boundaries?
>> (i.e., each type is globally uniquely identified by its qualified name).
>>
>> (B) Is JPMS a module system that maintains the assumption that from the
>> perspective of each module all relevant types can be distinguished using
>> their qualified name?
>> (i.e. admitting identical qualified names as long as no compilation of one
>> module will ever encounter several candidates at once).
>>
>> (C) Is JPMS a module system that establishes a separate namespace for each
>> module, where types with identical qualified name - but defined in
>> different modules - need to be distinguished?
>> (i.e., uniqueness is primarily required for module-prefixed qualified
>> names).
>>
>> Despite some efforts I fail to find a definite answer in JLS (and Alex
>> mentioned that some of this is still being discussed). Still JLS as of
>> today sounds mostly like (A). To me (B) sounds like the natural choice, but I
>> understood Alex as saying it *should* be (C). I don't see, however, how the
>> conceptual framework of JLS could possibly support such design.
>
> [...]
> (C)-style property is now expressed in 4.3.4:
>
> "Two reference types are the same compile-time type if they are declared in compilation units associated with the same module
> (§7.3), and they have the same binary name (§13.1), and their type arguments, if any, are the same, applying this definition
> recursively."

Admitted, this part looks good. And so does 6.5.5.2.

Meanwhile I've come to the interpretation that the main weakness of JLS concerns
handling of same-named packages in different modules.

Trouble seems to start at a difference between 6.5.5.2 and 6.5.3.1/2:
To identify a type, that type must be accessible from the current module,
but for identifying a package, the package only needs to be visible.
Ergo: identifying a package does not consider exports.

Furthermore, 6.5.3.2 implies that each qualified name uniquely defines a package,
when it speaks of "the member named Id within the package named by Q". Note the
two occurrences of "the".

This finally undermines the definition of accessibility (6.6.1), when it speaks
of the "module to which the package is exported". I read this as follows:
When M1 exports p1 to M2, this makes all public members of p1 accessible in M2,
even those that belong to totally unrelated modules, which may not export p1.

I recall Alex answering "this is still being clarified / discussed" to several
questions in this area.

As a result I can only conclude: JLS still doesn't tell us which module system
to implement.


If this were just a minor omission, why then would it still be subject to
discussion, this late in the game? I see one possible explanation: changing the
spec may involve much more trouble than meets the eye. Changes concerning packages
are very much focusing on the hierarchical structure of packages and sub packages,
despite the fact that 7.1. has always been describing this structure as having
    "no significance in itself".
7.4.3 already jumps through hoops, trying to balance the hierarchy-based notion of
"technically observable" with the concept of "really observable" which disregards
the hierarchy.
In my view, a forest rooted at toplevel packages is not suitable for specifying
the rules of accessibility, where each module may have a different interpretation
of a given package name, in a way that is completely unrelated to hierarchy.
Since "exports" refers to a package, this notion must be better aligned with modules.

best,
Stephan

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
In reply to this post by Alex Buckley
On 01.05.2017 20:47, Alex Buckley wrote:
> Yes, the API spec for java.lang.module will be updated to define the readability relation.

thanks.

> But instead of waiting for that, I
> recommend you watch https://youtu.be/Vxfd3ehdAZc?t=18m15s because readability has been stable for a long time.

I thought we agreed that challenging JLS is the best service we can give to the community? :)
I prefer not to undermine my scrutiny with too much of an assumed intuitive understanding.

>>      BTW: while pondering if the given package specification is sufficient,
>>      I wonder if "requires transitive" should work through multiple levels:
>>        M1
>>        M2 requires transitive M1
>>        M3 requires transitive M2
>>        M4 requires M3
>>      Does M4 read M1?
>
> It does work through multiple levels, in order to support arbitrary amounts of refactoring: once you've released a module that
> someone else reuses (via 'requires'), then you've committed to your module's name and API but are free to refactor its content into
> deeper modules which your original module "reuses" (via 'requires transitive') for the benefit of consumers. There is no
> "re-exporting", just modules being made to read one another.
>
> So, going top down (because resolution starts from a set of root modules) :- M4 requires and thus reads M3, and M3 requires
> transitive M2, so M4 reads M2. Since M4 reads M2, and M2 requires transitive M1, we have M4 reads M1.
>
>>      Looking at 7.7.1:
>>        [...]
>
> I understand the point; when we clarify the API spec for readability, I'll make sure the JLS usage of "depends" is explicitly aligned.

Thanks, this part resolved.

>> Revisiting other references to "Java Platform Module System" inside JLS,
>> what about the two occurrences in the body of 7.7:
>>
>> - One reference is used to discriminate "dependence" from "dependency":
>>    From a quick scan, I believe this sentence:
>>      "Generally, the  rules  of  the  Java  programming  language  are
>>       more  interested  in  dependences  than dependencies."
>>    can probably be made stronger:
>>      "The rules of the Java programming language are not interested in
>>       dependencies, only in dependences.".
>>    Or perhaps the paragraph about dependencies could be removed entirely.
>>    If this interpretation is wrong, another reference to detailed
>> specification
>>    would be needed. Perhaps it is only JLS, that is agnostic to
>> dependencies,
>>    whereas the API specification part indeed uses this concept?
>
> This text is an informative note distinguishing the "dependence" expressed rather statically in the Language, from the "dependency"
> module determined rather dynamically by the JPMS. I see no reason to change it.

Asked differently: when it says
      "Generally, the rules of the Java programming language are
       more  interested  in  dependences  than dependencies."
which are the aspects where the rules of the Java programming language *are*
interested in dependencies?


>> - Another reference links "automatic modules" into JLS and will probably
>>    link to ModuleFinder.of(Path...), right?
>
> This text is also an informative note. Automatic modules are discovered through ModuleFinder.of, sure, and they appear in other
> places in the java.lang.module API too -- but none of that is the point of the note. The point of the note is that the developer
> doesn't specify 'requires' any differently for an automatic module than for an explicit module.

You make it sound as if automatic modules are relevant only at runtime.
But how then could requiring an automatic module be resolved at compile time?
Asked differently: how to you plan to ensure that different compilers can resolve
automatic modules in the same way?

best,
Stephan


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
In reply to this post by Stephan Herrmann
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-info.java
> module M { exports pm; }
>
> //-- M/impl/Other.java
> package impl;
> public class Other { }
>
> //-- M/pm/C1.java
> package pm;
> import impl.Other;
> public class C1 extends Other {
>      public void m1(Other o) {}
> }
> //--
> //-- O/module-info.java
> module O { requires M; }
>
> //-- O/impl/Other.java
> package impl;
> public class Other { }
>
> //-- O/po/Client.java
> 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/Client.java), 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/Other.java is an observable ordinary compilation unit
associated with M, we have that M/impl/Other.java 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 6.5.3.2, 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:
https://bugs.openjdk.java.net/browse/JDK-8153362

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
In reply to this post by Stephan Herrmann
On 5/1/2017 12:23 PM, Stephan Herrmann wrote:

> Meanwhile I've come to the interpretation that the main weakness of JLS
> concerns
> handling of same-named packages in different modules.
>
> Trouble seems to start at a difference between 6.5.5.2 and 6.5.3.1/2:
> To identify a type, that type must be accessible from the current module,
> but for identifying a package, the package only needs to be visible.
> Ergo: identifying a package does not consider exports.
>
> Furthermore, 6.5.3.2 implies that each qualified name uniquely defines a
> package,
> when it speaks of "the member named Id within the package named by Q".
> Note the two occurrences of "the".

Understood. I need to clarify 6.5.* to accept that multiple packages may
be visible by the same name. But when we get to accessibility, only one
of the visible packages should matter.

> This finally undermines the definition of accessibility (6.6.1), when it
> speaks
> of the "module to which the package is exported". I read this as follows:
> When M1 exports p1 to M2, this makes all public members of p1 accessible
> in M2,
> even those that belong to totally unrelated modules, which may not
> export p1.
>
> I recall Alex answering "this is still being clarified / discussed" to
> several questions in this area.
>
> As a result I can only conclude: JLS still doesn't tell us which module
> system to implement.
>
>
> If this were just a minor omission, why then would it still be subject to
> discussion, this late in the game? I see one possible explanation:
> changing the
> spec may involve much more trouble than meets the eye. Changes
> concerning packages
> are very much focusing on the hierarchical structure of packages and sub
> packages,
> despite the fact that 7.1. has always been describing this structure as
> having
>     "no significance in itself".
> 7.4.3 already jumps through hoops, trying to balance the hierarchy-based
> notion of
> "technically observable" with the concept of "really observable" which
> disregards
> the hierarchy.
> In my view, a forest rooted at toplevel packages is not suitable for
> specifying
> the rules of accessibility, where each module may have a different
> interpretation
> of a given package name, in a way that is completely unrelated to
> hierarchy.
> Since "exports" refers to a package, this notion must be better aligned
> with modules.

It's hard to respond to the same point in multiple sub-threads. Please
see my other mail where I accept that package visibility is unrelated to
'exports'.

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
In reply to this post by Stephan Herrmann
On 5/1/2017 12:40 PM, Stephan Herrmann wrote:
> Asked differently: when it says
>       "Generally, the rules of the Java programming language are
>        more  interested  in  dependences  than dependencies."
> which are the aspects where the rules of the Java programming language
> *are* interested in dependencies?

I'm sorry that this attempt to be helpful -- to distinguish the popular
term "dependency" from the actual term "dependence" used by the JLS --
is causing so much confusion. The JLS has always contained rather
open-ended text intended to add color rather than to specify an
implementation. But to answer your question: When we fix up readability
in the API, I expect the JLS will then speak more about the dependencies
which result from resolution and are more numerous than the dependences
expressed with static 'requires' directives.

>>> - Another reference links "automatic modules" into JLS and will probably
>>>    link to ModuleFinder.of(Path...), right?
>>
>> This text is also an informative note. Automatic modules are
>> discovered through ModuleFinder.of, sure, and they appear in other
>> places in the java.lang.module API too -- but none of that is the
>> point of the note. The point of the note is that the developer
>> doesn't specify 'requires' any differently for an automatic module
>> than for an explicit module.
>
> You make it sound as if automatic modules are relevant only at runtime.

Huh? The JPMS is assumed to be present at compile time, not just run
time. And automatic modules are a feature of the JPMS.

Alex
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Stephan Herrmann
On 01.05.2017 22:17, Alex Buckley wrote:

>>>> - Another reference links "automatic modules" into JLS and will probably
>>>>    link to ModuleFinder.of(Path...), right?
>>>
>>> This text is also an informative note. Automatic modules are
>>> discovered through ModuleFinder.of, sure, and they appear in other
>>> places in the java.lang.module API too -- but none of that is the
>>> point of the note. The point of the note is that the developer
>>> doesn't specify 'requires' any differently for an automatic module
>>> than for an explicit module.
>>
>> You make it sound as if automatic modules are relevant only at runtime.
>
> Huh? The JPMS is assumed to be present at compile time, not just run time. And automatic modules are a feature of the JPMS.
>
> Alex

Wait, are you expecting compilers to actually use the implementation behind
ModuleFinder etc. in order to discover modules etc.?

When you said
   "The host system must use the Java Platform Module System (as if by
    execution of the 'resolve' method of java.lang.module.Configuration)"
I read this as requesting a compiler to perform the same operation as is
specified in that API.

Was the intention behind "must use the Java Platform Module System"
to say s.t. like "must call methods of API in java.lang.module"?


Stephan
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Java Platform Module System

Alex Buckley
On 5/1/2017 1:48 PM, Stephan Herrmann wrote:

> On 01.05.2017 22:17, Alex Buckley wrote:
>>>>> - Another reference links "automatic modules" into JLS and will
>>>>> probably
>>>>>    link to ModuleFinder.of(Path...), right?
>>>>
>>>> This text is also an informative note. Automatic modules are
>>>> discovered through ModuleFinder.of, sure, and they appear in other
>>>> places in the java.lang.module API too -- but none of that is the
>>>> point of the note. The point of the note is that the developer
>>>> doesn't specify 'requires' any differently for an automatic module
>>>> than for an explicit module.
>>>
>>> You make it sound as if automatic modules are relevant only at runtime.
>>
>> Huh? The JPMS is assumed to be present at compile time, not just run
>> time. And automatic modules are a feature of the JPMS.
>>
>> Alex
>
> Wait, are you expecting compilers to actually use the implementation behind
> ModuleFinder etc. in order to discover modules etc.?
>
> When you said
>    "The host system must use the Java Platform Module System (as if by
>     execution of the 'resolve' method of java.lang.module.Configuration)"
> I read this as requesting a compiler to perform the same operation as is
> specified in that API.
>
> Was the intention behind "must use the Java Platform Module System"
> to say s.t. like "must call methods of API in java.lang.module"?

A compiler is not required to physically invoke methods of the JPMS API.
A compiler is required to determine which modules are read by each
module *as if* by execution of Configuration::resolve, a Java SE API.
The as-if term is common in Java SE Platform specs to mean "Implement it
any way you like, but the result must agree with the result from <the
thing after as-if>."

Alex
12
Loading...