On 4/08/2026 1:34 am, Kevin Rushforth wrote:
Now that the JEP 401 value objects preview is integrated into JDK 28, I
want to share our experience running our existing JavaFX test suite. We
don't explicitly use value objects, so the behavioral differences we see
are due to the fact that several core Java classes are now value objects
when running with "--enable-preview".
All of the test failures we see are caused by the following aspect of
value objects, as specified in JEP 401:
"The garbage collection APIs in the java.lang.ref package and the
java.util.WeakHashMap class cannot be used with value objects.
Attempting to create Reference objects for value objects will cause an
IdentityException to be thrown."
We have APIs that accept an application-provided Object and we
internally create a weak reference to that Object. I filed an umbrella
task in JBS, JDK-8387264 [1], to track the issues we are facing.
These failures fall into two cases:
First, some JavaFX UI controls APIs take a list of objects. JavaFX
internally creates a WeakReference to an individual object in some
cases. This is tracked by JDK-8387301 [2].
Second, JavaFX WebView's Java <--> JavaScript bridge code allows passing
arbitrary objects from Java to JavaScript. The specification says that
we create a weak reference to the bound Java object. This is done to
avoid having the native WebKit code hold a strong reference, which would
lead to memory leaks.
Just for reference JVMTI/JDI/JDWP is also trying to deal with the
problem of weak/strong references in relation to value types. Some
initial spec updates were made to say tagged value objects are always
strongly referenced (ref CSR
https://bugs.openjdk.org/browse/JDK-8383266) but this is really
side-stepping the issue. The problem for the debugging/tooling
architecture is that it is fundamentally (and implicitly) identity and
object-lifetime based - e.g. creating an ObjectReference to mirror an
object in the target VM and using a WeakReference to avoid
retention/memory-leaks. Reframing this to handle value objects in a
clear/clean way is still a work-in-progress - see
https://bugs.openjdk.org/browse/JDK-8387647.
David
-----
Most of this implementation is in a set of native
C++ Java bridge classes that wrap JNI methods and objects. The native
code takes a jobject, creates a weak reference using the JNI
NewWeakGlobalRef call, and stores that reference. This is tracked by
JDK-8387634 [3].
I have two questions:
1. Has there been any discussion of allowing WeakReference (and the
corresponding JNI NewWeakGlobalRef) to accept value objects in a future
revision of the value objects feature? Obviously in this case, the
referent would never be cleared by GC, but it would allow common code to
be able to continue to function. There are some "gotchas" here. For
example, would such a reference ever be automatically enqueued on a
ReferenceQueue? If so, when and how would that work?
2. What is the best advice for applications or libraries like JavaFX to
deal with this? The current approach we are considering is described in
[2] and [3], where we would create a WeakReferenceWrapper class that
either creates and stores a reference (if the object has identity) or
stores the object itself (if it is either null or does not have
identity). Its get method would return either ref.get() or obj. Is there
a better approach?
Thanks.
-- Kevin
[1] https://bugs.openjdk.org/browse/JDK-8387264
[2] https://bugs.openjdk.org/browse/JDK-8387301
[3] https://bugs.openjdk.org/browse/JDK-8387634