Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Platform.exit() #247

Closed
anton-johansson opened this issue Feb 6, 2016 · 3 comments · Fixed by #288
Closed

Platform.exit() #247

anton-johansson opened this issue Feb 6, 2016 · 3 comments · Fixed by #288

Comments

@anton-johansson
Copy link

When I use Platform.exit() at points where I want to force a direct exit of the application, my unit tests with TestFX seem to hang. I'm guessing they're not shutting down properly.

Is it a bad idea using Platform.exit(), or can this be fixed within TestFX somehow?

@hastebrot
Copy link
Member

Is it a bad idea using Platform.exit()

Yes it is. It will shut the JavaFX Application Thread down. Any new requests to the thread, e.g. using Platform.runLater(), will cause the application to hang.

This also caused me some headaches searching for a bug when all Stages were closed. If they were all closed, JavaFX will automatically call Platform.exit(). I fixed that in [1].

can this be fixed within TestFX somehow

There is no workaround I know.

[1] https://github.com/TestFX/TestFX/blob/35c48e8513/subprojects/testfx-core/src/main/java/org/testfx/api/FxToolkit.java#L266-L268

@anton-johansson
Copy link
Author

That explains a lot, thanks! I guess I'll try to avoid using Platform.exit().

I have a scenario where I never actually show a stage. And it seems to me that doing stage.close() on this stage won't cause the application to close properly. Here is one example where I used Platform.exit(). I'll see if I can find a better workaround for that.

@aminabs
Copy link

aminabs commented Apr 28, 2016

Just call platform.setImplicitExit(false) to avoid your application being implicitly closed after all the stages are gone.

Ortner pushed a commit to Ortner/TestFX that referenced this issue May 27, 2016
Task-Url: http://github.com/TestFX/TestFX/issues/issue/287

Added method to detect whether FX Application Thread is running. Clean
up code is only pushed  on the FX-Thread if it is running.

fixes TestFX#287
fixes TestFX#247
yamidark added a commit to yamidark/addressbook-level4 that referenced this issue Feb 20, 2018
The MainWindow has no specified event handler when there are external
requests to close the MainWindow, such as the close button or through
the taskbar.

This may cause the app to not close properly since it will not raise an
ExitAppRequestEvent, in turn MainApp#stop() is not called.
MainApp#stop() is the method used to call Platform#exit() and
System#exit(int) which stops our app and closes all remaining open
windows. Thus, if MainApp#stop() is not called, the app may continue to
run even after the MainWindow is closed, causing any existing
HelpWindows to remain open even when the user expects the app to stop.

Based on the documentation on Life-Cycle of a JavaFX Application[1],
the app will only finish and call MainApp#stop() when the app either
calls Platform#exit() or when the last window has been closed. Thus,
should there be any HelpWindows still opened, the app will continue
running, causing those HelpWindows to remain open.

Let's add an event handler for onCloseRequest event, which is raised
when there is an external request to close the Window, in
MainWindow.fxml root to call handleExit().

MainApp#stop() calls both Platform#stop() and System#exit(int) in
order to shut down the app. As a result, we are unable to write
regression tests for this bug fix as the test classes terminates
prematurely after the MainWindow is closed via any of the exit methods.

Also, we are unable to write tests to stop and catch if
System#exit(int) was called through the use of Java SecurityManager[2]
or JUnit System Rules[3] due to an issue with TestFX[4] causing the
app to hang after calling Platform#exit().

[1] JavaFx documentation for Application:
https://docs.oracle.com/javafx/2/api/javafx/application/Application
.html

[2] Java documentation for SecurityManager:
https://docs.oracle.com/javase/8/docs/api/java/lang/SecurityManager
.html

[3] Documentation for JUnit System Rules:
http://stefanbirkner.github.io/system-rules/

[4] Issue with TestFX:
TestFX/TestFX#247
yamidark added a commit to yamidark/addressbook-level4 that referenced this issue Feb 22, 2018
The MainWindow has no specified event handler when there are external
requests to close the MainWindow, such as the close button or through
the taskbar.

This may cause the app to not close properly since it will not raise an
ExitAppRequestEvent, in turn MainApp#stop() is not called.
MainApp#stop() is the method used to call Platform#exit() and
System#exit(int) which stops our app and closes all remaining open
windows. Thus, if MainApp#stop() is not called, the app may continue to
run even after the MainWindow is closed, causing existing HelpWindows
to remain open even when the user expects the app to stop.

According to the life-cycle section in the documentation on JavaFX
Application[1], the app will only finish and call MainApp#stop() when
the app either calls Platform#exit() or when the last window has been
closed. Thus, should there be any HelpWindows still opened, the app
will continue running, causing those HelpWindows to remain open.

Let's add an event handler for the onCloseRequest event in the root of
MainWindow.fxml. This event will call MainWindow#handleExit() when
raised by an external request to close the app.

Since MainApp#stop() calls System#exit(int) in order to shut down the
app, we could try to stop and catch this System#exit(int) signal to
test that the app closes properly after MainWindow is closed.

However, while an extended SecurityManager class is able to stop and
catch the System#exit(int) by overriding the checkExit(int) method[2],
due to an issue with TestFX[3], the test will hang since MainApp#stop()
calls Platform#exit() before System#exit(int). Likewise, JUnit System
Rules[4] which is implemented using an extended SecurityManager class
too also faces the same issue. As a result, we are unable to write
regression tests for this bug fix as the test classes terminate
prematurely after the MainWindow is closed via any of the exit methods.

[1] JavaFx documentation for Application:
https://docs.oracle.com/javafx/2/api/javafx/application/Application.html

[2] StackOverFlow post on how to test methods that call System#exit(int):
https://stackoverflow.com/questions/309396/java-how-to-test-methods-that-call-system-exit

[3] Issue with TestFX interaction with Platform#exit():
TestFX/TestFX#247

[4] Documentation for JUnit System Rules:
http://stefanbirkner.github.io/system-rules/
yamidark added a commit to yamidark/addressbook-level4 that referenced this issue Feb 22, 2018
The MainWindow has no specified event handler when there are external
requests to close the MainWindow, such as the close button or through
the taskbar.

This may cause the app to not close properly since it will not raise an
ExitAppRequestEvent, in turn MainApp#stop() is not called.
MainApp#stop() is the method used to call Platform#exit() and
System#exit(int) which stops our app and closes all remaining open
windows. Thus, if MainApp#stop() is not called, the app may continue to
run even after the MainWindow is closed, causing existing HelpWindows
to remain open even when the user expects the app to stop.

According to the life-cycle section in the documentation on JavaFX
Application[1], the app will only finish and call MainApp#stop() when
the app either calls Platform#exit() or when the last window has been
closed. Thus, should there be any HelpWindows still opened, the app
will continue running, causing those HelpWindows to remain open.

Let's add an event handler for the onCloseRequest event in the root of
MainWindow.fxml. This event will call MainWindow#handleExit() when
raised by an external request to close the app.

Since MainApp#stop() calls System#exit(int) in order to shut down the
app, we could try to stop and catch this System#exit(int) signal to
test that the app closes properly after MainWindow is closed.

However, while an extended SecurityManager class is able to stop and
catch the System#exit(int) by overriding the checkExit(int) method[2],
due to an issue with TestFX[3], the test will hang since MainApp#stop()
calls Platform#exit() before System#exit(int). Likewise, JUnit System
Rules[4] which is implemented using an extended SecurityManager class
too also faces the same issue. As a result, we are unable to write
regression tests for this bug fix as the test classes terminate
prematurely after the MainWindow is closed via any of the exit methods.

[1] JavaFx documentation for Application:
https://docs.oracle.com/javafx/2/api/javafx/application/Application.html

[2] StackOverFlow post on how to test methods that call System#exit(int):
https://stackoverflow.com/questions/309396/java-how-to-test-methods-that-call-system-exit

[3] Issue with TestFX interaction with Platform#exit():
TestFX/TestFX#247

[4] Documentation for JUnit System Rules:
http://stefanbirkner.github.io/system-rules/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants