Reputation: 485
I have the following
System.setSecurityManager(new SecurityManager() {
@Override
public void checkExit(int status) {
super.checkExit(status);
//custom exception extends SecurityException
throw new SystemExitCalledException();
}
});
Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
@Override
public void uncaughtException(Thread t, Throwable e) {
//never reaches here somehow...
//maybe some3rdPartyStaticMethod sets this, too?
}
});
try {
//this method spawns threads and some call System.exit().
some3rdPartyStaticMethod.invoke(null, new Object[]{args});
} catch (SystemExitCalledException e) {
//it never reaches here because
//SystemExitCalledException is thrown on different thread??
//
}
Is there a way to prevent some3rdPartyStaticMethod's spawned thread's System.exit() call from halting jvm?
Upvotes: 1
Views: 1123
Reputation: 838906
You can start the code in a separate process and communicate with it using RMI. If the third party code calls System.exit
and kills its process, your process can continue to run and recreate the child process if necessary.
Note that there are some caveats with this approach:
Upvotes: 2
Reputation: 28772
Writing a custom SecurityManager policy should help -- I've never done this myself :)
According to this post (scroll down to the bottom):
However, when anything in the VM tries to call System.exit(), the VM exits. Since this includes a brutal shotdown of mvn, the normal mvn process is interrupted. A SecurityManager can be used to prevent code from calling System.exit(), but nobody mentions the side-effects.
A colleague of mine mentioned that you can setup your policies system-wide, per-user and as a system-property when starting the VM and after a quick test this has proven to solve my problem. I've since managed to figure out how to set my own policy from my code (before setting up the SecurityManager) and this solves my problems.
I used the following code:
//Setup security to prevent System.exit()
SecurityManager sm = System.getSecurityManager();
URL policy = getClass().getClassLoader().getResource("jsdoc.policy");
System.setProperty("java.security.policy", policy.toString());
System.setSecurityManager(new JSDocSecurityManager(getLog()));
With a simple, wide-open, policy file reading this:
grant {
permission java.security.AllPermission;
};
If it works it supposed to capture the System.exit()
request and throw a SecurityException
instead
Upvotes: 1