What is an appropriate way to programmatically exit an application? - java

I am evaluating user inputs as commands for my application. If the user presses Q, or q, and then hits enter, the application quits and execution terminates.
Is there a proper context, or best practices on how to do that? I do not have any resources to release, or anything like that. Should I just use System.exit(0);? Is there a recommended way to do that?
As my first approach I do something like this:
while (true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//Other logic goes here...
if (br.readLine().equalsIgnoreCase("Q")){
System.exit(0);
}
}
catch (IOException ioe) {
System.out.println("IO error trying to read your selection");
}
}

You might as well return up to main() and return from there.
private void loop() {
while (true){
try{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//other logic goes here...
if(br.readLine().equalsIgnoreCase("Q")){
return; // You're done and you are returning to the caller.
}
}
catch (IOException ioe) {
System.out.println("IO error trying to read your selection");
}
}
}
public static void main(String[] args) {
loop();
}
But if you don't have anything to release, System.exit(0) is fine.

Resources are cleaned up automatically by the OS when the process exits. There are two primary reasons to not just exit() from the middle of the code (this applies to all languages).
There may be some action that needs to be taken before the program ends. For example, you may need to save any open files (i.e. write changes that for performance or other reasons have not been sent to the file yet).
Someone may want to later use your code for some other purpose.
Take for example, the Git version control system. There's several efforts to turn the code into a library instead of a set of stand-alone executables so that it can be efficiently incorporated into other projects. One of the problems (from what I've heared) is that the code sometimes simply terminates instead of tracking and cleaning up the resources it's using. As an executable that's fine, but if it was imported as a library, you don't always want to just terminate the host application because you've finished your little part.

Returning all the way back to Returning out of main() is the cleanest way, of course, but if that's not easy to do, System.exit() is perfectly fine.
It's not directly relevant to your question, but throwing an (unhandled) exception is usually the way to terminate on a fatal condition, since it provides a lot of tracing info to the poor user.

I would like to say:
It doesn't matter, it's entirely up to
you!
And dough it sometimes is true, other times it depends on the program structure and code integrity.
The reasonable exit would be through main method, terminating all the threads.
System.exit forces termination of all the threads in the JVM. The System.exit never returns normally. It should be used for an error.

System.exit() is fine. And I agree with the other answers, returning to main would be the best way to exit - from a maintenance point of view. As your code expands you may forget the little method doing System.exit have to debug to remember it.
However you only need to use exit if you have a script which needs the information about an abnormal termination. Otherwise there is no need.
As I recall a Java program will exit with 0 by default - meaning normal termination. So you'd want to use System.exit(n) for cases where your program terminates due to some error.
Example (just using static methods you'd most likely want to instantiate...):
public static void main(String[] args) {
try {
doStuff();
} catch (SomeRuntimeException e) {
// marching orders! Exit with errorcode
<log the error with sufficient info for debugging>
System.exit(1);
}
}
private static doStuff() {
// doing my thing ...
...
//then some error occurs and I have no other choice but to do a hard exit
throw new SomeRuntimeException( ... some info would be nice ...)
...
return
}

Don't forget that if you perform a System.exit(), you can't easily later use your methods in a standalone library. If you want to reuse your code outside your existing solution (and you may not now, but decide to do so in the future), then you'll then have to revisit and refactor appropriately.
Otherwise the worst-case scenario is that you take the existing code without noticing the System.exit()s, use it and then have your library exit unexpectedly in a new application.
Just something to bear in mind re. code-reuse.

Related

How to deal with: Call to 'Thread.sleep()' in a loop, probably busy-waiting

Guys how to deal with such code and warning?
private void listenOnLogForResult() {
String logs = "";
int timeCounter = 1;
while (logs.isEmpty()) {
try {
timeCounter++;
Thread.sleep(2000); // Wait 2 seconds
} catch (InterruptedException e) {
log.error(e.getLocalizedMessage(), e);
}
if (timeCounter < 30) {
logs = checkLogs()
} else {
logs = "Time out";
}
}
}
I need to pause current thread for 2 seconds to wait file to be filled, but my Intelij Rise an issue here.
And also I am getting error from sonar:
SonarLint: Either re-interrupt this method or rethrow the "InterruptedException".
I've tried already with many ExecutorService, but it is always run in seperate thread, and I need to pause current one.
Please help..
The busy-waiting warning
This is a warning coming from intellij that is dubious, in the sense that what you're doing is often just straight up required. In other words, it is detecting a pattern that is overused, but whose usage cannot be reduced to 0. So, likely the right solution is to just tell intellij to shut up about it here.
The problem it is looking at is not that Thread.sleep. That is not the problem. However, intellij's detector of this pattern needs it to find this case, but it is not what it is complaining about, which might be a little hard to wrap your head around.
What IntelliJ is worried about, is that you're wasting cycles continually rechecking log.isEmpty() for no reason. It has a problem with the while aspect of this code, not the sleep. It would prefer to see code where you invoke some sort of logs.poll() method which will just wait until it is actively woken up by the act of new logs appearing.
If this is all running within a single java process, then you can indeed rewrite this entire system (which includes rewrites to whatever log is here, and a complete re-imagining of the checkLogs() method: Instead of going out and checking, whatever is making logs needs to wake up this code instead.
If it's not, it is likely that you need to tell intellij to shut it: What you are doing is unavoidable without a complete systems redesign.
The re-interrupt warning
You have some deplorable exception handling here.
Your exception handling in general
Do not write catch blocks that log something and keep moving. This is really bad error handling: The system's variables and fields are now in an unknown state (you just caught and logged some stuff: Surely that means you have no idea what conditions have occurred to cause this line of execution to happen!), and yet code will move right along. It is extremely likely that 'catch exceptions and just keep going' style code results in more exceptions down the line: Generally, code that operates on unknown state is going to crash and burn sooner rather than later.
Then, if that crash-and-burn is dealt with in the same fashion (catch it, log it, keep going), then you get another crash-and-burn. You end up with code that will, upon hitting a problem, print 186 exceptions to the log and they are all utterly irrelevant except the first one. That's bad yuyu.
You're also making it completely impossible for calling code to recover. The point of exceptions is that they need to bubble upwards endlessly: Either the exception is caught by code that actually knows how to deal with the problem (and logging it is not dealing with it!), which you are making impossible, or, the code exception should bubble up all the way to the entry-point handler which is the right place to log the error and abort the entry-point handler.
An entry-point handler is a generic module or application runner; out of the box, the code baked into java.exe itself that ends up invoking your psv main() method is the most obvious 'entry point runner', but there's more: Web frameworks will eventually invoke some code of yours that is supposed to handle a web request: That code of yours is analogous to psv main(): It is the entry-point, and the code in the web framework that invokes it, is the entry-point runner.
Entry-point runners have a good reason to catch (Throwable t), and to spend their catch block primarily logging it, though they should generally log a lot more than just the exception (a web handler should for example log the request details, such as which HTTP params were sent and which path request it was, maybe the headers, etc). Any other code should never do this, though.
If you have no idea what to do and don't want to think about what that exception might mean, the correct 'whatever, just compile already javac' code strategy is to add the exception type to your throws line. If that is not feasible, the right code in the catch block is:
} catch (ExceptionIDoNotWantToThinkAboutRightNow e) {
throw new RuntimeException("Uncaught", e);
}
This will ensure that code will not just merrily continue onwards, operating on unknown state, and will ensure you get complete details in logs, and ensures that calling code can catch and deal with it if it can, and ensures that any custom logging info such as the HTTP request details get a chance to make it to the logs. Win-win-win-win.
This case in particular: What does InterruptedEx mean?
When some code running in that java process invokes yourThread.interrupt(), that is how InterruptedException can happen, and it cannot possibly happen in any other way. If the user hits CTRL+C, or goes into task manager and clicks 'end process', or if your android phone decides it is time for your app to get out as the memory is needed for something else - none of those cases can possibly result in InterruptedExceptions. Your threads just get killed midstep by java (if you want to act on shutdowns, use Runtime.getRuntime().addShutdownHook). The only way is for some code to call .interrupt(), and nothing in the core libs is going to do that. Thus, InterruptedException means whatever you think 'call .interrupt() on this thread' means. It is up to you.
The most common definition is effectively 'I ask you to stop': Just shut down the thread nicely. Generally it is bad to try to shut down threads nicely if you want to exit the entire VM (just invoke System.shutdown - you already need to deal with users hitting CTRL+C, why write shutdown code twice in different ways?) - but sometimes you just want one thread to stop. So, usually the best code to put in a catch (InterruptedException e) block is just return; and nothing else. Don't log anything: The 'interrupt' is intentional: You wrote it. Most likely that is nowhere in your code base and the InterruptedException is moot: It won't ever happen.
In your specific code, what happens if your code decides to stop the logger thread is that the logger thread will log something to the error logs, and will then shortcut its 2 second wait period to immediately check the logs, and then just keeps going. That sounds completely useless.
But, it means whatever you want it to. If you want an ability for e.g. the user to hit a 'force check the logs right now' button, then you can define that interrupting the logging thread just shortcuts the 2 seconds (but then just have an empty catch block with a comment explaining that this is how you designed it, obviously don't log it). If you ALSO want a button to 'stop the logging thread', have an AtomicBoolean that tracks 'running' state: When the 'stop log-refreshes' button is hit, set the AB to 'false' and then interrupt the thread: Then the code you pasted needs to check the AB and return; to close the thread if it is false.
fun sleep(timeMillis: Long) {
val currentTimeMillis = System.currentTimeMillis()
while (true) {
if (System.currentTimeMillis() - currentTimeMillis >= timeMillis) {
break
}
}
}
and use this in your method(It's code by koltin,you should trans to java)

Why printing all running threads in Java unblocks an application?

I created a GUI Application in JavaFX which communicates with a serial device (I use a jssc connector). When I want to get data I send a communicate, then wait 1s until the wait function terminates. Communicate is also being sent, among other things, when I click one of the buttons (for starting a device, for identification, etc.). During development process I noticed a bug - communication hangs (but only when receiving messages, I still can send one-way communicates for ie. starting a device) when I click too many buttons too fast or I click buttons which send more than one communicate.
Communication is mainly handled by my own class SerialPortDevice. I create an object of a class' type and then invoke particular methods. Here's the method which waits for a message:
private String waitForMessage() throws SerialPortException {
long operationStartTime = System.currentTimeMillis();
long connectionTimeout = SerialPortCommunicationParameters.CONNECTION_TIMEOUT_IN_MILLIS;
String resultMessage = "";
do {
if (readEventOccurred) {
System.out.println();
resultMessage = receiveMessage();
System.out.println("After receiving a message");
messageReceived = true;
}
} while (((System.currentTimeMillis() - operationStartTime) < connectionTimeout) && (!messageReceived));
if (!readEventOccurred) {
resultMessage = NO_RESPONSE;
}
System.out.println("Time elapsed: " + (System.currentTimeMillis() - operationStartTime + "ms"));
return resultMessage;
}
One can notice that message is being received only when a flag readEventOccured is true. It's handled by my implementation of the SerialPortEventListener:
class SerialPortDeviceReader implements SerialPortEventListener {
private SerialPortDevice device;
SerialPortDeviceReader(SerialPortDevice device) {
this.device = device;
}
public void serialEvent(SerialPortEvent event) {
if (event.isRXCHAR()) {
System.out.println("Serial Event Occured!");
device.setReadEventOccurred(true);
}
}
}
readEventOccured is a boolean field in the SerialPortDevice class which contains waitForMessage function. Also, waitForMessage is invoked by another function, singleConversation:
String singleConversation(String testMessage) {
String resultMessage = NO_RESPONSE;
try {
openConnection();
sendMessage(testMessage);
resultMessage = waitForMessage();
closeConnection();
} catch (SerialPortException e) {
e.printStackTrace();
return resultMessage;
}
System.out.println();
readEventOccurred = false;
messageReceived = false;
return resultMessage;
}
... Which is the only function setting readEventOccured to false. And it is a "top level" function in a SerialPortDevice class which handles sending and receiving a communicates to and from a device.
So communication looks like this:
Button click -> Button handler invocation -> device.singleCommunication(buttons_specific_communicate) -> some methods run and then it comes to the waitForMessage -> method waits 1s for the event -> event occurs (everytime - I get the "Serial Event Occured" communicate) -> readEventOccured is being set to true -> if there is some time left (there is always some time left, everything lasts a miliseconds), message is being received in the waitForMessage method.
There is no problem if I click buttons with a short (in a human sense, 2-3s for example) delay or I don't click these which do send more than one communicate inside their handlers. In different situations weird things happen. I still get the message "Serial Event Occured" (so I suppose readEventOccured is also being set to true) but waitForMessage function does not execute
if(readEventOccured)
statement's code. Also, I have to run an application again to be able to communicate with a device (I mean receiving data, sending works perfectly).
What solved my problem was adding "volatile" modifier to the readEventOccured flag (makes sense by the way, things go fast sometimes). But it didn't please me. I wanted to make a code to run correctly without "volatile". My coworker came up with an idea something goes wrong with threads that are being created when I click buttons and invoke communication - maybe something blocks other thing somewhere? First thing I did was to print all the currently runnig threads and... Man, it solved a problem. App was not hanging anymore. Really, I performed "hanging" scenarios 10-20 times with and without
Set<Thread> threadSet = Thread.getAllStackTraces().keySet();
System.out.println(threadSet);
at the beginning of the waitForMessage method and result were unambigous - it somehow removed my problem.
I'm almost certainly sure getting and printing threads is not a solution itself. It's something that is being done by the way but I can't find out what is this. Any useful information? Maybe better understanding Threads in Java would help me? Or it is something else?
Cheers
What you're doing is the textbook example of what happens when there are no visibility guarantees. If we distil your code into its essential bits, we get something like this:
boolean flag = false;
void consume() {
while (true) {
if (flag) {
//we received flag, hooray
}
}
}
void produce() {
flag = true;
}
Now, if produce() and consume() run in different threads, there is absolutely no guarantee that consume() will EVER see flag set to true. volatile creates a memory barrier, meaning that all reads/writes of those variable will be fully ordered.
What you also have in the code though, is lots of System.out.println() lines. These complicate the picture, as they themselves are synchronized, and thus create happens-before relationships between different parts of the code. Unfortunately they don't create the correct sequence, but poke in a few more and you can accidentally get it right. The key word here is "accidentally", you shouldn't rely on this behaviour at all.
So marking readEventOccurred as volatile sort of fixes the problem but going a bit further we can see that your waitForMessage() spin-waits, which is rarely a good idea. I would take a look at the CountDownLatch class for example, designed for similar scenarios. (An even better candidate is its close friend, CyclicBarrier.)
What solved my problem was adding "volatile" modifier to the readEventOccured flag (makes sense by the way, things go fast sometimes). But it didn't please me. I wanted to make a code to run correctly without "volatile".
The fact that adding volatile fixes the problem indicates you've run into the lack of guarantees by the Java Memory Model when multiple threads are involved. Simply put there is no guarantee of when a change on one thread is visible on other threads except for specific situations.
The probably reason why printing 'fixes' the problem is the fact that it:
Changes the timing of the program, might mean the situation in which it fails no longer exists.
Temporarily suspends the threads to read out their current state, maybe the JVM also uses that as an opportunity to synchronize memory.
Multithreaded communication is hard, so I recommend you take a look at the classes available in java.util.concurrent, which have guarantees that you might be able to use to solve your problem more elegantly.

Best way to exit a program when I want an exception to be thrown?

I'm writing a Java program that reads in a file of words. The program crucially depends on this file, so I really do want the program to end if for whatever reason there's an IOException when reading the file.
What's the best way to end the program? I think I'm forced to surround my file-reading inside a try/catch block, so should I add a System.exit(0) inside my catch? For example, should I do something like the following?
try {
BufferedReader br = new BufferedReader(new FileReader("myfile.txt"));
String line;
while ((line = br.readLine()) != null) {
// process...
}
} catch(IOException e) {
System.out.println("Error: " + e);
System.exit(0); // ???
}
If you let the exception propagate all the way up to the main() method, the program will end. There's no need to call System.exit, just allow the exception to bubble up the stack naturally (by adding throws IOException) to the necessary methods.
Edit: As #Brian pointed out, you may want to catch the IOException in your main method, and call System.exit there instead, supplying a human-readable error message (stack traces can scare people). Also, as #MeBigFatGuy said, calling System.exit from inside your code stack is bad practice, and limits the reuseability of the code. If you must use System.exit, then keep it inside the body of the main method.
That's fine. However 0 as an exit code means the program ended as expected. You'll want to use a different number ;)
If you really do wish to terminate the program immediately, rather than letting upper levels of the program decide what to do (maybe the core of your program will be extended some day to allow selecting a source for myfile.txt from various websites, or speech-to-text synthesis, or direct brain transfer), you should call: System.exit(1) (or some other non-zero exit status).
An exit code of 0 says to the shell (and parent processes) that execution completed normally. Non-zero exit codes report that there was an error. This is vital for making excellent tools to notify admins of abnormal execution faults, or for writing friendly little programs:
./fiddle_with_words myfile.txt || mail -s "program failed" grautur#example.com
#gratur asks in a comment on #skaffman's answer.
So if I understand correctly, I let the exception bubble up by removing the try/catch block and adding a "throws IOException" to that method (and methods that call that method, and so on)? I feel kind of icky doing that, because now I have to add a bunch of "throws IOException"s everywhere -- is my ickiness misguided?
I think it depends. If the exception only has to bubble up a small number of levels, and it makes sense for the methods to propagate an IOException, then that's what you should do. There is nothing particularly "icky" about allowing an exception to propagate.
On the other hand, if the IOException has to propagate through many levels and there is no chance that it might be handled specifically beyond a certain point, you may want to:
define a custom ApplicationErrorException that is a subclass of RuntimeException,
catch the IOException near its source and throw an ApplicationErrorException in its place ... with the cause set of course, and
catch the ApplicationErrorException exception in your main method.
At the point in main where you catch the ApplicationErrorException, you can call System.exit() with a non-zero status code, and optionally print or log a stack trace. (In fact, you might want to distinguish the cases where you do and don't want a stack trace by specializing your "application error" exception.)
Note that we are still allowing an exception to propagate to main ... for the reasons explained in #skaffman's answer.
One last thing that complicates this question is exceptions that are thrown on the stack of some thread other than the main thread. You probably don't want the exception to be handled and turned into a System.exit() on the other thread's stack ... because that won't give other threads a chance to shut down cleanly. On the other hand, if you do nothing, the default behaviour is for the other thread to just terminate with an uncaught exception. If nothing is join()-ing the thread, this can go unnoticed. Unfortunately, there's no simple "one size fits all" solution.

Programming language for an app that needs to be running forever

I'm upgrading an app that registers the time employees arrive and leave the office. I would like not to install this app into one of our current servers, which are somewhat important, beacuse I would have to leave a session open and i'd like to keep things separated. So all I have is cheap, cheap hardware. Basically a 500MHz, 64MB RAM Debian Lenny with nothing but the app, and MySQL database to store the information, oh yes, and i'ts inside a stove.
Currently the app is written in Java. Just a console program with a Dilbert's face ascii art on it asking for the employee's ID. The actual line, that does the 'waiting' is :
id = cin.nextInt();
When the first employee arrives monday morning and types he's id, about 40 hours of no usage since last employee left, the app crashes. Cant remember the actual exception thrown.
So my question is: Is there a nice way to loop a Java app forever ? Or maybe a better question is, which programming language is better for this task ?
I guess it would seem obvious at first not to use big 'ol java on such poor system, but lets just say, I kinda like Java.
Edit: Thanks for all your replies. However I do all the try/catching there is. I'm the problem is an Error the app can not recover from such as OutOfMemoryError.
The actual code looks something like :
static boolean start() {
Scanner cin = new Scanner(System.in);
int id;
try{
id = cin.nextInt();
doStuff( id );
return true;
}catch (Exception e){
//which would trap all recoverable exceptions
System.out.println("Something is wrong. Try again.");
return false;
}
}
public static void main(String ... args){
boolean first = true;
while(true) {
if(first) showDilbert();
first = start();
}
}
I'm sorry I did not pay more attention to the actual exception, but I thought Java would be discarded quite faster from the hardware description.
There's absolutely no reason your program needs to maintain an open connection to the database. You can get by simply opening the connection, doing your work, and closing it every time the user enters their ID.
The truth is that the exception that you are getting is vitally important as to why it's crashing.
Your program should be little more than:
public class Go {
public static void main(String args[]) {
while(true) {
try {
String userID = getUserId();
Connection con = getConnection();
processUserId(connection, userId);
con.close();
catch(Exception e) {
logException(e);
}
}
}
}
If you're getting exceptions you need to hunt down and prevent those exceptions. Save MySQL going out to lunch, there's no reason you should be getting any exceptions at all in this program. And if MySQL goes to lunch, getting a new Connection each time solves that problem once MySQL is back up and running.
And, no, getting a new Connection each time is not "slow", unless you happen to be processing 100s or 1000s of employees per second.
while(true)
{
}
or
for(;;)
{
}
Should both loop infinitely and cause the application to continue running. You'll have to add some kind of code to make sure that your app doesn't peg the resources of the machine your running on though.
The simplest way I know of to give your Java application high availability is to just launch it from a bash script in a loop. Maybe put a sleep in there so that if your app goes into a state where it can't launch it doesn't try a million times a second. Something like this:
#!/bin/bash
while [ 1 ]
do
java ... MyApp
sleep 5
done
Doesn't matter WHAT happens in your JVM then...internal error, out of memory exception, JVM bug (they happen!) whatever. It's still going to boot right back up 5 seconds later.
Obviously this doesn't preclude steps to handle things cleanly within your application. This is the fallback.
Do you think perhaps that the input to your program is not in fact an integer, and you're getting an InputMismatchedException or something? Maybe over the weekend somebody hit a key that wasn't a number, and then when the first person on Monday types their number and presses Enter, it's got some extra cruft before it. Blammo, exception.
Are you trying to write a time entry kiosk yourself?
This problem is well solved, I'm sure you can find an affordable commercial solution.
There's nothing inherently wrong with Java for this task - although your machine specs are pretty limiting and I expect that memory consumption is your main issue - the JVM alone probably uses up most of your available RAM.
The technique I would use in Java to keep something running is:
while (true) {
try {
// do stuff here
Thread.sleep(1); // sleep a bit just to be nice to other processes
} catch (Throwable t) {
t.printStackTrace();
}
}
This way any exceptions get caught and you will see the errors, but the app will keep running.
Of course there is a big caveat emptor here - if you keep running after a critical exception and trash your data by having the code in an unstable state, you only have yourself to blame :-)
As everyone has said, there's no reason your app can't run forever. Well, nuclear holocaust would bring it to a screeching halt, but Dilbert and his tie would be the least of your concerns at that point.
Have you considered using an embedded system? You're using a general purpose computer and OS to do only one thing. It would be more economical and a great experience to implement this using Arduino or even some GP-DSP like Analog Devices' Blackfin. You can still program in C/C++ and even have an embedded OS such as ucLinux. Much much cheaper, and rock solid.
and what about migrating your app to a web based service, a simple html page will do the interface. Run a apache server behind it, that will handle your scripts (written in perl of course ;) ), and connection with bdd.
this is very light, reliable, and will run as long as you wish
I would suggest you edit your code as below. This will not make the program run longer, but you will know why it is crashing. Only then can you fix the problem.
Is this homework?
static boolean start() {
Scanner cin = new Scanner(System.in);
int id;
try{
id = cin.nextInt();
doStuff( id );
return true;
}catch (Exception e){
//which would trap all recoverable exceptions
System.out.println("Something is wrong. Try again.");
return false;
}catch(Throwable e){
// Add this.
System . err . println ( e ) ; // come back to SO with this
e . printStackTrace ( ) ; // come back to SO with this
System . exit ( 1 ) ;
}
}
public static void main(String ... args){
boolean first = true;
while(true) {
if(first) showDilbert();
first = start();
}
}
Programming language for an app that needs to be running forever
Answer: Java , you just have to be careful about the code.
Alternative answer: Any language will do, you just have to be careful about the code
I would suggest that you write the application in something like C rather than Java.

How to quit a java app from within the program

What's the best way to quit a Java application with code?
You can use System.exit() for this purpose.
According to oracle's Java 8 documentation:
public static void exit(int status)
Terminates the currently running Java Virtual Machine. The argument serves as a status code; by convention, a nonzero status code indicates abnormal termination.
This method calls the exit method in class Runtime. This method never returns normally.
The call System.exit(n) is effectively equivalent to the call:
Runtime.getRuntime().exit(n)
System.exit(0);
The "0" lets whomever called your program know that everything went OK. If, however, you are quitting due to an error, you should System.exit(1);, or with another non-zero number corresponding to the specific error.
Also, as others have mentioned, clean up first! That involves closing files and other open resources.
System.exit(int i) is to be used, but I would include it inside a more generic shutdown() method, where you would include "cleanup" steps as well, closing socket connections, file descriptors, then exiting with System.exit(x).
System.exit() is usually not the best way, but it depends on your application.
The usual way of ending an application is by exiting the main() method. This does not work when there are other non-deamon threads running, as is usual for applications with a graphical user interface (AWT, Swing etc.). For these applications, you either find a way to end the GUI event loop (don't know if that is possible with the AWT or Swing), or invoke System.exit().
Using dispose(); is a very effective way for closing your programs.
I found that using System.exit(x) resets the interactions pane and supposing you need some of the information there it all disappears.
I agree with Jon, have your application react to something and call System.exit().
Be sure that:
you use the appropriate exit value. 0 is normal exit, anything else indicates there was an error
you close all input and output streams. Files, network connections, etc.
you log or print a reason for exiting especially if its because of an error
The answer is System.exit(), but not a good thing to do as this aborts the program. Any cleaning up, destroy that you intend to do will not happen.
There's two simple answers to the question.
This is the "Professional way":
//This just terminates the program.
System.exit(0);
This is a more clumsier way:
//This just terminates the program, just like System.exit(0).
return;
Runtime.getCurrentRumtime().halt(0);
System.exit() will do what you want. But in most situations, you probably want to exit a thread, and leave the main thread alive. By doing that, you can terminate a task, but also keep the ability to start another task without restarting the app.
System.exit(ABORT);
Quit's the process immediately.
This should do it in the correct way:
mainFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
mainFrame.addWindowListener(new WindowListener() {
#Override
public void windowClosing(WindowEvent e) {
if (doQuestion("Really want to exit?")) {
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.dispose();
}
}

Categories