Proposal: #ResourceEncapsulation & #ClassFilesAsResources (revised)

Mark Reinhold mark.reinhold at oracle.com
Mon Sep 12 15:10:01 UTC 2016


Issue summaries
---------------
 #ClassFilesAsResources --- If a type is visible and was loaded from a
 class file then it should be possible to read that file by invoking the
 `getResourceAsStream` method of the type's class loader, as it is in
 earlier releases. [1]
 #ResourceEncapsulation --- The `Module::getResourceAsStream` method can
 be used to read the resources of any named module, without restriction,
 which violates the resource-encapsulation requirement [2]. This method
 should be restricted somehow so that only "suitably-privileged" code
 (for some definition of that term) can access resources in a named
 module other than its own. An alternative is to drop this
 requirement. [3]
Proposal
--------
Extend the notion of private exports, introduced nearby in the revised
proposal for #ReflectiveAccessToNonExportedTypes, to govern whether a
resource defined in a named module can be located by code in some other
module.
Resources are named by URL-like path strings. The _effective package
name_ of an absolute resource name is computed by removing the initial
slash character, removing the final slash character (`'/'`) and any
subsequent characters, and then converting any remaining slash characters
to periods (`'.'`). The effective package name of a resource named by
the string `"/foo/bar/baz"`, e.g., is 'foo.bar'. The effective package
name of a relative resource name is computed by resolving the resource
name against a particular class, as if by the `Class::getResource`
method, and then computing the effective package name of the result.
For a resource defined in a named module we impose the following
restrictions upon code in other modules:
 - If a resource's name ends in `".class"` then it can be located by
 code in any module.
 - If a resource's effective package name is not a valid Java language
 package name (e.g., `"META-INF.foo.bar"`) [4] then the resource can
 be located by code in any module.
 - If the package is exported privately, without qualification, then the
 resource can be located by code in any module.
 - If the package is exported privately to a specific set of modules
 then the resource can be located by code in those modules.
 - If the package is not exported privately in any way then the resource
 cannot be located by code outside of the module itself.
We revise the various `getResource*` methods to impose the above
constraints:
 - The `Module::getResourceAsStream` method allows a resource to be
 located directly within a module, without first having to load a
 class from that module. This method is caller-sensitive.
 - The `Class::getResource*` methods, when invoked upon a class defined
 in a named module, only locate resources from within that module.
 These methods are also caller-sensitive.
 - The `ClassLoader::getResource*` methods will locate resources in
 named modules subject to the above restrictions except that the
 effective package of the resource must be exported privately without
 qualification, since this method is not caller-sensitive. Custom
 class loaders that locate resources in modules should implement these
 restrictions, but there is no way to force them to do so. The order
 of the elements of an enumeration returned by the `getResources`
 method is unspecified, but for a given class loader `cl` the values
 of `cl.getResources(name).nextElement()` and `cl.getResource(name)`
 are always equal.
Every package in an unnamed, automatic, or weak module is exported
privately, so all of the resources in such modules can be located by
code in all other modules.
Notes
-----
 - The first proposal for these issues [5] suggested that we simply drop
 the agreed resource-encapsulation requirement [2]. As suggested both
 in the EG [6] and elsewhere [7][8], this revised proposal attempts to
 strike a balance between practical compatibility and modular
 encapsulation.
 - This proposal leverages private exports, i.e., the `exports private`
 directive, since the internal resources of a module are much like the
 non-public elements of the types defined in a module. This avoids
 leaking resources inadvertently from packages that are exported
 normally, i.e., without the `private` modifier. It also avoids the
 need to extend the syntax and semantics of module declarations with
 a completely new directive just for resources, which seems like
 overkill.
[1] http://openjdk.java.net/projects/jigsaw/spec/issues/#ClassFilesAsResources
[2] http://openjdk.java.net/projects/jigsaw/spec/reqs/#resource-encapsulation
[3] http://openjdk.java.net/projects/jigsaw/spec/issues/#ResourceEncapsulation
[4] http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-PackageName
[5] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2016-June/000309.html
[6] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2016-June/000322.html
[7] http://mail.openjdk.java.net/pipermail/jpms-spec-comments/2016-June/000050.html
[8] http://mail.openjdk.java.net/pipermail/jpms-spec-comments/2016-June/000051.html


More information about the jpms-spec-experts mailing list

AltStyle によって変換されたページ (->オリジナル) /