Java 9

created onOctober 7, 2022
last modified onOctober 8, 2022

general availability on 2017-09-22

JEPs

Java 9 comes with a vast list of features. There are 91 JEPs listed in the features and schedule page for JDK 9 (see also JDK 9) .

As such a huge list is not easily digestible, I first listed the most important feature in the first section of new features. The remaining features I sorted into aeras of application. The remainder of features, where the are less than three features for an area of application, is listed in section unassorted.

The feature list in section most important new features is certainly biased. It might include features you might not expect in this section, or, on the other hand, some features you might expect in this section might be missing here. However, I assume that for the most features listed in this section there is a common agreement between Java devs that these are the most important features.

new features

the most important new features

JEP state summary /remark
JEP 102: Process API Updates standard improves the API for controlling and managing operating-system processes, i.e. for retrieving the PID of a process.
JEP 110: HTTP/2 Client incubator defines a new HTTP client API that implements HTTP/2 and WebSocket, and can replace the legacy HttpURLConnection API.
JEP 200: The Modular JDK standard uses the Java Platform Module System, specified by JSR 376 and implemented by JEP 261, to modularize the JDK.
JEP 222: jshell standard provide an interactive tool to evaluate declarations, statements, and expressions of the Java programming language, together with an API so that other applications can leverage this functionality.
JEP 223: New Version-String Scheme standard defines a version-string scheme that easily distinguishes major, minor, and security-update releases, and apply it to the JDK. The old versioning scheme was some kind of insane, i.e. JDK 7 Update 55 and JDK 7 Update 60 contain exactly the same security fixes.
JEP 269: Convenience Factory Methods for Collections standard defines library APIs to make it convenient to create instances of collections and maps with small numbers of elements, without much of verbosity.
JEP 277: Enhanced Deprecation standard enhances the @Deprecated annotation which enables to make the intent of the deprecation clearer.
JEP 280: Indify String Concatenation standard No more StringBuilder dance necessary, you can now just use "a" + "b" to concatenate Strings without any performance penalty. This is due to the change in the static String-concatenation bytecode sequence generated by javac to use invokedynamic calls to JDK library functions.

compiler

JEP state summary /remark
JEP 165: Compiler Control standard proposes an improved way to control the JVM compilers. It enables runtime manageable, method dependent compiler flags. (Immutable for the duration of a compilation.)
JEP 199: Smart Java Compilation phase two improve the sjavac tool so that it can be used by default in the JDK build, and generalize it so that it can be used to build large projects other than the JDK.
JEP 211: Elide Deprecation Warnings on Import Statements standard as of Java SE 8, java compilers are required by reasonable interpretations of the Java Language Specification to issue deprecation warnings when a deprecated type is imported by name or when a deprecated member (method, field, nested type) is imported statically. These warnings are uninformative and should not be required.
JEP 243: Java-Level JVM Compiler Interface standard develop a Java based JVM compiler interface (JVMCI) enabling a compiler written in Java to be used by the JVM as a dynamic compiler.
JEP 247: Compile for Older Platform Versions standard enhances javac so that it can compile Java programs to run on selected older versions of the platform.
JEP 276: Dynamic Linking of Language-Defined Object Models standard provides a facility for linking high-level operations on objects such as “read a property”, “write a property”, “invoke a callable object”, etc., expressed as names in INVOKEDYNAMIC call sites.
JEP 295: Ahead-of-Time Compilation standard compile Java classes to native code prior to launching the virtual machine.

concurrency

JEP state summary /remark
JEP 266: More Concurrency Updates standard an interoperable publish-subscribe framework, enhancements to the CompletableFuture API, and various other improvements.
JEP 270: Reserved Stack Areas for Critical Sections standard reserve extra space on thread stacks for use by critical sections, so that they can complete even when stack overflows occur.
JEP 285: Spin-Wait Hints standard defines an API to allow Java code to hint that a spin loop is being executed.

documentation

JEP state summary /remark
JEP 224: HTML5 Javadoc standard enhances the javadoc tool to generate HTML5 markup.
JEP 225: Javadoc Search standard add a search box to API documentation generated by the standard doclet that can be used to search for program elements and tagged words and phrases within the documentation. The search box appears in the header of all pages generated by the standard doclet.
JEP 221: New Doclet API standard provides a replacement for the Doclet API to leverage appropriate Java SE and JDK APIs, and update the standard doclet to use the new API.
JEP 299: Reorganize Documentation standard update the organization of the documents in the JDK, in both the source repositories and the generated docs.

diagnostics

JEP state summary /remark
JEP 228: Add More Diagnostic Commands standard defines additional diagnostic commands, in order to improve the diagnosability of Hotspot and the JDK.
JEP 259: Stack-Walking API standard defines an efficient standard API for stack walking that allows easy filtering of, and lazy access to, the information in stack traces.
JEP 279: Improve Test-Failure Troubleshooting standard automatically collect diagnostic information which can be used for further troubleshooting in case of test failures and timeouts. Gathering information about Java processes will be done via available diagnostic commands which are heavily extended by JEP 228: Add More Diagnostic Commands

graphics and UI

JEP state summary /remark
JEP 251: Multi-Resolution Images standard defines a multi-resolution image API so that images with resolution variants can easily be manipulated and displayed.
JEP 253: Prepare JavaFX UI Controls & CSS APIs for Modularization standard defines public APIs for the JavaFX UI controls and CSS functionality that is presently only available via internal APIs and will hence become inaccessible due to modularization.
JEP 258: HarfBuzz Font-Layout Engine standard replace the existing ICU OpenType font-layout engine with HarfBuzz. An OpenType layout engine, such as HarfBuzz, provides script-aware code to process certain font tables required for the correct rendering of text for scripts such as Arabic and Indic.
JEP 262: TIFF Image I/O standard extend the standard set of Image I/O plugins to support the TIFF image format.
JEP 263: HiDPI Graphics on Windows and Linux standard implements HiDPI graphics on Windows and Linux.
JEP 265: Marlin Graphics Renderer standard update Java 2D to use the Marlin Renderer as the default graphics rasterizer.
JEP 272: Platform-Specific Desktop Features standard defines a new public API to access platform-specific desktop features such as interacting with a task bar or dock, or listening for system or application events.
JEP 283: Enable GTK 3 on Linux standard enable Java graphical applications, whether based on JavaFX, Swing, or AWT, to use either GTK 2 or GTK 3 on Linux. Supports native GTK 2 by default, with fail forward to GTK 3. Uses GTK 3 when indicated by a system property. In cases where GTK 3 is required for interoperability, and this requirement can be detected sufficiently early, enables GTK 3 automatically.

i18n and encoding

JEP state summary /remark
JEP 226: UTF-8 Property Resource Bundles standard defines a means for applications to specify property files encoded in UTF-8, and extend the ResourceBundle API to load them.
JEP 227: Unicode 7.0 standard upgrade existing platform APIs to support version 7.0 of the Unicode Standard.
JEP 252: Use CLDR Locale Data by Default standard use locale data from the Unicode Consortium’s Common Locale Data Repository (CLDR) by default.
JEP 267: Unicode 8.0 standard upgrade existing platform APIs to support version 8.0 of the Unicode Standard.

logging

JEP state summary /remark
JEP 158: Unified JVM Logging standard introduces a common logging system for all components of the JVM.
JEP 264: Platform Logging API and Service standard define a minimal logging API which platform classes can use to log messages, together with a service interface for consumers of those messages. A library or application can provide an implementation of this service in order to route platform log messages to the logging framework of its choice. If no implementation is provided then a default implementation based upon the java.util.logging API is used.
JEP 271: Unified GC Logging standard reimplement GC logging using the unified JVM logging framework introduced in JEP 158: Unified JVM Logging .

ports

JEP state summary /remark
JEP 237: Linux/AArch64 Port standard ports JDK 9 to Linux/AArch64. AArch64 is the new processor architecture from ARM Holdings plc. It is a departure from the 32-bit ARM processor architecture, and is effectively a complete redesign.
JEP 294: Linux/s390x Port standard port JDK 9 to Linux/s390x.
JEP 297: Unified arm32/arm64 Port standard integrate the unified port of HotSpot for arm32 and arm64, contributed by Oracle, into the JDK.

security

JEP state summary /remark
JEP 219: Datagram Transport Layer Security (DTLS) standard defines an API for Datagram Transport Layer Security (DTLS) version 1.0 (RFC 4347) and 1.2 (RFC 6347).
JEP 229: Create PKCS12 Keystores by Default standard transitions the default keystore type from JKS (a custom, JDK-specific keystore type) to PKCS12.
JEP 244: TLS Application-Layer Protocol Negotiation Extension standard extends the javax.net.ssl package to support the TLS Application Layer Protocol Negotiation (ALPN) Extension, which provides the means to negotiate an application protocol for a TLS connection.
JEP 249: OCSP Stapling for TLS standard implements OCSP stapling via the TLS Certificate Status Request extension (section 8 of RFC 6066) and the Multiple Certificate Status Request Extension (RFC 6961).
JEP 273: DRBG-Based SecureRandom Implementations standard implements the three Deterministic Random Bit Generator (DRBG) mechanisms described in NIST 800-90Ar1.
JEP 287: SHA-3 Hash Algorithms standard implement the SHA-3 cryptographic hash functions (BYTE-only) specified in NIST FIPS 202.
JEP 288: Disable SHA-1 Certificates standard improves the security configuration of the JDK by providing a more flexible mechanism to disable X.509 certificate chains with SHA-1 based signatures.

unassorted

This section contains new features in areas of application where there are less than three new feature in an area of application.

JEP state summary /remark
JEP 143: Improve Contended Locking standard improves the performance of contended Java object monitors.
JEP 193: Variable Handles standard define a standard means to invoke the equivalents of various java.util.concurrent.atomic and sun.misc.Unsafe operations upon object fields and array elements, a standard set of fence operations for fine-grained control of memory ordering, and a standard reachability-fence operation to ensure that a referenced object remains strongly reachable.
JEP 213: Milling Project Coin standard some amendments to project Coin (JDK 7), including: using underscore ("_") as an identifier, generates an error in Java SE 9. Private methods for non-abstract methods in interfaces.
JEP 236: Parser API for Nashorn standard defines a supported API for Nashorn’s ECMAScript abstract syntax tree.
JEP 238: Multi-Release JAR Files standard extends the JAR file format to allow multiple, Java-release-specific versions of class files to coexist in a single archive.
JEP 260: Encapsulate Most Internal APIs preparation 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.
JEP 261: Module System standard implement the Java Platform Module System, as specified by JSR 376, together with related JDK-specific changes and enhancements.
JEP 268: XML Catalogs standard provides standard XML Catalog API that supports the OASIS XML Catalogs standard, v1.1. The API defines catalog and catalog-resolver abstractions which can be used with the JAXP processors that accept resolvers.
JEP 274: Enhanced Method Handles standard enhances the MethodHandle, MethodHandles, and MethodHandles.Lookup classes of the java.lang.invoke package to ease common use cases and enable better compiler optimizations.
JEP 275: Modular Java Application Packaging standard integrates features from Project Jigsaw into the Java Packager, including module awareness and custom run-time creation.
JEP 290: Filter Incoming Serialization Data standard allow incoming streams of object-serialization data in RMI to be filtered in order to improve both security and robustness.
JEP 292: Implement Selected ECMAScript 6 Features in Nashorn standard implement, in Nashorn, a selected set of the many new features introduced in the 6th edition of ECMA-262, also known as ECMAScript 6, or ES6 for short.

JDK internal

JEP summary /remark
JEP 197: Segmented Code Cache divides the code cache into distinct segments, each of which contains compiled code of a particular type, in order to improve performance and enable future extensions.
JEP 201: Modular Source Code reorganizes the JDK source code into modules, enhances the build system to compile modules, and enforces module boundaries at build time.
JEP 212: Resolve Lint and Doclint Warnings the JDK code base contains numerous lint and doclint errors as reported by javac. These warnings should be resolved, at least for the fundamental parts of the platform.
JEP 215: Tiered Attribution for javac implements a new method type-checking strategy in javac to speed up attribution of poly expression in argument position.
JEP 216: Process Import Statements Correctly fixes javac to properly accept and reject programs regardless of the order of import statements and extends and implements clauses.
JEP 217: Annotations Pipeline 2.0 redesigns the javac annotations pipeline to better address the requirements of annotations and tools that process annotations.
JEP 220: Modular Run-Time Images restructure the JDK and JRE run-time images to accommodate modules and to improve performance, security, and maintainability. Define a new URI scheme for naming the modules, classes, and resources stored in a run-time image without revealing the internal structure or format of the image.
JEP 232: Improve Secure Application Performance improve the performance of applications that are run with a security manager installed.
JEP 233: Generate Run-Time Compiler Tests Automatically develop a tool to test the run-time compilers by automatically generating test cases.
JEP 235: Test Class-File Attributes Generated by javac write tests to verify the correctness of class-file attributes generated by javac.
JEP 245: Validate JVM Command-Line Flag Arguments validate the arguments to all JVM command-line flags so as to avoid crashes, and ensure that appropriate error messages are displayed when they are invalid.
JEP 246: Leverage CPU Instructions for GHASH and RSA improves the performance of GHASH and RSA cryptographic operations by leveraging recently-introduced SPARC and Intel x64 CPU instructions.
JEP 248: Make G1 the Default Garbage Collector makes G1 the default garbage collector on 32- and 64-bit server configurations.
JEP 250: Store Interned Strings in CDS Archives stores interned strings in class-data sharing (CDS) archives.
JEP 254: Compact Strings adopts a more space-efficient internal representation for strings.
JEP 255: Merge Selected Xerces 2.11.0 Updates into JAXP upgrades the version of the Xerces XML parser included in the JDK with important changes from Xerces 2.11.0.
JEP 256: BeanInfo Annotations replaces @beaninfo Javadoc tags with proper annotations, and process those annotations at run time to generate BeanInfo classes dynamically.
JEP 257: Update JavaFX/Media to Newer Version of GStreamer update the version of GStreamer included in FX/Media in order to improve security, stability, and performance.
JEP 278: Additional Tests for Humongous Objects in G1 develop additional white-box tests for the Humongous Objects feature of the G1 Garbage Collector.
JEP 281: HotSpot C++ Unit-Test Framework enable and encourage the development of C++ unit tests for HotSpot.
JEP 282: jlink create a tool that can assemble and optimize a set of modules and their dependencies into a custom run-time image as defined in JEP 220: Modular Run-Time Images .
JEP 284: New HotSpot Build System rewrite the HotSpot build system using the build-infra framework.

deprecated

JEP summary /remark
JEP 289: Deprecate the Applet API deprecates the Applet API, which is rapidly becoming irrelevant as web-browser vendors remove support for Java browser plug-ins
JEP 291: Deprecate the Concurrent Mark Sweep (CMS) Garbage Collector deprecates the Concurrent Mark Sweep (CMS) garbage collector, with the intent to stop supporting it in a future major release.

removed

JEP summary /remark
JEP 214: Remove GC Combinations Deprecated in JDK 8 removes the GC combinations that were previously deprecated in JDK 8 via JEP 173: Retire Some Rarely-Used GC Combinations
JEP 231: Remove Launch-Time JRE Version Selection removes the ability to request, at JRE launch time, a version of the JRE that is not the JRE being launched.
JEP 240: Remove the JVM TI hprof Agent removes the hprof agent from the JDK. The ability to create heap dumps in the hprof format will remain. The useful features of the hprof agent have been superseded by better alternatives, i.e. the diagnostic command GC.heap_dump and Java VisualVM.
JEP 241: Remove the jhat Tool removes the jhat tool, added in JDK 6. jhat is an experimental, unsupported, and out-of-date tool. Superior heap visualizers and analyzers have now been available for many years.
JEP 298: Remove Demos and Samples removes the outdated and unmaintained demos and samples in the JDK.

some feature details

JEP 102: Process API Updates

Before JDK 9, getting the PID of a process was tedious, the ceremony to return the PID of a process was specific to the OS the JVM was running on.

JDK 9 offers some updates for working with processes.

The class java.lang.Process class is enhanced to provide the following information about a process:

  • process id
  • arguments
  • command with which the process was invoked
  • arguments of the command
  • start time
  • accumulated cpu time
  • user name for the process

The class java.lang.ProcessHandle class offers the same information about a process as listed above for the java.lang.Process class. Additionally, ProcessHandle can return the process' parent, the direct children and all descendants via a stream of ProcessHandles.

ProcessHandles can be used to destroy processes and monitor process liveness. With ProcessHandle.onExit, the asynchronous mechanisms of CompletableFuture can be used to schedule an action to be taken when the process exits.

Access to information about processes and control of processes is subject to security manager permissions and are limited by the normal operating system access controls.

JEP 222: jshell: The Java Shell (Read-Eval-Print Loop)

The JShell API and tool provides a way to interactively evaluate declarations, statements, and expressions of the Java programming language. The JShell state includes an evolving code and execution state. To facilitate rapid investigation and coding, statements and expressions need not occur within a method, and variables and method need not occur within a class.

The jshell tool is a command-line tool with features to ease interaction including: a history with editing, tab-completion, automatic addition of needed terminal semicolons, and configurable predefined imports and definitions.

A jshell guide describing it’s features can be found here.

JEP 269: Convenience Factory Methods for Collections

Constructing a Collection of elements was very verbose in Java, i.e. to construct an unmodifiable Set of Strings, the ceremony was like:

Set<String> set = new HashSet<>(); set.add("a"); set.add("b"); set.add("c"); set = Collections.unmodifiableSet(set);

With the convenience factory methods for colĺections, the code above boils down to one statement:

Set<String> set = Set.of("a", "b", "c");

Collections can be constructed from other collections with copy constructors:

Set<String> set = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("a", "b", "c")));

An alternative, yet seen less often, is the so-called double brace technique:

Set<String> set = Collections.unmodifiableSet(new HashSet<String>() {{ add("a"); add("b"); add("c"); }});

The Java 8 Stream API can be used to construct collections, by combining stream factory methods and collectors:

Set<String> set = Collections.unmodifiableSet(Stream.of("a", "b", "c").collect(toSet()));

Also provided are fixed-argument overloads for up to ten of elements, i.e. a Map can be populated with a small number of elements in an oneliner, too:

Map<String, String> map = Map.of( "k1", "v1", "k2", "v2", "k3", "v3" );

JEP 277: Enhanced Deprecation

The message sent to devs with the @Deprecated annotation was in most cases unclear.

Some people believed that everything that was deprecated is about to be removed or might eventually be removed. But very few deprecated APIs were actually removed, leading some people to believe that nothing would ever be removed. For some people, it was just a don’t-care item.

The Java Language Specification for Java SE 7 does not state anything about the removal of APIs annotated with @Deprecated, instead the intent is defined as follows:

" A program element annotated @Deprecated is one that programmers are discouraged from using, typically because it is dangerous, or because a better alternative exists. "
The Java Language Specification, Java SE 7 Edition, section 9.6.3.6. @Deprecated

In most cases, the intent behind a deprecation is to advice users to not use the deprecated API for new code or while maintaining existing code and migrate any usage of the deprecated API to the most possible extent.

JEP 277: Enhanced Deprecation lists the following reasons for deprecation:

  • the API is flawed and is impractical to fix,
  • usage of the API is likely to lead to errors,
  • the API has been superseded by another API,
  • the API is obsolete,
  • the API is experimental and is subject to incompatible changes,
  • or any combination of the above.

The first two items in the list relate to the “dangerous” case, the following two items relate to the “better alternatives exist” case in the JLS statement about the intent of @Deprecated.

The reason for using @Deprecated because an API is experimental seems rather odd to me. This one looks to me like a stopgap solution and I recommend against using @Deprecated for experimental features.

Often, the exact reasons for deprecating an API are to subtle that they can be expressed as flags. An APIs documentation should describe the reasons for deprecating and it should also discuss potential replacements to help devs migrating away from the deprecated API.

new optional attributes

Java 9 introduces two optional attributes for @Deprecated.

To clarify if a deprecated API is to be removed in the future, the optional attribute of type boolean forRemoval is introduced. The default value is false. Example:

@Deprecated(forRemoval = false) void someDeprecatedMethod() { ... }

With @Deprecated(forRemoval = false), it can be made clear that no removal in the future is intended. forRemoval also gives you the opportunity to scan for deprecated API in your codebase, that is marked for removal in future versions.

The other introduced optional attribute since is of type String, where the string is in free form, but it is recommended that the string contains the version of the API when it was deprecated. The default value for since is the empty String “”. Example:

@Deprecated(since = "1.2", forRemoval = false) void someDeprecatedMethod() { ... }

reference

JEP 102: Process API Updates

JEP 222: jshell

JEP 269: Convenience Factory Methods for Collections

JEP 277: Enhanced Deprecation

The Java® Language Specification, Java SE 7 Edition, section 9.6.3.6. @Deprecated