aboutsummaryrefslogtreecommitdiffstats
path: root/util
diff options
context:
space:
mode:
authorwisberg <wisberg>2003-05-01 13:17:35 +0000
committerwisberg <wisberg>2003-05-01 13:17:35 +0000
commit85fd1bf2b7858c46ce39ad2c08fbcf2e7cb81212 (patch)
tree6828efaa6505b2cea6da4167b1bdbcb6df407e64 /util
parentc562ca65e19051e7d12d8db63d49f13445b12e87 (diff)
downloadaspectj-85fd1bf2b7858c46ce39ad2c08fbcf2e7cb81212.tar.gz
aspectj-85fd1bf2b7858c46ce39ad2c08fbcf2e7cb81212.zip
minimal run-in-same-vm feature for ajbrowser
Diffstat (limited to 'util')
-rw-r--r--util/src/org/aspectj/util/Reflection.java98
-rw-r--r--util/src/org/aspectj/util/UtilClassLoader.java140
2 files changed, 238 insertions, 0 deletions
diff --git a/util/src/org/aspectj/util/Reflection.java b/util/src/org/aspectj/util/Reflection.java
index bee7bd70e..6804afaa6 100644
--- a/util/src/org/aspectj/util/Reflection.java
+++ b/util/src/org/aspectj/util/Reflection.java
@@ -13,10 +13,15 @@
package org.aspectj.util;
+import java.io.File;
import java.lang.reflect.*;
import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
public class Reflection {
+ public static final Class[] MAIN_PARM_TYPES = new Class[] {String[].class};
private Reflection() {
}
@@ -103,4 +108,97 @@ public class Reflection {
}
}
+ public static void runMainInSameVM(
+ String classpath,
+ String className,
+ String[] args)
+ throws SecurityException, NoSuchMethodException,
+ IllegalArgumentException, IllegalAccessException,
+ InvocationTargetException, ClassNotFoundException {
+ LangUtil.throwIaxIfNull(className, "class name");
+ if (LangUtil.isEmpty(classpath)) {
+ Class mainClass = Class.forName(className);
+ runMainInSameVM(mainClass, args);
+ return;
+ }
+ ArrayList dirs = new ArrayList();
+ ArrayList libs = new ArrayList();
+ ArrayList urls = new ArrayList();
+ String[] entries = LangUtil.splitClasspath(classpath);
+ for (int i = 0; i < entries.length; i++) {
+ String entry = entries[i];
+ URL url = makeURL(entry);
+ if (null != url) {
+ urls.add(url);
+ }
+ File file = new File(entries[i]);
+// tolerate bad entries b/c bootclasspath sometimes has them
+// if (!file.canRead()) {
+// throw new IllegalArgumentException("cannot read " + file);
+// }
+ if (FileUtil.hasZipSuffix(file)) {
+ libs.add(file);
+ } else if (file.isDirectory()) {
+ dirs.add(file);
+ } else {
+ // not URL, zip, or dir - unsure what to do
+ }
+ }
+ File[] dirRa = (File[]) dirs.toArray(new File[0]);
+ File[] libRa = (File[]) libs.toArray(new File[0]);
+ URL[] urlRa = (URL[]) urls.toArray(new URL[0]);
+ runMainInSameVM(urlRa, libRa, dirRa, className, args);
+ }
+
+ public static void runMainInSameVM(
+ URL[] urls,
+ File[] libs,
+ File[] dirs,
+ String className,
+ String[] args)
+ throws SecurityException, NoSuchMethodException,
+ IllegalArgumentException, IllegalAccessException,
+ InvocationTargetException, ClassNotFoundException {
+ LangUtil.throwIaxIfNull(className, "class name");
+ LangUtil.throwIaxIfNotAssignable(libs, File.class, "jars");
+ LangUtil.throwIaxIfNotAssignable(dirs, File.class, "dirs");
+ URL[] libUrls = FileUtil.getFileURLs(libs);
+ if (!LangUtil.isEmpty(libUrls)) {
+ if (!LangUtil.isEmpty(urls)) {
+ URL[] temp = new URL[libUrls.length + urls.length];
+ System.arraycopy(urls, 0, temp, 0, urls.length);
+ System.arraycopy(urls, 0, temp, libUrls.length, urls.length);
+ urls = temp;
+ } else {
+ urls = libUrls;
+ }
+ }
+ UtilClassLoader loader = new UtilClassLoader(urls, dirs);
+ Class targetClass = null;
+ try {
+ targetClass = loader.loadClass(className);
+ } catch (ClassNotFoundException e) {
+ String s = "unable to load class " + className
+ + " using class loader " + loader;
+ throw new ClassNotFoundException(s);
+ }
+ Method main = targetClass.getMethod("main", MAIN_PARM_TYPES);
+ main.invoke(null, new Object[] { args });
+ }
+
+ public static void runMainInSameVM(Class mainClass, String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAccessException, InvocationTargetException {
+ LangUtil.throwIaxIfNull(mainClass, "main class");
+ Method main = mainClass.getMethod("main", MAIN_PARM_TYPES);
+ main.invoke(null, new Object[] { args });
+ }
+
+ /** @return URL if the input is valid as such */
+ private static URL makeURL(String s) {
+ try {
+ return new URL(s);
+ } catch (Throwable t) {
+ return null;
+ }
+ }
+
}
diff --git a/util/src/org/aspectj/util/UtilClassLoader.java b/util/src/org/aspectj/util/UtilClassLoader.java
new file mode 100644
index 000000000..dc4ec6fc7
--- /dev/null
+++ b/util/src/org/aspectj/util/UtilClassLoader.java
@@ -0,0 +1,140 @@
+/* *******************************************************************
+ * Copyright (c) 2003 Contributors.
+ * All rights reserved.
+ * This program and the accompanying materials are made available
+ * under the terms of the Common Public License v1.0
+ * which accompanies this distribution and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ *
+ * Contributors:
+ * Isberg initial implementation
+ * ******************************************************************/
+
+package org.aspectj.util;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Load classes as File from File[] dirs or URL[] jars.
+ */
+public class UtilClassLoader extends URLClassLoader {
+
+ /** seek classes in dirs first */
+ List /*File*/ dirs;
+
+ /** save URL[] only for toString */
+ private URL[] urlsForDebugString;
+
+ public UtilClassLoader(URL[] urls, File[] dirs) {
+ super(urls);
+ LangUtil.throwIaxIfNotAssignable(dirs, File.class, "dirs");
+ this.urlsForDebugString = urls;
+ ArrayList dcopy = new ArrayList();
+
+ if (!LangUtil.isEmpty(dirs)) {
+ dcopy.addAll(Arrays.asList(dirs));
+ }
+ this.dirs = Collections.unmodifiableList(dcopy);
+ }
+
+
+ public URL getResource(String name) {
+ return ClassLoader.getSystemResource(name);
+ }
+
+ public InputStream getResourceAsStream(String name) {
+ return ClassLoader.getSystemResourceAsStream(name);
+ }
+
+ public synchronized Class loadClass(String name, boolean resolve)
+ throws ClassNotFoundException {
+ // search the cache, our dirs (if maybe test),
+ // the system, the superclass (URL[]),
+ // and our dirs again (if not maybe test)
+ ClassNotFoundException thrown = null;
+ Class result = findLoadedClass(name);
+ if (null != result) {
+ resolve = false;
+ } else {
+ try {
+ result = findSystemClass(name);
+ } catch (ClassNotFoundException e) {
+ thrown = e;
+ }
+ }
+ if (null == result) {
+ try {
+ result = super.loadClass(name, resolve);
+ } catch (ClassNotFoundException e) {
+ thrown = e;
+ }
+ if (null != result) { // resolved by superclass
+ return result;
+ }
+ }
+ if (null == result) {
+ byte[] data = readClass(name);
+ if (data != null) {
+ result = defineClass(name, data, 0, data.length);
+ } // handle ClassFormatError?
+ }
+
+ if (null == result) {
+ throw (null != thrown ? thrown : new ClassNotFoundException(name));
+ }
+ if (resolve) {
+ resolveClass(result);
+ }
+ return result;
+ }
+
+ /** @return null if class not found or byte[] of class otherwise */
+ private byte[] readClass(String className) throws ClassNotFoundException {
+ final String fileName = className.replace('.', '/')+".class";
+ for (Iterator iter = dirs.iterator(); iter.hasNext();) {
+ File file = new File((File) iter.next(), fileName);
+ if (file.canRead()) {
+ return getClassData(file);
+ }
+ }
+ return null;
+ }
+
+ private byte[] getClassData(File f) {
+ try {
+ FileInputStream stream= new FileInputStream(f);
+ ByteArrayOutputStream out= new ByteArrayOutputStream(1000);
+ byte[] b= new byte[4096];
+ int n;
+ while ((n= stream.read(b)) != -1) {
+ out.write(b, 0, n);
+ }
+ stream.close();
+ out.close();
+ return out.toByteArray();
+ } catch (IOException e) {
+ }
+ return null;
+ }
+
+ /** @return String with debug info: urls and classes used */
+ public String toString() {
+ return "UtilClassLoader(urls="
+ + Arrays.asList(urlsForDebugString)
+ + ", dirs="
+ + dirs
+ + ")";
+ }
+}
+