aboutsummaryrefslogtreecommitdiffstats
path: root/testing
diff options
context:
space:
mode:
authorwisberg <wisberg>2003-05-31 22:24:48 +0000
committerwisberg <wisberg>2003-05-31 22:24:48 +0000
commit101a5f0a47d9ef664d54bd92d90fd0accb519339 (patch)
treed710ffada42a36df06f481db3faa87cb09b00dc1 /testing
parentdd76d2fc194461656360c5cdd6ad0769ace0184a (diff)
downloadaspectj-101a5f0a47d9ef664d54bd92d90fd0accb519339.tar.gz
aspectj-101a5f0a47d9ef664d54bd92d90fd0accb519339.zip
Added SecurityManager which halts any System.exit() call from JavaRun thread and puts the exit code in the status object.
This enables us to run the examples.
Diffstat (limited to 'testing')
-rw-r--r--testing/src/org/aspectj/testing/harness/bridge/JavaRun.java149
1 files changed, 138 insertions, 11 deletions
diff --git a/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java b/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java
index 718a423d2..43c5db4c9 100644
--- a/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java
+++ b/testing/src/org/aspectj/testing/harness/bridge/JavaRun.java
@@ -24,17 +24,11 @@ import org.aspectj.testing.xml.XMLWriter;
import org.aspectj.util.FileUtil;
import org.aspectj.util.LangUtil;
-import java.io.ByteArrayOutputStream;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.net.URL;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
+import java.io.*;
+import java.lang.reflect.*;
+import java.net.*;
+import java.security.Permission;
+import java.util.*;
/**
* Run a class in this VM using reflection.
@@ -59,6 +53,12 @@ public class JavaRun implements IAjcRun {
JAVA = getProperty(JAVA_KEY);
JAVA_HOME = getProperty(JAVA_HOME_KEY);
BOOTCLASSPATH = getProperty(BOOTCLASSPATH_KEY);
+ try {
+ System.setSecurityManager(RunSecurityManager.ME);
+ } catch (Throwable t) {
+ System.err.println("JavaRun: Security manager set - no System.exit() protection");
+ }
+
}
private static String getProperty(String key) {
try {
@@ -151,13 +151,38 @@ public class JavaRun implements IAjcRun {
targetClass = loader.loadClass(spec.className);
Method main = targetClass.getMethod("main", Globals.MAIN_PARM_TYPES);
setupTester(sandbox.getTestBaseSrcDir(this), loader, status);
+ RunSecurityManager.ME.setJavaRunThread(this);
main.invoke(null, new Object[] { spec.getOptionsArray() });
completedNormally = true;
+ } catch (InvocationTargetException e) {
+ // this and following clauses catch ExitCalledException
+ Throwable thrown = LangUtil.unwrapException(e);
+ if (null == thrown) {
+ throw e;
+ }
+ if (thrown instanceof RunSecurityManager.ExitCalledException) {
+ int i = ((RunSecurityManager.ExitCalledException) thrown).exitCode;
+ status.finish(new Integer(i));
+ } else if (thrown instanceof RunSecurityManager.AwtUsedException) {
+ MessageUtil.fail(status, "test code should not use the AWT event queue");
+ throw (RunSecurityManager.AwtUsedException) thrown;
+ // same as: status.thrown(thrown);
+ } else if (thrown instanceof RuntimeException) {
+ throw (RuntimeException) thrown;
+ } else if (thrown instanceof Error) {
+ throw (Error) thrown;
+ } else {
+ throw e;
+ }
+ } catch (RunSecurityManager.ExitCalledException e) {
+ // XXX need to update run validator (a) to accept null result or (b) to require zero result, and set 0 if completed normally
+ status.finish(new Integer(e.exitCode));
} catch (ClassNotFoundException e) {
String[] classes = FileUtil.listFiles(sandbox.classesDir);
MessageUtil.info(status, "sandbox.classes: " + Arrays.asList(classes));
MessageUtil.fail(status, null, e);
} finally {
+ RunSecurityManager.ME.releaseJavaRunThread(this);
if (!completedNormally) {
MessageUtil.info(status, "targetClass: " + targetClass);
MessageUtil.info(status, "loader: " + loader);
@@ -480,4 +505,106 @@ public class JavaRun implements IAjcRun {
return true;
}
}
+ /**
+ * This permits everything but System.exit() in the context of a
+ * thread set by JavaRun.
+ * XXX need to update for thread spawned by that thread
+ * XXX need to update for awt thread use after AJDE wrapper doesn't
+ */
+ public static class RunSecurityManager extends SecurityManager {
+ public static RunSecurityManager ME = new RunSecurityManager();
+ private Thread runThread;
+ private RunSecurityManager(){}
+ private synchronized void setJavaRunThread(JavaRun run) {
+ LangUtil.throwIaxIfNull(run, "run");
+ runThread = Thread.currentThread();
+ }
+ private synchronized void releaseJavaRunThread(JavaRun run) {
+ LangUtil.throwIaxIfNull(run, "run");
+ runThread = null;
+ }
+ /** @throws ExitCalledException if called from the JavaRun-set thread */
+ public void checkExit(int exitCode) throws ExitCalledException {
+ if ((null != runThread) && runThread.equals(Thread.currentThread())) {
+ throw new ExitCalledException(exitCode);
+ }
+ }
+ public void checkAwtEventQueueAccess() {
+ if ((null != runThread) && runThread.equals(Thread.currentThread())) {
+ throw new AwtUsedException();
+ }
+ }
+ public void checkSystemClipboardAccess() {
+ // permit
+ }
+ // used by constrained calls
+ public static class ExitCalledException extends SecurityException {
+ public final int exitCode;
+ public ExitCalledException(int exitCode) {
+ this.exitCode = exitCode;
+ }
+ }
+ public static class AwtUsedException extends SecurityException {
+ public AwtUsedException() { }
+ }
+ // permit everything else
+ public void checkAccept(String arg0, int arg1) {
+ }
+ public void checkAccess(Thread arg0) {
+ }
+ public void checkAccess(ThreadGroup arg0) {
+ }
+ public void checkConnect(String arg0, int arg1) {
+ }
+ public void checkConnect(String arg0, int arg1, Object arg2) {
+ }
+ public void checkCreateClassLoader() {
+ }
+ public void checkDelete(String arg0) {
+ }
+ public void checkExec(String arg0) {
+ }
+ public void checkLink(String arg0) {
+ }
+ public void checkListen(int arg0) {
+ }
+ public void checkMemberAccess(Class arg0, int arg1) {
+ }
+ public void checkMulticast(InetAddress arg0) {
+ }
+ public void checkMulticast(InetAddress arg0, byte arg1) {
+ }
+ public void checkPackageAccess(String arg0) {
+ }
+ public void checkPackageDefinition(String arg0) {
+ }
+ public void checkPermission(Permission arg0) {
+ }
+ public void checkPermission(Permission arg0, Object arg1) {
+ }
+ public void checkPrintJobAccess() {
+ }
+ public void checkPropertiesAccess() {
+ }
+ public void checkPropertyAccess(String arg0) {
+ }
+ public void checkRead(FileDescriptor arg0) {
+ }
+ public void checkRead(String arg0) {
+ }
+ public void checkRead(String arg0, Object arg1) {
+ }
+ public void checkSecurityAccess(String arg0) {
+ }
+ public void checkSetFactory() {
+ }
+ public boolean checkTopLevelWindow(Object arg0) {
+ return true;
+ }
+ public void checkWrite(FileDescriptor arg0) {
+ }
+ public void checkWrite(String arg0) {
+ }
+
+ }
}