01: package abbot;
02:
03: public abstract class NoExitSecurityManager extends SecurityManager {
04: private Exception creation;
05:
06: public NoExitSecurityManager() {
07: class CreationLocationException extends Exception {
08: }
09: creation = new CreationLocationException();
10: }
11:
12: public void checkPermission(java.security.Permission perm,
13: Object context) {
14: // allow everything
15: }
16:
17: public void checkPermission(java.security.Permission perm) {
18: // allow everything
19: }
20:
21: /**
22: * Returns true if the exit has been invoked through a call
23: * of Runtime.exit or Runtime.halt .
24: *
25: * @return true <=> An exit has been invoked through a call of Runtime.exit / Runtime.halt .
26: */
27: public boolean exitInvoked() {
28: // We only want to disallow Runtime.halt/Runtime.exit
29: // Anything else is ok (e.g. System.runFinalizersOnExit; some VMs do a
30: // check there as well -- 1.3 and prior, I think)
31: String stack = Log.getStack(Log.FULL_STACK);
32: return ((stack.indexOf("java.lang.Runtime.exit") != -1) || (stack
33: .indexOf("java.lang.Runtime.halt") != -1));
34: }
35:
36: public void checkExit(int status) {
37: if (exitInvoked()) {
38: exitCalled(status);
39: String msg = "Application exit denied";
40: Log.log(msg + " from security manager " + "created at "
41: + Log.getStack(Log.FULL_STACK, creation));
42: throw new ExitException(msg, status);
43: }
44: }
45:
46: /** Implement this method to do any context-specific cleanup. This
47: hook is provided since it may not always be possible to catch the
48: ExitException explicitly (like when it's caught by someone else, or
49: thrown from the event dispatch thread).
50: */
51: protected abstract void exitCalled(int status);
52: }
|