From 33d8ee9eededcd1219a6cbd1d063af005d40a3f7 Mon Sep 17 00:00:00 2001
From: acolyer <acolyer>
Date: Fri, 2 Apr 2004 12:03:40 +0000
Subject: fix for Bugzilla Bug 31460  	Weaving class loader

---
 docs/build.xml                                     |   7 +-
 docs/dist/doc/examples/build.xml                   |  58 ++++
 docs/dist/doc/examples/ltw/README                  |  22 ++
 docs/dist/doc/examples/ltw/aj                      |  16 +
 docs/dist/doc/examples/ltw/aj.bat                  |  22 ++
 .../testdata/src1/LTWAroundClosure.aj              |  20 ++
 org.aspectj.ajdt.core/testdata/src1/LTWAspect.aj   |  12 +
 org.aspectj.ajdt.core/testdata/src1/LTWFieldITD.aj |  16 +
 .../testdata/src1/LTWHelloWorld.java               |  24 ++
 .../testdata/src1/LTWInterfaceITD.aj               |  18 ++
 .../testdata/src1/LTWMethodITD.aj                  |  22 ++
 org.aspectj.ajdt.core/testdata/src1/LTWPerthis.aj  |  13 +
 .../testdata/src1/ltw/LTWPackageTest.java          |   8 +
 .../internal/compiler/batch/BcweaverJarMaker.java  |  82 +++++
 util/src/org/aspectj/util/FileUtil.java            |  11 +-
 .../aspectj/weaver/ExtensibleURLClassLoader.java   |  87 ++++++
 .../org/aspectj/weaver/WeavingURLClassLoader.java  | 123 ++++++++
 .../weaver/tools/GeneratedClassHandler.java        |  29 ++
 .../org/aspectj/weaver/tools/WeavingAdaptor.java   | 332 +++++++++++++++++++++
 .../aspectj/weaver/tools/WeavingClassLoader.java   |  31 ++
 weaver/src/org/aspectj/weaver/tools/package.html   |   7 +
 weaver/testdata/dummyAspect.jar                    | Bin 613 -> 819 bytes
 weaver/testdata/ltw-acaspects.jar                  | Bin 0 -> 2412 bytes
 weaver/testdata/ltw-aspects.jar                    | Bin 0 -> 1474 bytes
 weaver/testdata/ltw-classes.jar                    | Bin 0 -> 1410 bytes
 weaver/testdata/ltw-itdaspects.jar                 | Bin 0 -> 3214 bytes
 weaver/testdata/ltw-peraspects.jar                 | Bin 0 -> 1874 bytes
 weaver/testdata/ltw-woven.jar                      | Bin 0 -> 2653 bytes
 weaver/testdata/megatrace.jar                      | Bin 3777 -> 5285 bytes
 weaver/testdata/megatrace0easy.jar                 | Bin 3039 -> 3256 bytes
 weaver/testdata/megatrace0hard.jar                 | Bin 2940 -> 3152 bytes
 weaver/testdata/megatraceNoweave.jar               | Bin 2832 -> 3043 bytes
 weaver/testdata/tracing.jar                        | Bin 2406 -> 2616 bytes
 weaver/testsrc/BcweaverModuleTests.java            |   2 +-
 .../testsrc/org/aspectj/weaver/BcweaverTests.java  |   4 +-
 .../aspectj/weaver/WeavingURLClassLoaderTest.java  | 301 +++++++++++++++++++
 36 files changed, 1261 insertions(+), 6 deletions(-)
 create mode 100644 docs/dist/doc/examples/ltw/README
 create mode 100644 docs/dist/doc/examples/ltw/aj
 create mode 100644 docs/dist/doc/examples/ltw/aj.bat
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/LTWAroundClosure.aj
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/LTWAspect.aj
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/LTWFieldITD.aj
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/LTWHelloWorld.java
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/LTWInterfaceITD.aj
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/LTWMethodITD.aj
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/LTWPerthis.aj
 create mode 100644 org.aspectj.ajdt.core/testdata/src1/ltw/LTWPackageTest.java
 create mode 100644 weaver/src/org/aspectj/weaver/ExtensibleURLClassLoader.java
 create mode 100644 weaver/src/org/aspectj/weaver/WeavingURLClassLoader.java
 create mode 100644 weaver/src/org/aspectj/weaver/tools/GeneratedClassHandler.java
 create mode 100644 weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java
 create mode 100644 weaver/src/org/aspectj/weaver/tools/WeavingClassLoader.java
 create mode 100644 weaver/src/org/aspectj/weaver/tools/package.html
 create mode 100644 weaver/testdata/ltw-acaspects.jar
 create mode 100644 weaver/testdata/ltw-aspects.jar
 create mode 100644 weaver/testdata/ltw-classes.jar
 create mode 100644 weaver/testdata/ltw-itdaspects.jar
 create mode 100644 weaver/testdata/ltw-peraspects.jar
 create mode 100644 weaver/testdata/ltw-woven.jar
 create mode 100644 weaver/testsrc/org/aspectj/weaver/WeavingURLClassLoaderTest.java

diff --git a/docs/build.xml b/docs/build.xml
index d0b8248d0..107da3834 100644
--- a/docs/build.xml
+++ b/docs/build.xml
@@ -166,14 +166,15 @@
     </target>
 
     <target name="api" depends="init"
-       description="javadoc for AspectJ lang and lang.reflect">
+       description="javadoc for AspectJ lang, lang.reflect and org.aspectj.weaver.tools">
         <delete dir="${docs.dist.dir}/doc/api"/>
         <mkdir dir="${docs.dist.dir}/doc/api"/>
-        <javadoc sourcepath="${aspectj.modules.dir}/runtime/src"
+        <javadoc sourcepath="${aspectj.modules.dir}/runtime/src;${aspectj.modules.dir}/weaver/src"
                     destdir="${docs.dist.dir}/doc/api"
                 windowtitle="AspectJ(tm) runtime API"
                        link="http://java.sun.com/j2se/1.4.2/docs/api"
-               packagenames="org.aspectj.lang,org.aspectj.lang.reflect" />
+                       classpath="${aspectj.modules.dir}/asm/bin;${aspectj.modules.dir}/bridge/bin;${aspectj.modules.dir}/util/bin;${aspectj.modules.dir}/lib/bcel/bcel.jar"
+               packagenames="org.aspectj.lang,org.aspectj.lang.reflect,org.aspectj.weaver.tools" />
                <!-- note: link ineffective at avoiding see tag warning -->
     </target>
 
diff --git a/docs/dist/doc/examples/build.xml b/docs/dist/doc/examples/build.xml
index 8fd48dbc7..ba2931fba 100644
--- a/docs/dist/doc/examples/build.xml
+++ b/docs/dist/doc/examples/build.xml
@@ -394,4 +394,62 @@
 
     </target>
 
+    <!-- ============================================================= -->
+    <!-- do tracing example with 1.2 load-time weaving                 -->
+    <!-- (and use fork/forkclasspath to avoid Eclipse 2.x bug)         -->
+    <!-- ============================================================= -->
+    <target name="tracing-lt" depends="init"
+     description="tracing example with load-time aspect weaving">
+       <antcall target="clean" />
+
+       <!-- build application classes -->
+       <iajc outjar="${jar.dir}/tracingApp.jar"
+          classpath="${aspectjrt.jar}"
+          fork="true"
+          forkclasspath="${aspectjtools.jar}"
+            verbose="off">
+         <src path="${example.dir}"/>
+         <include name="tracing/*.java" />
+       </iajc>
+
+       <!-- Build a read-only tracing library -->
+       <iajc outjar="${jar.dir}/tracingLib.jar"
+          classpath="${aspectjrt.jar}:${jar.dir}/tracingApp.jar"
+          fork="true"
+          forkclasspath="${aspectjtools.jar}"
+            verbose="off">
+         <src path="${example.dir}"/>
+         <include name="tracing/version2/Trace.java" />
+         <include name="tracing/version2/TraceMyClasses.java" />
+       </iajc>
+
+       <!-- test standalone application by running without tracing -->
+       <echo message="---------- running without tracing - START"/>
+       <java classname="tracing.ExampleMain">
+         <classpath>
+            <pathelement path="${aspectjrt.jar}"/> 
+            <pathelement path="${jar.dir}/tracingApp.jar"/> 
+         </classpath>
+       </java>
+       <echo message="---------- running without tracing - FINISH "/>
+
+       <!-- run appliaction with LTW to add tracing -->
+       <echo message="---------- running with tracing - START"/>
+       <java classname="tracing.ExampleMain"
+         fork="true">
+         <classpath>
+            <pathelement path="${aspectjrt.jar}"/> 
+            <pathelement path="${aspectjtools.jar}"/> 
+            <pathelement path="d:/eclipse_aspectj/workspace/weaver/bin"/> 
+         </classpath>
+		 <jvmarg line="-showversion"/>
+		 <sysproperty key="java.system.class.loader" value="org.aspectj.weaver.WeavingURLClassLoader"/>
+         <sysproperty key="aj.weaving.verbose" value="True"/>
+         <sysproperty key="aj.class.path" path="${jar.dir}/tracingLib.jar:${jar.dir}/tracingApp.jar"/>
+         <sysproperty key="aj.aspect.path" path="${jar.dir}/tracingLib.jar"/>
+       </java>
+       <echo message="---------- running with tracing - FINISH"/>
+
+    </target>
+
 </project>
diff --git a/docs/dist/doc/examples/ltw/README b/docs/dist/doc/examples/ltw/README
new file mode 100644
index 000000000..bbeb56290
--- /dev/null
+++ b/docs/dist/doc/examples/ltw/README
@@ -0,0 +1,22 @@
+
+This directory contains a script "aj" to demonstrate load-time weaving. Java
+classes on the CLASSPATH are loaded and woven with aspects on the ASPECTPATH.
+This feature is only supported on JDK 1.4 and later.
+
+--To compile the tracing example--
+
+ ant -f ../build.xml tracing-lt
+
+--To run the example--
+
+ set CLASSPATH to include "../jars/tracingApp.jar"
+
+ aj tracing.ExampleMain
+
+--To run the example with tracing--
+
+ set ASPECTPATH=../jars/tracingLib.jar
+
+ aj tracing.ExampleMain
+
+
diff --git a/docs/dist/doc/examples/ltw/aj b/docs/dist/doc/examples/ltw/aj
new file mode 100644
index 000000000..8e7a250bb
--- /dev/null
+++ b/docs/dist/doc/examples/ltw/aj
@@ -0,0 +1,16 @@
+# *******************************************************************
+# Copyright (c) 2004 IBM Corporation
+# 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: 
+#     Matthew Webster     initial implementation 
+# ******************************************************************/
+
+if [ "$ASPECTJ_HOME" = "" ] ; then ASPECTJ_HOME=../../../
+fi
+
+"$JAVA_HOME/bin/java" -classpath "$ASPECTJ_HOME/lib/aspectjtools.jar" "-Djava.system.class.loader=org.aspectj.weaver.WeavingURLClassLoader" "-Daj.class.path=$ASPECTPATH:$CLASSPATH" "-Daj.aspect.path=$ASPECTPATH" "$@"
diff --git a/docs/dist/doc/examples/ltw/aj.bat b/docs/dist/doc/examples/ltw/aj.bat
new file mode 100644
index 000000000..c004598bb
--- /dev/null
+++ b/docs/dist/doc/examples/ltw/aj.bat
@@ -0,0 +1,22 @@
+@echo off
+rem *******************************************************************
+rem Copyright (c) 2004 IBM Corporation
+rem All rights reserved. 
+rem This program and the accompanying materials are made available 
+rem under the terms of the Common Public License v1.0 
+rem which accompanies this distribution and is available at 
+rem http://www.eclipse.org/legal/cpl-v10.html 
+rem  
+rem Contributors: 
+rem     Matthew Webster     initial implementation 
+rem ******************************************************************/
+
+if "%ASPECTJ_HOME%" == "" set ASPECTJ_HOME=..\..\..\
+
+if exist "%JAVA_HOME%\bin\java.exe" goto haveJava
+if exist "%JAVA_HOME%\bin\java.bat" goto haveJava
+if exist "%JAVA_HOME%\bin\java" goto haveJava
+echo java does not exist as %JAVA_HOME%\bin\java
+echo please fix the JAVA_HOME environment variable
+:haveJava
+"%JAVA_HOME%\bin\java" -classpath "%ASPECTJ_HOME%\lib\aspectjtools.jar" "-Djava.system.class.loader=org.aspectj.weaver.WeavingURLClassLoader" "-Daj.class.path=%ASPECTPATH%;%CLASSPATH%" "-Daj.aspect.path=%ASPECTPATH%" %1 %2 %3 %4 %5 %6 %7 %8 %9 
diff --git a/org.aspectj.ajdt.core/testdata/src1/LTWAroundClosure.aj b/org.aspectj.ajdt.core/testdata/src1/LTWAroundClosure.aj
new file mode 100644
index 000000000..80af46fd7
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/LTWAroundClosure.aj
@@ -0,0 +1,20 @@
+import java.util.List;
+
+public aspect LTWAroundClosure {
+
+	pointcut println (List list) :
+		execution(* println()) && this(list);
+	
+	void around (final List list) : println (list) {
+
+		Runnable runnable = new Runnable() {
+			public void run () {
+				System.err.println("LTWAroundClosure.run(" + thisJoinPointStaticPart + ")");
+				proceed(list);
+			}
+		};
+		runnable.run();
+		list.add("LTWAroundClosure");				
+	}
+
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/LTWAspect.aj b/org.aspectj.ajdt.core/testdata/src1/LTWAspect.aj
new file mode 100644
index 000000000..1721b4ef7
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/LTWAspect.aj
@@ -0,0 +1,12 @@
+import java.util.List;
+
+public privileged aspect LTWAspect {
+	
+	pointcut method (List list) :
+		execution(* LTWHelloWorld.*(..)) && this(list);
+	
+	before (List list) : method (list) {
+		System.err.println("LTWAspect.method(" + thisJoinPointStaticPart + ")");
+		list.add("LTWAspect");
+	}
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/LTWFieldITD.aj b/org.aspectj.ajdt.core/testdata/src1/LTWFieldITD.aj
new file mode 100644
index 000000000..87f441544
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/LTWFieldITD.aj
@@ -0,0 +1,16 @@
+import java.util.List;
+
+public aspect LTWFieldITD {
+
+	private int LTWHelloWorld.intField = 999;
+
+	pointcut init (LTWHelloWorld hw) :
+		execution(LTWHelloWorld.new()) && this(hw);
+		
+	after (LTWHelloWorld hw) : init (hw) {
+		System.err.println("LTWFieldITD.init(" + thisJoinPointStaticPart + ")");
+		hw.intField = 999999;
+		hw.add(getClass().getName());
+	}
+
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/LTWHelloWorld.java b/org.aspectj.ajdt.core/testdata/src1/LTWHelloWorld.java
new file mode 100644
index 000000000..ec533506d
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/LTWHelloWorld.java
@@ -0,0 +1,24 @@
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Properties;
+
+public class LTWHelloWorld extends ArrayList {
+
+	private String message = "Hello World!";
+
+	public void println () {
+		System.out.println(message);
+	}
+
+	public static void main(String[] args) {
+		LTWHelloWorld hw = new LTWHelloWorld();
+		hw.println();		
+		for (int i = 0; i < args.length; i++) {
+			String jp = args[i];
+			if (!hw.contains(jp)) {
+				throw new RuntimeException(jp + " missing"); 
+			}
+		}
+	}
+
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/LTWInterfaceITD.aj b/org.aspectj.ajdt.core/testdata/src1/LTWInterfaceITD.aj
new file mode 100644
index 000000000..e7fa6a46a
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/LTWInterfaceITD.aj
@@ -0,0 +1,18 @@
+import java.util.List;
+
+public privileged aspect LTWInterfaceITD {
+
+	declare parents : LTWHelloWorld implements Runnable;
+	
+	public void LTWHelloWorld.run () {
+		add("LTWInterfaceITD");
+	}
+
+	pointcut init (LTWHelloWorld hw) :
+		execution(LTWHelloWorld.new()) && this(hw);
+		
+	after (LTWHelloWorld hw) : init (hw) {
+		System.err.println("LTWInterfaceITD.init(" + thisJoinPointStaticPart + ")");
+		hw.run();
+	}
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/LTWMethodITD.aj b/org.aspectj.ajdt.core/testdata/src1/LTWMethodITD.aj
new file mode 100644
index 000000000..35049f04f
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/LTWMethodITD.aj
@@ -0,0 +1,22 @@
+import java.util.List;
+
+public privileged aspect LTWMethodITD {
+
+	public String LTWHelloWorld.getMessage () {
+		return message;
+	}
+	
+	public void LTWHelloWorld.setMessage (String newMessage) {
+		message = newMessage;
+	}
+
+	pointcut init (LTWHelloWorld hw) :
+		execution(LTWHelloWorld.new()) && this(hw);
+		
+	after (LTWHelloWorld hw) : init (hw) {
+		System.err.println("LTWMethodITD.init(" + thisJoinPointStaticPart + ")");
+		hw.getMessage();
+		hw.setMessage("Hello LTWMethodITD");
+		hw.add(getClass().getName());
+	}
+}
\ No newline at end of file
diff --git a/org.aspectj.ajdt.core/testdata/src1/LTWPerthis.aj b/org.aspectj.ajdt.core/testdata/src1/LTWPerthis.aj
new file mode 100644
index 000000000..955d72096
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/LTWPerthis.aj
@@ -0,0 +1,13 @@
+import java.util.List;
+
+public aspect LTWPerthis perthis(this(LTWHelloWorld)) {
+
+	pointcut println (List list) :
+		execution(* println()) && this(list);
+	
+	before (List list) : println (list) {
+		System.err.println("LTWPerthis.println(" + thisJoinPointStaticPart + ")");
+		list.add(getClass().getName());
+	}
+
+}
diff --git a/org.aspectj.ajdt.core/testdata/src1/ltw/LTWPackageTest.java b/org.aspectj.ajdt.core/testdata/src1/ltw/LTWPackageTest.java
new file mode 100644
index 000000000..e749db20c
--- /dev/null
+++ b/org.aspectj.ajdt.core/testdata/src1/ltw/LTWPackageTest.java
@@ -0,0 +1,8 @@
+package ltw;
+
+public class LTWPackageTest {
+
+	public static void main(String[] args) {
+	}
+
+}
diff --git a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java
index 25e621ca1..b6dfb5184 100644
--- a/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java
+++ b/org.aspectj.ajdt.core/testsrc/org/aspectj/ajdt/internal/compiler/batch/BcweaverJarMaker.java
@@ -36,6 +36,8 @@ public class BcweaverJarMaker {
 		
 		
 		makeTestJars();
+
+		makeURLWeavingClassLoaderJars();
 	}
 	
 	public static void makeJar0() throws IOException {
@@ -179,5 +181,85 @@ public class BcweaverJarMaker {
 		CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
 	}	
 	
+	public static void makeURLWeavingClassLoaderJars() throws IOException {
+		List args = new ArrayList();
+
+		/*
+		 * Vanilla classes
+		 */
+		args.add("-classpath"); 
+		args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar" +
+		   File.pathSeparator + System.getProperty("aspectjrt.path"));
+		args.add("-outjar");
+		args.add("../weaver/testdata/ltw-classes.jar");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWHelloWorld.java");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/ltw/LTWPackageTest.java");
+		CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+		/* 
+		 * Woven classes
+		 */
+		args = new ArrayList();
+		args.add("-classpath"); 
+		args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" +
+		   File.pathSeparator + System.getProperty("aspectjrt.path"));
+		args.add("-outjar");
+		args.add("../weaver/testdata/ltw-woven.jar");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWHelloWorld.java");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWAspect.aj");
+		CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+		/*
+		 * Advice
+		 */
+		args = new ArrayList();
+		args.add("-classpath"); 
+		args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" +
+		   File.pathSeparator + System.getProperty("aspectjrt.path"));
+		args.add("-outjar");
+		args.add("../weaver/testdata/ltw-aspects.jar");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWAspect.aj");
+		CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+		/*
+		 * Around closure advice
+		 */
+		args = new ArrayList();
+		args.add("-classpath"); 
+		args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" +
+		   File.pathSeparator + System.getProperty("aspectjrt.path"));
+		args.add("-outjar");
+		args.add("../weaver/testdata/ltw-acaspects.jar");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWAroundClosure.aj");
+		CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+		/*
+		 * ITD
+		 */
+		args = new ArrayList();
+		args.add("-Xlint:ignore"); 
+		args.add("-classpath"); 
+		args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" +
+		   File.pathSeparator + System.getProperty("aspectjrt.path"));
+		args.add("-outjar");
+		args.add("../weaver/testdata/ltw-itdaspects.jar");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWInterfaceITD.aj");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWFieldITD.aj");
+		/* Uncomment when bug #55341 fixed */
+//		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWMethodITD.aj");
+		CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+
+		/*
+		 * perXXX()
+		 */
+		args = new ArrayList();
+		args.add("-classpath"); 
+		args.add("../lib/test/aspectjrt.jar;../lib/test/testing-client.jar;../weaver/testdata/ltw-classes.jar" +
+		   File.pathSeparator + System.getProperty("aspectjrt.path"));
+		args.add("-outjar");
+		args.add("../weaver/testdata/ltw-peraspects.jar");
+		args.add(AjdtAjcTests.TESTDATA_PATH + "/src1/LTWPerthis.aj");
+		CommandTestCase.runCompiler(args, CommandTestCase.NO_ERRORS);
+	}	
 	
 }
diff --git a/util/src/org/aspectj/util/FileUtil.java b/util/src/org/aspectj/util/FileUtil.java
index 34bf103a9..ccf54831f 100644
--- a/util/src/org/aspectj/util/FileUtil.java
+++ b/util/src/org/aspectj/util/FileUtil.java
@@ -1262,7 +1262,16 @@ public class FileUtil {
     }
 
     private FileUtil() { throw new Error("utility class"); }
-
+	
+	public static List makeClasspath(URL[] urls) {
+		List ret = new LinkedList();
+		if (urls != null) {
+			for (int i = 0; i < urls.length; i++) {
+				ret.add(urls[i].getPath());
+			}
+		}
+		return ret;
+	}
 
     /**
      * A pipe when run reads from an input stream to an output stream,
diff --git a/weaver/src/org/aspectj/weaver/ExtensibleURLClassLoader.java b/weaver/src/org/aspectj/weaver/ExtensibleURLClassLoader.java
new file mode 100644
index 000000000..1117c6b96
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/ExtensibleURLClassLoader.java
@@ -0,0 +1,87 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 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: 
+ *     Matthew Webster, Adrian Colyer, 
+ *     Martin Lippert     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.weaver;
+
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.CodeSource;
+
+import org.aspectj.util.FileUtil;
+import org.aspectj.weaver.bcel.ClassPathManager;
+import org.aspectj.weaver.tools.*;
+
+public abstract class ExtensibleURLClassLoader extends URLClassLoader {
+	
+	private ClassPathManager classPath;
+	
+	public ExtensibleURLClassLoader (URL[] urls, ClassLoader parent) {
+		super(urls,parent);
+
+//		System.err.println("? ExtensibleURLClassLoader.<init>() path=" + WeavingAdaptor.makeClasspath(urls));
+		classPath = new ClassPathManager(FileUtil.makeClasspath(urls),null);
+	}
+
+	protected void addURL(URL url) {
+		classPath.addPath(url.getPath(),null);
+	}
+	
+	protected Class findClass(String name) throws ClassNotFoundException {
+//		System.err.println("? ExtensibleURLClassLoader.findClass(" + name + ")");
+		try {
+			byte[] bytes = getBytes(name);
+			if (bytes != null) {
+				return defineClass(name,bytes);
+			}
+			else {
+				throw new ClassNotFoundException(name);
+			}
+		}
+		catch (IOException ex) {
+			throw new ClassNotFoundException(name);
+		}
+	}
+
+	protected Class defineClass(String name, byte[] b, CodeSource cs) throws IOException {
+//		System.err.println("? ExtensibleURLClassLoader.defineClass(" + name + ",[" + b.length + "])");
+		return defineClass(name, b, 0, b.length, cs);
+	}
+
+	protected byte[] getBytes (String name) throws IOException {
+		byte[] b = null;
+		ClassPathManager.ClassFile classFile = classPath.find(TypeX.forName(name));
+		if (classFile != null) {
+			b = FileUtil.readAsByteArray(classFile.getInputStream());
+		}
+		return b;
+	}
+
+	private Class defineClass(String name, byte[] bytes /*ClassPathManager.ClassFile classFile*/) throws IOException {
+		String packageName = getPackageName(name);
+		if (packageName != null) {
+			Package pakkage = getPackage(packageName);
+			if (pakkage == null) {
+				definePackage(packageName,null,null,null,null,null,null,null);
+			}
+		}
+		
+		return defineClass(name, bytes, null);
+	}
+
+	private String getPackageName (String className) {
+		int offset = className.lastIndexOf('.');
+		return (offset == -1)? null : className.substring(0,offset);  
+	}
+
+}
diff --git a/weaver/src/org/aspectj/weaver/WeavingURLClassLoader.java b/weaver/src/org/aspectj/weaver/WeavingURLClassLoader.java
new file mode 100644
index 000000000..c01f18812
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/WeavingURLClassLoader.java
@@ -0,0 +1,123 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 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: 
+ *     Matthew Webster, Adrian Colyer, 
+ *     Martin Lippert     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.weaver;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.net.URLStreamHandlerFactory;
+import java.security.CodeSource;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.StringTokenizer;
+
+import org.aspectj.util.UtilClassLoader;
+import org.aspectj.weaver.tools.*;
+
+public class WeavingURLClassLoader extends ExtensibleURLClassLoader implements WeavingClassLoader {
+
+	public static final String WEAVING_CLASS_PATH = "aj.class.path"; 
+	public static final String WEAVING_ASPECT_PATH = "aj.aspect.path"; 
+	
+	private URL[] aspectURLs;
+	private WeavingAdaptor adaptor; 
+	private Map generatedClasses = new HashMap(); /* String -> byte[] */ 
+
+	/*
+	 * This constructor is needed when using "-Djava.system.class.loader". 
+	 */
+	public WeavingURLClassLoader (ClassLoader parent) {
+		this(getURLs(getClassPath()),getURLs(getAspectPath()),parent);
+//		System.err.println("? WeavingURLClassLoader.<init>(" + parent + ")");
+	}
+	
+	public WeavingURLClassLoader (URL[] classURLs, URL[] aspectURLs, ClassLoader parent) {
+		super(classURLs,parent);
+//		System.err.println("? WeavingURLClassLoader.<init>()");
+		this.aspectURLs = aspectURLs;
+		adaptor = new WeavingAdaptor(this);
+	}
+	
+	private static String getAspectPath () {
+		return System.getProperty(WEAVING_ASPECT_PATH,"");
+	}
+	
+	private static String getClassPath () {
+		return System.getProperty(WEAVING_CLASS_PATH,"");
+	}
+	
+	private static URL[] getURLs (String path) {
+		List urlList = new ArrayList();
+		for (StringTokenizer t = new StringTokenizer(path,File.pathSeparator);
+			 t.hasMoreTokens();) {
+			File f = new File(t.nextToken().trim());
+			try {
+				if (f.exists()) {
+					URL url = f.toURL();
+					if (url != null) urlList.add(url);
+				}
+			} catch (MalformedURLException e) {}
+		}
+
+		URL[] urls = new URL[urlList.size()];
+		urlList.toArray(urls);
+		return urls;
+	}
+
+	protected void addURL(URL url) {
+		adaptor.addURL(url);
+		super.addURL(url);
+	}
+
+	/**
+	 * Override to weave class using WeavingAdaptor 
+	 */
+	protected Class defineClass(String name, byte[] b, CodeSource cs) throws IOException {
+//		System.err.println("? WeavingURLClassLoader.defineClass(" + name + ", [" + b.length + "])");
+		b = adaptor.weaveClass(name,b);
+		return super.defineClass(name, b, cs);
+	}
+
+	/**
+	 * Override to find classes generated by WeavingAdaptor
+	 */
+	protected byte[] getBytes (String name) throws IOException {
+		byte[] bytes = super.getBytes(name);
+		
+		if (bytes == null) {
+//			return adaptor.findClass(name);
+			return (byte[])generatedClasses.remove(name);
+		}
+		
+		return bytes;
+	}
+
+	/**
+	 * Implement method from WeavingClassLoader
+	 */
+	public URL[] getAspectURLs() {
+		return aspectURLs;
+	}
+
+	public void acceptClass (String name, byte[] bytes) {
+		generatedClasses.put(name,bytes);
+	}
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/GeneratedClassHandler.java b/weaver/src/org/aspectj/weaver/tools/GeneratedClassHandler.java
new file mode 100644
index 000000000..0a782452c
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/tools/GeneratedClassHandler.java
@@ -0,0 +1,29 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 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: 
+ *     Matthew Webster, Adrian Colyer, 
+ *     Martin Lippert     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.tools;
+
+/**
+ * Interface implemented by weaving class loaders to allow classes generated by
+ * the weaving process to be defined.
+ */
+public interface GeneratedClassHandler {
+	
+	/**
+	 * Accept class generated by WeavingAdaptor. The class loader should store
+	 * the class definition in its local cache until called upon to load it.
+	 * @param name class name
+	 * @param bytes class definition
+	 */
+	public void acceptClass (String name, byte[] bytes);
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java
new file mode 100644
index 000000000..a7cd1ed74
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/tools/WeavingAdaptor.java
@@ -0,0 +1,332 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 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: 
+ *     Matthew Webster, Adrian Colyer, 
+ *     Martin Lippert     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.weaver.tools;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.StringTokenizer;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+
+import org.aspectj.bridge.AbortException;
+import org.aspectj.bridge.IMessage;
+import org.aspectj.bridge.IMessageHandler;
+import org.aspectj.bridge.MessageHandler;
+import org.aspectj.bridge.IMessage.Kind;
+import org.aspectj.util.FileUtil;
+import org.aspectj.weaver.IClassFileProvider;
+import org.aspectj.weaver.IWeaveRequestor;
+import org.aspectj.weaver.ResolvedTypeX;
+import org.aspectj.weaver.bcel.BcelObjectType;
+import org.aspectj.weaver.bcel.BcelWeaver;
+import org.aspectj.weaver.bcel.BcelWorld;
+import org.aspectj.weaver.bcel.LazyClassGen;
+import org.aspectj.weaver.bcel.UnwovenClassFile;
+
+/**
+ * This adaptor allows the AspectJ compiler to be embedded in an existing
+ * system to facilitate load-time weaving. It provides an interface for a
+ * weaving class loader to provide a classpath to be woven by a set of
+ * aspects. A callback is supplied to allow a class loader to define classes
+ * generated by the compiler during the weaving process.
+ * <p>
+ * A weaving class loader should create a <code>WeavingAdaptor</code> before
+ * any classes are defined, typically during construction. The set of aspects 
+ * passed to the adaptor is fixed for the lifetime of the adaptor although the
+ * classpath can be augmented. A system property can be set to allow verbose
+ * weaving messages to be written to the console.
+ *
+ */
+public class WeavingAdaptor {
+
+	/**
+	 * System property used to turn on verbose weaving messages 
+	 */
+	public static final String WEAVING_ADAPTOR_VERBOSE = "aj.weaving.verbose"; 
+
+	private boolean enabled = true;
+	private boolean verbose = getVerbose();
+	private BcelWorld bcelWorld = null;
+	private BcelWeaver weaver = null;
+	private IMessageHandler messageHandler = null;
+	private GeneratedClassHandler generatedClassHandler;
+	private Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */ 
+
+	/**
+	 * Construct a WeavingAdaptor with a reference to a weaving class loader. The
+	 * adaptor will automatically search the class loader hierarchy to resolve
+	 * classes. The adaptor will also search the hierarchy for WeavingClassLoader
+	 * instances to determine the set of aspects to be used ofr weaving. 
+     * @param loader instance of <code>ClassLoader</code>
+	 */
+	public WeavingAdaptor (WeavingClassLoader loader) {
+//		System.err.println("? WeavingAdaptor.<init>(" + loader +"," + aspectURLs.length + ")");
+		generatedClassHandler = loader;
+		init(getFullClassPath((ClassLoader)loader),getFullAspectPath((ClassLoader)loader/*,aspectURLs*/));
+	}
+
+	/**
+	 * Construct a WeavingAdator with a reference to a
+	 * <code>GeneratedClassHandler</code>, a full search path for resolving 
+	 * classes and a complete set of aspects. The search path must include
+	 * classes loaded by the class loader constructing the WeavingAdaptor and
+	 * all its parents in the hierarchy.   
+	 * @param handler <code>GeneratedClassHandler</code>
+     * @param classURLs the URLs from which to resolve classes
+     * @param aspectURLs the aspects used to weave classes defined by this class loader
+	 */
+	public WeavingAdaptor (GeneratedClassHandler handler, URL[] classURLs, URL[] aspectURLs) {
+//		System.err.println("? WeavingAdaptor.<init>()");
+		generatedClassHandler = handler;
+		init(FileUtil.makeClasspath(classURLs),FileUtil.makeClasspath(aspectURLs));
+	}
+	
+	private List getFullClassPath (ClassLoader loader) {
+		List list = new LinkedList();
+		for (; loader != null; loader = loader.getParent()) {
+			if (loader instanceof URLClassLoader) {
+				URL[] urls = ((URLClassLoader)loader).getURLs();
+				list.addAll(0,FileUtil.makeClasspath(urls));
+			}
+			else {
+				if (verbose) System.err.println("WeavingAdaptor: Warning - could not determine classpath for " + loader); 
+			}
+		}
+
+		list.addAll(0,makeClasspath(System.getProperty("sun.boot.class.path")));
+
+		return list;
+	}
+	
+	private List getFullAspectPath (ClassLoader loader) {
+		List list = new LinkedList();
+		for (; loader != null; loader = loader.getParent()) {
+			if (loader instanceof WeavingClassLoader) {
+				URL[] urls = ((WeavingClassLoader)loader).getAspectURLs();
+				list.addAll(0,FileUtil.makeClasspath(urls));
+			}
+		}
+
+		return list;
+	}
+	
+	private static boolean getVerbose () {
+		return Boolean.getBoolean(WEAVING_ADAPTOR_VERBOSE);
+	}
+	
+	private void init(List classPath, List aspectPath) {
+		if (verbose) System.out.println("WeavingAdaptor: classPath='" + classPath + "'");
+		
+		// make sure the weaver can find all types...
+		messageHandler = new MessageHandler();
+		bcelWorld = new BcelWorld(classPath,messageHandler,null);
+		bcelWorld.setXnoInline(false);
+		bcelWorld.getLint().loadDefaultProperties();
+
+		weaver = new BcelWeaver(bcelWorld);
+		registerAspectLibraries(aspectPath);
+	}
+	
+	/**
+	 * Appends URL to path used by the WeavingAdptor to resolve classes
+	 * @param url to be appended to search path
+	 */
+	public void addURL(URL url) {
+		try {
+			weaver.addLibraryJarFile(new File(url.getPath()));
+		}
+		catch (IOException ex) {
+		}
+	}
+
+	/**
+	 * Weave a class using aspects previously supplied to the adaptor.
+	 * @param name the name of the class
+	 * @param bytes the class bytes
+	 * @return the woven bytes
+     * @exception IOException weave failed
+	 */
+	public byte[] weaveClass (String name, byte[] bytes) throws IOException {
+		if (shouldWeave(name)) {
+			bytes = getWovenBytes(name, bytes);
+		}
+		return bytes;
+	}
+
+	private boolean shouldWeave (String name) {
+		name = name.replace('/','.');
+		boolean b = (enabled && !generatedClasses.containsKey(name) && shouldWeaveName(name) && shouldWeaveAspect(name));
+		if (verbose) System.out.println("WeavingAdaptor: shouldWeave('" + name + "') " + b);
+		return b;
+	}
+	
+	private boolean shouldWeaveName (String name) {
+		return !((name.startsWith("org.apache.bcel.") || name.startsWith("org.aspectj.") || name.startsWith("java.") || name.startsWith("javax.")));
+	}
+	
+	private boolean shouldWeaveAspect (String name) {
+		ResolvedTypeX type = bcelWorld.resolve(name);
+		return (type == null || !type.isAspect());
+	}
+
+	/**
+	 * Weave a set of bytes defining a class. 
+	 * @param name the name of the class being woven
+	 * @param bytes the bytes that define the class
+	 * @return byte[] the woven bytes for the class
+	 * @throws IOException
+	 * @throws FileNotFoundException
+	 */
+	private byte[] getWovenBytes(String name, byte[] bytes) throws IOException {
+		WeavingClassFileProvider wcp = new WeavingClassFileProvider(name,bytes);
+		weaver.weave(wcp);
+		return wcp.getBytes();		
+		
+//		UnwovenClassFile unwoven = new UnwovenClassFile(name,bytes);
+//		
+//		// weave
+//		BcelObjectType bcelType = bcelWorld.addSourceObjectType(unwoven.getJavaClass());
+//		LazyClassGen woven = weaver.weaveWithoutDump(unwoven,bcelType);
+//		
+//		byte[] wovenBytes = woven != null ? woven.getJavaClass(bcelWorld).getBytes() : bytes;
+//		return wovenBytes;
+	}
+	
+	private void registerAspectLibraries(List aspectPath) {
+//		System.err.println("? WeavingAdaptor.registerAspectLibraries(" + aspectPath + ")");
+		for (Iterator i = aspectPath.iterator(); i.hasNext();) {
+			String lib = (String)i.next();
+			File libFile = new File(lib);
+			if (libFile.isFile() && lib.endsWith(".jar")) {
+				try {
+					if (verbose) System.out.println("WeavingAdaptor: adding aspect '" + lib + "' to weaver");
+					addAspectLibrary(new File(lib));
+				} catch (IOException ioEx) {
+					if (verbose) System.err.println(
+						"WeavingAdaptor: Warning - could not load aspect path entry " 
+						+ lib + " : " + ioEx);
+				}
+			} else {
+				if (verbose) System.err.println(
+					"WeavingAdaptor: Warning - ignoring aspect path entry: " + lib);
+			}
+		}
+		
+		weaver.prepareForWeave();
+	}
+
+	/*
+	 * Register an aspect library with this classloader for use during
+	 * weaving. This class loader will also return (unmodified) any of the
+	 * classes in the library in response to a <code>findClass()</code> request.
+	 * The library is not required to be on the weavingClasspath given when this
+	 * classloader was constructed. 
+	 * @param aspectLibraryJarFile a jar file representing an aspect library
+	 * @throws IOException
+	 */
+	private void addAspectLibrary(File aspectLibraryJarFile) throws IOException {
+		weaver.addLibraryJarFile(aspectLibraryJarFile);
+//		weaver.prepareForWeave();
+	}
+	
+	private static List makeClasspath(String cp) {
+		List ret = new ArrayList();
+		if (cp != null) {
+			StringTokenizer tok = new StringTokenizer(cp,File.pathSeparator);
+			while (tok.hasMoreTokens()) {
+				ret.add(tok.nextToken());
+			}
+		}
+		return ret;
+	}
+
+	/**
+	 * Processes messages arising from weaver operations. 
+	 * Tell weaver to abort on any non-informational error.
+	 */
+	private class MessageHandler implements IMessageHandler {
+
+		public boolean handleMessage(IMessage message) throws AbortException {
+			if (!isIgnoring(message.getKind())) {
+				if (verbose) System.err.println(message.getMessage());
+				throw new AbortException(message);
+			}
+			return true;
+		}
+
+		public boolean isIgnoring(Kind kind) {
+			return ((kind == IMessage.INFO) || (kind == IMessage.DEBUG));
+		}
+	}
+
+	private class WeavingClassFileProvider implements IClassFileProvider {
+
+		private List unwovenClasses = new ArrayList(); /* List<UnovenClassFile> */
+		private UnwovenClassFile wovenClass;
+
+		public WeavingClassFileProvider (String name, byte[] bytes) {
+			UnwovenClassFile unwoven = new UnwovenClassFile(name,bytes);
+			unwovenClasses.add(unwoven);
+			bcelWorld.addSourceObjectType(unwoven.getJavaClass());
+		}
+
+		public byte[] getBytes () {
+			return wovenClass.getBytes();
+		}
+
+		public Iterator getClassFileIterator() {
+			return unwovenClasses.iterator();
+		}
+
+		public IWeaveRequestor getRequestor() {
+			return new IWeaveRequestor() {
+
+				public void acceptResult(UnwovenClassFile result) {
+					if (wovenClass == null) {
+						wovenClass = result;
+					}
+					
+					/* Classes generated by weaver e.g. around closure advice */
+					else {
+						String className = result.getClassName();
+						generatedClasses.put(className,result);
+						generatedClassHandler.acceptClass(className,result.getBytes());
+					}
+				}
+
+				public void processingReweavableState() {	}
+
+				public void addingTypeMungers() {}
+
+				public void weavingAspects() {}
+
+				public void weavingClasses() {}
+
+				public void weaveCompleted() {}
+			};				
+		}
+	}
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/WeavingClassLoader.java b/weaver/src/org/aspectj/weaver/tools/WeavingClassLoader.java
new file mode 100644
index 000000000..045cd6c8b
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/tools/WeavingClassLoader.java
@@ -0,0 +1,31 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 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: 
+ *     Matthew Webster, Adrian Colyer, 
+ *     Martin Lippert     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.weaver.tools;
+
+import java.net.URL;
+
+/**
+ * An interface for weaving class loaders to provide callbacks for a
+ * WeavingAdaptor.
+ */
+public interface WeavingClassLoader extends GeneratedClassHandler {
+	
+	/**
+	 * Returns the aspects to be used by a WeavingAdaptor to weave classes
+	 * defined by the class loader.
+	 * @return the aspects used for weaving classes.
+	 */
+	public URL[] getAspectURLs ();
+
+}
diff --git a/weaver/src/org/aspectj/weaver/tools/package.html b/weaver/src/org/aspectj/weaver/tools/package.html
new file mode 100644
index 000000000..b996ebb69
--- /dev/null
+++ b/weaver/src/org/aspectj/weaver/tools/package.html
@@ -0,0 +1,7 @@
+<html>
+<body>
+Provides a set of interfaces to allow a class loader to perform
+load-time weaving.
+
+</body>
+</html>
diff --git a/weaver/testdata/dummyAspect.jar b/weaver/testdata/dummyAspect.jar
index 321efc4e4..6bc31ed85 100644
Binary files a/weaver/testdata/dummyAspect.jar and b/weaver/testdata/dummyAspect.jar differ
diff --git a/weaver/testdata/ltw-acaspects.jar b/weaver/testdata/ltw-acaspects.jar
new file mode 100644
index 000000000..c49320821
Binary files /dev/null and b/weaver/testdata/ltw-acaspects.jar differ
diff --git a/weaver/testdata/ltw-aspects.jar b/weaver/testdata/ltw-aspects.jar
new file mode 100644
index 000000000..428c2b156
Binary files /dev/null and b/weaver/testdata/ltw-aspects.jar differ
diff --git a/weaver/testdata/ltw-classes.jar b/weaver/testdata/ltw-classes.jar
new file mode 100644
index 000000000..f74d613b7
Binary files /dev/null and b/weaver/testdata/ltw-classes.jar differ
diff --git a/weaver/testdata/ltw-itdaspects.jar b/weaver/testdata/ltw-itdaspects.jar
new file mode 100644
index 000000000..0870a4a73
Binary files /dev/null and b/weaver/testdata/ltw-itdaspects.jar differ
diff --git a/weaver/testdata/ltw-peraspects.jar b/weaver/testdata/ltw-peraspects.jar
new file mode 100644
index 000000000..071d2bbfa
Binary files /dev/null and b/weaver/testdata/ltw-peraspects.jar differ
diff --git a/weaver/testdata/ltw-woven.jar b/weaver/testdata/ltw-woven.jar
new file mode 100644
index 000000000..b0b6368f4
Binary files /dev/null and b/weaver/testdata/ltw-woven.jar differ
diff --git a/weaver/testdata/megatrace.jar b/weaver/testdata/megatrace.jar
index 31c8d0dc2..aff5ffe96 100644
Binary files a/weaver/testdata/megatrace.jar and b/weaver/testdata/megatrace.jar differ
diff --git a/weaver/testdata/megatrace0easy.jar b/weaver/testdata/megatrace0easy.jar
index a7499e84d..97c8081aa 100644
Binary files a/weaver/testdata/megatrace0easy.jar and b/weaver/testdata/megatrace0easy.jar differ
diff --git a/weaver/testdata/megatrace0hard.jar b/weaver/testdata/megatrace0hard.jar
index 114217106..583926b3f 100644
Binary files a/weaver/testdata/megatrace0hard.jar and b/weaver/testdata/megatrace0hard.jar differ
diff --git a/weaver/testdata/megatraceNoweave.jar b/weaver/testdata/megatraceNoweave.jar
index f51ebb94f..8d454e6a2 100644
Binary files a/weaver/testdata/megatraceNoweave.jar and b/weaver/testdata/megatraceNoweave.jar differ
diff --git a/weaver/testdata/tracing.jar b/weaver/testdata/tracing.jar
index 93f0d578a..2c8cafbcc 100644
Binary files a/weaver/testdata/tracing.jar and b/weaver/testdata/tracing.jar differ
diff --git a/weaver/testsrc/BcweaverModuleTests.java b/weaver/testsrc/BcweaverModuleTests.java
index 82ea4979f..4e8ff7a79 100644
--- a/weaver/testsrc/BcweaverModuleTests.java
+++ b/weaver/testsrc/BcweaverModuleTests.java
@@ -21,7 +21,7 @@ public class BcweaverModuleTests extends TestCase {
         TestSuite suite = new TestSuite(BcweaverModuleTests.class.getName());
         suite.addTest(org.aspectj.weaver.bcel.BcelTests.suite()); 
         suite.addTest(org.aspectj.weaver.BcweaverTests.suite()); 
-        suite.addTest(org.aspectj.weaver.patterns.PatternsTests.suite()); 
+		suite.addTest(org.aspectj.weaver.patterns.PatternsTests.suite()); 
         suite.addTestSuite(LocaleTest.class);
         return suite;
     }
diff --git a/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java b/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java
index 35e7c5473..e2e58a36c 100644
--- a/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java
+++ b/weaver/testsrc/org/aspectj/weaver/BcweaverTests.java
@@ -16,6 +16,7 @@ package org.aspectj.weaver;
 import java.io.File;
 
 import org.aspectj.util.FileUtil;
+import org.aspectj.weaver.tools.*;
 
 import junit.framework.*;
 
@@ -49,7 +50,8 @@ public class BcweaverTests extends TestCase {
         //suite.addTestSuite(AbstractWorldTestCase.class); 
         //$JUnit-BEGIN$
         suite.addTestSuite(MemberTestCase.class); 
-        suite.addTestSuite(TypeXTestCase.class); 
+		suite.addTestSuite(TypeXTestCase.class); 
+		suite.addTestSuite(WeavingURLClassLoaderTest.class); 
         //$JUnit-END$
         return suite;
     }
diff --git a/weaver/testsrc/org/aspectj/weaver/WeavingURLClassLoaderTest.java b/weaver/testsrc/org/aspectj/weaver/WeavingURLClassLoaderTest.java
new file mode 100644
index 000000000..41f9b56ab
--- /dev/null
+++ b/weaver/testsrc/org/aspectj/weaver/WeavingURLClassLoaderTest.java
@@ -0,0 +1,301 @@
+/* *******************************************************************
+ * Copyright (c) 2004 IBM Corporation
+ * 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: 
+ *     Matthew Webster     initial implementation 
+ * ******************************************************************/
+
+package org.aspectj.weaver;
+
+import java.io.File;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.aspectj.bridge.AbortException;
+import org.aspectj.util.FileUtil;
+import org.aspectj.weaver.tools.WeavingAdaptor;
+
+/**
+ * @author websterm
+ *
+ * To change the template for this generated type comment go to
+ * Window>Preferences>Java>Code Generation>Code and Comments
+ */
+public class WeavingURLClassLoaderTest extends TestCase {
+
+	private final static String CLASSES_JAR = BcweaverTests.TESTDATA_PATH + "/ltw-classes.jar";
+	private final static String WOVEN_JAR = BcweaverTests.TESTDATA_PATH + "/ltw-woven.jar";
+	private final static String JUNK_JAR = BcweaverTests.TESTDATA_PATH + "/ltw-junk.jar";
+	private final static String ADVICE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-aspects.jar";
+	private final static String AROUNDCLOSURE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-acaspects.jar";
+	private final static String ITD_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-itdaspects.jar";
+	private final static String PER_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-peraspects.jar";
+
+
+	public WeavingURLClassLoaderTest(String name) {
+		super(name);
+		System.setProperty(WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE,"true");
+	}
+
+	public void testLoadClass () {
+		System.setProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,"");
+		System.setProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,CLASSES_JAR);
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] {}); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testLoadWovenClass () {
+		System.setProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,"");
+		System.setProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,WOVEN_JAR);
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWAspect" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testWeaveWovenClass () {
+		System.setProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
+		System.setProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + WOVEN_JAR);
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			fail("Expecting org.aspectj.bridge.AbortException");
+		}
+		catch (Exception ex) {
+			assertTrue("Expecting org.aspectj.bridge.AbortException caught " + ex,(ex instanceof AbortException));
+		}
+	}
+
+	public void testWeavingURLClassLoader () {
+		URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
+		URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
+		URL[] classURLs = new URL[] { aspects, classes };
+		URL[] aspectURLs = new URL[] { aspects };
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWAspect" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testWeaveAdvice () {
+		System.setProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
+		System.setProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR);
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWAspect" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testWeaveAroundClosure () {
+		System.setProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,AROUNDCLOSURE_ASPECTS);
+		System.setProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,AROUNDCLOSURE_ASPECTS + File.pathSeparator + CLASSES_JAR);
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWAroundClosure" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testWeavingITD () {
+		URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
+		URL aspects = FileUtil.getFileURL(new File(ITD_ASPECTS));
+		URL[] classURLs = new URL[] { aspects, classes };
+		URL[] aspectURLs = new URL[] { aspects };
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			/* Uncomment when bug #55341 fixed */
+//			invokeMain(clazz,new String[] { "LTWInterfaceITD", "LTWFieldITD", "LTWMethodITD" }); 
+			invokeMain(clazz,new String[] { "LTWInterfaceITD", "LTWFieldITD" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testWeavingPer () {
+		URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
+		URL aspects = FileUtil.getFileURL(new File(PER_ASPECTS));
+		URL[] classURLs = new URL[] { aspects, classes };
+		URL[] aspectURLs = new URL[] { aspects };
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWPerthis" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testWeavingAspects () {
+		URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
+		URL aspects1 = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
+		URL aspects2 = FileUtil.getFileURL(new File(AROUNDCLOSURE_ASPECTS));
+		URL aspects3 = FileUtil.getFileURL(new File(ITD_ASPECTS));
+		URL aspects4 = FileUtil.getFileURL(new File(PER_ASPECTS));
+		URL[] classURLs = new URL[] {  aspects1, aspects2, aspects3, aspects4, classes };
+		URL[] aspectURLs = new URL[] { aspects1, aspects2, aspects3, aspects4 };
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			/* Uncomment when bug #55341 fixed */
+//			invokeMain(clazz,new String[] { "LTWAspect", "LTWAroundClosure", "LTWPerthis", "LTWInterfaceITD", "LTWFieldITD", "LTWMethodITD", "LTWPerthis"}); 
+			invokeMain(clazz,new String[] { "LTWAspect", "LTWAroundClosure", "LTWPerthis", "LTWInterfaceITD", "LTWFieldITD", "LTWPerthis"}); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testJunkJar () {		
+		File junkJar = new File(JUNK_JAR);
+		assertFalse(junkJar + " should not exist",junkJar.exists());
+		
+		URL classes = FileUtil.getFileURL(junkJar);
+		URL[] classURLs = new URL[] { classes };
+		URL[] aspectURLs = new URL[] { };
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			fail("Expecting java.lang.ClassNotFoundException");
+		}
+		catch (Exception ex) {
+			assertTrue("Expecting java.lang.ClassNotFoundException caught " + ex,(ex instanceof ClassNotFoundException));
+		}
+	}
+
+	public void testAddURL () {
+		URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
+		URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
+		URL[] classURLs = new URL[] { aspects };
+		URL[] aspectURLs = new URL[] { aspects };
+
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
+		loader.addURL(classes);
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWAspect" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public void testParentChild() {
+		URL classes = FileUtil.getFileURL(new File(CLASSES_JAR));
+		URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS));
+		
+		URL[] classURLs = new URL[] { aspects };
+		URL[] aspectURLs = new URL[] { aspects };
+		WeavingURLClassLoader parent = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader());
+		
+		classURLs = new URL[] { classes };
+		aspectURLs = new URL[] { };
+		WeavingURLClassLoader child = new WeavingURLClassLoader(classURLs,aspectURLs,parent);
+
+		try {
+			Class clazz = child.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWAspect" }); 
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	/*
+	 * Aspects on ASPECTPATH but missing from CLASSPATH
+	 */
+	public void testIncompletePath () {
+		System.setProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS);
+		System.setProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,CLASSES_JAR);
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("LTWHelloWorld");
+			invokeMain(clazz,new String[] { "LTWAspect" }); 
+			fail("Expecting java.lang.NoClassDefFoundError");
+		}
+		catch (Exception ex) {
+		}
+	}
+
+	/*
+	 * Ensure package object is correct
+	 */
+	public void testPackage () {
+		System.setProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,"");
+		System.setProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,CLASSES_JAR);
+		WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader());
+
+		try {
+			Class clazz = loader.loadClass("ltw.LTWPackageTest");
+			invokeMain(clazz,new String[] { }); 
+			Package pakkage = clazz.getPackage();
+			assertTrue("Expected 'ltw' got " + pakkage,(pakkage != null));
+		}
+		catch (Exception ex) {
+			fail(ex.toString());
+		}
+	}
+
+	public static void invokeMain (Class clazz, String[] args)
+	{
+		Class[] paramTypes = new Class[1];
+		paramTypes[0] = args.getClass();
+	
+		try {
+			Method method = clazz.getDeclaredMethod("main",paramTypes);
+			Object[] params = new Object[1];
+			params[0] = args;
+			method.invoke(null,params);
+		}
+		catch (InvocationTargetException ex) {
+			throw new RuntimeException(ex.getTargetException().toString());
+		}
+		catch (Exception ex) {
+			throw new RuntimeException(ex.toString());
+		}
+	}
+
+}
-- 
cgit v1.2.3