The JMX Subject Delegation feature has been removed. The method
javax.management.remote.JMXConnector.getMBeanServerConnection(Subject
delegationSubject)
will throw an
UnsupportedOperationException
if a non-null delegation
subject is provided. If a client application needs to perform
operations as or on behalf of multiple identities, it will need to
make multiple calls to JMXConnectorFactory.connect()
and to the getMBeanServerConnection()
method on the
returned JMXConnector
.
JDK 23 Early-Access Release Notes
This is a draft of the release notes that will accompany JDK 23. The contents are subject to change until release.
Build 18
JMX Subject Delegation Has Been Removed (JDK-8326666)
Build 16
Fallback Option For POST-only OCSP Requests (JDK-8328638)
JDK 17 introduced the performance improvement that made OCSP client unconditionally use GET requests for small requests, while doing POST requests for everything else. This is explicitly allowed and recommended by RFC 5019 and RFC 6960. However, we have seen OCSP responders that, despite RFC requirements, are not working well with GET requests.
This release introduces a new JDK system property to allow
fallback to POST-only behavior to unblock interaction with those
OCSP responders:
-Dcom.sun.security.ocsp.useget={false,true}
. This
amends the original change that introduced GET OCSP requests
(JDK-8179503). The
default behavior is not changed; the option defaults to
true
. Set the option to false
to disable
GET OCSP requests. Any value other than false
(case-insensitive) defaults to true
.
This option is non-standard, and might go away once problematic OCSP responders get upgraded.
Build 15
Alternate implementation of user-based authorization Subject APIs that doesn’t depend on Security Manager APIs (JDK-8296244)
The current javax.security.auth.Subject::doAs
and
Subject::getSubject
APIs are deprecated for removal as
they have dependencies on Security Manager APIs that are also
deprecated for removal. These APIs will not work as expected when
the Security Manager support is removed in a future release.
Applications should be transitioning to the replacement APIs
(Subject::callAs
and Subject::current
)
that were introduced in JDK 18.
To further prepare applications for the eventual removal of the Security Manager, we have implemented a new mechanism for subject authorization and have modified the behavior of the APIs above to behave differently depending on whether a Security Manager is allowed or disallowed:
-
If a Security Manager is allowed, which means it is either already set or allowed to be set dynamically, there is no behavior change.
-
If a Security Manager is disallowed, which means it is not set and not allowed to be set dynamically, a
doAs
orcallAs
call binds aSubject
object to the period of execution of an action. This subject can be inherited by child threads if they are started and terminate within the execution of its parent thread using structured concurrency. The subject can only be retrieved using thecurrent
method inside the action. ThegetSubject
method will always throw anUnsupportedOperationException
.
For applications or libraries that do not use the Security
Manager, developers should switch to the new current
method to retrieve the current subject. Actions should always be
executed using the doAs
or callAs
APIs.
If in a rare case you are storing a subject in an
AccessControlContext
and then calling
AccessController.doPrivileged
with that context, the
code will not work correctly in this mode. Instead, you should
replace that code with callAs
or doAs
on
the subject itself, preferably callAs
since it is not
deprecated. If your code depends on the automatic inheritance of
subject in a newly created platform thread, it should either be
modified to use structured concurrency or the current subject
should be explicitly passed into the new thread.
If you are not using a Security Manager and cannot transition to
the replacement APIs, you can continue using the current APIs by
adding -Djava.security.manager=allow
on the command
line as a workaround. This allows the old implementation to be used
even if a Security Manager is never set. Please note that in a
future version the Security Manager will be removed and this
workaround will no longer work.
Enhance Kerberos debug output (JDK-8327818)
Debug output related to JGSS/Kerberos, including those for the
JAAS Krb5LoginModule
, the JGSS framework, and the
Kerberos 5 and SPNEGO mechanisms (whether implemented in pure Java
or through a native bridge), is now directed to the standard error
output stream (System.err
) instead of the standard
output stream (System.out
). Additionally, debug output
is now prefixed with a category tag, such as
krb5loginmodule
, jgss
, krb5
,
etc.
Change LockingMode Default from LM_LEGACY
to
LM_LIGHTWEIGHT
(JDK-8319251)
A new lightweight locking mechanism for uncontended object
monitor locking was introduced in JDK 21 under JDK-8291555. The
LockingMode
flag was introduced to allow selection of
this new mechanism (LM_LIGHTWEIGHT
, value 2) in place
of the default mechanism (LM_LEGACY
, value 1). In this
release the LockingMode
default has been changed to
LM_LIGHTWEIGHT
.
This is not expected to change any semantic behavior of Java monitor locking and it is expected to be performance neutral for almost all applications.
If you need to revert to the legacy mechanism you can set the
command-line flag -XX:LockingMode=1
, but note that it
is expected the legacy mode will be removed in a future
release.
Build 14
java.text.DecimalFormat Change of the Default Maximum Fraction Digits for the Empty Pattern (JDK-8326908)
For a java.text.DecimalFormat
created with an empty
String pattern, the value returned by
DecimalFormat.getMaximumFractionDigits()
will now be
340, instead of the previous value, Integer.MAX_VALUE
.
This prevents an OutOfMemoryError
from occurring when
DecimalFormat.toPattern()
is called. If the desired
maximum fractional digits should exceed 340, it is recommended to
achieve this behavior using the method
DecimalFormat.setMaximumFractionDigits()
.
The Meaning of Contended Monitor Has Been Clarified in JVM TI, JDWP and JDI (JDK-8256314)
The JVMTI GetCurrentContendedMonitor
implementation
has been aligned with the spec, so the monitor is returned only
when the specified thread is waiting to enter or re-enter the
monitor and the monitor is not returned when the specified thread
is waiting in the java.lang.Object.wait
to be
notified.
The JDWP ThreadReference.CurrentContendedMonitor
command spec was updated to match the JVMTI
GetCurrentContendedMonitor
spec. It states now: "The
thread may be waiting to enter the object's monitor, or in
java.lang.Object.wait waiting to re-enter the monitor after being
notified, interrupted, or timed-out."
This part has been removed from the command description: "... it may be waiting, via the java.lang.Object.wait method, for another thread to invoke the notify method."
The JDI ThreadReference.currentContendedMonitor
method spec was updated to match the JVMTI
GetCurrentContendedMonitor
spec. It states now: "The
thread can be waiting for a monitor through entry into a
synchronized method, the synchronized statement, or Object.wait()
waiting to re-enter the monitor after being notified, interrupted,
or timed-out."
This part has been added to the method description: "... or Object.wait() waiting to re-enter the monitor after being notified, interrupted, or timed-out."
And this part has been removed from the method description: "The status() method can be used to differentiate between the first two cases and the third."
The Implementation of JVMTI GetObjectMonitorUsage
Has Been Corrected (JDK-8247972)
The JVMTI GetObjectMonitorUsage
function returns
the following data structure:
typedef struct {
jthread owner;
jint entry_count;
jint waiter_count;
jthread* waiters;
jint notify_waiter_count;
jthread* notify_waiters;
} jvmtiMonitorUsage;
Two fields in this structure are specified as:
waiter_count
[jint
]: The number of threads waiting to own this monitorwaiters
[jthread*
]: Thewaiter_count
waiting threads
In previous releases, the waiters
field included
the threads waiting to enter or re-enter the monitor as specified,
but also (incorrectly) the threads waiting to be notified in
java.lang.Object.wait()
. That has been fixed in the
current release. The waiter_count
always matches the
returned number of threads in the waiters
field.
Also, the JDWP ObjectReference.MonitorInfo
command
spec was updated to clarify what the waiters
threads
are:
waiters
: "The total number of threads that are waiting to enter or re-enter the monitor, or waiting to be notified by the monitor."
The behavior of this JDWP command is kept the same, and is
intentionally different to GetObjectMonitorUsage
.
Build 13
Native Executables and Libraries on Linux Use
RPATH
Instead of RUNPATH
(JDK-8326891)
Native executables and libraries on Linux have switched to using
RPATH
instead of RUNPATH
in this
release.
JDK native executables and libraries use embedded runtime search
paths to locate other internal JDK native libraries. On Linux these
can be defined as either RPATH
or
RUNPATH
. The main difference is that the dynamic
linker considers RPATH
before the
LD_LIBRARY_PATH
environment variable, while
RUNPATH
is only considered after
LD_LIBRARY_PATH
.
By making the change to using RPATH
, it is no
longer possible to inject external replacements for JDK internal
native libraries using LD_LIBRARY_PATH
.
Removal of the Legacy Locale Data (JDK-8174269)
The legacy JRE
locale data has been removed from
the JDK. The legacy JRE
locale data,
(COMPAT
is an alias for this locale data), remained
after the CLDR
locale data based on the Unicode
Consortium's Common Locale Data
Registry became the default since JDK 9. It served as an
application's migration means for the time being. Since JDK 21,
users have been notified of its future removal with the startup
warning message as the use of JRE
/COMPAT
locale data was deprecated. It is now removed from JDK 23, so
specifying JRE
or COMPAT
in
java.locale.providers
system property no longer has
any effect. Applications using JRE
/COMPAT
locale data are encouraged to migrate to CLDR locale data or
consider a workaround discussed in the CSR.
Build 12
Relax alignment of array elements (JDK-8139457)
Array element bases are no longer unconditionally aligned to 8 bytes. Instead, they are now aligned to their element type size. This improves footprint in some JVM modes. As Java array element alignment is not exposed to users, there is no impact on regular Java code that accesses individual elements.
There are implications for bulk access methods. Unsafe accesses
to arrays could now be unaligned. For example,
Unsafe.getLong(byteArray, BYTE_ARRAY_BASE_OFFSET + 0)
is not guaranteed to work on platforms that do not allow unaligned
accesses, the workaround is Unsafe.{get,
put}Unaligned*
family of methods. The
ByteBuffer
and VarHandle
APIs that allow
views of byte[]
are updated to reflect this change
(JDK-8318966).
Arrays that are acquired via GetPrimitiveArrayCritical
should not be operated upon under the assumption of particular
array base alignment as well.
Build 11
Added Certainly R1 and E1 Root Certificates (JDK-8321408)
The following root certificates have been added to the cacerts truststore:
+ Certainly
+ certainlyrootr1
DN: CN=Certainly Root R1, O=Certainly, C=US
+ Certainly
+ certainlyroote1
DN: CN=Certainly Root E1, O=Certainly, C=US
Make TrimNativeHeapInterval
a Product Switch
(JDK-8325496)
TrimNativeHeapInterval
has been made an official
product switch. It allows the JVM to trim the native heap at
periodic intervals.
This option is only available on Linux with glibc.
Build 10
Removal of Aligned Access Modes for
MethodHandles::byteArrayViewVarHandle
,
byteBufferViewVarHandle
and Related Methods
(JDK-8318966)
The var handle returned by
MethodHandles::byteArrayViewVarHandle
no longer
supports atomic access modes, and the var handle returned by
MethodHandles::byteBufferViewVarHandle
no longer
supports atomic access modes when accessing heap buffers.
Additionally, the ByteBuffer::alignedSlice
and
ByteBuffer::alignmentOffset
methods are updated to
reflect these changes. They no longer report aligned slices or
offsets for heap byte buffers when the accessed 'unitSize' is
greater than 1, and instead throw an
UnsupportedOperationException
in those cases.
The removed functionality was based on an implementation detail in the reference JVM implementation that is not mandated by the JVM specification, and is therefore not guaranteed to work on an arbitrary JVM implementation. This also allows the reference implementation to align array elements more loosely, if it is deemed beneficial 1.
Affected clients should consider using direct (off-heap) byte
buffers, for which aligned access can reliably be guaranteed. Or
they should use a long[]
to store their data, which
has stronger alignment guarantees than byte[]
. A
MemorySegment
backed by a long[]
array
can be accessed through an atomic access mode and any primitive
type, using the newly introduced Foreign Function and Memory API
3 as
follows:
long[] arr = new long[10];
MemorySegment arrSeg = MemorySegment.ofArray(arr);
VarHandle vh = ValueLayout.JAVA_INT.varHandle(); // accessing aligned ints
vh.setVolatile(arrSeg, 0L, 42); // 0L is offset in bytes
long result = vh.getVolatile(arrSeg, 0L); // 42
Build 9
Loose Matching of Space Separators in Lenient Date/Time Parsing Mode (JDK-8324665)
Parsing of date/time strings now allows the "loose matching" of
spaces. This enhancement is mainly to address the [incompatible
changes](https://www.oracle.com/java/technologies/javase/20-relnote-issues.html#JDK-8284840)
introduced in JDK 20 with CLDR version 42. That version replaced
ASCII spaces (U+0020
) between time and the am/pm
marker with NNBSP
(Narrow No-Break Space,
U+202F
) in some locales. The "loose matching" is
performed in the "lenient" parsing style for both date/time parsers
in java.time.format
and java.text
packages. In the "strict" parsing style, those spaces are
considered distinct, as before.
To utilize the "loose matching" in the
java.time.format
package, applications will need to
explicitly set the leniency by calling
DateTimeFormatterBuilder.parseLenient()
because the
default parsing mode is strict:
var dtf = new DateTimeFormatterBuilder()
.parseLenient()
.append(DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT))
.toFormatter(Locale.ENGLISH);
In the java.text
package, the default parsing mode
is lenient. Applications will be able to parse all space separators
automatically, which is the default behavior changes with this
feature. In case they need to strictly parse the text, they can
do:
var df = DateFormat.getTimeInstance(DateFormat.SHORT, Locale.ENGLISH);
df.setLenient(false);
Build 6
Removal of the JMX Management Applet (m-let) Feature (JDK-8318707)
The m-let feature has been removed. This removal has no impact on the JMX agent used for local and remote monitoring, the built-in instrumentation of the Java virtual machine, or tooling that uses JMX. The API classes that have been removed are:
javax.management.loading.MLet
javax.management.loading.MLetContent
javax.management.loading.PrivateMLet
javax.management.loading.MLetMBean
Build 2
ThreadGroup.stop is removed (JDK-8320786)
The method java.lang.ThreadGroup.stop()
has been
removed in this release. This inherently unsafe method was
deprecated in JDK 1.2 (1998), deprecated for removal in Java 18,
and re-specified/degraded in Java 20 to throw
UnsupportedOperationException
unconditionally. Code
that uses this method will no longer compile. Code using this
method that is compiled to older releases will throw
NoSuchMethodError
if executed on JDK 23. It previously
threw UnsupportedOperationException`.
Thread.suspend/resume and ThreadGroup.suspend/resume are removed (JDK-8320532)
The methods java.lang.Thread.suspend()
,
java.lang.Thread.resume()
,
java.lang.ThreadGroup.suspend()
, and
java.lang.ThreadGroup.resume()
have been removed in
this release. These deadlock prone methods were deprecated in JDK
1.2 (1998), deprecated for removal in Java 14, and
re-specified/degraded in Java 19/20 to throw
UnsupportedOperationException
unconditionally. Code
that uses these methods will no longer compile. Code using these
methods that is compiled to older releases will throw
NoSuchMethodError
if executed on JDK 23. It previously
threw UnsupportedOperationException`.