From 33d8ee9eededcd1219a6cbd1d063af005d40a3f7 Mon Sep 17 00:00:00 2001 From: acolyer Date: Fri, 2 Apr 2004 12:03:40 +0000 Subject: [PATCH] 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 ++ .../testdata/src1/LTWAspect.aj | 12 + .../testdata/src1/LTWFieldITD.aj | 16 + .../testdata/src1/LTWHelloWorld.java | 24 ++ .../testdata/src1/LTWInterfaceITD.aj | 18 + .../testdata/src1/LTWMethodITD.aj | 22 ++ .../testdata/src1/LTWPerthis.aj | 13 + .../testdata/src1/ltw/LTWPackageTest.java | 8 + .../compiler/batch/BcweaverJarMaker.java | 82 +++++ util/src/org/aspectj/util/FileUtil.java | 11 +- .../weaver/ExtensibleURLClassLoader.java | 87 +++++ .../aspectj/weaver/WeavingURLClassLoader.java | 123 +++++++ .../weaver/tools/GeneratedClassHandler.java | 29 ++ .../aspectj/weaver/tools/WeavingAdaptor.java | 332 ++++++++++++++++++ .../weaver/tools/WeavingClassLoader.java | 31 ++ .../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 +- .../org/aspectj/weaver/BcweaverTests.java | 4 +- .../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 @@ + description="javadoc for AspectJ lang, lang.reflect and org.aspectj.weaver.tools"> - + 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" /> 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 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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.() 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.(" + parent + ")"); + } + + public WeavingURLClassLoader (URL[] classURLs, URL[] aspectURLs, ClassLoader parent) { + super(classURLs,parent); +// System.err.println("? WeavingURLClassLoader.()"); + 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. + *

+ * A weaving class loader should create a WeavingAdaptor 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 ClassLoader + */ + public WeavingAdaptor (WeavingClassLoader loader) { +// System.err.println("? WeavingAdaptor.(" + loader +"," + aspectURLs.length + ")"); + generatedClassHandler = loader; + init(getFullClassPath((ClassLoader)loader),getFullAspectPath((ClassLoader)loader/*,aspectURLs*/)); + } + + /** + * Construct a WeavingAdator with a reference to a + * GeneratedClassHandler, 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 GeneratedClassHandler + * @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.()"); + 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 findClass() 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 */ + 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 @@ + + +Provides a set of interfaces to allow a class loader to perform +load-time weaving. + + + diff --git a/weaver/testdata/dummyAspect.jar b/weaver/testdata/dummyAspect.jar index 321efc4e49656d2cdb482a28e4365c207f7efd9c..6bc31ed856134b2dcea2c9db33bfa602fb0467c4 100644 GIT binary patch literal 819 zcmWIWW@Zs#-~hspX-x(UNI-;vg~8V~#8KDN&rRRg(a+P(H8@1i*X`da28PeRXHNTg z>*`(P_14uocjo-&AcHH$51tn3dHL#i`d%zuwI!%PN6*7o?_*HGx%0Xw&UorRdiv-o z6GMPEJIAIg;a!$Mi_C#I0H^hWKv|d4+}ujX;)2xV620V{#Ny)8pxFG&1|qg`m-1el zg&kvi!)my4!9nL$qPhG$ioUuw3z#mm-S%E`vha+@lw&6f4;^D}ntw!Ci2n~mok+o3 zv8bt!Ui|n~cjNh!SO0$ed~4mnFq_AFZ;`M`oqu-KaOMdllk2|y~&|jiu2XN!it+rHXP+CPq(RFG3idnr7ufP?0BXY__O}U z+|vcsZh0qehwhvx9#WL;c5`bm{br zcsaI{>n7w1ywXeRUY{^^)vPDBiQH2RW^qe4S8ld?qQUL-GkeR6If7cVElSx}CtnW~ zJ{WPhRQ!NPb8PrVw?E0IroYzh{8gGW;jND^%Y)4u_eFlX*2x-?Qh)TW!gt|C?+$NR zy~%rJ{}iLderY+r`!&}lU!DK>=I6beotOGr+^n8=OijR~apA<)&bMcsy5|;DncVSb zDCcl*x!%Ix(%*7^hv)9+jQbfu38Uj*VbCo`28JYNP{Lqj5@A53OyooZN|~qtS2{&E g1=$8r0z-g$AQL0G1$eWvfs`--VJncH!35#~0G;td>;M1& delta 567 zcmdnY_LPM;z?+#xgnh_HCj9W6Gr{5m^N+v-Z_Kh5B^;YIcYXT)EbMlKP3@y8Y`bWwv;KkEt=i+X3uXcpPcK8Ci9O*u9+`9=dQat%l7&1S(3aa z(e(uz9U^3p%&ZFKbq?JloVbc3yE&%oi;Kv{mB)R<>wCNpol5BX+OR=a=qBgY_B{b} zS9&hL{_*?#H$NAC;+(y^IWm>q?NnIYoa#f5gx?2sPSo0SI77sHS@D&rCSLz4Ctk2R zx7umd^ozcvSzrGn*RvwPc=xln&u4~(^X!ag zw%qzKf_v?q+%q5Bde1hVIrMYR^HrxOTA0bzAAe+S9rvjC=dP25t;yYcGp*TbxL5aN z6@P6Kt60FT7|K%g$}C0G``fGYH!S>bx~COn2`^4QA7p&c<*@AS0};&|Z$~8m>zu`A z|5|K+qi^58GrbJ;F|%H*p1l2_&H<&n9lK9IO=tPLobmshAB#d7@4vqLm5ZfevCXP#6zT(8cX@B>ovh3SXf7I4ami-5JfHynG whU*4d7a18CVwf2i0=yZSL>St<8 diff --git a/weaver/testdata/ltw-acaspects.jar b/weaver/testdata/ltw-acaspects.jar new file mode 100644 index 0000000000000000000000000000000000000000..c4932082150baa821444c15b33b28a99f6a7f4a4 GIT binary patch literal 2412 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 literal 0 HcmV?d00001 diff --git a/weaver/testdata/ltw-classes.jar b/weaver/testdata/ltw-classes.jar new file mode 100644 index 0000000000000000000000000000000000000000..f74d613b7d7d43dd06433b265f48d4c3d7132a4b GIT binary patch literal 1410 zcmWIWW@Zs#-~hr;X-x(UNI-;vg~8V~#8KDN&rRRg(a+P(H8@1i*X`da28PeRXHNTg z>*`(P_14uocjo-&AcHH$51tn3dHL#i`d%zuwI!%PN6*7o?_*HGx%0Xw&UorRdiv-o z6GMPEJIAIg;a!$Mi_C#I0H^iBKv|!VaF5iSoc!?oqMQ`HHdvd5AhzpwJ9e#oH4mW{zZG$wntpb z*7>)81;$ydYf@+qdepaA+|pU+eIn0YowVz*(KC+9IG^q@Xth2r;Iqt3(y9BJ-t`3v zYm``~I({zsWxKG^z=U`D1tCXW&!Wyg@1cCD<6NV%F4MZB{Zh3B|kdi=5ryxb35ZsW$tKNEm-pKmgn2& zj9lx2vo>vfa%EYY-wK(X6ei}!5oPv4a<0(}BR|EfN;D3L!_JBwj&%(G{Dhch-?#xrg~rG^$xOZ1|@2-^j} zZ0SbFOhvDNmvH1 zG#zk~ZG0=m_E|af4$rwd7qz>_`>ZCdRQkzRTe@WXYl*w(Y7STMeox|GHDg`Ux;A(F zdu$Q@zkd9kAHV!nb4t)OVYew$Zl82y7g}=H`_*KT^Ox@{#V)N)wOJ-CP&MmY;is!@ zoH~yw)6sJ>eK=Fz6(|G(&iQnw24?FDn07#QkV@TG1EVCv2(Dc1+4@PNeR?8Nlc zkksN5Xc74}mSDE_%3oR8<>t{K|W^7mgX<7Z| zi-k*ff9ZPGqV2`+3Z@zfCI9{*d3Wpb4n4H^mD{sV z@@M$Q_k|BaPqKqTkU8Uy(jQ>>bTWcMkdaA*0Z~99mmQ!23KifguFy?Ejw4Vxg8=nF kCYDkM-2h}Kf}#=uVwrJAY=Ac_8%QNH5S|6n^TF;10D!1EWB>pF literal 0 HcmV?d00001 diff --git a/weaver/testdata/ltw-itdaspects.jar b/weaver/testdata/ltw-itdaspects.jar new file mode 100644 index 0000000000000000000000000000000000000000..0870a4a73c00f18c174dcb9677f7ad996b5f133f GIT binary patch literal 3214 zcmaKuc{CL49>+(PEGhe5LiQ!H6Ov_YGZl55RgD>j6osfZxOi zU;=>59F3JN!RBW{#$ZcxGY3Z%koo=)0I&ff4ck~NtBi44D=WMtksBeZRQ0*V2o)=k zk|k&?8rKAYDXCb1RK7xBFUiUSBunLm#f8Nq06XiWtPNBblI5|T61{u2p zUZRuQZ+#%S9_(*t88HYMr_Xx_+zNk_(=87(u_4#=cpp3I-!%kOoK`^3ddPE_Ai1GB zq~X4V;KFqlZN+F{)s0RWA;P&1%7%3RtzH)e-;xTKbeEJ|O}wv}#Z*yCNRAuJqo{zQ zXE`^Z-4Es7xdzF^d*@r8 zd{k$Ue*Vt{ht>hJbFZH2*HLuC^oiV_wLC?OcY#Sy*aM+ByKA);PNG`fCd-G`kAa~g>d-E_#Koj|u7oA3rO z7S`QX-Xz*6Y>&U2IrmxSr-vE4WAq4CNM*qzh0Q)%8OfFSV%|uM;-9H zhlK0bg^pl>#|&`8aI01~U1Z}ES6|d?eu7)Mo!t0%#ps6#hDCajv~?1xm)qR*PJ&WQ zSh(I5uZbtQ@R=c711(dhq89!>;4u@!sZoL0@#fl|q3n)y&(EPx zBJwWkSV6AIwc;D^!e`iOj129_6Q*yOJgyg5I83G=lSYRvj1U8|xJ$YdKG<(1zhTQI zKO|@#yj3imt}&hhNAM0tE8o1N?>v1PnWhi?*$j{tg*dP)Eq`DP&5_&6+U7Dc&Z}mx z&qa;BWOuATjo%X$LL_Ebr(bVbn_ZKU;c?LpkK=VHZi`#hJ=gJQyJP(n4OJ|`b$=-! zyr7Ct>}V6!IH^3j%b}EMP|UEZ5pfw9(`CWzU^~IGRNyJO*~6ivbl79LABVNkm#WW_ zGmGsR3x=mO?puC}?2cz_F9_l=;4}=Q+=(HmZHZ!xuiGVC{p4V}*RnRKev>d;^^EL* z_I8z86V|~uCMKL+IFW|(W}=qWM?AUe8jF)-v)tUdYN?8!t;fXbukDs%bd#40$yo|< z%bMmHL@fbGig9uLk@&kkax|`|qLtz`%>1|GDIzDja10&kv1xkgu?8PK-#bZ6qSY$8 zUmFXiX=U4b3}Wd+MX=S$7817oz3z3?3^?O;7(8Z)vR?9eV0yNqcQ{7Zmxdm&w9k#f zx<+Q!yRTTt*s@_x#l20C#}u1-am86~-d+~Oc%|Qx+D$%EGerV(%}DN|mfbL4(#s%& z!Q)(y503m|aD9?#zcDia;LGv<7|i`|2Ac=_heH3u-%@8c2L~6veK^kmF+qrUrPGO; zz=|rs*_~yw*O1hF#0SbKhUS)R!oaZ&yo=gV)#N?qu$t)VBuyQ?SKkIx_frg;I zJP;2U&q%;=g|50Q^v?0tanIJcTR(mf$p98Re_Ec6ZI);^2~^de4elf?@N`&#M`k916{Q9D{`h8PfV4F3ls4ZP(4LQcIT{De}io^+0P2J}Ey#gmJ( zkM+DOg^_p7d#_wX3or5%Om^$*8NPtg;OmUf+%f0mj-TgyrcjbtyRoqu;%GKB;N}id zyRoXNn;mO?v_(r_bqq0KGW#TZ=e&gW=~B9cEfSn2f!r7wvRuD8x-qSsE!yG(;vOu^ zdruhvhXX&+=^^0*itV@xTyvc$B*R}`AV~+Dq97KC|IUek4N1`QqL{pd(7s%<-Bfp3 z;g*SD>zu(XXSo|-t{R~hYAN)Blh66v>P#ZGT8ejbaTkoz<}_Z~kE}y1FY!IykF{@g zNkwP}b;u0jIfR^9r5v3)CEPs2^Xi zCeqtd`MxtB@28-N@Sd!Z$^wiIs_oN;8&vk}!yhs2k5QGgXwNh1t!h}pH>r@+>XFkB zXws(aPEy)}-=eKZUZ@dyu?X`_gn+QWnN-M{KW)I`H80U~{B`J+=tfViW59#JxG@R$ zim8qFXHH_mzkj~s6icLHq&bpKV^}4t%xA=0r@dj6E{qrOGb+DhS5DE2@)UnMLPE3u z$7N{iViUYpQ9SWNVt`FzfyX6-tS`YU3gS}+Mw0R!3s7QP#Zq8k9QTG~&#b^vtF!ld z@u+-3sygs8eWl!AF~SB4T7^ZYX=`9VOe6{*>Ri~0`^Zw0dQV^NR^&**vXAqY>yM_U z5x{9vSYHrXbuTqIzs@{%rAD?ga8pgN ze)wA?$3>~z&i%?WN_NjR#`d&=Dm%u{@3R3<@%A+FKj^EjyD3YD3nH}HuI7qvmw<BJTyZZ=gOw2u~Keu%3@$Q{yf6GM`}2^cp`hztk|L zE^N;IK>Ls0EkiC>Djp@o0i9$r*PmgDNOJWx&>%JTUnSC$c+B0r1 zH_zdOq~jy-x~a?k)lbfM&ih9*dW&*A464Lqm2ZMJPhJv#TDIX_BJi_pSrH@t^BS%! z&{Pv6YpPhb$v&j86v}BsS<$|c-Ii@hTf)FrX)UD8@Im!eR)U%gu9i;6H#R!7NU3k} zrV2(zoW7zjDP`umlov2LSVq!7TQ^Y5noPD&!R{@K*`tHXmaQ>@rk~vQG_fmu_Bla` zX$?IC!Omu8oF~}lp8tZiO={lQ)k9dn{u9;=NB97LIriVp^e@N$cm0!px3m6xmfy$0 xFXR1};t!Ai(}w?dir<_3H8=heBg>yD{ys(QteFq50RYCs7&zRY9{vpg_!s3PwPyeT literal 0 HcmV?d00001 diff --git a/weaver/testdata/ltw-peraspects.jar b/weaver/testdata/ltw-peraspects.jar new file mode 100644 index 0000000000000000000000000000000000000000..071d2bbfa08d9715c35fce32e29c56387953fb6e GIT binary patch literal 1874 zcmWIWW@Zs#-~hr;X-x(UNI-;vg~8V~#8KDN&rRRg(a+P(H8@1i*X`da28PeRXHNTg z>*`(P_14uocjo-&AcHH$51tn3dHL#i`d%zuwI!%PN6*7o?_*HGx%0Xw&UorRdiv-o z6GMPEJIAIg;a!$Mi_C#I0H^iJKv|!V@PO2!l8nq^mBg%M-^}!k5|6~PRLA0i)Z`Mq z?x`JzeHz)hOu(9Nx)XFNzaS7#;m@WdSaxzzRK%DkDDD|>kMaCq)LqNC=Myj~SR@hZe$y^vx1~bekq&XlCcrz zJGOi|bhe-|{gR{Y>eHI*q*=X>R4D38=p8$K%R747&xZBVNi7fWthgkbT+se&x}=R^ zuy9?)#TzXAvm|akstP+JzU_MJ)+Ig?Oohg0dsFjXX2t(`5x7F)&qpJ-qI=6Xtm)>x zEOhXbV}ZenyK*AV&bNHq9!_9hqfn|Wb^UXZN?z3Lz`F&ok#yJfS%N;HXXmNKxao(^ zeqN;Hy?0OG%2y@%Oa4#UDm%&!_J_s?t&Ue{x?4Qb&`kV2=->yqaEqyshFxY9i zuE%!y#HH2_o!3@Q5?^mr(Vh8QFm$Es2Pw;YB1UN+Y&I@fd}`z0iGS`LdEFJ9FR(m| zZ|@FQyOVYE@`Zoi3t`B6tlM@iE33kBPEoP%YR#{nf8YK7Xm)ItVOM#_M7Br)-mI5L zFRZi*e-tt^i0Ar$_3s+d?wN_r9&y{Jh8ACl?q5FhNnBVS=ckhwf(>O&jEjFgn>I&n zYvJu<-I;B9rrx4imWh@J-*GzKlUl{~^0>~u++#eCrd(M$=b7*E_brhpvdYUZE2)*p671H-}z$GUv`P>Lf$0PMJBTn-d(=a{;S&U({1~s z_EG;mKJ9LoyT7WHSJ}Pb?iarLcJaQ#O4ARI6xZFcIB>c#oKL`tL6@EV5W9rcfe(W3 zc5DbbcI$bB*v3^?E!1+hBpxyFjN+`VM=Y2zQ>w{b&N#}WM{2eq=UMEATtTrIKslX-|v?()a$?|$5V;)4wD zJoR_#rhQi4eUlgBaNd1Sv&QB9`qls6-jYg{nv>?pTx@*X z+c}aq)#*yKU~J=gk1|iY^7$v%>U-`}`q}g(Fz~OSUD%nj-7~xEd<8CKCQ3Z(%9Nay zThgxLx5%t`jYx6tHvWxb(tbyMlKmsPmuUu1j`=jj`0(b*NzYSunw4kkCPo>BT6Wkh zKIt*5u4>7W6W+d&&(?lPSoO+kp@MGN_C~!)u9H+JF`Z1Fl<)CxN!Lei4RRd-s%TIFu4)I}6y)L+R9_%KJ&;L6 j?SXC}vXeojG6G~VA{z)PqXWEI*+43of$%DjP6zV0? literal 0 HcmV?d00001 diff --git a/weaver/testdata/ltw-woven.jar b/weaver/testdata/ltw-woven.jar new file mode 100644 index 0000000000000000000000000000000000000000..b0b6368f4cd5237da9d68b8940913b51c660722a GIT binary patch literal 2653 zcmaKuc{CJiAID{jLBv>wC`%YI29Y)UWH4eHMs*cg2H6KA!p$;_vPRL!ZVC}&h-4}I zl4)F9Ls^otj;(ALFXuh)xxM$i_x=9PbDrlp&vU-N-(R2ewYFek1u}6Q)|y)sl<5}% znOK<+rYJ)txD`wpVQ2-1nO;Fb5U~9oCZ=^nU$3Qw5`@NMp`_5?N3BLe2h}FO20+Xa zif{xisFZ^AQ-qiyAgf5feyUPeA6#kr>-1M&5W_##p?BM6OnI@ zK@%9DYvcvuW~^&Hu>!NC;K(g*+C)|R+CouX&*|hPlTORWtH{@`gx}!fCV06!`#($R zX3Loal0f~`%p_2sN*jBehR8J6a>a*ygCV}Sj=VVCa7mkHfJ3KNwl7TJ8i-CNN!#`O zOj;SVn5b)+j{-luEB6bjt-&;j`;0XR;*hAWbI{VxZQzht7~_?^jd{nnjF4+ z)g{7m{D}xL+aQpN5qh|71U zjG(106c?}jdH+LODAG4#=iAG8hX4o3dR1;g@1mloKnDY1k9reNpMg!?Jr=W!l6cU~ z0q(BQgwHx==yN{Sc{q-8E|xlrtVEjUoDAn2wAtW5rM6aJj39SuYniVj8f8?(9}CEN zbz88mc{(*+##9MU4I9lqmkB-tGWxjPzPd(|?_v@$ z#t?j0)4R)S1{clYxjQ2LD@aK3-z>Ue+BKZa2 zYuo@H*Ee5~XYB5sS^8M2$IqQ4Xj%MIC|Wtk-f;!9Cjb%>1|0&%Ci7(783hixKQlw(rKJjpNH^EHo-`nME%b|CA7 z*(E;-VI$4Bi}+xh3f-;L(5^B&>enNNdC| zmL=O+Me}M(<+^tp_VUEGo2eCcF;z>A$d$hx8dsTZjUh@EKSmy7kDo zzVQc3^I4VW>{k09MvbQ9z1jS7o$}zZPx|Y|BzfO;-NJuP3Azy+G_Q4Im^AbzILs;r z8{7_#2OGb4n0bEk4q+zvFHLAM1+-s&>BjYL{-jg|x;SfCV~3XpZuFsu6=l#ww|T_%r9&bo*|c#R zgk+h*wx`1)n=vILoyH_xmxY##p}~|AHS^T4_-eYnUY)RS${>-_3w`a4l@sg3y#eP( z?3ySatVXmQ7zO4P?7&s%_m$<%PnYjC)P?+RVL{suZ#%vT6+tXJh43<#oi;qr@9A`0 zuMC-S&E;BqgBoX5rBfp;r%%AaR2>Q`UiXAFY}P3A-K9Vr+BtoD0a&sVv~(+UPVmoW zi8BpA1fu|Zx;k=ztqgAd7z2sXy8GKR*$T$J6^KNWQQ1K~;|`0)qEqYq7i1jbgVp+R z_p9_v%WSha(Uv8NI-cC`+=`B=!=GMLiNiMKU8_+P)!d&|8BK10V00#_(Ot*Q#<*E# z2jIoj7m2ELJLOgIlE6y4&@?iP@JPP-?Q=;LgRs)WmSQzZMl%dadv%2IzR^6>aSlGWc0ejV`$nSbfy;Y^1HzXH_Sf{p#?1IuBx L9q!SbN4I|glXIj$ literal 0 HcmV?d00001 diff --git a/weaver/testdata/megatrace.jar b/weaver/testdata/megatrace.jar index 31c8d0dc2ce583999a6ff91e0187b97450cec67f..aff5ffe9642c30b42245d85aa920a907846eb584 100644 GIT binary patch literal 5285 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 delta 3373 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 diff --git a/weaver/testdata/megatrace0easy.jar b/weaver/testdata/megatrace0easy.jar index a7499e84d3012eca8aaea8e3f080b9193cf26d1e..97c8081aa81de8bd1bd36f6024397e1e63500976 100644 GIT binary patch delta 2767 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 z zXC-aL({=T-DOOSgo?jHNl1B6KVvehQD0o$04mk%5no|*YK~%(+Qt&HJQeFP z-Fv@u^0eRQtKQeQU`;rlpky+hG|s{juf3S1sXpoJH`c=S{^oNnbx& zPV*INR`r)aiu?xwA)fuKbrl~22PC%h=e9J#;vEaop#eV=X#*V_t(mq|O$+{)6Fz-H zk9f9?0tc%;t`Q2a!Bf?RwkUVZ_By=Mjz{U}#8Cz`>{g>+ubXnZu<#>6@}Fq)>l`zW z?t4*muf-LpUVe}3@%kH|OTuGgxW;&Mxs`<;J$0Udya|2T=>N`@JNLgWlQb``!UuA~cE(EjUXXLs)HF_E@b~`P+ z7;bQR!?h+tHjwui4P|hq6>XKqnHn?Oe;YZ;uw3@{a!YPR|cWk94aKc$( z1qtNx9JIIYgsD?VpPIFs_#>9!z`;v8_eyScI`FA<%2!4`H=uyiIm38b4;NW)CLG{I z{~AGtx5MUvm0ot_ofuG=DV%rFA4%?tfdW;AimkqkNJ&hHfJ@az-bN2ugCF<7`sXh- z^mu$b+o+BNSvcS3t7eQQt6*ULDIxOE?+Mg@TzN3 zv<#=x>Pl-5gO5Ull91Yx%RyyBqZ2=aYXZ#vXl|&80OQ;F9Gi>O4`A!g;o_&sg2y#d znPl7Ps2x?8upYFf$Mo0-LHibZHdN^Br3ZR+Ggk8TK1w;AIkCCDa$t?}hsv#VFZb_N zBL{O!RaaEBw)DTn2hX||DR-twWMJMWsF z0HZXX7w>X_W%$IilL8j$c3R@qj805Q3i&J=Ea5U&UY9(hx6)IakS$pY3Vrp^nWbEj z)r{xIGJP+SRpmkbTsnX0nMvv{F`lA!BvKn`0t)EixvlG{Y>PhuIzw9D9TOw~<`P zZ}_y;+ zxAiTLz7PyXkmFkLPlgF{N6^B@%SQ@1@78Nyc~!Sp;+V%QqY$HqF*}Hz0I+*n5x+m> z>~;u!YCcX=HN{lRWhJz8(fBZabX5u;eJ%2Eby*YGT)-$MYi{ChTrcj-7Wxzj$#_`rk+}gzjlVi}H+@ZQ4r^~&&gvJ)9WJX{G71w%3p}>$tvfVl0Zcw^x34 zH9XL%KrOU!x9OSiT&APK%QCFmu=`dt=XrN;Y}yvbJ6waCH9*+86ajfHaN;{+67dG% zJaLh*sGxk0Q+&@6V+LYz1Ak6c-Uk8z6fOYZ_u~Lz(Zs9r(C3=6Wkx^(GY9fX024w? z2PY37GfzAw*-}u@sC2H}TT5}Xce7>>!~>@Tgr%jGj7N?!%zSf*y+T4|sKN`odKYi1 zdj9FE`*8Gk`o1~=S|lP{vs6($Z-0B=O*vPygEZl%Y%@euc|?I&Y>N>)}7E%mI!POWYGl`wX*~8F%r1%%}1O0;3p+Y06gb+%zi4kfV`5rO!FW)F+IX zxvuLV;6oKtBWY0vejqDQ7klES&9v?_xOU@lq7e!x86itM)E1ldVpMP7+naPxU>wD+ z0==5IQA)dHaO=(e>>Et;LNoW+d!0vCA_$+Qv#2iP^4lV~u0(5hWt#^2uLZK*cOlNO z)!$E2a_s__`c2a)>(PmR>C`af7o^pq1;`4~og8qe!sZR3w|RJoHo}KSz5Da;cHudP zHM~%g;gihHh^Lri-F4v1_PTG!xA#j$08AMtoOugJlAqwS;dM==N09RI-C&f160BqtB9X9BT}R$mwNvC<=27{-#T&q-SbWV69=jI2S9**(zQ)(v9e#Q__ z&C|3n4zuSLcpp|5PeE^3j1xkCiUn+{SI-EU^2Eflm&930)%K?EJLoU=JB{JBOJxyI z7sQy~kHSQ->hN2i1#L;~BS2y=8XXv2)>~<|!e1LNvCI(#r&~jZ;~fZ`PED2D&#_IN zlNVpy>2cs|KI2thia^J<>v-1%J6t?PYJX#gWy`#QBvRk6ufs0qCjdVQqik$Au|FPm z=$JKZn9A7M#e^sLF0iHR%p{BJ_9s oVT5Bl8v_8a|0~3P!*f`l=12%(%z(d!1OS+R`OL4p%l1$8U)i&yzW@LL diff --git a/weaver/testdata/megatrace0hard.jar b/weaver/testdata/megatrace0hard.jar index 1142171060c6f1aa8cd49501c8d9f5bdb8e071b5..583926b3f14234435c264809ee1b73e88768aa37 100644 GIT binary patch delta 2668 zcmZ{mS5y<&7KW2Z525!G=}ibt1_eb45(yzlmtI6E()-XRL#gcVEZ0hUJo{Vr6?Zc02X*_eQ$kFXX5GcoTLc z5PW8!9EdU|NZeMyU^44t$XrdtOijSQCO$MhGBF@m$Yh%O3(`%_x6a74-nUKEP5;xh z_QZi+01rr7Xs!vAGM~^>E0xnK#p7q!1d#6GcDJG77m9_8E-;Hl%Ydn}Z0FT!3BqUl&G4>q_i#Wg>rgD~Ci@$i#&_U) zK^J}=yVfKKt>XXs; z92WZ3LLXSm;G!3&MQhGo($sV5_H2wY{ML<;y>a*t&qlH^$9oga)vRBNX){eTBdq2( zztrjB@+>Wi$zs)ABYl$D@z_k|sX#=mGbblC1c7}}+%M{ps&ZekPB^_a{7>egu}2BO z6+%QeOjx+qV3j*3nMGvXIchoHMa8X;H?|Vr|BM^hyIyy9>_t@@-%W9ko-aK@pCCBQ z9rpU%9{CNp^}dc}cDt{@q)Pypr0%qQwcsWY4wVQ=Bm3VO&mIEZ7wK&cv`+9x$e$Cs z5p;?H*mlNc_8Em2x+*{2$TcY`^l4kbHH>8#6N)pHG_j^2GmX_&Po<0$7G|O?NAbkw zH@@nSmfm0Xb77(N&y?ICvGfnxv+WqLAPYrSNv~?xwxM%_iYi%t%SU(+4*9kQ6RGq? ztlW>5>uL3QD-JkoMM*lMfRv)Q#)IiK)*mDZ7bOT5uxkTI7*74g__tOaq^Pk

_`5Xha-IvG5%1(m*JH<{J=;w8*TN#y>XL$E|N5F zF{p(6Fjy|8gx^7ITxs0NAxLv`V>e~uY$|%PQYM4;Mln_y4^uK_wso9TjH{e^y);a9 z7t)}gV1Jyl+a%d6`o1h%sHn_rW1Xsa>qZ*#58`pMfRJ_%jz15D%}FiKWJl7cXlj?1 zf|{R`Q+&9U?1Hroq?uFIQv;tCZ8YDK+ta_XSYtFPxF@ke$z(KgaM~?I2os;?my4jy zAHTNsn8RqGi%LJ|DwdhX2Us;WMhSb9Rmnw#W_H3}<>&!JNQD$RW4Q;u& zF<#p6wjzM;s~aq4Fr(CHM=l>g^>47X!)wGL#wo3~j~*hIl#=O5q7+ zd0SK-h26(e5-3==glh>;^Q}jc^$yPea0^k#P8Ee6W&ogp3-H}O&X_~q6&7{O+%0}X zo>R4TOGlM?y`aghQ2{$~8De_9bzq0?n}I zuWkp}&uxb!l;aO2+ocqZ$xFi?-TyJkGO2#8NLb1Do>od+-fTntniq#`TW@ybcIAM#(=oaBp5yd+ zg~uubNuj-+-i~>%O)zD;oSgi;%<3r0WS|j+gFqJ4HP+xnL@3mp&uG#aNTW?IKFkbU zbLuF#I0^F14=Y7nXtNCM}2csokJ`sy)6(v7-zf0fOJbx#3N2c^Xz zgCIeViyrYfu;q})G+#jN8w~jCqEmpVNTJdifuw%A7)c8w4b81^C^DM0*Ec?*vm+*A z`nX0S(zhz^x_iUD-e)6c`+8n$IQX$zB|pBB$UmR8?)J78?mu{>u+nr{&*7L!&F@1$ zR5~gcI17CsX*Q*@X)&5GJap*b~8ubriW9j9Zvy*KGYR{v~Ic`US~k~^$Y zUI}4eh}^B5WxeNQb~&^$g+{VcMCuMmAg^!U$`U(w0{XGpw`c!94%~ delta 2479 zcmZ8jX*3j!8Xkv_)mjzSKFPnx6HfIu?KGlSv6`-2btm*vc`Q zaxPk9Dm5XAR92Mpwgnc~PPsw5#K2$lI>%7+5Xo3bu#h$n8?G}6G5qt)jMh0m@p`89 zNn~j*jE0{7XF~q=xKsxs2*X8+hd=7d3|0bV0a# z)DTa9kXaE8?ozGd?({XKj;o|_FH>XJ3X9QcW76wu!y9W(7J+u^b0SQ#sjlyLOBWSJ zc`@wAxH@hUjCia$RL2lJwIkzT&|lnfdbR7=`z_;vw(i)yOr?I*`~9%RxUmc7+1om` z;~Xd9whMeWlZoVY$lbj0V?TV-Je0T@<)%?psUAJ-NxQh_-V}7uw+tb!2xhUDJ7_kX ze|g=$HMVACK91}Qo@TmYAhPV8Ue{7PyfTw8~MSi}l^u68O zYpSklsIlT&bU!=YX)H{LV|)IoGxqX%v_goEMT+*_zg6QGt_;}MLBpACY^C#y+mNJr zai_kL^~$UU2^(Bj%Z)OzNB7hu>|8qIfe>NO9T!iEpgYe&l8|-vr)_YwbW4x&Zc>?L z(3D;4zz;H!UKErkhrdMY{?jvwj4nG2Cw^@94S8c+!lU+ddk=`&qp%jV#Cv~YUi z1N`^v!-{-p0;#Dnwjd9^FPZ2mcRw$G0VUq-h~MKU;;QrAPx|^0g0JfD?j4LTo1z?f zPXJwMXTJl3UvRca_GlgNSd}NfperL#16ffmvQqkN_;RYH=`vSDqnC-6ER7#79 zt0qtHJqLYVvr3Flp-2AaYEr1r>+~|lP#*{B!FAGZA}^d25=_sdzx(;7kfQYW(wq;K zLVAJM8uoFvp?`CZj7bC-yH=i7Tv#lCxSkFmhM~%A5o!X{jjiDZ?7<7ue|;a$!=C!fA!lZFv%qsh zHw}9}4;IYc9Z`#rMIItk5hmXn&r>>&!uVTD*>r_M=a`$eAH*b|-my`e5LKC*oxocy zF)KEbQ!U4{?D|baGTmqhCQj_|LN?B(H#e<1XBeSBQb!LA->x9oXK~M@v~-Iio&O}7 zJlxCKBXUd$D(H#vpGzR95gG^~1QKB*QHqd9$nz531%@Zq0!Kj2M$M*?CXvWP!$bW; zVmeV1-HvB5M{#oPhWG8PvI7JFMW+CO-_L?Dmm>bwO+g)@;{=>nlQm74CF9YVy3(qp zYyrVaz7(*jF-#@JZTi%jYH-8*Tub=Y?p|kXJDa}1eMW~=G38lx5qwa_gE^ElxSOl& zf&aO`C8#aT3+XMUE2Ktrvq3AfZ#Am;Y1TV1afOSC zSMh%PG14}r+t(;Q{v}znm0|a?H{jiZ3EYbxg`85KsK#M)Gl_~cSBpM9Y4PlW&+=&9 z+gIHQMas88W6ihnA6IB(uM9S;%BIG774X_VfsN)teIMV3#~FdTtZ#PUy7gBW#7)(A z=ei6#UWd9qim2D%%si4mt&x~+EZKwT5X4`}^9*RacxnGm=54uLTF!CZicPJ=r|^1( zJ<4WH#m;A0gUPtMDj64oe2p4JxL-wtibMEOD-QOCeAP2v-$%iV*EFt}{KQwTIdvoM zh?2)070uHrE&>PVpDEb9R}fUDzIj|4&=y;A>&R)sQbB^3E9*wXqMgeey2@w=>468c zb|DQr{2XUf(I_nubZmqJxC16S`3w-H+C9lK(nJ*cTdDcg#$V`k2c98*=7kiTl!*#o zk!iWp#Jy29odysaw$VVd@Y=qFZQGe+?`4SY!-Mlki?c;3Pd-Y0fT?inxLqc|$!7j* z=DI0mdbubQ&zI}-K#QkmUaXj-it(X(QQpNw|5|LqQiIh{y8c%p3>&lW?1pi?Xr(g% zT*oXRv+C;EzVZu?VDxy;a9(?LhtH?{(--931T*{VH=LJ&%dT#xB4RjWFl?yCfu^@` z%#b%Ej9|vvI#@g5kd4uZ=4E*l%++`+>F0Brs0-|3p%X`~ZSA$E>`MA&{|>enRk H{ImTF&q0Q) diff --git a/weaver/testdata/megatraceNoweave.jar b/weaver/testdata/megatraceNoweave.jar index f51ebb94f1f8f95a7f03b5e44304763e5bcefc24..8d454e6a2d0f4e9519e236e1bd76388436cd3e4e 100644 GIT binary patch delta 2734 zcmZ`*XE+;-8jTsVwO6PbMU~jKKYK>fP#;BYRTL$5jokW-Ca6TTR?VUn#b>Kgs;C)J zBSy6$($6NOzPhTt`s3c)-sidR`@BESpL5L=i^9Axz8y0JgKG`6sIaei{J) zGXQGgXrgQbvs8haz-%lnt~-LEmfuDJfJ5l`m>onJJjD%BRwRs1Han=!XppH0uq{-{ z209gmZ*d4y0$W4DG>0(4r1J2%jq)mWmC6W!Lx5~eGtOw;Ga>D>h*>OlxI;uzLPFB;4F*Lhbdn=vupH=v+HKQj4w2IJAcq^QlY=UY zR(8~JpAkM>ROeOlR&}TnX4u*kQFDj$eGcxlIV%%m1q|E^i`(0Ge@#l!N>FR9zEkn= z^}s!QbOInACEhG6dZeGe;h*qYTAw|Ty`+@O*GSK;@x1#$QbdjFYQ#GHG=!zitDumFncV+yb&IbtIe6~Jle}IhFAq)MNmBtD8c?Bu<}tKfhc-5@bBdZ#~>4qRg(q{Mc|~=Mu&PGfmg!t-yj4{&~0RnNC)w zrRO$7bRyD(|9n4vuidlFOZzlkf~BRr*s@cjF}+1EAnBcOWolP#KVM%jRkFwPl3D^i z#tjNTye?-X>)fsRFcHP{kxbl@NS7qflUYla`cT|l=L`l$jwh<7I;+Z01cCb7GK}l8 zvdfX%Y%30gp(jtr2>1n&p%8$tPU>_^7YMj-fF$sAly!OsB;0or)W_+#g{xZ@Dsv>f zpt{9shi$~i?k(-t=B8Z9we#+@vyqIbO3A|6VeTkZ%eA3EelupiB)R!9=IAoUHnB`h z-JIo(rI4*+LL0{r7*v3!Ji<#}h%x$2`uN5%?S5g$N%#&bDH3zqbB+E~kVJFP?H#g4 zT7}PwZRN+Ou$QZCo3O2}8|MOs&}mcmh0zDR0a3<=RNjS|ZG@ zYwYEP2ZsH3xMsud1s63?vYrJ@@68+7EpC4C3MTW0>h9NCisr0e(a>@{s;{CPCC-pm zR>U5;X$2;Y}5fTPExG zuRU+>lwT;7MK%igH#4+VvL!`d%YZ|t)@A>;Xi)KicGeC7rFp^8gLi^1q42!R z!Ffk*+VBYF)r+$g*IVcuEiwJNok>uva2agSr+*RIs6nme7Ptw|L8o&^0+HajcY%YX zXM>BMBI9=H2g!jWejyQ`7IMYs)=v~KTi9365Gty&WJ5f0pS8~|Y)aWTelSCz%~N62 zXBG#7BiYPF=;F^gbga1z0oM&Z0FRu=mgamlKhPLyknQEwS)_iCZ}+F1|*+3;&CLa}=+06_9Nz*$uMluS5(_94!nFqT^w2WJ&Q?jSA;t~m^V z&=qaJyJZalwPamY?Z+;eS`#hRgVUoS%Tm*q^MIb2d$01p@F%R8>@z$?y*egmJ51W; zF;0Xcq6trq2{Es9^_!93lD@NF%y8pMbPac2t8Po_^6G~D=@jOg8^@EW&PBuP?;e*V z_4l}%p$zWMu$VQ$sUQQSGbKs49d3`nHOve!rSUR(3I}~S9MdYV`aaWeXSXZ&ooB!m z+x`0V&2u@!QbK^rv=u*JVU=I+&OrJ|#DYfy~fC@v2x#z|+gP7Lp%5Hk={5uhuay7kX z-hqi2`Ms76rL1#3U6)6RX3brGnMyS7p34rrDAmHu+y@#q>6G>Z-Tbs=xbUL6agreNl3!CT`f!@09?TEnnaR@S<6-Qhz2Z*te75ARwqVumG{rv8)T*<(Hb6LdR f@^$>d3ib{5j);ImSXh6kGM}vw0|3y@@dNz}Dnaff delta 2492 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 literal 2406 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 KVV~ss?fwBhlW3p- 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()); + } + } + +} -- 2.39.5