/******************************************************************************* * Copyright (c) 2000, 2014 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: * IBM Corporation - initial API and implementation *******************************************************************************/ package org.eclipse.jdt.core.tests.util; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.net.ServerSocket; import java.net.Socket; import java.util.StringTokenizer; /****************************************************** * * IMPORTANT NOTE: If modifying this class, copy the source to TestVerifier#getVerifyTestsCode() * (see this method for details) * ******************************************************/ @SuppressWarnings({ "unchecked", "rawtypes" }) public class VerifyTests { int portNumber; Socket socket; /** * NOTE: Code copied from junit.util.TestCaseClassLoader. * * A custom class loader which enables the reloading * of classes for each test run. The class loader * can be configured with a list of package paths that * should be excluded from loading. The loading * of these packages is delegated to the system class * loader. They will be shared across test runs. * <p> * The list of excluded package paths is specified in * a properties file "excluded.properties" that is located in * the same place as the TestCaseClassLoader class. * <p> * <b>Known limitation:</b> the VerifyClassLoader cannot load classes * from jar files. */ public class VerifyClassLoader extends ClassLoader { /** scanned class path */ private String[] pathItems; /** excluded paths */ private String[] excluded= {}; /** * Constructs a VerifyClassLoader. It scans the class path * and the excluded package paths */ public VerifyClassLoader() { super(); String classPath= System.getProperty("java.class.path"); String separator= System.getProperty("path.separator"); // first pass: count elements StringTokenizer st= new StringTokenizer(classPath, separator); int i= 0; while (st.hasMoreTokens()) { st.nextToken(); i++; } // second pass: split this.pathItems= new String[i]; st= new StringTokenizer(classPath, separator); i= 0; while (st.hasMoreTokens()) { this.pathItems[i++]= st.nextToken(); } } public java.net.URL getResource(String name) { return ClassLoader.getSystemResource(name); } public InputStream getResourceAsStream(String name) { return ClassLoader.getSystemResourceAsStream(name); } protected boolean isExcluded(String name) { // exclude the "java" packages. // They always need to be excluded so that they are loaded by the system class loader if (name.startsWith("java") || name.startsWith("[Ljava")) return true; // exclude the user defined package paths for (int i= 0; i < this.excluded.length; i++) { if (name.startsWith(this.excluded[i])) { return true; } } return false; } public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { Class c= findLoadedClass(name); if (c != null) return c; // // Delegate the loading of excluded classes to the // standard class loader. // if (isExcluded(name)) { try { c= findSystemClass(name); return c; } catch (ClassNotFoundException e) { // keep searching } } File file= locate(name); if (file == null) throw new ClassNotFoundException(); byte data[]= loadClassData(file); c= defineClass(name, data, 0, data.length); if (resolve) resolveClass(c); return c; } private byte[] loadClassData(File f) throws ClassNotFoundException { FileInputStream stream = null; try { //System.out.println("loading: "+f.getPath()); stream = new FileInputStream(f); try { byte[] b= new byte[stream.available()]; stream.read(b); return b; } catch (IOException e) { throw new ClassNotFoundException(); } } catch (FileNotFoundException e) { throw new ClassNotFoundException(); } finally { if (stream != null) { try { stream.close(); } catch (IOException e) { /* ignore */ } } } } /** * Locate the given file. * @return Returns null if file couldn't be found. */ private File locate(String fileName) { if (fileName != null) { fileName= fileName.replace('.', '/')+".class"; File path= null; for (int i= 0; i < this.pathItems.length; i++) { path= new File(this.pathItems[i], fileName); if (path.exists()) return path; } } return null; } } public void loadAndRun(String className) throws Throwable { //System.out.println("Loading " + className + "..."); Class testClass = new VerifyClassLoader().loadClass(className); //System.out.println("Loaded " + className); try { Method main = testClass.getMethod("main", new Class[] {String[].class}); //System.out.println("Running " + className); main.invoke(null, new Object[] {new String[] {}}); //System.out.println("Finished running " + className); } catch (NoSuchMethodException e) { return; } catch (InvocationTargetException e) { throw e.getTargetException(); } } public static void main(String[] args) throws IOException { VerifyTests verify = new VerifyTests(); verify.portNumber = Integer.parseInt(args[0]); verify.run(); } public void run() throws IOException { ServerSocket server = new ServerSocket(this.portNumber); this.socket = server.accept(); this.socket.setTcpNoDelay(true); server.close(); DataInputStream in = new DataInputStream(this.socket.getInputStream()); final DataOutputStream out = new DataOutputStream(this.socket.getOutputStream()); while (true) { final String className = in.readUTF(); Thread thread = new Thread() { public void run() { try { loadAndRun(className); out.writeBoolean(true); System.err.println(VerifyTests.class.getName()); System.out.println(VerifyTests.class.getName()); } catch (Throwable e) { e.printStackTrace(); try { System.err.println(VerifyTests.class.getName()); System.out.println(VerifyTests.class.getName()); out.writeBoolean(false); } catch (IOException e1) { e1.printStackTrace(); } } try { out.flush(); } catch (IOException e) { e.printStackTrace(); } } }; thread.start(); } } }