FULL PRODUCT VERSION :
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
We embbed a WebView into a JFXPanel. If the web page which is shown by the WebView contains elements with tooltips, e.g. a button, and the tooltip is shown, then the WebView is not garbage collected even if the surrounding frame is disposed. There seems to be still a reference to the tooltip component via the com.sun.webkit.WebPage instance.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the source code below.
We open a frame with a JFXPanel that contains a WebView. The WebView shows a page with a button with a tooltip. Do the following steps:
- start the application with the VM-argument "-DUSE_CLEANUP_WORKAROUND=false"
- click on "Open new browser window"
- hover over the upcoming button "Show my tooltip" until the tooltip is shown
- close the web view frame
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
After closeing the frame of the JXFPanel all WebView instance are garbage collected.
ACTUAL -
If you use a profiler you'll see that the WebView is not garbage collected since it is still referenced by the tooltip component which is referenced by an com.sun.webkit.WebPage instance.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
=== TooltipTestFXSwing.java ===
package tooltiptest;
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URISyntaxException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.sun.javafx.application.PlatformImpl;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.web.WebView;
public class TooltipTestFXSwing
{
public static boolean USE_CLEANUP_WORKAROUND = Boolean.getBoolean("USE_CLEANUP_WORKAROUND");
/**
* @see javafx.application.Application#start(javafx.stage.Stage)
*/
public void start()
{
JFrame frame = new JFrame("TooltipTestSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = (JPanel) frame.getContentPane();
panel.setLayout(new BorderLayout());
JButton btn = new JButton("Open new browser window");
btn.addActionListener(e -> reloadPage());
panel.add(btn, BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
PlatformImpl.startup(() -> System.out.println("init"));
}
public void reloadPage()
{
JFrame frame = new JFrame("TooltipTestSwing");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = (JPanel) frame.getContentPane();
panel.setLayout(new BorderLayout());
JFXPanel jfxPanel = new JFXPanel();
panel.add(jfxPanel, BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setVisible(true);
Platform.setImplicitExit(false);
Platform.runLater(() ->
{
WebView webView = new WebView();
try
{
webView.getEngine().load(TooltipTestFXSwing.class.getResource("tooltip.html").toURI().toString());
}
catch (URISyntaxException e1)
{
e1.printStackTrace();
}
Scene scene = new Scene(webView, 800, 600);
jfxPanel.setScene(scene);
});
frame.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
if (USE_CLEANUP_WORKAROUND)
{
Platform.runLater(() -> jfxPanel.setScene(new Scene(new Region())));
frame.removeAll();
}
frame.dispose();
}
});
}
public static void main(String[] args)
{
new TooltipTestFXSwing().start();
}
}
=== tooltip.html ===
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<button title="Tooltip" type="button">Show my tooltip</button>
</form>
</body>
</html>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Before disposeing the frame call this:
Platform.runLater(() -> jfxPanel.setScene(new Scene(new Region())));
frame.removeAll();
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
We embbed a WebView into a JFXPanel. If the web page which is shown by the WebView contains elements with tooltips, e.g. a button, and the tooltip is shown, then the WebView is not garbage collected even if the surrounding frame is disposed. There seems to be still a reference to the tooltip component via the com.sun.webkit.WebPage instance.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Use the source code below.
We open a frame with a JFXPanel that contains a WebView. The WebView shows a page with a button with a tooltip. Do the following steps:
- start the application with the VM-argument "-DUSE_CLEANUP_WORKAROUND=false"
- click on "Open new browser window"
- hover over the upcoming button "Show my tooltip" until the tooltip is shown
- close the web view frame
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
After closeing the frame of the JXFPanel all WebView instance are garbage collected.
ACTUAL -
If you use a profiler you'll see that the WebView is not garbage collected since it is still referenced by the tooltip component which is referenced by an com.sun.webkit.WebPage instance.
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
=== TooltipTestFXSwing.java ===
package tooltiptest;
import java.awt.BorderLayout;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.net.URISyntaxException;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import com.sun.javafx.application.PlatformImpl;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.scene.Scene;
import javafx.scene.layout.Region;
import javafx.scene.web.WebView;
public class TooltipTestFXSwing
{
public static boolean USE_CLEANUP_WORKAROUND = Boolean.getBoolean("USE_CLEANUP_WORKAROUND");
/**
* @see javafx.application.Application#start(javafx.stage.Stage)
*/
public void start()
{
JFrame frame = new JFrame("TooltipTestSwing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = (JPanel) frame.getContentPane();
panel.setLayout(new BorderLayout());
JButton btn = new JButton("Open new browser window");
btn.addActionListener(e -> reloadPage());
panel.add(btn, BorderLayout.NORTH);
frame.pack();
frame.setVisible(true);
PlatformImpl.startup(() -> System.out.println("init"));
}
public void reloadPage()
{
JFrame frame = new JFrame("TooltipTestSwing");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = (JPanel) frame.getContentPane();
panel.setLayout(new BorderLayout());
JFXPanel jfxPanel = new JFXPanel();
panel.add(jfxPanel, BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setVisible(true);
Platform.setImplicitExit(false);
Platform.runLater(() ->
{
WebView webView = new WebView();
try
{
webView.getEngine().load(TooltipTestFXSwing.class.getResource("tooltip.html").toURI().toString());
}
catch (URISyntaxException e1)
{
e1.printStackTrace();
}
Scene scene = new Scene(webView, 800, 600);
jfxPanel.setScene(scene);
});
frame.addWindowListener(new WindowAdapter()
{
@Override
public void windowClosing(WindowEvent e)
{
if (USE_CLEANUP_WORKAROUND)
{
Platform.runLater(() -> jfxPanel.setScene(new Scene(new Region())));
frame.removeAll();
}
frame.dispose();
}
});
}
public static void main(String[] args)
{
new TooltipTestFXSwing().start();
}
}
=== tooltip.html ===
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<form>
<button title="Tooltip" type="button">Show my tooltip</button>
</form>
</body>
</html>
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Before disposeing the frame call this:
Platform.runLater(() -> jfxPanel.setScene(new Scene(new Region())));
frame.removeAll();
- relates to
-
JDK-8213139 TooltipFXTest.testTooltipLeak failing intermittently
- Resolved