-
Notifications
You must be signed in to change notification settings - Fork 443
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
8334593: Adding, removing and then adding a JFXPanel again leads to NullPointerException #1493
base: master
Are you sure you want to change the base?
Conversation
…ullPointerException
👋 Welcome back psadhukhan! A progress list of the required criteria for merging this PR into |
❗ This change is not yet ready to be integrated. |
Webrevs
|
Can you add an automated test to cover this fix? Worth noting, this won't fully solve the problem that the reporter of this bug filed. The null check will prevent the NPE, but the scene will still not be visible. To allow removing and then re-adding the |
@prsadhuk One more question: Do you know what changed in JavaFX 21 to trigger the NPE? |
Since this problem straddles two different toolkits, I would suggest to specify a minimum of 2 reviewers. |
I am not sure if this is a problem as just as |
It is not reproducible in jfx21 as per my testing...The problematic code to call updateSceneState was added for JDK-8274932 so it has regressed from jfx22 |
Check is not without precedence in this file..There are instance of jfx/modules/javafx.graphics/src/main/java/com/sun/javafx/tk/quantum/EmbeddedScene.java Line 185 in 6a586b6
|
Automated test added |
@@ -157,7 +157,9 @@ public void setPixelScaleFactors(float scalex, float scaley) { | |||
entireSceneNeedsRepaint(); | |||
Platform.runLater(() -> { | |||
QuantumToolkit.runWithRenderLock(() -> { | |||
updateSceneState(); | |||
if (host != null) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need a different solution here, as mentioned in line 58
// TODO: synchronize access to embedder from ET and RT
Kevin is right, this fix does not solve the issue mentioned in the ticket. Once the fxPanel is added back, its content is not visible. Does not matter whether removing/adding happens at startup or the button event handler. (attaching a slightly modified test case to the ticket, notice lines 30 and 44. Also, I think swing requires validate() and repaint() called after modifying the component's children. |
// fxPanel removed from frame | ||
frame.remove(fxPanel); | ||
// fxPanel added to frame again | ||
frame.add(fxPanel); // <-- leads to NullPointerException |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use JUnit5 to write this test (class) and use assertDoesNotThrow(() -> frame.add(fxPanel));
, which makes this a bit better to understand
OK..I guess I probably misunderstood the expectation...it says
which I deciphered as the JFXPanel window being visible and I guess in original testcase execution, the "TestButton" was still visible, only NPE was thrown.. ANyway, I guess it was mentioned that "We should file a follow-on Enhancement to consider doing this" and regarding synchro mentioned at line58, I guess we already have |
locking a class field may not be sufficient. or rather, cannot be sufficient when multiple threads are accessing the field, as there are no guarantees as to the order of invocations. Instead, we might need to pass the reference as a variable to the lambda which executes in a different thread. This way no matter what happens to the field, the code that executes in a different context will always have the right object. And, it might be better not to share the field between the threads and toolkits. Always mutate a particular field in the context of one toolkit - like fieldAWT / fieldFX. Just a suggestion. |
Adding, then removing, and then adding a JFXPanel to the same component in the Swing scene graph leads to a NullPointerException in GlassScene because the sceneState is null.
Removing JFXPanel calls JFXPanel.removeNotify which calls Window.hide which calls SceneHelper.disposePeer -> Scene.disposePeer -> EmbeddedScene.dispose -> GlassScene.dispose which sets "sceneState" to null...
so when GlassScene.updateSceneState is called, it results in NPE.
Fix is to check if
host
(which is usually javafx.embed.swing.JFXPanel$HostContainer for active JFXPanel) has been reset/deleted which is done whenEmbeddedScene.dispose
is called during removeNotify and abstain from updating the scene stateProgress
Issue
Reviewing
Using
git
Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1493/head:pull/1493
$ git checkout pull/1493
Update a local copy of the PR:
$ git checkout pull/1493
$ git pull https://git.openjdk.org/jfx.git pull/1493/head
Using Skara CLI tools
Checkout this PR locally:
$ git pr checkout 1493
View PR using the GUI difftool:
$ git pr show -t 1493
Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1493.diff
Webrev
Link to Webrev Comment