Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plaform.exit() crashes Java

Here is a simple JavaFX Program. It comppiles and runs normally util the button is clicked upon.

import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.control.Button;
import javafx.scene.layout.VBox;

public class Window extends Application
{
    @Override
    public void start(Stage primary)
    {
        primary.setTitle("Window");
        Button b = new Button("Clickez-vous moi!");
        VBox vb = new VBox();
        vb.getChildren().add(b);
        primary.setScene(new Scene(vb, 400,400));
        b.setOnAction( e -> Platform.exit());
        primary.show();
    }
}

}

This is the error message I get.

Java has been detached already, but someone is still trying to use it at -[GlassViewDelegate dealloc]:/Users/jenkins/workspace/OpenJFX-mac/modules/javafx.graphics/src/main/native-glass/mac/GlassViewDelegate.m:198
0   libglass.dylib                      0x000000012a1dbf92 -[GlassViewDelegate dealloc] + 290
1   libglass.dylib                      0x000000012a1e1c9c -[GlassView3D dealloc] + 252
2   libobjc.A.dylib                     0x00007fff645894ea _ZN19AutoreleasePoolPage12releaseUntilEPP11objc_object + 134
3   libobjc.A.dylib                     0x00007fff6456f440 objc_autoreleasePoolPop + 175
4   CoreFoundation                      0x00007fff2e45f66e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
5   CoreFoundation                      0x00007fff2e45f594 __CFRunLoopDoObservers + 457
6   CoreFoundation                      0x00007fff2e40272b __CFRunLoopRun + 1219
7   CoreFoundation                      0x00007fff2e401fe3 CFRunLoopRunSpecific + 499
8   libjli.dylib                        0x000000010735b619 CreateExecutionEnvironment + 399
9   libjli.dylib                        0x000000010735775e JLI_Launch + 1354
10  java                                0x000000010734dca5 main + 375
11  libdyld.dylib                       0x00007fff658dc2e5 start + 1
MAC:Wed Dec 04:13:10:426> 

I am running the latest version of MACOSX Catalina.

like image 419
ncmathsadist Avatar asked Dec 04 '19 18:12

ncmathsadist


People also ask

What is a Java crash and why is it dangerous?

A Java crash can be a nightmare for developers. The dreaded Java Virtual Machine (JVM) crashes are quite common, and if you are a Java developer, you would probably know how difficult it is to diagnose and recover from a crash.

What is a crash file in JVM?

JVM produces this file itself when it crashes and proves extremely useful for classifying the Java crashes. It indicates that the JVM process has run out-of-virtual memory, and stack overflow errors are also mentioned. .core is a binary crash file produced on UNIX-based systems such as Linux and Solaris.

How to stop or terminate the JavaFX application?

In this tutorial, we will learn how to stop or terminate the JavaFX application. In the following example, we have a Button control. When we click on the button, the application terminates. When a button is pressed and released, an ActionEvent is sent. Let's understand the above JavaFX program.

What causes a JVM to crash during code generation?

A JVM crash could also be caused due to a programming error or an error in third-party library code. The Following are the ways to identify and troubleshoot a JVM crash during code generation. If Java crashes while generating a code, the most common reason could be an error during method compilation.


1 Answers

USE

stage.setOnCloseRequest((event) -> {
    Platform.exit();
});

and invoke .close() in the button.onAction() method like so:

button.setOnAction((event) -> {
    stage.close();
});

the old style annonymous inner class impl for both event types is as follows:

button.setOnAction(new EventHandler<ActionEvent>() { // note event handler class (ACTION)
    @Override
    public void handle(ActionEvent event) {
        stage.close();
    }
});

and

stage.setOnCloseRequest(new EventHandler<WindowEvent>() { // note event handler class (WINDOW)
    @Override
    public void handle(WindowEvent event) {
        Platform.exit();
    }
});

Curiously enough, I can run your code on windows and it gives off the BUILD SUCCESSFUL message after clicking the button. so I might be talking complete bollocks.

Nevertheless, there is a difference between event handling at OS level so it should be worth taking the time to CTRL C; CTRL V some code.

edit...

Also I've noticed you're lacking a main method in the application class which is kind of weird for me to see.

I'm pretty sure I tried spawning 2 distinct Application instances at some point in the past and was unable to do so for various javaFX reasons, so if you managed to pull it off, it's possible you're calling the platform.close() routine from the wrong primaryStage

look for something like

public static void main(String[] args) {
    Application.launch(args); // this directly references the class it's housed in since it expects to be in xxxx extends Application{} classes
}

or

public static void main(String[] args) {
    LauncherImpl.launchApplication(someClass.class, args); // this can be used to launch any class as long as it extends Application.class.
}

Lastly, make sure you're not doing something stupid like having

Window x = new Window(); // pretty sure you can't actually do this but fk knows.... can't be bothered to check.
x.start();

Called from somewhere in your code.

Application =/= Application Windows.

If you want to create a multi-window application, all you need to do is something like:

public class ProperMultiWindowApp extends Application {

public static void main(String[] args) {
    Application.launch(args);
}

@Override
public void start(Stage primary) {
    primary.setTitle("Window");
    Button b = new Button("Clickez-vous moi!");
    VBox vb = new VBox();
    vb.getChildren().add(b);
    primary.setScene(new Scene(vb, 400, 400));
    
    b.setOnAction(e -> primary.close());

    Stage secondary = new Stage();
    secondary.setScene(new Scene(new HBox(new Label("here be content zeh 2nd"))));

    Stage tertiary = new Stage();
    tertiary.setScene(new Scene(new HBox(new Label("here be content le 3rd"))));

    primary.show();
    secondary.show();
    tertiary.show();

    primary.setOnCloseRequest(e -> Platform.exit());

}

@Override
public void stop() throws Exception {
    System.out.println("proof that this is stopping"); // this should be called during Platform.exit();
    super.stop();
}

}

Note that for standard JavaSE using JavaFX, the class that you start the application in is what the javaFX JVM considers to be the main class.

If all this fails it's either a bug, or something to do with your mac.... since it's a mac.

If this is the case, I wholeheartedly advise you to proceed to repeatedly bash that thing against a rock in order to ensure that the application is effectively closed.

like image 139
EverNight Avatar answered Nov 14 '22 05:11

EverNight