For various reasons calling System.exit
is frowned upon when writing Java Applications, so how can I notify the calling process that not everything is going according to plan?
Edit: The 1 is a standin
for any non-zero exit code.
For various reasons calling System.exit
is frowned upon when writing Java Applications, so how can I notify the calling process that not everything is going according to plan?
Edit: The 1 is a standin
for any non-zero exit code.
The use of System.exit
is frowned upon when the 'application' is really a sub-application (e.g. servlet, applet) of a larger Java application (server): in this case the System.exit
could stop the JVM and hence also all other sub-applications. In this situation, throwing an appropriate exception, which could be caught and handled by the application framework/server is the best option.
If the java application is really meant to be run as a standalone application, there is nothing wrong with using System.exit
. in this case, setting an exit value is probably the easiest (and also most used) way of communicating failure or success to the parent process.
I agree with the "throw an Exception" crowd. One reason is that calling System.exit makes your code difficult to use if you want other code to be able to use it. For example, if you find out that your class would be useful from a web app, or some kind of message consuming app, it would be nice to allow those containers the opportunity to deal with the failure somehow. A container may want to retry the operation, decide to log and ignore the problem, send an email to an administrator, etc.
An exception to this would be your main()
method; this could trap the Exception, and call System.exit()
with some value that can be recognized by the calling process or shell script.
System.exit()
will block, and create a deadlock if the thread that initiated it is used in a shutdown hook.
Our company's policy is that it's OK (even preferred) to call System.exit(-1), but only in init() methods. I would definitely think twice before calling it during a program's normal flow.
I think throwing an exception is what you should do when something goes wrong. This way, if your application is not running as a stand-alone app the caller can react to it and has some information about what went wrong. It is also easier for debugging purposes because you as well get a better idea about what went wrong when you see a stack trace.
One important thing to note is that when the exception reaches the top level and therefore causes the VM to quit the VM returns a return code of 1, therefore outside applications that use the return code see that something went wrong.
The only case where I think System.exit() makes sense is when your app is meant to be called by applications which are not Java and therefore have to use return codes to see if your app worked or not and you want those applications to have a chance to react differently on different things going wrong, i.e. you need different return codes.
It can be dangerous / problematic in web servlet environments also.
Throwing an Exception is generally considered the other alternative.
Throwing exceptions is the best way to send information about a certain error up and out of the app.
A number doesn't tell you as much as:
Exception at thread 'main': FileNotFoundException "The file 'foo' doesn't exist"
(or something close to that)
It's frowned upon for normal exits. If "not everything is going according to plan", then System.exit is fine.
Update: I should add that I assume your '1' has meaning that is documented somewhere.
I feel impelled to add some salt of mine too. This is a great question that always pops up when I write an application.
As everyone here seems to agree, you should be careful using System.exit()
, and if possible, use exceptions. However, System.exit()
still seems the only way to return basic informations to the system, and thus required if you want to make your application scriptable. If you don't need that, just throw an exception and be done with it.
But if (and only if) your application is single-threaded, then it's fine to use it -- it's guaranteed that no other stuff is going in, and no resources are open (at least if you consistently use the try-with-resource idiom, which I'd highly recommend as it also makes the code cleaner and more compact).
On the other hand, as soon as your application creates any kind of thread that may write resources, System.exit() is a total "no, no", because it can (and, with time, will) corrupt data.
To be able to use a multi-threaded and scripted application and still guarantee the data integrity, my best solution so far is to save any resource-modifying thread you create (for example by consistently using a factory method which adds the thread to the list), and also installing a shutdown hook that cleanly ends each thread by interrupting and joining it. As the shutdown hook is also called by System.exit()
, this will guarantee (minus programming errors) that no thread is killed in mid-resource writing.
Oh yes, maybe I shouldn't even mention it, but: never, EVER, use that horrible System.halt()
method. It just shoots the VM in the head and doesn't call any shutdown hook.