123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- /*******************************************************************************
- * Copyright (c) 2006,2017 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
- *******************************************************************************/
- 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;
-
- /**
- * @author Matthew Webster
- * @author Andy Clement
- */
- public class TestServer implements Runnable {
-
- private static final boolean debug = Boolean.getBoolean("org.aspectj.testing.server.debug");
- // AspectJ project root folder nameing pattern, case-insensitive (i.e. org.aspectj, AspectJ)
- protected static final String REGEX_PROJECT_ROOT_FOLDER = "(?i)(org[.])?aspectj";
-
- private boolean exitOnError = true;
- private File workingDirectory;
- private ClassLoader rootLoader;
- private Map<String,ClassLoader> loaders = new HashMap<>();
-
- private String mainClass = "UnknownClass";
- private String mainLoader = "UnknownLoader";
-
- 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 (debug) System.err.println("Creating loader "+name+" with classpath "+classpath);
- if (st.hasMoreTokens()) {
- String parentName = st.nextToken();
- parent = loaders.get(parentName);
- if (parent == null) error("No such loader: " + parentName);
- }
-
- List<URL> 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.toURI().toURL();
- urlList.add(url);
- }
- URL[] urls = new URL[urlList.size()];
- urlList.toArray(urls);
- ClassLoader loader = new URLClassLoader(urls, parent);
- if (debug) System.err.println("? TestServer.createLoader() loader=" + loader + ", name='" + name + "', urls=" + urlList + ", parent=" + parent);
-
- loaders.put(name,loader);
- }
-
- private void createRootLoader() throws IOException {
- List<URL> urlList = new ArrayList<>();
-
- // Sandbox
- urlList.add(workingDirectory.getCanonicalFile().toURI().toURL());
- File projectRootFolder = findProjectRootFolder();
- urlList.add(new File(projectRootFolder,"runtime/target/classes").toURI().toURL());
- // urlList.add(new File(projectRootFolder,"aspectjrt/target/classes").toURI().toURL());
- // urlList.add(new File(projectRootFolder,"aspectj5rt/target/classes").toURI().toURL());
-
- URL[] urls = new URL[urlList.size()];
- urlList.toArray(urls);
- ClassLoader parent = getClass().getClassLoader().getParent();
- rootLoader = new URLClassLoader(urls,parent);
- if (debug) System.err.println("? TestServer.createRootLoader() loader=" + rootLoader + ", urlList=" + urlList + ", parent=" + parent);
- }
-
- // Make protected in order to at least make this part of the code testable -> TestServerTest
- protected File findProjectRootFolder() throws IOException {
- // Find the AspectJ project root folder
- File currentFolder = new File(".").getCanonicalFile();
- while (currentFolder != null && !currentFolder.getName().matches(REGEX_PROJECT_ROOT_FOLDER)) {
- currentFolder = currentFolder.getParentFile();
- }
- if (currentFolder == null) {
- error(
- "Unable to locate project root folder matching regex '" + REGEX_PROJECT_ROOT_FOLDER +
- "' in " + new File(".").getCanonicalPath()
- );
- }
- return currentFolder;
- }
-
- 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,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);
- // FIXME:
- // This is horrible: Why not just throw an exception? And if we exit, why with exit code 0?
- // It basically makes the tests useless because they might log errors without checking any conditions.
- if (exitOnError) System.exit(0);
- }
- }
|