I have a JavaFX application which I want to run under the JVisualVM profiler. However, I cannot access the menu items from the menu bar when running it under the profiler.
So far, my application is just a simple scene built with SceneBuilder. It has an AnchorPane and a default Menubar.
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane minHeight="-Infinity" minWidth="-Infinity" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<MenuBar layoutX="-41.0" layoutY="-12.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<menus>
<Menu mnemonicParsing="false" text="File">
<items>
<MenuItem mnemonicParsing="false" text="Close" />
</items>
</Menu>
</menus>
</MenuBar>
</children>
</AnchorPane>
The code is also straight-forward, nothing special:
@Override
public void start(Stage primaryStage) throws IOException
{
String path = "Window.fxml";
URL url = getClass().getClassLoader().getResource(path);
FXMLLoader loader = new FXMLLoader();
loader.setLocation(url);
Parent root = loader.load();
Scene scene = new Scene(root, 600, 400);
primaryStage.setScene(scene);
primaryStage.show();
}
I do the following:
- run the application from Eclipse until the window shows up,
- click on "File" to see whether "Close" becomes visible
- start JVisualVM,
- double click my application,
- go to the "Profiler" tab
- click "CPU" and wait until it has injected profiling instructions
- click on "File" again, but "Close" does not appear
In Eclipse I see the following error messages coming up in the Console window very fast:
Exception in thread "JavaFX Application Thread" java.lang.NoClassDefFoundError: com/sun/javafx/tk/Toolkit$$Lambda$166
at com.sun.javafx.tk.Toolkit$$Lambda$166/563347763.get$Lambda(Unknown Source)
at com.sun.javafx.tk.Toolkit.runPulse(Unknown Source)
at com.sun.javafx.tk.Toolkit.firePulse(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.pulse(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit.lambda$runToolkit$363(Unknown Source)
at com.sun.javafx.tk.quantum.QuantumToolkit$$Lambda$41/353428524.run(Unknown Source)
at com.sun.glass.ui.InvokeLaterDispatcher$Future.run(Unknown Source)
at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
at com.sun.glass.ui.win.WinApplication.lambda$null$141(Unknown Source)
at com.sun.glass.ui.win.WinApplication$$Lambda$37/1109371569.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
How can I profile a method that gets called from a menu of my JavaFX application?
I have also tried packaging the application into an executable JAR file, so that Eclipse is not involved.
If the profiler uses BCI/instrumentation, then this problem might be relevant: Transforming lambdas in Java 8
Should the profiler have any option(s) to stop tracing performance of lambdas, try using it.
It would be interesting to know whether your problem still persists with newer versions of Java.