3 回答

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;
}
}

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代碼,但不能訪問第三方庫的源代碼。
添加回答
舉報