0

I have a set of error codes in my java application. Currently I'm using System.exit(code); to return error codes from the application to external applications. Is there any alternatives of System.exit as using this is bad practice because it may shutdown the entire JVM.

4
  • 2
    Your question doesn't make sense. The only way you can return a code to an external application is as a process exit code. Commented Jun 3, 2015 at 7:37
  • It will shutdown the JVM but why is that a problem if what you want is to exit? Commented Jun 3, 2015 at 7:37
  • System.exit() is a "bad" way to exit your application. Many static analysis tools highlight it as such. Reason being is that you may not have cleaned up everything before exiting. Also it can be quite bewildering for a user. To my mind the only reason you "should" ever use it (in normal circumstances) is if you want to return an exit-code to the shell. Commented Jun 3, 2015 at 8:14
  • I've just thought of another reason it's bad: reusability. If you have your code peppered with System.exit() it can cause problems for people wanting to use your code in a larger application. Just like goto it may be used as a short-cut to end your application without cleanly unwinding your stack. In the end, if somebody wants to use your code they'll not only have to eliminate all your System.exit() but they may have to restructure your code too! Commented Jun 3, 2015 at 8:19

3 Answers 3

2

I have shared your experience in the past, and tried to engineer out System.exit(). One possibility is to leave a RuntimeException uncaught and you will return 1 to the shell, but ultimately if you want any more versatility than that (and don't want an ugly stack-trace polluting your output), you must have at least "one" call to System.exit().

public class Splat {

    public static void main(String[] args) {

        if (args.length > 0 && "splat".equals(args[0]))
            throw new RuntimeException("splat");
    }
}

Output:

 $ java Splat
 $ echo $?
 > 0
 $ java Splat splat
 > Exception in thread "main" java.lang.RuntimeException: splat
 >         at Splat.main(Splat.java:9)
 $ echo $?
 > 1

My reason for doing this was our organisation started using static analysis results from sonar as a KPI and it was my job to get the numbers down. It's a terrible reason for doing anything, but an interesting engineering challenge nonetheless ....

An approach I tried was throwing a specific class of RuntimeException, with an exit-code instance variable, and catching it at the outer scope. That way you can be sure that when you do murder the VM you're at the tail of the stack anyway ...

public class Splat {

    public static final class Exit extends RuntimeException {

        private int exitCode;

        public Exit(int exitCode) {
            this.exitCode = exitCode;
        }
    }

    public static void main(String[] args) {

        try {

            wrappedMain(args);

        } catch (Exit e) {

            System.exit(e.exitCode);
        }
    }

    public static void wrappedMain(String[] args) {

        if (args.length > 0 && "splat".equals(args[0])) {

            int code = (args.length > 1) ? Integer.parseInt(args[1]) : 0;

            throw new Exit(code);
        }
    }
}

Output:

 $ java Splat
 $ java Splat splat
 $ echo $?
 > 0
 $ java Splat splat 1
 $ echo $?
 > 1
 > $ java Splat splat 2
 $ echo $?
 > 2
 $ java Splat splat -1
 $ echo $?
 > 127

There are caveats to this approach of course! It is a bit of an odd way to exit and anybody unfamiliar with your constraints will scratch their head. Also, if somebody does catch (Throwable t) later on, then you wont be able to exit!!! If you are working in a static analysis CI environment then that should be quickly highlighted as a more grievous violation!

Sign up to request clarification or add additional context in comments.

Comments

0

As already commented: When you wait for some code in a batch or shell you are actually waiting for the program to finish and that means your java program exits and so does the JVM. And the one and only way is then to use System.exit(code) as you are already doing.

Comments

0

If you are talking about the exit code of a process then System.exit(int) is the way to go since you want the whole process to exit and so the JVM should shutdown as well.
But if you want to send out some error messages to the batch or shell (without exiting the process) then you will have to use System.err.println(). This will write to the error stream instead of the output stream.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.