I have three classes say alpha, beta, gamma and each of the three classes has a main
method.
Both alpha and beta classes have, inside their main
method, a try...catch...finally
block like:
public class alpha{
public static void main(String[] args){
try{
Do something;
}catch(Exception ex){
ex.printStackTrace();
}
finally{
System.exit(0);
}
}
}
public class beta{
public static void main(String[] args){
try{
Do something;
}catch(Exception ex){
ex.printStackTrace();
}
finally{
System.exit(0);
}
}
}
Now in gamma class i call main methods of alpha and beta classes to run continuously like below
public gamma{
public static void main(String[] args) {
try {
alpha.main(arg);
beta.main(arg1);
} catch (Exception e) {
e.printStackTrace();
}
}
The problem is that the code beta.main(arg1)
is never reached due to the System.exit(0)
inside the alpha class's finally
block.
Since alpha and beta are standalone applications when they executed separately they should terminate the service at the end of program.
So now this there any way to reach the beta.main(arg1)
line without much changing the actual functionality of alpha and beta classes.
Kindly let me know if you need further details. Thanks in advance...
In such case, shutdown hook can be used:
public class Gamma{
public static void main(String[] args) {
try {
Thread hook = new Thread() { public void run() { Beta.main(args); } };
hook.setDaemon(true);
Runtime.getRuntime().addShutdownHook(hook);
Alpha.main(args);
} catch (Exception e) {
e.printStackTrace();
}
}
}
(Ideally, nothing that is part of a module's public API should ever do anything that calls exit
, and the main
method of a class should just be a small shim that invokes something else that does the real work before producing the proper exit code.)
That said, if you want to prevent System.exit
, you can register a SecurityManager
that converts calls to System.exit
into SecurityException
s or Error
s.
System.exit
:
throws
SecurityException
- if a security manager exists and itscheckExit
method doesn't allow exit with the specified status.
Something like
System.setSecurityManager(new SecurityManager() {
@Override
public void checkExit(int exitCode) throws SecurityException {
throw new SecurityException("stop that");
}
});
Then the method which is calling main methods can just catch and suppress that SecurityException
. You could make it more robust by creating your own ExitCalledError
and throwing that instead and only suppressing that.
I find this very useful for preventing unit-test runners from spuriously reporting success when the test runner is exit
ed by code under test with a zero exit code.
Really, the only solution is to get rid of the System.exit() call. This is why System.exit() is evil. A good way to replace them is by throwing an exception -- you can add an exception handler to the system (look into adding them to ThreadGroups to add one for every exception path) and then decide what you want to do.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With