]> source.dussan.org Git - aspectj.git/commitdiff
Bug 158205 "NullPointerException when weaving with bootstrap agent" (custom agent...
authormwebster <mwebster>
Mon, 2 Oct 2006 10:00:33 +0000 (10:00 +0000)
committermwebster <mwebster>
Mon, 2 Oct 2006 10:00:33 +0000 (10:00 +0000)
tests/ltw/NullSecurityManager.java [new file with mode: 0644]
tests/ltw/ant.xml
tests/ltw/java/net/URLClassLoader.java [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc153/Ajc153Tests.java
tests/src/org/aspectj/systemtest/ajc153/ajc153.xml

diff --git a/tests/ltw/NullSecurityManager.java b/tests/ltw/NullSecurityManager.java
new file mode 100644 (file)
index 0000000..c41e8c9
--- /dev/null
@@ -0,0 +1,4 @@
+
+public class NullSecurityManager extends SecurityManager {
+
+}
index db38cb16a195d4a6df40e92127d87889b647c0eb..c7f5cc26c08dd8b902ae584d51751e04472657b5 100644 (file)
@@ -5,6 +5,7 @@
     <property
         name="jdwp"
         value="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"/>
+       <property name="aj.bootpath" refid="aj.path"/>
 
     <target name="JDK14 LTW with XML">
         <java fork="yes" classname="HelloWorld" failonerror="yes">
         </java>
     </target>
 
+       <!-- Beware, this is complicated! We need to intercept class loading on 
+            the System class loader before any classes are loaded. We do this
+            by replacing the URLClassLoader. We then define a custom
+            SecurityManager that will be loaded _before_ the class loader
+            hierarch is fully initialized. -->
+    <target name="NPE with custom agent">
+        <java fork="yes" classname="HelloWorld" failonerror="yes">
+               
+               <!-- Prepend custom URLClassLoader and append AspectJ
+                    to bootclasspath -->
+               <jvmarg value="-Xbootclasspath/p:${aj.sandbox}"/>
+            <jvmarg value="-Xbootclasspath/a:${aj.bootpath}"/>
+
+               <classpath>
+                <pathelement path="${aj.sandbox}/hello.jar:${aj.sandbox}/handler.jar:${aj.sandbox}/security.jar"/>
+            </classpath>
+
+               <!-- Specify custom SecurityManager that will be loaded
+                    and woven very early -->
+               <jvmarg value="-Djava.security.manager=NullSecurityManager"/>
+               
+            <jvmarg value="-Daj.weaving.verbose=true"/>
+            <jvmarg value="-Dorg.aspectj.weaver.showWeaveInfo=true"/>
+               
+<!--           
+            <jvmarg value="-Dorg.aspectj.tracing.enabled=true"/>
+            <jvmarg value="-Dorg.aspectj.tracing.factory=default"/>
+            <jvmarg value="-Dorg.aspectj.tracing.messages=true"/>
+-->            
+        </java>
+    </target>
+
 </project>
diff --git a/tests/ltw/java/net/URLClassLoader.java b/tests/ltw/java/net/URLClassLoader.java
new file mode 100644 (file)
index 0000000..770c7f3
--- /dev/null
@@ -0,0 +1,274 @@
+package java.net;
+
+import java.io.ByteArrayInputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.security.SecureClassLoader;
+import java.util.Enumeration;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Vector;
+import java.util.jar.JarFile;
+import java.util.zip.ZipEntry;
+
+import org.aspectj.weaver.loadtime.Aj;
+
+public class URLClassLoader extends SecureClassLoader {
+       
+       public final static boolean debug = false;
+       
+       private List path = new LinkedList();
+       private Aj agent;
+
+       public URLClassLoader() {
+               super();
+       }
+
+       public URLClassLoader(ClassLoader parent) {
+               super(parent);
+       }
+
+       public URLClassLoader(URL[] urls) throws IOException {
+               this(urls,null,null);
+       }
+       
+       public URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) throws IOException {
+               super(parent);
+               if (debug) System.err.println("> URLClassLoader.URLClassLoader() parent=" + parent);
+
+               for (int i = 0; i < urls.length; i++) {
+                       Object pathElement;
+                       URL url = urls[i];
+                       if (debug) System.err.println("- URLClassLoader.URLClassLoader() url=" + url.getPath());
+                       File file = new File(encode(url.getFile()));
+                       if (debug) System.err.println("- URLClassLoader.URLClassLoader() file" + file);
+                       if (file.isDirectory()) pathElement = file;
+                       else if (file.exists() && file.getName().endsWith(".jar")) pathElement = new JarFile(file);
+                       else throw new RuntimeException(file.getAbsolutePath().toString());
+                       path.add(pathElement);
+               }
+
+               agent = new Aj();
+               
+               if (debug) System.err.println("< URLClassLoader.URLClassLoader() path=" + path);
+       }
+       
+//     public final static boolean debug = false;
+//     
+//     private List path = new LinkedList();
+////   private com.bea.jvm.ClassPreProcessor agent;
+//     private Object agent;
+//     private Method preProcess;
+       
+//     public JRockitClassLoader (URLClassLoader clone) throws Exception {
+//             /* Use extensions loader */
+//             super(clone.getParent());
+//
+//             URL[] urls = clone.getURLs();
+//             for (int i = 0; i < urls.length; i++) {
+//                     Object pathElement;
+//                     URL url = urls[i];
+//                     if (debug) System.err.println("JRockitClassLoader.JRockitClassLoader() url=" + url.getPath());
+//                     File file = new File(encode(url.getFile()));
+//                     if (debug) System.err.println("JRockitClassLoader.JRockitClassLoader() file" + file);
+//                     if (file.isDirectory()) pathElement = file;
+//                     else if (file.exists() && file.getName().endsWith(".jar")) pathElement = new JarFile(file);
+//                     else throw new RuntimeException(file.getAbsolutePath().toString());
+//                     path.add(pathElement);
+//             }
+//             
+//             Class agentClazz = Class.forName("org.aspectj.weaver.loadtime.JRockitAgent",false,this);
+//             Object obj = agentClazz.newInstance();
+//             if (debug) System.err.println("JRockitClassLoader.JRockitClassLoader() obj=" + obj);
+//             this.agent = obj;
+//             byte[] bytes = new byte[] {};
+//             Class[] parameterTypes = new Class[] { java.lang.ClassLoader.class, java.lang.String.class, bytes.getClass() }; 
+//             preProcess = agentClazz.getMethod("preProcess",parameterTypes);
+//     }
+       
+       /* Get rid of escaped characters */
+       private String encode (String s) {
+               StringBuffer result = new StringBuffer();
+               int i = s.indexOf("%");
+               while (i != -1) {
+                       result.append(s.substring(0,i));
+                       String escaped = s.substring(i+1,i+3);
+                       s = s.substring(i+3);
+                       Integer value = Integer.valueOf(escaped,16);
+                       result.append(new Character((char)value.intValue()));
+                       i = s.indexOf("%");
+               }
+               result.append(s);
+               return result.toString();
+       }
+       
+       protected Class findClass(String name) throws ClassNotFoundException {
+               if (debug) System.err.println("> URLClassLoader.findClass() name=" + name);
+               Class clazz = null;
+               try {
+                       clazz = super.findClass(name);
+               }
+               catch (ClassNotFoundException ex) {
+                       for (Iterator i = path.iterator(); clazz ==  null && i.hasNext();) {
+                               byte[] classBytes = null;
+                               try {
+                                       Object pathElement = i.next();
+                                       if (pathElement instanceof File) {
+                                               File dir = (File)pathElement;
+                                               String className = name.replace('.','/') + ".class";
+                                               File classFile = new File(dir,className);
+                                               if (debug) System.err.println("- URLClassLoader.findClass() classFile=" + classFile);
+                                               if (classFile.exists()) classBytes = loadClassFromFile(name,classFile);
+                                       }
+                                       else {
+                                               JarFile jar = (JarFile)pathElement;
+                                               String className = name.replace('.','/') + ".class";
+                                               ZipEntry entry = jar.getEntry(className);
+                                               if (entry != null) classBytes = loadBytesFromZipEntry(jar,entry);
+                                       }
+                                       
+                                       if (classBytes != null) {
+                                               clazz = defineClass(name,classBytes);
+                                       }
+                               }
+                               catch (IOException ioException) {
+                                       ex.printStackTrace();
+                               }
+                       }
+               }
+               
+               if (debug) System.err.println("< URLClassLoader.findClass() clazz=" + clazz);
+               if (clazz == null) throw new ClassNotFoundException(name);
+               return clazz;
+       }
+
+       protected URL findResource (String name) {
+               if (debug) System.err.println("> URLClassLoader.findResource() name=" + name);
+               URL url = null;
+
+               try {
+                       Enumeration enu = findResources(name);
+                       if (enu.hasMoreElements()) url = (URL)enu.nextElement();
+               }
+               catch (IOException ex) {
+                       ex.printStackTrace();
+               }
+
+               if (debug) System.err.println("< URLClassLoader.findResource() url=" + url);
+               return url;
+       }
+       
+       
+       protected Enumeration findResources (String name) throws IOException {
+               if (debug) System.err.println("> URLClassLoader.findResources() name=" + name);
+               Vector urls = new Vector();
+               
+               for (Iterator i = path.iterator(); i.hasNext();) {
+                       Object pathElement = i.next();
+                       if (pathElement instanceof File) {
+                               File dir = (File)pathElement;
+                               File resourceFile = new File(dir,name);
+//                             if (debug) System.err.println("- URLClassLoader.findResources() file=" + resourceFile);
+                       }
+                       else {
+                               JarFile jar = (JarFile)pathElement;
+                               ZipEntry entry = jar.getEntry(name);
+//                             if (debug) System.err.println("- URLClassLoader.findResources() entry=" + entry);
+                               if (entry != null) {
+                                       if (debug) System.err.println("- URLClassLoader.findResources() jar=" + jar.getName());
+
+                                       final byte[] bytes = loadBytesFromZipEntry(jar,entry);
+                                       URLStreamHandler streamHandler = new URLStreamHandler() {
+                                       
+                                               protected URLConnection openConnection(URL u) throws IOException {
+                                                       URLConnection connection = new URLConnection(u) {
+                                                               
+                                                               public void connect() throws IOException {
+                                                               }
+
+                                                               public InputStream getInputStream() throws IOException {
+                                                                       return new ByteArrayInputStream(bytes);
+                                                               }
+                                                               
+                                                       };
+                                                       return connection;
+                                           }
+                                       
+                                       };
+                                       URL url = new URL("file",null,0,jar.getName(),streamHandler);
+                                       urls.add(url);
+                               }
+                       }
+               }
+               
+               Enumeration enu = urls.elements();
+               
+               if (debug) System.err.println("< URLClassLoader.findResources() enu=" + enu);
+               return enu;
+       }
+       
+       private Class defineClass (String name, byte[] bytes) {
+               if (debug) System.err.println("> URLClassLoader.defineClass() name=" + name);
+//             try {
+                       if (agent != null) bytes = agent.preProcess(name,bytes,this);
+//             }
+//             catch (IllegalAccessException iae) {
+//                     iae.printStackTrace();
+//                     throw new ClassFormatError(iae.getMessage());
+//             }
+//             catch (InvocationTargetException ite) {
+//                     ite.printStackTrace();
+//                     throw new ClassFormatError(ite.getTargetException().getMessage());
+//             }
+               if (debug) System.err.println("< URLClassLoader.defineClass() name=" + name);
+               return super.defineClass(name,bytes,0,bytes.length);
+       }
+       
+       private byte[] loadClassFromFile (String name, File file) throws IOException {
+               if (debug) System.err.println("> URLClassLoader.loadClassFromFile() file=" + file);
+
+               byte[] bytes;
+               bytes = new byte[(int)file.length()];
+               FileInputStream fis = null;
+               try {
+                       fis = new FileInputStream(file);
+                       bytes = readBytes(fis,bytes);
+               }
+               finally {
+                       if (fis != null) fis.close();
+               }
+               
+               if (debug) System.err.println("< URLClassLoader.loadClassFromFile() bytes=b[" + bytes.length + "]");
+               return bytes;
+       }
+       
+       private byte[] loadBytesFromZipEntry (JarFile jar, ZipEntry entry) throws IOException {
+               if (debug) System.err.println("> URLClassLoader.loadBytesFromZipEntry() entry=" + entry);
+
+               byte[] bytes;
+               bytes = new byte[(int)entry.getSize()];
+               InputStream is = null;
+               try {
+                       is = jar.getInputStream(entry);
+                       bytes = readBytes(is,bytes);
+               }
+               finally {
+                       if (is != null) is.close();
+               }
+               
+               if (debug) System.err.println("< URLClassLoader.loadBytesFromZipEntry() bytes=b[" + bytes.length + "]");
+               return bytes;
+       }
+       
+       private byte[] readBytes (InputStream is, byte[] bytes) throws IOException {
+               for (int offset = 0; offset < bytes.length;) {
+                       int read = is.read(bytes,offset,bytes.length - offset);
+                       offset += read;
+               }
+               return bytes;
+       }
+
+}
index ab1c5524bba3e3ef52eb4327540a52eb85c85f16..50998bf7fcace76aaa5011a1a5999df79879674d 100644 (file)
@@ -129,6 +129,10 @@ public class Ajc153Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
                                        " but found " + ipe.getSourceSignature(), 
                                        expected, ipe.getSourceSignature());
   }
+
+  public void testNPEWithCustomAgent_pr158005() {
+         runTest("NPE with custom agent");
+  }
   
     /////////////////////////////////////////
   public static Test suite() {
index 6c5b05e6e38677cc36f78ea648fb23979f348ff3..710a1480987dd3620c347970d821df830dc0ad3d 100644 (file)
       <compile files="SampleTest.java"/>
     </ajc-test>
 
+       <ajc-test dir="ltw" title="NPE with custom agent" keywords="ltw">
+        <compile files="java/net/URLClassLoader.java"/>
+        <compile files="HelloWorld.java" options="-outjar hello.jar"/>
+        <compile files="ExceptionHandler.aj" options="-outxml -outjar handler.jar"/>
+        <compile files="NullSecurityManager.java" options="-outjar security.jar"/>
+               <ant file="ant.xml" target="NPE with custom agent" verbose="true">
+               <stdout>
+               <line text="Hello World!"/>
+               </stdout>
+        </ant>
+    </ajc-test>
+
 </suite>
\ No newline at end of file