为了账号安全,请及时绑定邮箱和手机立即绑定

从API阻止System.exit()

从API阻止System.exit()

小怪兽爱吃肉 2019-10-21 11:04:18
我使用的第三方库System.exit()在遇到异常时会执行a 。我从罐子里使用API。无论如何,System.exit()由于它导致我的应用程序关闭,我可以阻止该调用吗?System.exit()由于其他许多许可问题,删除后我无法反编译和重新编译jar 。我曾经在stackoverflow中遇到一个[我不记得的其他问题]的答案,我们可以使用SecurityManagerJava来做这样的事情。
查看完整描述

3 回答

?
30秒到达战场

TA贡献1828条经验 获得超6个赞

请参阅我对如何避免JFrame EXIT_ON_CLOSE操作退出整个应用程序的答复?。


编辑1:链接的源。演示如何使用SecurityManager来预防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;

  }

}


查看完整回答
反对 回复 2019-10-21
?
慕容森

TA贡献1853条经验 获得超18个赞

先前的代码示例部分正确,但是我发现它最终阻止了我的代码对文件的访问。为了解决这个问题,我写了一些不同的SecurityManager:


public class MySecurityManager extends SecurityManager {


private SecurityManager baseSecurityManager;


public MySecurityManager(SecurityManager baseSecurityManager) {

    this.baseSecurityManager = baseSecurityManager;

}


@Override

public void checkPermission(Permission permission) {

    if (permission.getName().startsWith("exitVM")) {

        throw new SecurityException("System exit not allowed");

    }

    if (baseSecurityManager != null) {

        baseSecurityManager.checkPermission(permission);

    } else {

        return;

    }

}


}

就我而言,我需要防止第三方库终止VM。但是也有一些grails测试调用System.exit。因此,我编写了代码,以使其仅在调用第三方库之前立即激活了自定义安全管理器(不是常见事件),然后立即恢复了原始安全管理器(如果有)。


有点丑陋。理想情况下,我宁愿只删除System.exit代码,但不能访问第三方库的源代码。


查看完整回答
反对 回复 2019-10-21
  • 3 回答
  • 0 关注
  • 699 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信