|
Blocks :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
|
|
Relates :
|
Summary
-------
Encapsulate most of the JDK's internal APIs by default so that they are
inaccessible at compile time, and prepare for a future release in which
they will be inaccessible at run time. Ensure that critical, widely-used
internal APIs are not encapsulated, so that they remain accessible until
supported replacements exist for all or most of their functionality.
Non-Goals
---------
This JEP does not define replacements for any internal APIs; that work is
or will be covered by separate JEPs and, where appropriate, JSRs.
This JEP does not commit to preserve the compatibility of any internal
APIs across releases; they continue to remain unstable and subject to
change without notice.
Motivation
----------
Some popular libraries make use of non-standard, unstable, and
unsupported APIs that are internal implementation details of the JDK and
[were never intended for external use][sun-faq]. In the modular JDK
([JEP 200][jep-mp]), limiting access to these APIs by leveraging the
module system ([JEP 261][jep-ms]) improves the integrity and security of
the platform since many of these internal APIs define privileged,
security-sensitive operations. In the long run this change will reduce
the costs borne by the maintainers of the JDK itself and by the
maintainers of libraries and applications that, knowingly or not, make
use of these internal APIs.
[sun-faq]: http://web.archive.org/web/19980215011039/http://java.sun.com/products/jdk/faq/faq-sun-packages.html
Description
-----------
Based upon analyses of various large collections of code, including Maven
Central, and also feedback received since the release of JDK 8 and its
[dependency analysis tool][jdeps] (`jdeps`), we divide the JDK's internal
APIs into two broad categories:
- _Non-critical internal APIs_ which do not appear to be used by code
outside of the JDK or are used by outside code merely for
convenience, _i.e._, for functionality that is available in supported
APIs or can easily be provided by libraries (_e.g._,
`sun.misc.BASE64Decoder`); and
- _Critical internal APIs_ which provide critical functionality that
would be difficult, if not impossible, to implement outside of the
JDK itself (_e.g._, `sun.misc.Unsafe`).
Critical internal APIs are encapsulated in JDK 9, or not, according
to whether supported replacements exist in JDK 8. A supported
replacement is one that was either part of the Java SE 8 standard,
_i.e._, in a `java.*` or `javax.*` package, or else JDK-specific and
annotated with `@jdk.Exported`, typically in a `com.sun.*` or `jdk.*`
package. In detail:
- Critical internal APIs for which supported replacements exist in
JDK 8 are encapsulated in JDK 9.
- Critical internal APIs for which supported replacements did not exist
in JDK 8 are not encapsulated in JDK 9. A detailed list is
provided below.
- Critical internal APIs for which supported replacements exist in
JDK 9 are deprecated and will be either encapsulated or removed
in a future release.
All non-critical internal APIs are encapsulated in JDK 9.
Internal APIs that are encapsulated in JDK 9 are inaccessible at
compile time. They can be made accessible at compile time via the
`--add-exports` [command-line option][add-exports]. At run time they
remain accessible if they were in JDK 8 but in a future release they
will become inaccessible, at which point the `--add-exports` or
`--add-opens` options can be used to make them accessible at run time as
well. The `--illegal-access` option
[controls the run-time accessibility of these APIs][illegal-access] and
can be used to emulate the future run-time inaccessibility of internal
APIs.
[illegal-access]: http://openjdk.java.net/jeps/261#Relaxed-strong-encapsulation
### Critical internal APIs not encapsulated in JDK 9
The critical internal APIs that are not encapsulated in JDK 9,
because supported replacements did not exist in JDK 8, are listed
here.
- `sun.misc.{Signal,SignalHandler}`
- `sun.misc.Unsafe` (The functionality of many of the methods in this
class is available via _variable handles_
([JEP 193](http://openjdk.java.net/jeps/193)).)
- `sun.reflect.Reflection::getCallerClass(int)` (The functionality of
this method is available in the stack-walking API defined by
[JEP 259](http://openjdk.java.net/jeps/259).)
- `sun.reflect.ReflectionFactory`
- `com.sun.nio.file.{ExtendedCopyOption,ExtendedOpenOption,
ExtendedWatchEventModifier,SensitivityWatchEventModifier}`
These APIs are defined in, and exported by, the JDK-specific
`jdk.unsupported` module. This module is present in full JRE and JDK
images. These APIs are thus accessible by default to code on the class
path, and accessible to code in modules if those modules declare
dependences upon the `jdk.unsupported` module.
> **Critical internal APIs for which replacements are introduced in
JDK 9 are deprecated in JDK 9 and will be either
encapsulated or removed in a future release.**
A consequence of `jdk.unsupported` exporting and opening the `sun.misc`
and `sun.reflect` packages is that all non-critical internal APIs in
those packages were either moved to some other package or removed, as
appropriate. Standard and JDK modules that are not upgradeable should
not depend upon the `jdk.unsupported` module, but instead use proper
internal APIs.
Maintainers of libraries that use critical internal APIs for which
replacements exist in JDK 9 may wish to use
[Multi-Release JAR Files (JEP 238)][jep-mrjar] in order to ship
single artifacts that use the old APIs on releases prior to JDK 9
and the replacement APIs on later releases.
[jdeps]: https://wiki.openjdk.java.net/display/JDK8/Java+Dependency+Analysis+Tool
[jep-mp]: http://openjdk.java.net/jeps/200
[jep-ms]: http://openjdk.java.net/jeps/261
[ea]: http://jdk9.java.net/
[jep-mrjar]: http://openjdk.java.net/jeps/238
[cleaner]: https://bugs.openjdk.java.net/browse/JDK-8138696
[add-exports]: http://openjdk.java.net/jeps/261#Breaking-encapsulation
Risks and Assumptions
---------------------
If some widely-used critical internal API was not identified as critical,
and that API was moved or removed, then applications that depend upon it
will fail.
If some widely-used critical internal API was not identified as critical
but still exists then applications that depend upon it may cause a
warning to be issued in this release and will fail in a future release.
The short-term workaround for both such situations is for the end user to
expose the API via the above-mentioned command-line option; in the longer
term, in a later release the API could be moved to the `jdk.unsupported`
module and exported for external use.
The non-critical internal APIs previously present in the `sun.misc` and
`sun.reflect` packages have been either moved or removed. Existing code
that depends upon them may not work correctly.
Dependences
-----------
[JEP 200 (The Modular JDK)][jep-mp] defines the modular structure of the
JDK, and [JEP 261 (Module System)][jep-ms] implements the module system.
|