Proposal: #ResourceEncapsulation & #ClassFilesAsResources (revised)

David M. Lloyd david.lloyd at redhat.com
Mon Sep 12 21:06:58 UTC 2016


We are also reviewing this one internally and will respond soon.

On 09/12/2016 10:10 AM, Mark Reinhold wrote:
> 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
>

-- 
- DML


More information about the jpms-spec-experts mailing list