From 3b517caf402c6d7c52d4bcbdc86c7528ab828ec9 Mon Sep 17 00:00:00 2001 From: mwebster Date: Tue, 15 Aug 2006 15:34:56 +0000 Subject: [PATCH] Bug 153907 "Facilitate LTW testing in a custom ClassLoader hierarchy" (TestServer, TestServerTest and LTWServerTests) --- .../aspectj/testing/server/TestServer.java | 185 ++++++++++++++++++ testing-client/testdata/server.properties | 0 .../org/aspectj/testing/TestingTests.java | 3 + .../testing/server/TestServerTest.java | 40 ++++ tests/ltw/Child.java | 9 + tests/ltw/Parent.java | 5 + tests/ltw/ant-server.xml | 33 ++++ tests/ltw/server-helloworld.properties | 5 + tests/ltw/server-parentandchild.properties | 6 + .../systemtest/ajc150/AllTestsAspectJ150.java | 2 + .../systemtest/ajc150/ltw/LTWServerTests.java | 27 +++ .../systemtest/ajc150/ltw/ltw-tests.xml | 27 +++ 12 files changed, 342 insertions(+) create mode 100644 testing-client/src/org/aspectj/testing/server/TestServer.java create mode 100644 testing-client/testdata/server.properties create mode 100644 testing-client/testsrc/org/aspectj/testing/server/TestServerTest.java create mode 100644 tests/ltw/Child.java create mode 100644 tests/ltw/Parent.java create mode 100644 tests/ltw/ant-server.xml create mode 100644 tests/ltw/server-helloworld.properties create mode 100644 tests/ltw/server-parentandchild.properties create mode 100644 tests/src/org/aspectj/systemtest/ajc150/ltw/LTWServerTests.java diff --git a/testing-client/src/org/aspectj/testing/server/TestServer.java b/testing-client/src/org/aspectj/testing/server/TestServer.java new file mode 100644 index 000000000..4e2f15388 --- /dev/null +++ b/testing-client/src/org/aspectj/testing/server/TestServer.java @@ -0,0 +1,185 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.testing.server; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.StringTokenizer; + +public class TestServer implements Runnable { + + private static final boolean debug = false; + + private boolean exitOnError = true; + private File workingDirectory; + private ClassLoader rootLoader; + private Map loaders = new HashMap(); + + private String mainClass = "UnknowClass"; + private String mainLoader = "UnknowLoader"; + + public void initialize () throws IOException { + createRootLoader(); + loadConfiguration(); + } + + private void loadConfiguration () throws IOException { + File file = new File(workingDirectory,"server.properties"); + Properties props = new Properties(); + FileInputStream in = new FileInputStream(file); + props.load(in); + in.close(); + + Enumeration enu = props.propertyNames(); + while (enu.hasMoreElements()) { + String key = (String)enu.nextElement(); + if (key.startsWith("loader.")) { + createLoader(props.getProperty(key)); + } + else if (key.equals("main")) { + StringTokenizer st = new StringTokenizer(props.getProperty(key),","); + mainClass = st.nextToken(); + mainLoader = st.nextToken(); + } + } + } + + private void createLoader (String property) throws IOException { + ClassLoader parent = rootLoader; + + StringTokenizer st = new StringTokenizer(property,","); + String name = st.nextToken(); + String classpath = st.nextToken(); + if (st.hasMoreTokens()) { + String parentName = st.nextToken(); + parent = (ClassLoader)loaders.get(parentName); + if (parent == null) error("No such loader: " + parentName); + } + + List urlList = new ArrayList(); + st = new StringTokenizer(classpath,";"); + while (st.hasMoreTokens()) { + String fileName = st.nextToken(); + File file = new File(workingDirectory,fileName).getCanonicalFile(); + if (!file.exists()) error("Missing or invalid file: " + file.getPath()); + URL url = file.toURL(); + urlList.add(url); + } + URL[] urls = new URL[urlList.size()]; + urlList.toArray(urls); + ClassLoader loader = new URLClassLoader(urls, parent); + + loaders.put(name,loader); + } + + private void createRootLoader () throws IOException { + List urlList = new ArrayList(); + + /* Sandbox */ + URL url = workingDirectory.getCanonicalFile().toURL(); + urlList.add(url); + + /* AspectJ runtime */ + URL[] urls = ((URLClassLoader)getClass().getClassLoader()).getURLs(); + for (int i = 0; i < urls.length; i++) { + url = urls[i]; + if (debug) System.err.println("? TestServer.initialize() " + url); + String file = url.getFile(); + if (file.indexOf("runtime") != -1 || file.indexOf("aspectj5rt") != -1) { + urlList.add(url); + } + } + if (debug) System.err.println("? TestServer.initialize() urlList=" + urlList); + + urls = new URL[urlList.size()]; + urlList.toArray(urls); + ClassLoader parent = getClass().getClassLoader().getParent(); + rootLoader = new URLClassLoader(urls,parent); + + } + + public void setExitOntError (boolean b) { + exitOnError = b; + } + + public void setWorkingDirectory (String name) { + workingDirectory = new File(name); + if (!workingDirectory.exists()) error("Missing or invalid working directory: " + workingDirectory.getPath()); + } + + public static void main(String[] args) throws Exception { + System.out.println("Starting ..."); + + TestServer server = new TestServer(); + server.setWorkingDirectory(args[0]); + server.initialize(); + + Thread thread = new Thread(server,"application"); + thread.start(); + thread.join(); + + System.out.println("Stopping ..."); + } + + public void run() { + System.out.println("Running " + mainClass); + runClass(mainClass,(ClassLoader)loaders.get(mainLoader)); + } + + private void runClass (String className, ClassLoader classLoader) { + try { + Class clazz = Class.forName(className,false,classLoader); + invokeMain(clazz,new String[] {}); + } + catch (ClassNotFoundException ex) { + ex.printStackTrace(); + error(ex.toString()); + } + } + + public 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 th = ex.getTargetException(); + th.printStackTrace(); + error(th.toString()); + } + catch (Throwable th) { + th.printStackTrace(); + error(th.toString()); + } + } + + private void error (String message) { + System.out.println(message); + if (exitOnError) System.exit(0); + } +} diff --git a/testing-client/testdata/server.properties b/testing-client/testdata/server.properties new file mode 100644 index 000000000..e69de29bb diff --git a/testing-client/testsrc/org/aspectj/testing/TestingTests.java b/testing-client/testsrc/org/aspectj/testing/TestingTests.java index 781ccf995..ea5e7ee14 100644 --- a/testing-client/testsrc/org/aspectj/testing/TestingTests.java +++ b/testing-client/testsrc/org/aspectj/testing/TestingTests.java @@ -14,6 +14,8 @@ package org.aspectj.testing; +import org.aspectj.testing.server.TestServerTest; + import junit.framework.*; public class TestingTests extends TestCase { @@ -23,6 +25,7 @@ public class TestingTests extends TestCase { // for now, do not include SuiteTest because it would take 15 minutes //$JUnit-BEGIN$ suite.addTestSuite(TesterTest.class); + suite.addTestSuite(TestServerTest.class); //$JUnit-END$ return suite; } diff --git a/testing-client/testsrc/org/aspectj/testing/server/TestServerTest.java b/testing-client/testsrc/org/aspectj/testing/server/TestServerTest.java new file mode 100644 index 000000000..f0f043e67 --- /dev/null +++ b/testing-client/testsrc/org/aspectj/testing/server/TestServerTest.java @@ -0,0 +1,40 @@ +/******************************************************************************* + * Copyright (c) 2006 IBM Corporation and others. + * 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://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Matthew Webster - initial implementation + *******************************************************************************/ +package org.aspectj.testing.server; + +import java.io.IOException; + +import junit.framework.TestCase; + +public class TestServerTest extends TestCase { + + private TestServer server; + + protected void setUp() throws Exception { + super.setUp(); + server = new TestServer(); + server.setExitOntError(false); + } + + public void testInitialize() { + try { + server.setWorkingDirectory("./testdata"); + server.initialize(); + } + catch (IOException ex) { + fail(ex.toString()); + } + } + + public void testSetWorkingDirectory() { + server.setWorkingDirectory("./testdata"); + } +} diff --git a/tests/ltw/Child.java b/tests/ltw/Child.java new file mode 100644 index 000000000..4719933f0 --- /dev/null +++ b/tests/ltw/Child.java @@ -0,0 +1,9 @@ +public class Child extends Parent { + public Child () { + System.out.println("Child"); + } + + public static void main (String[] args) { + new Child(); + } +} \ No newline at end of file diff --git a/tests/ltw/Parent.java b/tests/ltw/Parent.java new file mode 100644 index 000000000..b239a9829 --- /dev/null +++ b/tests/ltw/Parent.java @@ -0,0 +1,5 @@ +public class Parent { + public Parent () { + System.out.println("Parent"); + } +} \ No newline at end of file diff --git a/tests/ltw/ant-server.xml b/tests/ltw/ant-server.xml new file mode 100644 index 000000000..15ec3b945 --- /dev/null +++ b/tests/ltw/ant-server.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/ltw/server-helloworld.properties b/tests/ltw/server-helloworld.properties new file mode 100644 index 000000000..baf42dbe0 --- /dev/null +++ b/tests/ltw/server-helloworld.properties @@ -0,0 +1,5 @@ +# loader.XXX=Name,Classpath[,Parent] +loader.application=Application,hello.jar;handler.jar + +# main=Class,Loader +main=HelloWorld,Application \ No newline at end of file diff --git a/tests/ltw/server-parentandchild.properties b/tests/ltw/server-parentandchild.properties new file mode 100644 index 000000000..d0a7af85e --- /dev/null +++ b/tests/ltw/server-parentandchild.properties @@ -0,0 +1,6 @@ +# loader.XXX=Name,Classpath[,Parent] +loader.parent=Parent,parent.jar +loader.child=Child,child.jar,Parent + +# main=Class,Loader +main=Child,Child \ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java index 472809138..0d83ed149 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java +++ b/tests/src/org/aspectj/systemtest/ajc150/AllTestsAspectJ150.java @@ -13,6 +13,7 @@ package org.aspectj.systemtest.ajc150; import org.aspectj.systemtest.ajc150.ataspectj.AtAjSyntaxTests; import org.aspectj.systemtest.ajc150.ataspectj.AtAjMisuseTests; import org.aspectj.systemtest.ajc150.ataspectj.AtAjLTWTests; +import org.aspectj.systemtest.ajc150.ltw.LTWServerTests; import org.aspectj.systemtest.ajc150.ltw.LTWTests; import junit.framework.Test; @@ -55,6 +56,7 @@ public class AllTestsAspectJ150 { suite.addTest(HasMember.suite()); suite.addTestSuite(LTWTests.class); + suite.addTestSuite(LTWServerTests.class); //$JUnit-END$ return suite; } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ltw/LTWServerTests.java b/tests/src/org/aspectj/systemtest/ajc150/ltw/LTWServerTests.java new file mode 100644 index 000000000..b187c609b --- /dev/null +++ b/tests/src/org/aspectj/systemtest/ajc150/ltw/LTWServerTests.java @@ -0,0 +1,27 @@ +package org.aspectj.systemtest.ajc150.ltw; + +import java.io.File; + +import junit.framework.Test; + +import org.aspectj.testing.XMLBasedAjcTestCase; + +public class LTWServerTests extends XMLBasedAjcTestCase { + + public static Test suite() { + return loadSuite(LTWServerTests.class); + } + + protected File getSpecFile() { + return new File("../tests/src/org/aspectj/systemtest/ajc150/ltw/ltw.xml"); + } + + public void testServerWithHelloWorld () { + runTest("TestServer with HelloWorld"); + } + + public void testServerWithParentAndChild () { + runTest("TestServer with Parent and Child"); + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/ltw/ltw-tests.xml b/tests/src/org/aspectj/systemtest/ajc150/ltw/ltw-tests.xml index 1866789ef..e80293aee 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ltw/ltw-tests.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ltw/ltw-tests.xml @@ -558,4 +558,31 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file -- 2.39.5