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 SecurityExceptions or Errors.
System.exit:
throws
SecurityException- if a security manager exists and itscheckExitmethod 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 exited 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