OpenJDK 8 Maintenance Release 4

Updated -

Java SE is one of the most stable and carefully well-maintained language runtime in existence. However, occasionally the world changes and Java has to change with it, and occasionally old problems arise that require a specification change, even in a very long-term release such as JDK 8.

Maintainers of programs written in Java SE Version 8 need to be aware of some upcoming changes.

A critical issue has arisen, JDK-8202260, that affects current JDK 8 releases. This issue is one of undefined behavior in a core low-level API, java.lang.ref.Reference. The lack of specification may also result in, at worst, a reproducible VM crash. Also, two related (but less critical) issues affecting java.lang.ref need attention.

In order to fix these issues, it's necessary to change not only the OpenJDK code but the Java specification itself. To achieve this, a Maintenance Release 4 (MR4) of the Java SE 8 Platform JSR (the Java Platform specification) will be released. This change is expected to be part of the expected October update of OpenJDK 8u.

Changes that may be required in JDK 8 programs

OpenJDK 8 customers should be aware of two changes that might affect their code.

Runtime.runFinalizersOnExit() will throw an UnsupportedOperationException

Runtime.runFinalizersOnExit() has never worked properly, and it has been deprecated since Java 1.2 in 1998, along with a dire warning in the API description that it should not be used. In effect, runFinalizersOnExit() runs finalizers while objects are still active, which makes little sense and can lead to reliability problems. Because of this, runFinalizersOnExit() was finally removed in JDK 9.

As part of MR4, the JDK 11 implementation of reference processing will be back-ported to OpenJDK 8. This implementation maintains the invariant that finalizers are never called until a reference is inactive. As a result of this, runFinalizersOnExit() cannot work, so it had to be disabled.

We expect this change to affect very few programs, possibly zero.

There is no simple workaround for this change. If there is an invocation of runFinalizersOnExit() in your program, you must remove it. If you need to do some sort of cleanup at exit, you must do it explicitly.

Please note that System.runFinalizers() is not affected by this change.

java.lang.ref.Reference.clone() will throw a CloneNotSupportedException

This change is needed because there is a race between user code and garbage collectors. A GC might detect that a referent is no longer reachable and enqueue a Reference object before user code invokes clone() on it. If this happens, the clone of the Reference will never be enqueued, so it will never be processed. This almost certainly is not what the programmer wants, and leads to very unpredictable reference processing.

The workaround for code that needs to clone a reference object is to replace clone() with the creation of a new instance with the same referent.


Pre-release binaries of OpenJDK 8 Maintenance Release 4 are available from Adoptium for x86 and everything else.