/* ******************************************************************* * 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.loadtime; import java.io.File; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.URL; import java.util.Enumeration; import java.util.Properties; import junit.framework.TestCase; import org.aspectj.bridge.AbortException; import org.aspectj.testing.util.TestUtil.TestError; import org.aspectj.util.FileUtil; import org.aspectj.weaver.BcweaverTests; 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 ASPECTJRT = "../runtime/bin"; 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 DW_ADVICE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-dwaspects.jar"; private final static String DE_ADVICE_ASPECTS = BcweaverTests.TESTDATA_PATH + "/ltw-deaspects.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"; private final static String TEST_BASE = BcweaverTests.TESTDATA_PATH + "/WeavingURLClassLoaderTest/builtLibs"; private final static String NULL = "null"; private Properties savedProperties; public WeavingURLClassLoaderTest(String name) { super(name); } public void testLoadClass () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,""); setSystemProperty(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()); } } /* * 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 () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,""); setSystemProperty(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()); } } /* * We get an exception because the class was not built reweavable */ public void testWeaveWovenClass () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS); setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + WOVEN_JAR); WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader()); try { 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 aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS)); URL[] classURLs = new URL[] { aspects, classes, aspectjrt }; 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 () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS); setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT); 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 testWeaveAdviceWithVerbose () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS); setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT); setSystemProperty(WeavingAdaptor.WEAVING_ADAPTOR_VERBOSE,"true"); 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 testWeaveAdviceWithWeaveInfo () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS); setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT); setSystemProperty(WeavingAdaptor.SHOW_WEAVE_INFO_PROPERTY,"true"); 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 testWeaveDeclareWarningAdvice () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,DW_ADVICE_ASPECTS); setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,DW_ADVICE_ASPECTS + File.pathSeparator + 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 testWeaveDeclareErrorAdvice () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,DE_ADVICE_ASPECTS); setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,DE_ADVICE_ASPECTS + File.pathSeparator + CLASSES_JAR); WeavingURLClassLoader loader = new WeavingURLClassLoader(getClass().getClassLoader()); try { Class clazz = loader.loadClass("LTWHelloWorld"); invokeMain(clazz,new String[] {} ); fail("Expecting org.aspectj.bridge.AbortException"); } catch (Exception ex) { assertTrue("Expecting org.aspectj.bridge.AbortException caught " + ex,(ex instanceof AbortException)); } } public void testWeaveAroundClosure () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,AROUNDCLOSURE_ASPECTS); setSystemProperty(WeavingURLClassLoader.WEAVING_CLASS_PATH,AROUNDCLOSURE_ASPECTS + File.pathSeparator + CLASSES_JAR + File.pathSeparator + ASPECTJRT); 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 aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); URL aspects = FileUtil.getFileURL(new File(ITD_ASPECTS)); URL[] classURLs = new URL[] { aspects, classes, aspectjrt }; URL[] aspectURLs = new URL[] { aspects }; WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader()); try { Class clazz = loader.loadClass("LTWHelloWorld"); invokeMain(clazz,new String[] { "LTWInterfaceITD", "LTWFieldITD", "LTWMethodITD" }); } catch (Exception ex) { fail(ex.toString()); } } public void testWeavingPer () { URL classes = FileUtil.getFileURL(new File(CLASSES_JAR)); URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); URL aspects = FileUtil.getFileURL(new File(PER_ASPECTS)); URL[] classURLs = new URL[] { aspects, classes, aspectjrt }; 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 aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); 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, aspectjrt }; URL[] aspectURLs = new URL[] { aspects1, aspects2, aspects3, aspects4 }; WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader()); try { Class clazz = loader.loadClass("LTWHelloWorld"); invokeMain(clazz,new String[] { "LTWAspect", "LTWAroundClosure", "LTWPerthis", "LTWInterfaceITD", "LTWFieldITD", "LTWMethodITD", "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 { loader.loadClass("LTWHelloWorld"); fail("Expecting java.lang.ClassNotFoundException"); } catch (Exception ex) { assertTrue("Expecting java.lang.ClassNotFoundException caught " + ex,(ex instanceof ClassNotFoundException)); } } public void testJunkAspectJar () { File junkJar = new File(JUNK_JAR); assertFalse(junkJar + " should not exist",junkJar.exists()); URL aspects = FileUtil.getFileURL(junkJar); URL[] classURLs = new URL[] { aspects }; URL[] aspectURLs = new URL[] { aspects }; try { new WeavingURLClassLoader(classURLs,aspectURLs,getClass().getClassLoader()); fail("Expecting org.aspectj.bridge.AbortException"); } catch (Exception ex) { assertTrue("Expecting org.aspectj.bridge.AbortException caught " + ex,(ex instanceof org.aspectj.bridge.AbortException)); } } public void testAddURL () { URL classes = FileUtil.getFileURL(new File(CLASSES_JAR)); URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS)); URL[] classURLs = new URL[] { aspects, aspectjrt }; 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 aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); URL aspects = FileUtil.getFileURL(new File(ADVICE_ASPECTS)); URL[] classURLs = new URL[] { aspects, aspectjrt }; 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 () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,ADVICE_ASPECTS); setSystemProperty(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) { assertTrue("Expecting java.lang.NoClassDefFoundError but caught " + ex,ex.getMessage().contains("java.lang.NoClassDefFoundError")); } } /* * Ensure package object is correct */ public void testPackage () { setSystemProperty(WeavingURLClassLoader.WEAVING_ASPECT_PATH,""); setSystemProperty(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 void testZipAspects() { try { doTestZipAspects(TEST_BASE + "/aspect.zip"); } catch (Error ex) { failWithException(ex); } catch (Exception ex) { failWithException(ex); } } public void testJarAspects() { try { doTestZipAspects(TEST_BASE + "/aspect.jar"); } catch (Error ex) { failWithException(ex); } catch (Exception ex) { failWithException(ex); } } /** PR#106736 */ public void testClassAspects() { try { doTestZipAspects(TEST_BASE + "/classes"); } catch (Error ex) { failWithException(ex); } catch (Exception ex) { failWithException(ex); } } public void testZipJarAspectsTest() { try { doTestZipAspectsTest(); // bug: doTestZipAspects("") attempts to load packag.Aspect? fail("expected error to be thrown"); } catch (InvocationTargetException ex) { // expecting error assertTrue(ex.getTargetException() instanceof Error); } catch (RuntimeException ex) { // expecting error String message = ex.getMessage(); // expecting error - seems to be wrapped wrong if (-1 == message.indexOf("around advice")) { failWithException(ex); } } catch (Error ex) { failWithException(ex); } catch (Exception ex) { failWithException(ex); } } private void doTestZipAspects(String aspectLib) throws Exception { File classZip = new File(TEST_BASE + "/main.zip"); File zipLib = new File(aspectLib); URL classes = FileUtil.getFileURL(classZip); URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); URL aspects = FileUtil.getFileURL(zipLib); URL[] classURLs = new URL[] { aspects, classes, aspectjrt }; URL[] aspectURLs = new URL[] { aspects }; ClassLoader parent = getClass().getClassLoader(); WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs, aspectURLs, parent); Class clazz = loader.loadClass("packag.Main"); invokeMain(clazz,new String[] { }); // throws Error unless advice applies } private void doTestZipAspectsTest() throws Exception { URL classes = FileUtil.getFileURL(new File(TEST_BASE + "/main.zip")); URL aspectjrt = FileUtil.getFileURL(new File(ASPECTJRT)); URL[] classURLs = new URL[] { classes, aspectjrt }; ClassLoader parent = getClass().getClassLoader(); WeavingURLClassLoader loader = new WeavingURLClassLoader(classURLs, new URL[] { }, parent); Class clazz = loader.loadClass("packag.Main"); invokeMain(clazz,new String[] { }); // throws Error because advice does not apply } private void failWithException(Throwable t) { throw new TestError(t.getMessage(), t); } 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) { Throwable targetException = ex.getTargetException(); if (targetException instanceof RuntimeException) throw (RuntimeException)ex.getTargetException(); else throw new RuntimeException(ex.getTargetException().toString()); } catch (Exception ex) { throw new RuntimeException(ex.toString()); } } private 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); } } }