]> source.dussan.org Git - aspectj.git/commitdiff
minimal run-in-same-vm feature for ajbrowser
authorwisberg <wisberg>
Thu, 1 May 2003 13:17:35 +0000 (13:17 +0000)
committerwisberg <wisberg>
Thu, 1 May 2003 13:17:35 +0000 (13:17 +0000)
ajbrowser/src/org/aspectj/tools/ajbrowser/BrowserManager.java
ajde/src/org/aspectj/ajde/Ajde.java
util/src/org/aspectj/util/Reflection.java
util/src/org/aspectj/util/UtilClassLoader.java [new file with mode: 0644]

index b2ec905711231d61da24db27537d521d180a6dc7..d03e38304aa58c3f500a12d9669a95b5d1f8e2e0 100644 (file)
@@ -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() {
                
index 7f02929823c28db92b305b1694dbb443295b7ba8..bc9893dea75bf2737fed09df105ac8232d017e60 100644 (file)
@@ -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;
index bee7bd70e27fd273f008191d8c166b083ae9f99a..6804afaa690f7d3a4774254a0d9e8816af2fc547 100644 (file)
 
 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 (file)
index 0000000..dc4ec6f
--- /dev/null
@@ -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
+            + ")";
+    }
+}
+