Exporting things (Was: Re: Module-system requirements)

David M. Lloyd david.lloyd at redhat.com
Wed Feb 11 19:27:06 UTC 2015

On 02/11/2015 12:38 PM, mark.reinhold at oracle.com wrote:
> This is the first draft, and I'm sure you'll all have many comments and
> suggestions.  I'd like to finalize the requirements by the end of this
> month (February 2015), so fire away!

OK, here goes :-)

I notice that under Exports, it is defined that only packages (i.e. 
classes within those packages) are considered to be exportable, and not 
resources.  I'm not certain how I feel about that... in our 
implementation we flattened the concepts of packages and directories. 
This was mainly to solve a few specific difficulties of supporting plain 
JARs as module content; a JAR has a mix of classes and resources, and it 
is hard to deterministically tell the difference, especially when you 
can do such (commonly done) things as: 

By leveraging this approach a little more, we were able to have common 
configuration switches to do things like, export the contents of 
META-INF/services to modules which elect to import it, which is handy in 
some specific (but, in our distribution, common) use cases.

However this approach is not without its difficulties: it requires the 
modules' internal index to contain multiple entries for directories 
which commonly appear in imported modules (especially META-INF and its 
children, and the root directory).  This adds a marginal bit of 
complexity to the algorithm, but also a bit of complexity in the "human 
expectation" dimension as well.  Also we implicitly allow a module to 
"see" more than one package with the same name which can lead to various 
problems with linkage in some cases, especially of one dependency 
"overlays" another one (in particular if such overlaying is partial or 
imperfect), though in practice this has proven to only rarely be an 
issue.  To sum up though, I'd be glad to see (from my perspective) this 
behavior go away in favor of the simpler model of restricting exports to 
packages (and isolating classes and resources), but only if we can be 
reasonably sure that the use cases solved thereby are somehow sorted 
out, which include:

• Supporting this case (or determining that it is not relevant): A 
module privately uses services provided by one or more specific peer 
module(s) (via ServiceLoader), the arrangement of which is determined 
statically by distribution.
• Having (generally) the same visibility to .class files as to the 
classes themselves, from a given resource-loading entry point (Class or 
ClassLoader), i.e. if I have visibility to 
classLoader.loadClass("SomeClass"), I also have visibility to 
classLoader.getResource("SomeClass.class"), and vice-versa (any security 
restrictions aside).
• A consistent ruling on the right behavior of general resources which 
are co-packaged with classes that use them (typically loaded via e.g. 
getClass().getResourceAsStream("MyResource.properties") or similar).
• A consistent ruling on whether it makes sense generally to be able to 
export resources to dependents.

A minor, somewhat related point that this raises...

The term "dependences" (rarely-used pl. of "dependence") is used quite a 
lot in the document (whether intentional or otherwise), but I think that 
the term "dependencies" (pl. of "dependency") is probably a better term, 
and is definitely a more ubiquitous one.  The inverse of "dependency" is 
"dependent", which forms a concise term pair that we use quite a lot 
internally (i.e. if A is a dependency of B, B is a dependent of A).


More information about the jpms-spec-observers mailing list