Exit the application gracefully?

I have an application with a well-defined Try / Catch / finally chain that completes and executes a finally block, which works fine under normal conditions, however, when someone gets into red X prematurely in the GUI, the program fully exists (code = 0 ), and the final block of the main thread is not called.

Actually, I want the program to exit by clicking the red letter X, but I do not want to skip the finally {} block! I kind of inserted the most important part of the finally block manually into the GUI, but I really do not want to do this, since I want the GUI to be separated from the real program:

class GUI { // ... ... mainFrame.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent evt) { try { processObject.getIndicatorFileStream().close(); } catch (Exception ignore) {} System.exit(0); } }); ... } 

But I would rather just call like this:

 mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

And make sure that all finally {} blocks are called from each thread after exiting.

I know this is really expected. If the application is closed from a separate thread (say, a GUI thread), then the main thread will simply stop on its tracks.

In short - how can I guarantee that System.exit (0) or JFrame.EXIT_ON_CLOSE will still cause each finally block to execute?

+7
java user-interface try-catch-finally jframe exit
source share
3 answers

If you have no other design change options, then you may need the JVM shutdown hook , which you can add to run a piece of code when calling System.exit .

Shutdown Hooks is a special design that allows developers to connect in a piece of code that must be executed when the JVM closes. This is useful in cases where we need to perform a special cleaning operation in the event of a VM shutdown.

You can add a trip hook as indicated here:

 Runtime.getRuntime().addShutdownHook(Thread) 

More on shutdown stops here:

http://java.dzone.com/articles/know-jvm-series-2-shutdown

A word of caution:

We must keep in mind that it is not guaranteed that turning off hooks will always work. If the JVM crashes due to some internal error, then it may crash without the ability to execute a single instruction. In addition, if O / S gives a SIGKILL ( http://en.wikipedia.org/wiki/SIGKILL ) signal (kill -9 on Unix / Linux) or TerminateProcess (Windows), then the application is required to immediately stop working, not even awaiting any cleaning activities. In addition to the above, it is also possible to terminate the JVM by preventing the launch hooks from invoking Runime.halt () calls.

+8
source share

If you have threads that can be legally stopped at any time, at any time within their cycle, at any point in any method that they call, and I can warn you that this is very unlikely, you can stop all of them when you exit the program. This will throw an exception in each thread, and finally blocks will execute.

However, the correct way to achieve your goal and the graphical interface, separate from the program logic, is to release one "exit" from the graphical interface, which initiates the entire cleaning of the application, which is written in a completely different class. If you have threads, then implement interrupt mechanism in each of them.

There are many ways to achieve output signaling. For example, your business code may register a GUI receiver for a special event, which will clear it. You can also have a thread that does nothing but await on a CountDownLatch , which will be countDown from the GUI.

Please in no case use the disconnect hook . This is the dirtiest mechanism you can imagine, and it exists only as a last resort, when all regular cleaning procedures fail. It should never be used as part of a normal shutdown procedure.

Thus, there is no clear way to clean applications. You must implement specific mechanisms for each specific problem.

+3
source share

With modern Java, Window.dispose() in all application windows can offer a more graceful ability to exit an AWT application than System.exit(0) , see
https://docs.oracle.com/javase/8/docs/api/java/awt/Window.html#dispose--

 /** Listens and closes AWT windows. * The class is implemented as singleton since only one is needed. */ public class ExitListener extends WindowAdapter { /** the instance object */ private static final ExitListener INSTANCE = new ExitListener(); // hide the constructor private ExitListener () {} /** retrieve the listener object */ public static ExitListener getInstance () { return INSTANCE; } @Override public void windowClosing ( final WindowEvent e ) { e.getWindow().dispose(); } } 

and with your windows

 window.addWindowListener( ExitListener.getInstance() ); 

However, be careful in adverse conditions, see:
https://docs.oracle.com/javase/8/docs/api/java/awt/doc-files/AWTThreadIssues.html#Autoshutdown

0
source share

All Articles