Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing System.exit() from API

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.

like image 260
Swaranga Sarma Avatar asked Mar 23 '11 05:03

Swaranga Sarma


People also ask

What can I use instead of a system exit?

What are the alternatives? The System. exit(0) call simply calls Runtime. getRuntime().

Is it a good practice to use system exit in Java?

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.

Is it good to use system exit?

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.

What is a Java security manager?

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.


2 Answers

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;   } } 
like image 20
Andrew Thompson Avatar answered Oct 16 '22 10:10

Andrew Thompson


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).

like image 167
sbridges Avatar answered Oct 16 '22 10:10

sbridges