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
• 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