Skip to content

8387301: ListView, ComboBox, TableView, TreeTableView fail when item type is a value class - #2250

Open
kevinrushforth wants to merge 9 commits into
openjdk:masterfrom
kevinrushforth:8387301-control-weakref
Open

8387301: ListView, ComboBox, TableView, TreeTableView fail when item type is a value class#2250
kevinrushforth wants to merge 9 commits into
openjdk:masterfrom
kevinrushforth:8387301-control-weakref

Conversation

@kevinrushforth

@kevinrushforth kevinrushforth commented Aug 6, 2026

Copy link
Copy Markdown
Member

This PR creates a WeakReferenceWrapper object to replace direct uses of WeakReference in controls where the referent is a user-supplied object of an unknown type.

As noted in JEP 401, which is now integrated into JDK 28, "The garbage collection APIs in java.lang.ref ... do not allow developers to manually manage value objects in the heap. Attempts to create Reference objects for value objects throw IdentityException at run time."

Several core JDK classes such as all of the primitive wrappers (e.g., Integer, Character), Optional, LocalDateTime, and a few others are now value types if JDK 28 is run with the --enable-preview option.

The ListView, ComboBox, TableView, and TreeTableView controls take a parameterized item type and hold items of that type. The following places in the implementation create weak references to an item. If that item type is a value class -- meaning that it does not have identity -- creating the WeakReference fails.

As noted in the JBS issue, there are 3 cases to consider.

  1. SelectedItemsReadOnlyObservableList<E> -- E is the item type (created by MultipleSelectionModelBase<T>) : ListView, TableView, ComboBox (due to its skin creating a ListView<T>) -- replace with WeakReferenceWrapper

  2. TablePosition<S,T> -- S is the item type : TableView -- the reference is unused, so I removed it

  3. TableCell<S,T> and TreeTableCell<S,T> -- S is the item type : TableView, TreeTableView -- replace with WeakReferenceWrapper

The new WeakReferenceWrapper class takes a referent of any type and either creates a WeakReference (if it has identity) or directly stores the reference (if it is null or does not have identity). I added a test for the wrapper.

All of the controls tests pass with this fix. I did three test runs as follows:

  1. JDK 25
  2. JDK 28 without --enable-preview
  3. JDK 28 with --enable-preview

Without the fix, 31 controls tests fails on the 3rd run.



Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

  • JDK-8387301: ListView, ComboBox, TableView, TreeTableView fail when item type is a value class (Bug - P3)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/2250/head:pull/2250
$ git checkout pull/2250

Update a local copy of the PR:
$ git checkout pull/2250
$ git pull https://git.openjdk.org/jfx.git pull/2250/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 2250

View PR using the GUI difftool:
$ git pr show -t 2250

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/2250.diff

Using Webrev

Link to Webrev Comment

@bridgekeeper

bridgekeeper Bot commented Aug 6, 2026

Copy link
Copy Markdown

👋 Welcome back kcr! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk

openjdk Bot commented Aug 6, 2026

Copy link
Copy Markdown

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

return true;
} else {
try {
System.err.println("[3] Calling Ojbects.hasIdentityMethod(obj)");

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ojbects

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. My fingers do that all the time!

@kevinrushforth kevinrushforth changed the title WIP: 8387301: WeakReferenceWrapper 8387301: ListView, ComboBox, TableView, TreeTableView fail when item type is a value class Aug 14, 2026
@kevinrushforth
kevinrushforth marked this pull request as ready for review August 14, 2026 19:30
@openjdk openjdk Bot added the rfr Ready for review label Aug 14, 2026
@kevinrushforth

Copy link
Copy Markdown
Member Author

Reviewers: @andy-goryachev-oracle @arapte

@dansmithcode Your comments would be welcome if you have time to look at this.

@openjdk

openjdk Bot commented Aug 14, 2026

Copy link
Copy Markdown

The total number of required reviews for this PR has been set to 2 based on the presence of this label: rfr. This can be overridden with the /reviewers command.

@mlbridge

mlbridge Bot commented Aug 14, 2026

Copy link
Copy Markdown

Webrevs

*
* @param <T> the type of the referent
*/
public class WeakReferenceWrapper<T> {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An application or a library should not be forced to do this, in my opinion.

WeakReference(T) should work as before - in case of a value object it should hold the reference indefinitely because it's the same behavior as before. It may work differently with the WeakReference(T,ReferenceQueue) constructor which is ok because it would affect a much smaller space of use cases.

It is probably ok to do it right now, to avoid javafx breaking with the value objects preview enabled.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WeakReference(T) should work as before

But that isn't the case.

* <p>
* In the case of a value object, the referent is never collected, so it is only
* suitable for uses that do not rely on the object being placed onto a reference
* queue.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I might suggest to include the JBS number for when we need to undo / redo things due to inevitable change in the value objects JEP (and possibly a link to the JEP itself).

Perhaps also say a couple of words about the fact that this class should not exist had they decided to make the WeakReference implementation handle this case transparently.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no JBS issue or JEP that will eliminate the need for this. The restriction is intentional with no current plan to change it.

I could add a comment that this class might become unnecessary in the future, if a there is a change in the way WeakReference deals with value objects, but it is uncertain if or when that might be.

private boolean isFirstRun = true;

private WeakReference<S> oldRowItemRef;
private WeakReferenceWrapper<S> oldRowItemRef;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While it is ok to apply this workaround (WeakReferenceWrapper) here, this kind of change in the WeakReference behavior is just awful: we should never force the application developers (r a third party library developers) to make a change like this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

rfr Ready for review

Development

Successfully merging this pull request may close these issues.

2 participants