I am using a third party library that does a System.exit()
if it encounters exceptions. I am using the APIs from a jar. Is there anyway that I can prevent the System.exit()
call because it causes my application to shutdown? I cannot decompile and recompile the jar after removing the System.exit()
because of a lot of other licensing issues. I once came across an answer [to some other question that I do not remember] in stackoverflow that we can use the SecurityManager
in Java to do something like this.
What are the alternatives? The System. exit(0) call simply calls Runtime. getRuntime().
It's a good practice to use exception handling or plain return statements to exit a program when working with application servers and other regular applications. Usage of System. exit method suit better for script-based applications or wherever the status codes are interpreted.
exit() it will do so with a non-zero status (as long as the main thread ends and there are no running daemon threads). That's all about Why you should not use System. exit() inside Java application. It can be dangerous and potentially shut down the whole server, which is hosting other critical Java application.
The security manager is a class that allows applications to implement a security policy. It allows an application to determine, before performing a possibly unsafe or sensitive operation, what the operation is and whether it is being attempted in a security context that allows the operation to be performed.
See my reply to How to avoid JFrame EXIT_ON_CLOSE operation to exit the entire application?.
Edit 1: The source that was linked. Demonstrates how to use a SecurityManager
to prevent System.exit(n)
.
import java.awt.*; import java.awt.event.*; import java.security.Permission; /** NoExit demonstrates how to prevent 'child' applications from ending the VM with a call to System.exit(0). @author Andrew Thompson */ public class NoExit extends Frame implements ActionListener { Button frameLaunch = new Button("Frame"), exitLaunch = new Button("Exit"); /** Stores a reference to the original security manager. */ ExitManager sm; public NoExit() { super("Launcher Application"); sm = new ExitManager( System.getSecurityManager() ); System.setSecurityManager(sm); setLayout(new GridLayout(0,1)); frameLaunch.addActionListener(this); exitLaunch.addActionListener(this); add( frameLaunch ); add( exitLaunch ); pack(); setSize( getPreferredSize() ); } public void actionPerformed(ActionEvent ae) { if ( ae.getSource()==frameLaunch ) { TargetFrame tf = new TargetFrame(); } else { // change back to the standard SM that allows exit. System.setSecurityManager( sm.getOriginalSecurityManager() ); // exit the VM when *we* want System.exit(0); } } public static void main(String[] args) { NoExit ne = new NoExit(); ne.setVisible(true); } } /** This example frame attempts to System.exit(0) on closing, we must prevent it from doing so. */ class TargetFrame extends Frame { static int x=0, y=0; TargetFrame() { super("Close Me!"); add(new Label("Hi!")); addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent we) { System.out.println("Bye!"); System.exit(0); } }); pack(); setSize( getPreferredSize() ); setLocation(++x*10,++y*10); setVisible(true); } } /** Our custom ExitManager does not allow the VM to exit, but does allow itself to be replaced by the original security manager. @author Andrew Thompson */ class ExitManager extends SecurityManager { SecurityManager original; ExitManager(SecurityManager original) { this.original = original; } /** Deny permission to exit the VM. */ public void checkExit(int status) { throw( new SecurityException() ); } /** Allow this security manager to be replaced, if fact, allow pretty much everything. */ public void checkPermission(Permission perm) { } public SecurityManager getOriginalSecurityManager() { return original; } }
There is a blog post here,
http://jroller.com/ethdsy/entry/disabling_system_exit
Basically it installs a security manager which disables System.exit() with code from here,
private static class ExitTrappedException extends SecurityException { } private static void forbidSystemExitCall() { final SecurityManager securityManager = new SecurityManager() { public void checkPermission( Permission permission ) { if( "exitVM".equals( permission.getName() ) ) { throw new ExitTrappedException() ; } } } ; System.setSecurityManager( securityManager ) ; } private static void enableSystemExitCall() { System.setSecurityManager( null ) ; }
Edit: Max points out in comments below that
as of Java 6, the permission name is actually "exitVM."+status, e.g. "exitVM.0".
However, the permission exitVM.*
refers to all exit statuses, and exitVM
is retained as a shorthand for exitVM.*
, so the above code still works (see the documentation for RuntimePermission
).
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