我还阅读了有关更改 JVM 本身以拦截文件访问的信息。这听起来很不错。但我需要根据用户动态更改策略。
设置一个SecurityManager
覆盖checkWrite(String)
以引发异常的自定义。
这是一个防止子框架退出 VM 的简单示例 ( checkExit(int)
)。
import java.awt.GridLayout;
import java.awt.event.*;
import java.security.Permission;
import javax.swing.*;
/** NoExit demonstrates how to prevent 'child' applications from
* ending the VM with a call to System.exit(0). */
public class NoExit extends JFrame implements ActionListener {
JButton frameLaunch = new JButton("Frame");
JButton exitLaunch = new JButton("Exit");
/** Stores a reference to the original security manager. */
ExitManager sm;
public NoExit() {
super("Launcher Application");
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
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() );
setLocationByPlatform(true);
}
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);
}
}
/** Our custom ExitManager does not allow the VM to exit, but does
* allow itself to be replaced by the original security manager. */
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;
}
}
/** This example frame attempts to System.exit(0) on closing, we must
* prevent it from doing so. */
class TargetFrame extends JFrame {
TargetFrame() {
super("Close Me!");
add(new JLabel("Hi!"));
addWindowListener( new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.out.println("Bye!");
System.exit(0);
}
});
pack();
setSize( getPreferredSize() );
setLocationByPlatform(true);
setVisible(true);
}
}