diff options
author | wisberg <wisberg> | 2003-05-01 13:17:35 +0000 |
---|---|---|
committer | wisberg <wisberg> | 2003-05-01 13:17:35 +0000 |
commit | 85fd1bf2b7858c46ce39ad2c08fbcf2e7cb81212 (patch) | |
tree | 6828efaa6505b2cea6da4167b1bdbcb6df407e64 /util | |
parent | c562ca65e19051e7d12d8db63d49f13445b12e87 (diff) | |
download | aspectj-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.java | 98 | ||||
-rw-r--r-- | util/src/org/aspectj/util/UtilClassLoader.java | 140 |
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 + + ")"; + } +} + |