aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java69
-rw-r--r--ajde/src/org/aspectj/ajde/Ajde.java30
-rw-r--r--util/src/org/aspectj/util/Reflection.java98
-rw-r--r--util/src/org/aspectj/util/UtilClassLoader.java140
4 files changed, 300 insertions, 37 deletions
diff --git a/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java b/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java
index b2ec90571..d03e38304 100644
--- a/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java
+++ b/ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java
@@ -14,6 +14,7 @@
package org.aspectj.tools.ajbrowser;
+import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
@@ -23,6 +24,7 @@ import javax.swing.JFrame;
import org.aspectj.ajde.Ajde;
import org.aspectj.ajde.BuildConfigManager;
import org.aspectj.ajde.BuildListener;
+import org.aspectj.ajde.ProjectPropertiesAdapter;
import org.aspectj.ajde.TaskListManager;
import org.aspectj.ajde.ui.InvalidResourceException;
import org.aspectj.ajde.ui.UserPreferencesAdapter;
@@ -31,6 +33,8 @@ import org.aspectj.ajde.ui.swing.AjdeUIManager;
import org.aspectj.ajde.ui.swing.BasicEditor;
import org.aspectj.ajde.ui.swing.IconRegistry;
import org.aspectj.ajde.ui.swing.MultiStructureViewPanel;
+import org.aspectj.util.LangUtil;
+import org.aspectj.util.Reflection;
/**
* IDE manager for standalone AJDE application.
@@ -45,7 +49,7 @@ public class BrowserManager {
public static BrowserManager getDefault() {
return INSTANCE;
}
-
+
private List configFiles = new ArrayList();
public static final String TITLE = "AspectJ Browser";
@@ -131,8 +135,8 @@ public class BrowserManager {
topFrame.setTitle(BrowserManager.TITLE + " - " + text);
}
- public void run() {
- Runner.run(Ajde.getDefault().getProjectProperties().getClassToExecute());
+ public void run() {
+ Ajde.runInSameVM(Ajde.getDefault().getProjectProperties());
}
public void saveAll() {
@@ -181,40 +185,31 @@ public class BrowserManager {
return configs;
}
- private static class Runner {
- public static void run(String className) {
- try {
- Process p = Runtime.getRuntime().exec("java "
- //+ "-classpath" + Ajde.getDefault().getProjectProperties().getClasspath() + " "
- + className);
- } catch(IOException ioe) {
- Ajde.getDefault().getErrorHandler().handleError("Coud not run: " + className, ioe);
- }
- }
-
- public static void invoke(String className) {
- try {
- if (className == null || className.length() == 0) {
- Ajde.getDefault().getErrorHandler().handleWarning("No main class specified, please select a class to run.");
-
- } else {
- Class[] argTypes = { String[].class };
- java.lang.reflect.Method method = Class.forName(className).getDeclaredMethod("main", argTypes);
- Object[] args = { new String[0] };
- method.invoke(null, args);
- }
- } catch(ClassNotFoundException cnfe) {
- Ajde.getDefault().getErrorHandler().handleWarning("Main class not found: " + className +
- "\nMake sure that you have \".\" on your classpath.");
- } catch(NoSuchMethodException nsme) {
- Ajde.getDefault().getErrorHandler().handleWarning("Class: " + className + " does not declare public static void main(String[])");
- } catch(java.lang.reflect.InvocationTargetException ite) {
- Ajde.getDefault().getErrorHandler().handleWarning("Could not execute: " + className);
- } catch(IllegalAccessException iae) {
- Ajde.getDefault().getErrorHandler().handleWarning("Class: " + className + " does not declare public main method");
- }
- }
- }
+// private static class Runner {
+//
+// public static void invoke(String className) {
+// try {
+// if (className == null || className.length() == 0) {
+// Ajde.getDefault().getErrorHandler().handleWarning("No main class specified, please select a class to run.");
+//
+// } else {
+// Class[] argTypes = { String[].class };
+// java.lang.reflect.Method method = Class.forName(className).getDeclaredMethod("main", argTypes);
+// Object[] args = { new String[0] };
+// method.invoke(null, args);
+// }
+// } catch(ClassNotFoundException cnfe) {
+// Ajde.getDefault().getErrorHandler().handleWarning("Main class not found: " + className +
+// "\nMake sure that you have \".\" on your classpath.");
+// } catch(NoSuchMethodException nsme) {
+// Ajde.getDefault().getErrorHandler().handleWarning("Class: " + className + " does not declare public static void main(String[])");
+// } catch(java.lang.reflect.InvocationTargetException ite) {
+// Ajde.getDefault().getErrorHandler().handleWarning("Could not execute: " + className);
+// } catch(IllegalAccessException iae) {
+// Ajde.getDefault().getErrorHandler().handleWarning("Class: " + className + " does not declare public main method");
+// }
+// }
+// }
private final BuildListener BUILD_MESSAGES_LISTENER = new BuildListener() {
diff --git a/ajde/src/org/aspectj/ajde/Ajde.java b/ajde/src/org/aspectj/ajde/Ajde.java
index 7f0292982..bc9893dea 100644
--- a/ajde/src/org/aspectj/ajde/Ajde.java
+++ b/ajde/src/org/aspectj/ajde/Ajde.java
@@ -14,6 +14,7 @@
package org.aspectj.ajde;
+import java.io.File;
import java.io.PrintStream;
import java.util.List;
@@ -26,6 +27,8 @@ import org.aspectj.ajde.ui.StructureViewManager;
import org.aspectj.ajde.ui.StructureViewNodeFactory;
import org.aspectj.asm.StructureModelManager;
import org.aspectj.bridge.Version;
+import org.aspectj.util.LangUtil;
+import org.aspectj.util.Reflection;
/**
* Singleton class responsible for AJDE initialization, and the main point of access to
@@ -38,6 +41,33 @@ public class Ajde {
private static final Ajde INSTANCE = new Ajde();
private static final String NOT_INITIALIZED_MESSAGE = "Ajde is not initialized.";
private static boolean isInitialized = false;
+
+ /**
+ * Utility to run the project main class in the same VM
+ * using a class loader populated with the classpath
+ * and output path or jar.
+ * @param project the ProjectPropertiesAdapter specifying the
+ * main class, classpath, and executable arguments.
+ */
+ public static void runInSameVM(ProjectPropertiesAdapter project) {
+ String mainClass = "<none>";
+ try {
+ mainClass = project.getClassToExecute();
+ if (LangUtil.isEmpty(mainClass)) {
+ Ajde.getDefault().getErrorHandler().handleWarning("No main class specified");
+ }
+ String classpath = project.getOutputPath();
+ if (LangUtil.isEmpty(classpath)) {
+ classpath = project.getOutJar();
+ }
+ classpath += File.pathSeparator + project.getClasspath();
+ String[] args = LangUtil.split(project.getExecutionArgs());
+ Reflection.runMainInSameVM(classpath, mainClass, args);
+ } catch(Throwable e) {
+ Ajde.getDefault().getErrorHandler().handleError("Error running " + mainClass, e);
+ }
+ }
+
private BuildManager buildManager;
private EditorManager editorManager;
private StructureViewManager structureViewManager;
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
+ + ")";
+ }
+}
+