Skip to content


8315317: Add test for JDK-8262518
Browse files Browse the repository at this point in the history
Reviewed-by: angorya
  • Loading branch information
prsadhuk committed Sep 8, 2023
1 parent ed92171 commit eb7de72
Showing 1 changed file with 131 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
* Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved.
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit if you need additional information or have any
* questions.

package test.javafx.embed.swing;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeTrue;

import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;

import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import javafx.application.Application;
import javafx.embed.swing.SwingNode;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;

import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;

import com.sun.javafx.PlatformUtil;

import test.util.Util;

public class SwingNodeContentMemoryLeakTest {

static CountDownLatch launchLatch = new CountDownLatch(1);

//Keep week references to all panels that we've ever generated to see if any
//of them get collected.
private Collection<WeakReference<JPanel>> panels = new CopyOnWriteArrayList<>();
private int count = 0;
private int fail = 0;
private SwingNode node;
private long panelCount;

public static void setupOnce() {
Util.launch(launchLatch, 50, MyApp.class);

public static void teardownOnce() {

public void testSwingNodeContentMemoryLeak() throws InterruptedException,
InvocationTargetException {
Util.runAndWait(() -> {
node = new SwingNode();
Pane root = new Pane();

Stage stage = new Stage();
Scene scene = new Scene(root, 150, 100);

//Kick off a thread that repeatedly creates new JPanels and resets the swing node's content
new Thread(() -> {
while(count < 50) {
//Lets throw in a little sleep so we can read the output
try {
} catch (InterruptedException e) {

SwingUtilities.invokeLater(() -> {
JPanel panel = new JPanel();
panels.add(new WeakReference<>(panel));

panelCount = ->
ref.get() != null).count();
System.out.println("iteration " + count + " Panels in memory: " + panelCount);

//I know this doesn't guarantee anything, but prompting a GC gives me more confidence that this
//truly is a bug.
// Check if panelCount has not increased beyond certain threshold
assertFalse(panelCount > count/2);


// Invoke a noop on EDT thread and wait for a bit to make sure EDT processed node objects
SwingUtilities.invokeAndWait(() -> {});

public static class MyApp extends Application {
public void start(Stage stage) throws Exception {

1 comment on commit eb7de72

Copy link

Choose a reason for hiding this comment

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

Please sign in to comment.