0

I have (sometimes) the following exception in a loop when I exit my JavaFX application:

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
    at com.sun.javafx.tk.quantum.QuantumToolkit.isSupported(QuantumToolkit.java:1196)
    at com.sun.javafx.application.PlatformImpl.isSupportedImpl(PlatformImpl.java:809)
    at com.sun.javafx.application.PlatformImpl.isSupported(PlatformImpl.java:482)
    at javafx.application.Platform.isSupported(Platform.java:168)
    at com.sun.javafx.scene.input.PickResultChooser.processOffer(PickResultChooser.java:182)
    at com.sun.javafx.scene.input.PickResultChooser.offer(PickResultChooser.java:143)
    at javafx.scene.Node.impl_intersects(Node.java:4943)
    at javafx.scene.layout.Region.impl_pickNodeLocal(Region.java:2942)
    at javafx.scene.Node.impl_pickNode(Node.java:4912)
    at javafx.scene.layout.Region.impl_pickNodeLocal(Region.java:2936)
    at javafx.scene.Node.impl_pickNode(Node.java:4912)
    at javafx.scene.layout.Region.impl_pickNodeLocal(Region.java:2936)
    at javafx.scene.Node.impl_pickNode(Node.java:4912)
    at javafx.scene.layout.Region.impl_pickNodeLocal(Region.java:2936)
    at javafx.scene.Node.impl_pickNode(Node.java:4912)
    at javafx.scene.layout.Region.impl_pickNodeLocal(Region.java:2936)
    at javafx.scene.Node.impl_pickNode(Node.java:4912)
    at javafx.scene.Scene$MouseHandler.pickNode(Scene.java:3899)
    at javafx.scene.Scene$MouseHandler.access$1600(Scene.java:3485)
    at javafx.scene.Scene.pick(Scene.java:1942)
    at javafx.scene.Scene.access$6700(Scene.java:159)
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3711)
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485)
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762)
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:394)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$2(GlassViewEventHandler.java:432)
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:410)
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:431)
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555)
    at com.sun.glass.ui.View.notifyMouse(View.java:937)
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method)
    at com.sun.glass.ui.win.WinApplication.lambda$null$4(WinApplication.java:187)
    at java.lang.Thread.run(Thread.java:748)

It does not impact my app in another way, and it seems to happen when I'm quitting the app by clicking on the close button on my Window. When I'm quitting (and not always), I have several of this stack (last time it was 3, it's not an endless loop of course).

Note that I'm using Java 8, and I'm using a JavaFX Scene which is called from a non-JavaFX Thread (but using a Platform.runLater() code), and added as a JFXPanel in a Swing component. I'm create it in my main Thread by:

JFXPanel jfxPanel = new JFXPanel();
JFrame frame = new JFrame("GUI");
initGUI();
Container pane = frame.getContentPane();
pane.setLayout(new BorderLayout());
pane.add(jfxPanel, BorderLayout.CENTER);
frame.setVisible(true);

All the JavaFX code is performed in the following code:

private void initGUI() {
  Platform.runLater(new Runnable() {
     @Override
     public void run() {
        initFX();
     }
  });
}

To answer a question in the comments, The com.sun.glass.ui.win.WinApplication.lambda$null$4 Stack element is in the following code (which explains why this exception happens in a loop):

 @Override
 protected void runLoop(final Runnable launchable) {
boolean isEventThread = AccessController
    .doPrivileged((PrivilegedAction<Boolean>) () -> Boolean.getBoolean("javafx.embed.isEventThread"));
int awareness = getDesiredAwarenesslevel();

ClassLoader classLoader = WinApplication.class.getClassLoader();
_setClassLoader(classLoader);

if (isEventThread) {
    _init(awareness);
    setEventThread(Thread.currentThread());
    launchable.run();
    return;
}
// Default stack size of Windows 32-bit application is 320K and which is
// not sufficient for few WebView based applications. Increase the stack
// size to 1MB to keep those apps running.
final long stackSize = AccessController.doPrivileged(
        (PrivilegedAction<Long>)
                () -> Long.getLong("glass.win.stackSize", PlatformUtil.isWindows32Bit() ? 1024 * 1024 : 0));
final Thread toolkitThread =
    AccessController.doPrivileged((PrivilegedAction<Thread>) () -> new Thread(
        null,
        () -> {
            _init(awareness);
            _runLoop(launchable); // this is here
        },
        "WindowsNativeRunloopThread",
        stackSize));
setEventThread(toolkitThread);
toolkitThread.start();

}

It's the _runLoop(launchable); call. The origin of the NPE seems to be in this code:

  @Override
    public boolean isSupported(ConditionalFeature feature) {
        switch (feature) {
            case SCENE3D:
                return GraphicsPipeline.getPipeline().is3DSupported(); // this is here
            ...

Which means that the GraphicsPipeline.getPipeline() method is called but returns null in my case "when I'm quitting the app".

I looked in the GraphicsPipeline class. The getPipeline() method is:

public static GraphicsPipeline getPipeline() {
    return installedPipeline;
}

The installedPipeline is set to null only when calling:

public void dispose() {
    notifyDisposeHooks();
    installedPipeline = null;
}

So it appear that I'm calling GraphicsPipeline.dispose() indirectly when quitting my app, but the loop called through public void runLoop(final Runnable launchable) method might not be interrupted yet.

I have absolutely no problem when I use the app, its just when I'm quitting that I (sometimes) have this exception. What did I do wrong?

Hervé Girod
  • 465
  • 3
  • 12
  • 1
    Where's the portion of your stack trace that starts "Caused by..."? – MarsAtomic Feb 01 '22 at 17:30
  • I don't have any Cause By... (strangely) in the stack. Maybe because the JVM does not have the time to print the whole stack before it is closed? (it happens when I'm quitting the app) – Hervé Girod Feb 01 '22 at 17:35
  • I will try -XX:-OmitStackTraceInFastThrow as explained here, maybe I will have the "Caused by" then : https://stackoverflow.com/questions/58696093/when-does-jvm-start-to-omit-stack-traces – Hervé Girod Feb 01 '22 at 17:40
  • I explained what I think about the origin of the NPE in the question. However I still don't know why it happens and how to fix it. – Hervé Girod Feb 01 '22 at 18:15
  • 1
    You could try a recent stable version of JavaFX, e.g., 17.0.2 and see if the issue reproduces. If the error is happening on quit and there are no other adverse problems with the app, then you could just ignore the error. – jewelsea Feb 01 '22 at 19:42
  • [mcve] please.. – kleopatra Feb 01 '22 at 21:40
  • 1
    You could try explicitly calling Platform.exit() when the app is quit. – jewelsea Feb 03 '22 at 08:10

0 Answers0