private IWeavingContext weavingContext; | private IWeavingContext weavingContext; | ||||
public ClassLoaderWeavingAdaptor(final ClassLoader loader, IWeavingContext wContext) { | public ClassLoaderWeavingAdaptor(final ClassLoader loader, IWeavingContext wContext) { | ||||
super(null); | |||||
this.weavingContext = wContext; | |||||
} | } | ||||
void initialize(final ClassLoader loader, IWeavingContext wContext) { | void initialize(final ClassLoader loader, IWeavingContext wContext) { | ||||
*/ | */ | ||||
private void registerDefinitions(final BcelWeaver weaver, final ClassLoader loader) { | private void registerDefinitions(final BcelWeaver weaver, final ClassLoader loader) { | ||||
try { | try { | ||||
MessageUtil.info(messageHandler, "register classloader " + ((loader!=null)?loader.getClass().getName()+"@"+loader.hashCode():"null")); | |||||
MessageUtil.info(messageHandler, "register classloader " + getClassLoaderName(loader)); | |||||
//TODO av underoptimized: we will parse each XML once per CL that see it | //TODO av underoptimized: we will parse each XML once per CL that see it | ||||
List definitions = new ArrayList(); | List definitions = new ArrayList(); | ||||
registerDump(weaver, loader, definitions); | registerDump(weaver, loader, definitions); | ||||
} else { | } else { | ||||
enabled = false;// will allow very fast skip in shouldWeave() | enabled = false;// will allow very fast skip in shouldWeave() | ||||
info("no configuration found. Disabling weaver for class loader " + getClassLoaderName(loader)); | |||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
weaver.getWorld().getMessageHandler().handleMessage( | weaver.getWorld().getMessageHandler().handleMessage( | ||||
} | } | ||||
} | } | ||||
private String getClassLoaderName (ClassLoader loader) { | |||||
return weavingContext.getClassLoaderName(); | |||||
} | |||||
/** | /** | ||||
* Configure the weaver according to the option directives | * Configure the weaver according to the option directives | ||||
* TODO av - don't know if it is that good to reuse, since we only allow a small subset of options in LTW | * TODO av - don't know if it is that good to reuse, since we only allow a small subset of options in LTW | ||||
allOptions.append(definition.getWeaverOptions()).append(' '); | allOptions.append(definition.getWeaverOptions()).append(' '); | ||||
} | } | ||||
Options.WeaverOption weaverOption = Options.parse(allOptions.toString(), loader); | |||||
Options.WeaverOption weaverOption = Options.parse(allOptions.toString(), loader, messageHandler); | |||||
// configure the weaver and world | // configure the weaver and world | ||||
// AV - code duplicates AspectJBuilder.initWorldAndWeaver() | // AV - code duplicates AspectJBuilder.initWorldAndWeaver() | ||||
for (Iterator aspects = definition.getAspectClassNames().iterator(); aspects.hasNext();) { | for (Iterator aspects = definition.getAspectClassNames().iterator(); aspects.hasNext();) { | ||||
String aspectClassName = (String) aspects.next(); | String aspectClassName = (String) aspects.next(); | ||||
if (acceptAspect(aspectClassName)) { | if (acceptAspect(aspectClassName)) { | ||||
info("register aspect " + aspectClassName); | |||||
ResolvedType aspect = weaver.addLibraryAspect(aspectClassName); | ResolvedType aspect = weaver.addLibraryAspect(aspectClassName); | ||||
if (aspect.isAbstract()) { | |||||
// this is a warning | |||||
weaver.getWorld().getMessageHandler().handleMessage( | |||||
new Message("Abstract aspect registered in aop.xml, use a <concrete-aspect> element instead", IMessage.WARNING, null, null) | |||||
); | |||||
} | |||||
//generate key for SC | //generate key for SC | ||||
if(namespace==null){ | if(namespace==null){ | ||||
namespace=new StringBuffer(aspectClassName); | namespace=new StringBuffer(aspectClassName); | ||||
if (acceptAspect(concreteAspect.name)) { | if (acceptAspect(concreteAspect.name)) { | ||||
ConcreteAspectCodeGen gen = new ConcreteAspectCodeGen(concreteAspect, weaver.getWorld()); | ConcreteAspectCodeGen gen = new ConcreteAspectCodeGen(concreteAspect, weaver.getWorld()); | ||||
if (!gen.validate()) { | if (!gen.validate()) { | ||||
weaver.getWorld().getMessageHandler().handleMessage( | |||||
new Message("Concrete-aspect '"+concreteAspect.name+"' could not be registered", IMessage.ERROR, null, null) | |||||
); | |||||
error("Concrete-aspect '"+concreteAspect.name+"' could not be registered"); | |||||
break; | break; | ||||
} | } | ||||
this.generatedClassHandler.acceptClass( | this.generatedClassHandler.acceptClass( |
*/ | */ | ||||
public class DefaultWeavingContext implements IWeavingContext { | public class DefaultWeavingContext implements IWeavingContext { | ||||
private ClassLoader loader; | |||||
protected ClassLoader loader; | |||||
public DefaultWeavingContext(){ | public DefaultWeavingContext(){ | ||||
loader = getClass().getClassLoader(); | loader = getClass().getClassLoader(); | ||||
return null; | return null; | ||||
} | } | ||||
/** | |||||
* @return classname@hashcode | |||||
*/ | |||||
public String getClassLoaderName() { | |||||
return ((loader!=null)?loader.getClass().getName()+"@"+loader.hashCode():"null"); | |||||
} | |||||
} | } |
* @return | * @return | ||||
*/ | */ | ||||
public String getBundleIdFromURL(URL url); | public String getBundleIdFromURL(URL url); | ||||
/** | |||||
* In an environment with multiple class loaders allows each to be | |||||
* identified using something safer and than toString | |||||
* @return name of the associated class loader | |||||
*/ | |||||
public String getClassLoaderName (); | |||||
} | } |
private static final String OPTIONVALUED_Xlint = "-Xlint:"; | private static final String OPTIONVALUED_Xlint = "-Xlint:"; | ||||
public static WeaverOption parse(String options, ClassLoader laoder) { | |||||
public static WeaverOption parse(String options, ClassLoader laoder, IMessageHandler imh) { | |||||
WeaverOption weaverOption = new WeaverOption(imh); | |||||
if (LangUtil.isEmpty(options)) { | if (LangUtil.isEmpty(options)) { | ||||
return new WeaverOption(); | |||||
return weaverOption; | |||||
} | } | ||||
// the first option wins | // the first option wins | ||||
List flags = LangUtil.anySplit(options, " "); | List flags = LangUtil.anySplit(options, " "); | ||||
Collections.reverse(flags); | Collections.reverse(flags); | ||||
WeaverOption weaverOption = new WeaverOption(); | |||||
// do a first round on the message handler since it will report the options themselves | // do a first round on the message handler since it will report the options themselves | ||||
for (Iterator iterator = flags.iterator(); iterator.hasNext();) { | for (Iterator iterator = flags.iterator(); iterator.hasNext();) { | ||||
String arg = (String) iterator.next(); | String arg = (String) iterator.next(); | ||||
String lint; | String lint; | ||||
String lintFile; | String lintFile; | ||||
public WeaverOption() { | |||||
messageHandler = new DefaultMessageHandler();//default | |||||
public WeaverOption(IMessageHandler imh) { | |||||
// messageHandler = new DefaultMessageHandler();//default | |||||
this.messageHandler = imh; | |||||
} | } | ||||
} | } | ||||
} | } |
public static final String WEAVING_ASPECT_PATH = "aj.aspect.path"; | public static final String WEAVING_ASPECT_PATH = "aj.aspect.path"; | ||||
private URL[] aspectURLs; | private URL[] aspectURLs; | ||||
private WeavingAdaptor adaptor; | |||||
private WeavingAdaptor adaptor; | |||||
private boolean initializingAdaptor; | |||||
private Map generatedClasses = new HashMap(); /* String -> byte[] */ | private Map generatedClasses = new HashMap(); /* String -> byte[] */ | ||||
/* | /* | ||||
*/ | */ | ||||
protected Class defineClass(String name, byte[] b, CodeSource cs) throws IOException { | protected Class defineClass(String name, byte[] b, CodeSource cs) throws IOException { | ||||
// System.err.println("? WeavingURLClassLoader.defineClass(" + name + ", [" + b.length + "])"); | // System.err.println("? WeavingURLClassLoader.defineClass(" + name + ", [" + b.length + "])"); | ||||
/* Need to defer creation because of possible recursion during constructor execution */ | |||||
if (adaptor == null) { | |||||
ClassLoaderWeavingAdaptor clwAdaptor = new ClassLoaderWeavingAdaptor(this,null); | |||||
clwAdaptor.initialize(this,null); | |||||
adaptor = clwAdaptor; | |||||
/* Avoid recursion during adaptor initialization */ | |||||
if (!initializingAdaptor) { | |||||
/* Need to defer creation because of possible recursion during constructor execution */ | |||||
if (adaptor == null && !initializingAdaptor) { | |||||
DefaultWeavingContext weavingContext = new DefaultWeavingContext (this) { | |||||
/* Ensures consistent LTW messages for testing */ | |||||
public String getClassLoaderName() { | |||||
return loader.getClass().getName(); | |||||
} | |||||
}; | |||||
ClassLoaderWeavingAdaptor clwAdaptor = new ClassLoaderWeavingAdaptor(this,weavingContext); | |||||
initializingAdaptor = true; | |||||
clwAdaptor.initialize(this,weavingContext); | |||||
initializingAdaptor = false; | |||||
adaptor = clwAdaptor; | |||||
} | |||||
b = adaptor.weaveClass(name,b); | |||||
} | } | ||||
b = adaptor.weaveClass(name,b); | |||||
return super.defineClass(name, b, cs); | return super.defineClass(name, b, cs); | ||||
} | } | ||||
} | } | ||||
} | } | ||||
/* | |||||
* We won't get an exception because the aspect path is empty and there is | |||||
* no aop.xml file so the weaver will be disabled and no reweaving will | |||||
* take place | |||||
*/ | |||||
public void testLoadWovenClass () { | public void testLoadWovenClass () { | ||||
setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,""); | setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,""); | ||||
setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,WOVEN_JAR); | setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,WOVEN_JAR); | ||||
} | } | ||||
} | } | ||||
/* | |||||
* We get an exception because the class was not built reweavable | |||||
*/ | |||||
public void testWeaveWovenClass () { | public void testWeaveWovenClass () { | ||||
setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS); | setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS); | ||||
setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + WOVEN_JAR); | setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + WOVEN_JAR); | ||||
fail("Expecting java.lang.NoClassDefFoundError"); | fail("Expecting java.lang.NoClassDefFoundError"); | ||||
} | } | ||||
catch (Exception ex) { | catch (Exception ex) { | ||||
assertTrue("Expecting java.lang.NoClassDefFoundError but caught " + ex,ex.getMessage().contains("java.lang.NoClassDefFoundError")); | |||||
} | } | ||||
} | } | ||||
method.invoke(null,params); | method.invoke(null,params); | ||||
} | } | ||||
catch (InvocationTargetException ex) { | catch (InvocationTargetException ex) { | ||||
throw new RuntimeException(ex.getTargetException().toString()); | |||||
Throwable targetException = ex.getTargetException(); | |||||
if (targetException instanceof RuntimeException) throw (RuntimeException)ex.getTargetException(); | |||||
else throw new RuntimeException(ex.getTargetException().toString()); | |||||
} | } | ||||
catch (Exception ex) { | catch (Exception ex) { | ||||
throw new RuntimeException(ex.toString()); | throw new RuntimeException(ex.toString()); |
URLClassLoader cLoader; | URLClassLoader cLoader; | ||||
if (useLTW) { | if (useLTW) { | ||||
cLoader = new WeavingURLClassLoader(urls,null); | |||||
ClassLoader parent = getClass().getClassLoader(); | |||||
cLoader = new WeavingURLClassLoader(urls,parent); | |||||
} | } | ||||
else { | else { | ||||
cLoader = new URLClassLoader(urls,null); | cLoader = new URLClassLoader(urls,null); | ||||
} catch (Exception ex) { | } catch (Exception ex) { | ||||
fail ("Unable to prepare org.aspectj.testing.Tester for test run: " + ex); | fail ("Unable to prepare org.aspectj.testing.Tester for test run: " + ex); | ||||
} | } | ||||
Class toRun = cLoader.loadClass(className); | |||||
Method mainMethod = toRun.getMethod("main",new Class[] {String[].class}); | |||||
System.setOut(new PrintStream(baosOut)); | System.setOut(new PrintStream(baosOut)); | ||||
System.setErr(new PrintStream(baosErr)); | System.setErr(new PrintStream(baosErr)); | ||||
Class toRun = cLoader.loadClass(className); | |||||
Method mainMethod = toRun.getMethod("main",new Class[] {String[].class}); | |||||
mainMethod.invoke(null,new Object[] {args}); | mainMethod.invoke(null,new Object[] {args}); | ||||
lastRunResult = new RunResult(command.toString(),new String(baosOut.toByteArray()),new String(baosErr.toByteArray())); | lastRunResult = new RunResult(command.toString(),new String(baosOut.toByteArray()),new String(baosErr.toByteArray())); | ||||
} catch(ClassNotFoundException cnf) { | } catch(ClassNotFoundException cnf) { |
useLtw = true; | useLtw = true; | ||||
} | } | ||||
catch (IOException ex) { | catch (IOException ex) { | ||||
ex.printStackTrace(); | |||||
AjcTestCase.fail(ex.toString()); | |||||
} | } | ||||
} | } | ||||
/******************************************************************************* | |||||
* Copyright (c) 2005 Contributors. | |||||
* All rights reserved. | |||||
* This program and the accompanying materials are made available | |||||
* under the terms of the Eclipse Public License v1.0 | |||||
* which accompanies this distribution and is available at | |||||
* http://eclipse.org/legal/epl-v10.html | |||||
* | |||||
* Contributors: | |||||
* Matthew Webster initial implementation | |||||
*******************************************************************************/ | |||||
import java.lang.reflect.*; | |||||
public abstract aspect AbstractAspect { | |||||
/* | |||||
* These should not take effect unless a concrete sub-aspect is defined | |||||
*/ | |||||
declare parents : TestITDMethod implements Runnable; | |||||
declare soft : InvocationTargetException : execution(public void TestITDMethod.*()); | |||||
declare warning : execution(public void main(..)) : | |||||
"AbstractAspect_main"; | |||||
/* | |||||
* This should always take effect | |||||
*/ | |||||
public void TestITDMethod.test () { | |||||
System.err.println("AbstractAspect_TestITDMethod.test"); | |||||
} | |||||
} |
/******************************************************************************* | |||||
* Copyright (c) 2005 Contributors. | |||||
* All rights reserved. | |||||
* This program and the accompanying materials are made available | |||||
* under the terms of the Eclipse Public License v1.0 | |||||
* which accompanies this distribution and is available at | |||||
* http://eclipse.org/legal/epl-v10.html | |||||
* | |||||
* Contributors: | |||||
* Matthew Webster initial implementation | |||||
*******************************************************************************/ | |||||
public abstract aspect AbstractSuperAspect { | |||||
protected abstract pointcut scope (); | |||||
before () : execution(void test1()) && scope() { | |||||
System.err.println("AbstractSuperAspect.before_" + thisJoinPoint.getSignature().getName()); | |||||
} | |||||
} |
* Contributors: | * Contributors: | ||||
* Matthew Webster initial implementation | * Matthew Webster initial implementation | ||||
*******************************************************************************/ | *******************************************************************************/ | ||||
import java.lang.reflect.Method; | |||||
import java.lang.reflect.Modifier; | |||||
public class Main { | public class Main { | ||||
System.out.println("Main.test2"); | System.out.println("Main.test2"); | ||||
} | } | ||||
public static void main (String[] args) { | |||||
public void invokeDeclaredMethods () throws Exception { | |||||
Method[] methods = getClass().getDeclaredMethods(); | |||||
for (int i = 0; i < methods.length; i++) { | |||||
Method method = methods[i]; | |||||
int modifiers = method.getModifiers(); | |||||
if (!Modifier.isStatic(modifiers) && !method.getName().equals("invokeDeclaredMethods")) { | |||||
method.invoke(this,new Object[] {}); | |||||
} | |||||
} | |||||
} | |||||
public static void main (String[] args) throws Exception { | |||||
System.out.println("Main.main"); | System.out.println("Main.main"); | ||||
new Main().test1(); | new Main().test1(); | ||||
new Main().test2(); | new Main().test2(); |
/******************************************************************************* | |||||
* Copyright (c) 2005 Contributors. | |||||
* All rights reserved. | |||||
* This program and the accompanying materials are made available | |||||
* under the terms of the Eclipse Public License v1.0 | |||||
* which accompanies this distribution and is available at | |||||
* http://eclipse.org/legal/epl-v10.html | |||||
* | |||||
* Contributors: | |||||
* Matthew Webster initial implementation | |||||
*******************************************************************************/ | |||||
import java.lang.reflect.Method; | |||||
import java.lang.reflect.Modifier; | |||||
public class TestITDMethod { | |||||
public void invokeDeclaredMethods (String[] names) throws Exception { | |||||
for (int i = 0; i < names.length; i++) { | |||||
Method method = getClass().getDeclaredMethod(names[i],new Class[] {}); | |||||
method.invoke(this,new Object[] {}); | |||||
} | |||||
} | |||||
public static void main (String[] args) throws Exception { | |||||
System.out.println("TestITDMethod.main"); | |||||
new TestITDMethod().invokeDeclaredMethods(args); | |||||
} | |||||
} |
/******************************************************************************* | |||||
* Copyright (c) 2005 Contributors. | |||||
* All rights reserved. | |||||
* This program and the accompanying materials are made available | |||||
* under the terms of the Eclipse Public License v1.0 | |||||
* which accompanies this distribution and is available at | |||||
* http://eclipse.org/legal/epl-v10.html | |||||
* | |||||
* Contributors: | |||||
* Matthew Webster initial implementation | |||||
*******************************************************************************/ | |||||
import java.lang.reflect.Method; | |||||
import java.lang.reflect.Modifier; | |||||
public class TestMain { | |||||
public static void main (String[] args) throws Exception { | |||||
Main.main(args); | |||||
} | |||||
} |
<aspectj> | |||||
<aspects> | |||||
<aspect name="AbstractAspect"/> | |||||
</aspects> | |||||
<weaver options="-showWeaveInfo -verbose"/> | |||||
</aspectj> | |||||
<aspectj> | |||||
<aspects> | |||||
<concrete-aspect name="ConcreteAspect" extends="AbstractSuperAspect"> | |||||
<pointcut name="scope" expression="within(Main)"/> | |||||
</concrete-aspect> | |||||
</aspects> | |||||
</aspectj> | |||||
package org.aspectj.systemtest.ajc150.ltw; | package org.aspectj.systemtest.ajc150.ltw; | ||||
import java.io.File; | import java.io.File; | ||||
import java.util.Enumeration; | |||||
import java.util.Properties; | |||||
import junit.framework.Test; | import junit.framework.Test; | ||||
import org.aspectj.testing.XMLBasedAjcTestCase; | import org.aspectj.testing.XMLBasedAjcTestCase; | ||||
import org.aspectj.weaver.tools.WeavingAdaptor; | |||||
public class LTWTests extends org.aspectj.testing.XMLBasedAjcTestCase { | public class LTWTests extends org.aspectj.testing.XMLBasedAjcTestCase { | ||||
public void testOutxmlJar (){ | public void testOutxmlJar (){ | ||||
runTest("Ensure valid aop.xml is generated for -outjar"); | runTest("Ensure valid aop.xml is generated for -outjar"); | ||||
} | } | ||||
public void testNoAopxml(){ | |||||
setSystemProperty(WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE,"true"); | |||||
runTest("Ensure no weaving without visible aop.xml"); | |||||
} | |||||
public void testDefineConcreteAspect(){ | |||||
runTest("Define concrete sub-aspect using aop.xml"); | |||||
} | |||||
public void testDeclareAbstractAspect(){ | |||||
// setSystemProperty(WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE,"true"); | |||||
// setSystemProperty(WeavingAdaptor.SHOW_WEAVE_INFO_PROPERTY,"true"); | |||||
runTest("Use abstract aspect for ITD using aop.xml"); | |||||
} | |||||
/* | |||||
* Allow system properties to be set and restored | |||||
* TODO maw move to XMLBasedAjcTestCase or RunSpec | |||||
*/ | |||||
private final static String NULL = "null"; | |||||
private Properties savedProperties; | |||||
protected void setSystemProperty (String key, String value) { | |||||
Properties systemProperties = System.getProperties(); | |||||
copyProperty(key,systemProperties,savedProperties); | |||||
systemProperties.setProperty(key,value); | |||||
} | |||||
private static void copyProperty (String key, Properties from, Properties to) { | |||||
String value = from.getProperty(key,NULL); | |||||
to.setProperty(key,value); | |||||
} | |||||
protected void setUp() throws Exception { | |||||
super.setUp(); | |||||
savedProperties = new Properties(); | |||||
} | |||||
protected void tearDown() throws Exception { | |||||
super.tearDown(); | |||||
/* Restore system properties */ | |||||
Properties systemProperties = System.getProperties(); | |||||
for (Enumeration enu = savedProperties.keys(); enu.hasMoreElements(); ) { | |||||
String key = (String)enu.nextElement(); | |||||
String value = savedProperties.getProperty(key); | |||||
if (value == NULL) systemProperties.remove(key); | |||||
else systemProperties.setProperty(key,value); | |||||
} | |||||
} | |||||
} | } | ||||
outjar="main1.jar" | outjar="main1.jar" | ||||
options="-showWeaveInfo" | options="-showWeaveInfo" | ||||
> | > | ||||
<message kind="weave" text="method-execution(void Main.test1())' in Type 'Main' (Main.java:15) advised by before advice from 'Aspect1' (Aspect1.aj:16)"/> | |||||
<message kind="weave" text="method-execution(void Main.test1())' in Type 'Main' (Main.java:17) advised by before advice from 'Aspect1' (Aspect1.aj:16)"/> | |||||
</compile> | </compile> | ||||
<compile | <compile | ||||
classpath="main1.jar" | classpath="main1.jar" | ||||
<line text="Main.test2"/> | <line text="Main.test2"/> | ||||
</stdout> | </stdout> | ||||
<stderr> | <stderr> | ||||
<line text="weaveinfo Join point 'method-execution(void Main.test1())' in Type 'Main' (Main.java:17) advised by before advice from 'Aspect1' (Aspect1.aj:16)"/> | |||||
<line text="weaveinfo Join point 'method-execution(void Main.test2())' in Type 'Main' (Main.java:21) advised by before advice from 'Aspect2' (Aspect2.aj:16)"/> | |||||
<line text="Aspect1.before_test1"/> | <line text="Aspect1.before_test1"/> | ||||
<line text="Aspect2.before_test2"/> | <line text="Aspect2.before_test2"/> | ||||
</stderr> | </stderr> | ||||
</run> | </run> | ||||
</ajc-test> | </ajc-test> | ||||
<ajc-test dir="ltw" | |||||
title="Ensure no weaving without visible aop.xml" | |||||
keywords="reweavable"> | |||||
<compile | |||||
files="TestMain.java, Main.java" | |||||
> | |||||
</compile> | |||||
<run class="TestMain" ltw=""> | |||||
<stdout> | |||||
<line text="Main.main"/> | |||||
<line text="Main.test1"/> | |||||
<line text="Main.test2"/> | |||||
</stdout> | |||||
<stderr> | |||||
<line text="info register classloader org.aspectj.weaver.loadtime.WeavingURLClassLoader"/> | |||||
<line text="info no configuration found. Disabling weaver for class loader org.aspectj.weaver.loadtime.WeavingURLClassLoader"/> | |||||
</stderr> | |||||
</run> | |||||
</ajc-test> | |||||
<ajc-test dir="ltw" | |||||
title="Define concrete sub-aspect using aop.xml" | |||||
keywords="aop.xml"> | |||||
<compile | |||||
files="Main.java" | |||||
outjar="main.jar" | |||||
> | |||||
</compile> | |||||
<compile | |||||
classpath="main1.jar" | |||||
files="AbstractSuperAspect.aj" | |||||
outjar="aspect.jar" | |||||
> | |||||
</compile> | |||||
<run class="Main" ltw="aop-defineaspect.xml"> | |||||
<stdout> | |||||
<line text="Main.main"/> | |||||
<line text="Main.test1"/> | |||||
<line text="Main.test2"/> | |||||
</stdout> | |||||
<stderr> | |||||
<line text="AbstractSuperAspect.before_test1"/> | |||||
</stderr> | |||||
</run> | |||||
</ajc-test> | |||||
<ajc-test dir="ltw" | |||||
title="Use abstract aspect for ITD using aop.xml" | |||||
keywords="abstract aspect, ITD"> | |||||
<compile | |||||
files="TestITDMethod.java" | |||||
> | |||||
</compile> | |||||
<compile | |||||
files="AbstractAspect.aj" | |||||
> | |||||
<message kind="warning" text="this affected type is not exposed to the weaver: TestITDMethod"/> | |||||
</compile> | |||||
<run class="TestITDMethod" options="test" ltw="aop-abstractaspect.xml"> | |||||
<stdout> | |||||
<line text="TestITDMethod.main"/> | |||||
</stdout> | |||||
<stderr> | |||||
<line text="weaveinfo Type 'TestITDMethod' (TestITDMethod.java) has intertyped method from 'AbstractAspect' (AbstractAspect.aj:'void TestITDMethod.test()')"/> | |||||
<line text="AbstractAspect_TestITDMethod.test"/> | |||||
</stderr> | |||||
</run> | |||||
</ajc-test> | |||||
protected GeneratedClassHandler generatedClassHandler; | protected GeneratedClassHandler generatedClassHandler; | ||||
protected Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */ | protected Map generatedClasses = new HashMap(); /* String -> UnwovenClassFile */ | ||||
protected WeavingAdaptor () { | |||||
createMessageHandler(); | |||||
} | |||||
/** | /** | ||||
* Construct a WeavingAdaptor with a reference to a weaving class loader. The | * Construct a WeavingAdaptor with a reference to a weaving class loader. The | ||||
* adaptor will automatically search the class loader hierarchy to resolve | * adaptor will automatically search the class loader hierarchy to resolve | ||||
} | } | ||||
private void init(List classPath, List aspectPath) { | private void init(List classPath, List aspectPath) { | ||||
messageHandler = new WeavingAdaptorMessageHandler(new PrintWriter(System.err)); | |||||
if (verbose) messageHandler.dontIgnore(IMessage.INFO); | |||||
if (Boolean.getBoolean(SHOW_WEAVE_INFO_PROPERTY)) messageHandler.dontIgnore(IMessage.WEAVEINFO); | |||||
createMessageHandler(); | |||||
info("using classpath: " + classPath); | info("using classpath: " + classPath); | ||||
info("using aspectpath: " + aspectPath); | info("using aspectpath: " + aspectPath); | ||||
weaver = new BcelWeaver(bcelWorld); | weaver = new BcelWeaver(bcelWorld); | ||||
registerAspectLibraries(aspectPath); | registerAspectLibraries(aspectPath); | ||||
} | } | ||||
private void createMessageHandler() { | |||||
messageHandler = new WeavingAdaptorMessageHandler(new PrintWriter(System.err)); | |||||
if (verbose) messageHandler.dontIgnore(IMessage.INFO); | |||||
if (Boolean.getBoolean(SHOW_WEAVE_INFO_PROPERTY)) messageHandler.dontIgnore(IMessage.WEAVEINFO); | |||||
} | |||||
/** | /** | ||||
* Appends URL to path used by the WeavingAdptor to resolve classes | * Appends URL to path used by the WeavingAdptor to resolve classes | ||||
return ret; | return ret; | ||||
} | } | ||||
private boolean info (String message) { | |||||
protected boolean info (String message) { | |||||
return MessageUtil.info(messageHandler,message); | return MessageUtil.info(messageHandler,message); | ||||
} | } | ||||
private boolean warn (String message) { | |||||
protected boolean warn (String message) { | |||||
return MessageUtil.warn(messageHandler,message); | return MessageUtil.warn(messageHandler,message); | ||||
} | } | ||||
private boolean error (String message) { | |||||
protected boolean error (String message) { | |||||
return MessageUtil.error(messageHandler,message); | return MessageUtil.error(messageHandler,message); | ||||
} | } | ||||