*/ | */ | ||||
public WeavingURLClassLoader (ClassLoader parent) { | public WeavingURLClassLoader (ClassLoader parent) { | ||||
this(getURLs(getClassPath()),getURLs(getAspectPath()),parent); | this(getURLs(getClassPath()),getURLs(getAspectPath()),parent); | ||||
// System.err.println("? WeavingURLClassLoader.<init>(" + m_parent + ")"); | |||||
// System.out.println("? WeavingURLClassLoader.WeavingURLClassLoader()"); | |||||
} | } | ||||
public WeavingURLClassLoader (URL[] urls, ClassLoader parent) { | public WeavingURLClassLoader (URL[] urls, ClassLoader parent) { | ||||
public WeavingURLClassLoader (URL[] classURLs, URL[] aspectURLs, ClassLoader parent) { | public WeavingURLClassLoader (URL[] classURLs, URL[] aspectURLs, ClassLoader parent) { | ||||
super(classURLs,parent); | super(classURLs,parent); | ||||
// System.err.println("? WeavingURLClassLoader.<init>() classURLs=" + classURLs.length + ", aspectURLs=" + aspectURLs.length); | |||||
// System.out.println("> WeavingURLClassLoader.WeavingURLClassLoader() classURLs=" + Arrays.asList(classURLs)); | |||||
this.aspectURLs = aspectURLs; | this.aspectURLs = aspectURLs; | ||||
/* If either we nor our m_parent is using an ASPECT_PATH use a new-style | |||||
/* If either we nor our parent is using an ASPECT_PATH use a new-style | |||||
* adaptor | * adaptor | ||||
*/ | */ | ||||
if (this.aspectURLs.length > 0 || parent instanceof WeavingClassLoader) { | |||||
adaptor = new WeavingAdaptor(this); | |||||
if (this.aspectURLs.length > 0 || getParent() instanceof WeavingClassLoader) { | |||||
try { | |||||
adaptor = new WeavingAdaptor(this); | |||||
} | |||||
catch (ExceptionInInitializerError ex) { | |||||
ex.printStackTrace(System.out); | |||||
throw ex; | |||||
} | |||||
} | } | ||||
// System.out.println("< WeavingURLClassLoader.WeavingURLClassLoader() adaptor=" + adaptor); | |||||
} | } | ||||
private static String getAspectPath () { | private static String getAspectPath () { | ||||
/* Need to defer creation because of possible recursion during constructor execution */ | /* Need to defer creation because of possible recursion during constructor execution */ | ||||
if (adaptor == null && !initializingAdaptor) { | 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(); | |||||
initializingAdaptor = true; | |||||
clwAdaptor.initialize(this,weavingContext); | |||||
initializingAdaptor = false; | |||||
adaptor = clwAdaptor; | |||||
createAdaptor(); | |||||
} | } | ||||
b = adaptor.weaveClass(name,b); | b = adaptor.weaveClass(name,b); | ||||
} | } | ||||
return super.defineClass(name, b, cs); | return super.defineClass(name, b, cs); | ||||
} | } | ||||
private void createAdaptor () { | |||||
DefaultWeavingContext weavingContext = new DefaultWeavingContext (this) { | |||||
/* Ensures consistent LTW messages for testing */ | |||||
public String getClassLoaderName() { | |||||
return loader.getClass().getName(); | |||||
} | |||||
}; | |||||
ClassLoaderWeavingAdaptor clwAdaptor = new ClassLoaderWeavingAdaptor(); | |||||
initializingAdaptor = true; | |||||
clwAdaptor.initialize(this,weavingContext); | |||||
initializingAdaptor = false; | |||||
adaptor = clwAdaptor; | |||||
} | |||||
/** | /** | ||||
* Override to find classes generated by WeavingAdaptor | * Override to find classes generated by WeavingAdaptor |
public aspect ExceptionHandler { | |||||
void around() : execution(public void main(String[])) { | |||||
try { | |||||
proceed(); | |||||
} | |||||
catch (Exception ex) { | |||||
} | |||||
} | |||||
} |
public static void main (String[] args) throws Exception { | public static void main (String[] args) throws Exception { | ||||
System.out.println("Hello World!"); | System.out.println("Hello World!"); | ||||
throw new Exception(); | |||||
} | } | ||||
} | } |
name="jdwp" | name="jdwp" | ||||
value="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"/> | value="-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005"/> | ||||
<target name="JDK14 LTW"> | |||||
<target name="JDK14 LTW with XML"> | |||||
<java fork="yes" classname="HelloWorld" failonerror="yes"> | <java fork="yes" classname="HelloWorld" failonerror="yes"> | ||||
<classpath refid="aj.path"/> | <classpath refid="aj.path"/> | ||||
<!-- | |||||
<classpath> | <classpath> | ||||
<pathelement path="${aj.sandbox}/hello.jar"/> | <pathelement path="${aj.sandbox}/hello.jar"/> | ||||
</classpath> | </classpath> | ||||
--> | |||||
<jvmarg value="-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader"/> | <jvmarg value="-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader"/> | ||||
<jvmarg value="-Daj.class.path=${aj.sandbox}/hello.jar;${aj.sandbox}/handler.jar"/> | |||||
<jvmarg value="-Daj.weaving.verbose=true"/> | |||||
<jvmarg value="-Dorg.aspectj.weaver.showWeaveInfo=true"/> | |||||
<jvmarg value="-Dorg.aspectj.tracing.debug=true"/> | |||||
<!-- use META-INF/aop.xml style --> | |||||
<!-- <jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/>--> | |||||
<!-- <jvmarg line="${jdwp}"/>--> | |||||
</java> | |||||
</target> | |||||
<target name="JDK14 LTW with ASPECTPATH"> | |||||
<java fork="yes" classname="HelloWorld" failonerror="yes"> | |||||
<classpath refid="aj.path"/> | |||||
<!-- | <!-- | ||||
<classpath> | |||||
<pathelement path="${aj.sandbox}/hello.jar"/> | |||||
</classpath> | |||||
--> | --> | ||||
<jvmarg value="-Daj.class.path=${aj.sandbox}/hello.jar"/> | |||||
<jvmarg value="-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader"/> | |||||
<jvmarg value="-Daj.class.path=${aj.sandbox}/hello.jar;${aj.sandbox}/handler.jar"/> | |||||
<jvmarg value="-Daj.aspect.path=${aj.sandbox}/handler.jar"/> | |||||
<jvmarg value="-Daj.weaving.verbose=true"/> | |||||
<jvmarg value="-Dorg.aspectj.weaver.showWeaveInfo=true"/> | |||||
<jvmarg value="-Dorg.aspectj.tracing.debug=true"/> | <jvmarg value="-Dorg.aspectj.tracing.debug=true"/> | ||||
<!-- use META-INF/aop.xml style --> | <!-- use META-INF/aop.xml style --> | ||||
<!-- <jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/>--> | <!-- <jvmarg value="-javaagent:${aj.root}/lib/test/loadtime5.jar"/>--> |
runTest("Odd zip on classpath"); | runTest("Odd zip on classpath"); | ||||
} | } | ||||
public void testJDK14LTW() { | |||||
runTest("JDK14 LTW"); | |||||
public void testJ14LTWWithXML() { | |||||
runTest("JDK14 LTW with XML"); | |||||
} | |||||
public void testJ14LTWWithASPECTPATH() { | |||||
runTest("JDK14 LTW with ASPECTPATH"); | |||||
} | } | ||||
// separate bugzilla patch has this one... commented out | // separate bugzilla patch has this one... commented out |
</run> | </run> | ||||
</ajc-test> | </ajc-test> | ||||
--> | --> | ||||
<ajc-test dir="ltw" title="JDK14 LTW" keywords="ltw"> | |||||
<compile | |||||
files="HelloWorld.java" | |||||
options="-outjar hello.jar" | |||||
/> | |||||
<ant file="ant.xml" target="JDK14 LTW" verbose="true"/> | |||||
<ajc-test dir="ltw" title="JDK14 LTW with XML" keywords="ltw"> | |||||
<compile files="HelloWorld.java" options="-outjar hello.jar"/> | |||||
<compile files="ExceptionHandler.aj" options="-outxml -outjar handler.jar"/> | |||||
<ant file="ant.xml" target="JDK14 LTW with XML" verbose="true"/> | |||||
</ajc-test> | |||||
<ajc-test dir="ltw" title="JDK14 LTW with ASPECTPATH" keywords="ltw"> | |||||
<compile files="HelloWorld.java" options="-outjar hello.jar"/> | |||||
<compile files="ExceptionHandler.aj" options="-outjar handler.jar"/> | |||||
<ant file="ant.xml" target="JDK14 LTW with ASPECTPATH" verbose="true"/> | |||||
</ajc-test> | </ajc-test> | ||||
super(urls,parent); | super(urls,parent); | ||||
// System.err.println("? ExtensibleURLClassLoader.<init>() path=" + WeavingAdaptor.makeClasspath(urls)); | // System.err.println("? ExtensibleURLClassLoader.<init>() path=" + WeavingAdaptor.makeClasspath(urls)); | ||||
classPath = new ClassPathManager(FileUtil.makeClasspath(urls),null); | |||||
try { | |||||
classPath = new ClassPathManager(FileUtil.makeClasspath(urls),null); | |||||
} | |||||
catch (ExceptionInInitializerError ex) { | |||||
ex.printStackTrace(System.out); | |||||
throw ex; | |||||
} | |||||
} | } | ||||
protected void addURL(URL url) { | protected void addURL(URL url) { |
private static int maxOpenArchives = -1; | private static int maxOpenArchives = -1; | ||||
private static final int MAXOPEN_DEFAULT = 1000; | private static final int MAXOPEN_DEFAULT = 1000; | ||||
/* | |||||
* FIXME maw Tracing ClassPathManager can cause recursion for JDK 1.4 | |||||
* LTW i.e. -Djava.system.class.loader | |||||
*/ | |||||
// private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassPathManager.class); | |||||
private static Trace trace = TraceFactory.getTraceFactory().getTrace(ClassPathManager.class); | |||||
static { | static { | ||||
String openzipsString = getSystemPropertyWithoutSecurityException("org.aspectj.weaver.openarchives",Integer.toString(MAXOPEN_DEFAULT)); | String openzipsString = getSystemPropertyWithoutSecurityException("org.aspectj.weaver.openarchives",Integer.toString(MAXOPEN_DEFAULT)); | ||||
public ClassPathManager(List classpath, IMessageHandler handler) { | public ClassPathManager(List classpath, IMessageHandler handler) { | ||||
// if (trace.isTraceEnabled()) trace.enter("<init>",this,new Object[] { classpath, handler }); | |||||
if (trace.isTraceEnabled()) trace.enter("<init>",this,new Object[] { classpath, handler }); | |||||
entries = new ArrayList(); | entries = new ArrayList(); | ||||
for (Iterator i = classpath.iterator(); i.hasNext();) { | for (Iterator i = classpath.iterator(); i.hasNext();) { | ||||
String name = (String) i.next(); | String name = (String) i.next(); | ||||
addPath(name, handler); | addPath(name, handler); | ||||
} | } | ||||
// if (trace.isTraceEnabled()) trace.exit("<init>"); | |||||
if (trace.isTraceEnabled()) trace.exit("<init>"); | |||||
} | } | ||||
protected ClassPathManager() {}; | protected ClassPathManager() {}; |
protected Class tracedClass; | protected Class tracedClass; | ||||
private static SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss.SSS"); | |||||
private static SimpleDateFormat timeFormat; | |||||
protected AbstractTrace (Class clazz) { | protected AbstractTrace (Class clazz) { | ||||
this.tracedClass = clazz; | this.tracedClass = clazz; | ||||
protected String formatMessage(String kind, String className, String methodName, Object thiz, Object[] args) { | protected String formatMessage(String kind, String className, String methodName, Object thiz, Object[] args) { | ||||
StringBuffer message = new StringBuffer(); | StringBuffer message = new StringBuffer(); | ||||
Date now = new Date(); | Date now = new Date(); | ||||
message.append(time.format(now)).append(" "); | |||||
message.append(formatDate(now)).append(" "); | |||||
message.append(Thread.currentThread().getName()).append(" "); | message.append(Thread.currentThread().getName()).append(" "); | ||||
message.append(kind).append(" "); | message.append(kind).append(" "); | ||||
message.append(className); | message.append(className); | ||||
if (args != null) message.append(" ").append(formatArgs(args)); | if (args != null) message.append(" ").append(formatArgs(args)); | ||||
return message.toString(); | return message.toString(); | ||||
} | } | ||||
private static String formatDate (Date date) { | |||||
if (timeFormat == null) { | |||||
timeFormat = new SimpleDateFormat("HH:mm:ss.SSS"); | |||||
} | |||||
return timeFormat.format(date); | |||||
} | |||||
/** | /** | ||||
* Format objects safely avoiding toString which can cause recursion, | * Format objects safely avoiding toString which can cause recursion, |