Proposal: #ResourceEncapsulation and #ClassFilesAsResources
Tim Ellison
Tim_Ellison at uk.ibm.com
Wed Jun 29 10:15:38 UTC 2016
mark.reinhold at oracle.com (Mark Reinhold) wrote on 28/06/2016 22:20:15:
> 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
> --------
>
> Drop the agreed resource-encapsulation requirement, which reads:
>
> Resource encapsulation --- The run-time system must ensure that the
> static resource files within a module are directly accessible only by
> code within that module. The existing resource-access APIs should
> continue to work as they do today when used to access a module's own
> resource files. [2]
>
> Make the following changes to the various `getResource*` methods:
>
> - The `ClassLoader::getResource*` methods will first delegate to the
> loader's parent, if any, and will then search for resources in the
> named modules defined to the loader, and will then search in the
> loader's unnamed module, typically defined by a class path. In the
> case of the `getResources` method the order of the resources in the
> returned enumeration will be unspecified, except that the values of
> `cl.getResources(name).nextElement()` and `cl.getResource(name)`
> will be equal.
>
> - The `Class::getResource*` methods will only search for resources in
> the module that defines the class. In the case of a class in an
> unnamed module this will typically result in searching the class
> path of the corresponding class loader.
>
> The `java.lang.reflect.Module::getResourceAsStream` method will remain,
> so that it's possible to look up a resource in a module without having a
> reference to a class defined in that module. It will always be the case
> that, for a given a class `c`, `c.getResourceAsStream(name)` will be
> equivalent to `c.getModule().getResourceAsStream(name)`.
>
>
> Rationale
> ---------
>
> The encapsulation of resources was intended to be part of the overall
> encapsulation story, on the view that a module's resources are just
> internal implementation details that need not, and should not, be
> available to code in other modules. Allowing external code to depend
> upon a module's internal resources is just as problematic as allowing
> such code to depend upon internal APIs.
>
> The reality of existing code today, however, is rather different, with
> two common use cases:
>
> - Resources are often used intentionally to convey information to
> external code, e.g., as a way to publish configuration files such as
> `persistence.xml`. This sort of thing should, ideally, be done via
> services [4][5], but that is not the current practice and it will
> take years to migrate to it.
>
> - Various popular tools and byte-code manipulation frameworks expect
to
> be able to load class files as resources, i.e., to access the class
> file that defines a class `p.q.C` by invoking `getResource("p.q.C")`
> on that class's loader.
>
> With the API as it stands today these use cases can still be supported,
> but the code that looks up the resource must be converted to use the
> `Module::getResourceAsStream` method. This is a barrier to migration,
> since it means that fewer existing frameworks will work out-of-the-box
> as automatic modules.
>
> We should not drop agreed requirements lightly, but now that we have
> some practical experience with an implementation of this one I think
> it's clear that the pain outweighs the gain.
>
>
> [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://mail.openjdk.java.net/pipermail/jpms-spec-experts/2015-
> October/000163.html
> [5] http://mail.openjdk.java.net/pipermail/jpms-spec-experts/2015-
> December/000207.html
> [6] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2015-
> September/004486.html
> [7] http://mail.openjdk.java.net/pipermail/jigsaw-dev/2015-November/
> 005240.html
The proposal to drop this requirement leaves no way for a module to
encapsulate
its resources. Have you considered an alternative that preserves the
compatibility
of existing APIs which I agree is desirable to support existing
applications,
but introduces a module-level resource API that allows those modules that
want
to hide their implementation details?
Regards,
Tim
Unless stated otherwise above:
IBM United Kingdom Limited - Registered in England and Wales with number
741598.
Registered office: PO Box 41, North Harbour, Portsmouth, Hampshire PO6 3AU
More information about the jpms-spec-observers
mailing list