Proposal: #AddExportsInManifest
Mark Reinhold
mark.reinhold at oracle.com
Mon Sep 12 15:09:01 UTC 2016
Issue summary
-------------
#AddExportsInManifest -- Using a command-line option such as
`--add-exports` to make JDK-internal APIs available to existing code is
difficult, if not impossible, for applications that are delivered as
executable JAR files. To ease migration, consider allowing such a JAR
file to include the equivalent of such options in its `MANIFEST.MF`
file. [1]
Proposal
--------
Define two new JAR-file manifest attributes [2], `Add-Exports` and
`Add-Exports-Private`. Each attribute can occur at most once, in the
main section of a `MANIFEST.MF` file. The parameter of each attribute is
a space-separated list of slash-separated module-name/package-name pairs.
At run time the presence of a pair `m/p` in the value of each attribute
is interpreted as follows:
- If `m/p` is listed in the value of the `Add-Exports` attribute then
package `p` of module `m` is exported to all unnamed modules, as if
by invoking the `Module::addExports` method. This makes all of
package `p`'s public elements immediately accessible to code in
unnamed modules.
- If `m/p` is listed in the value of the `Add-Exports-Private`
attribute then package `p` of module `m` is exported to all unnamed
modules and its non-public elements are made available for deep
reflection, as if by invoking the `Module::addExportsPrivate` method
[3]. This makes all of package `p`'s public elements immediately
accessible to code in the unnamed module, and all of its non-public
elements accessible to code in unnamed modules via the
`setAccessible` method of the core reflection API.
In contrast to language-level module declarations some sloppiness is
allowed in the values of these attributes, as is traditional in JAR-file
manifests. A particular module-name/package-name pair can be listed more
than once in either of these attributes. It can also be listed in both
attributes, in which case the package will be exported privately. A
module or package specified in such a pair need not actually exist in
the run-time module graph.
These attributes are interpreted only in the main executable JAR file
of an application, i.e., in the JAR file specified to the `-jar`
command-line option of typical Java run-time launchers. They are
ignored in all other JAR files.
As an example, the Spring Boot framework [4] uses `setAccessible` to
access a protected `defineClass` method of `java.lang.ClassLoader` and
a private constructor of `java.lang.invoke.MethodHandles.Lookup`. An
application that uses Spring Boot can be made to work by adding the
line
Add-Exports-Private: java.base/java.lang java.base/java.lang.invoke
to the `MANIFEST.MF` file of its executable JAR file.
[1] http://openjdk.java.net/projects/jigsaw/spec/issues/#AddExportsInManifest
[2] http://download.java.net/java/jdk9/docs/technotes/guides/jar/jar.html#JAR_Manifest
[3] See the nearby proposal for #ReflectiveAccessToNonExportedTypes
[4] http://projects.spring.io/spring-boot/
More information about the jpms-spec-experts
mailing list