JPMS Module Path question

Alex Buckley alex.buckley at oracle.com
Wed Jun 14 18:59:12 UTC 2017


On 6/14/2017 5:59 AM, Peter Kriens wrote:
> I am trying to formally specify JPMS using Alloy. One of the questions that is popping up is about the consistency of the Module Path.
>
> The Module Path is defined as a set of directories (and files?) containing modules. Duplicate names seem to be disallowed in one directory but allowed between directories (and files?), where the first one wins. (Though useful for overrides, it is a rather error prone solution as we learned from the linear search of the class path).
>
> However, I cannot seem to find consensus on the consistency of modules in this module path. Must the set of available modules on the module path be consistent or is there no relation between these modules. For example, can these modules contain the same package?

First, please review the latest updates to the java.lang.module API spec 
-- 
http://cr.openjdk.java.net/~mr/jigsaw/spec/api/java/lang/module/package-summary.html.

Then, it'll be clear that you should be defining two functions: one to 
compute the readability graph, and one to determine the observability of 
a module. These are Java SE concepts.

The observability of a module is "implemented" by searching some paths, 
such as the upgrade module path and the application module path. These 
are not Java SE concepts but rather JDK concepts defined in JEP 261 and 
mentioned for color in the java.lang.module API spec.

The path-oriented implementation of observability is unconcerned with 
the consistency of modules that are physically found on paths. Let's 
look at your example, assuming the modulepath = dir-x:dir-y.

> That is, is the module path a giant repository and will a resolution pick out the needed modules and verify this subset for consistency, or is it supposed to be a subset optimised for an application?
>
> For example:
>
> 	dir-x: A { exports a, requires B }
This module is observable. I note that this module 'exports a', which I 
am going to take to mean 'contains and exports a', because there is no 
"re-exporting" of other modules' APIs in the JPMS.

> 	dir-x: B { exports b }
This module is observable. I note that this module 'exports b', which I 
am going to take to mean 'contains and exports b'.

> 	dir-x: C { requires A,D }
This module is observable.

> 	dir-y: D { contains a, b }
This module is observable.

> 	dir-y: A { exports a, b }
This module is NOT observable. Informally speaking, it's shadowed by the 
A in dir-x.

> Loading A would be ok but loading C would fail. Is it intended that you can have potentially inconsistent modules?

The java.lang.module API spec never speaks of modules being loaded. 
Modules are resolved. Suppose the root module to be resolved is C. C is 
observable, and the recursive enumeration of required modules will 
succeed because A, B, and D are observable. To cut a long story short, 
resolution will succeed; a readability graph is produced; a 
java.lang.module.Configuration object is produced.

There could be thousands of other modules observable in dir-x and dir-y, 
all containing packages called a and b, but no-one requires them so 
resolution does not enumerate them.

Anyway, it remains to reify this readability graph into class loaders 
that can load the classes contained in the modules indicated by the 
graph. In other words, it remains to build a ModuleLayer object out of 
the Configuration object. Here are your options:

- If you try to build a single-loader layer, you will get an exception 
because two modules in the readability graph (A and D) contain a package 
(a) with the same name. This is what happens for "java -m C".

- If you try to build a multi-loader layer, you will succeed because 
each module C, A, B, and D will be mapped to its own loader.

We are now a great distance beyond observability and paths. We've 
progressed to thinking about readability and, because of class loader 
creation, about visibility. The final step is of course accessibility, 
which brings it own challenges because of wanting to support run-time 
access (VM symbolic resolution of constant pool entries) distinct from 
reflective access (java.lang.reflect API). But I think you should have a 
better picture now of what modular JARs (and exploded directories) can 
be placed on a path for observation.

Alex


More information about the jpms-spec-observers mailing list