首页

基于aspectjweaver中的UtilClassLoader实现URLClassLoader自定义类加载器实例源码

标签:aspectj,UtilClassLoader,URLClassLoader,自定义类加载器     发布时间:2017-12-31   

一、前言

基于aspect的aspectjweaver(1.6.9)包org.aspectj.util.UtilClassLoader对类加载器URLClassLoader进行自定义,对自定义的目录路径下的.class文件进行动态加载初始化处理,具体参见如下源码所示

二、源码说明

1.UtilClassLoader部分

package org.aspectj.util;@b@@b@import java.io.ByteArrayOutputStream;@b@import java.io.File;@b@import java.io.FileInputStream;@b@import java.io.IOException;@b@import java.io.InputStream;@b@import java.net.URL;@b@import java.net.URLClassLoader;@b@import java.util.ArrayList;@b@import java.util.Arrays;@b@import java.util.Collections;@b@import java.util.Iterator;@b@import java.util.List;@b@@b@public class UtilClassLoader extends URLClassLoader@b@{@b@  List dirs;@b@  private URL[] urlsForDebugString;@b@@b@  public UtilClassLoader(URL[] urls, File[] dirs)@b@  {@b@    super(urls);@b@    LangUtil.throwIaxIfNotAssignable(dirs, File.class, "dirs");@b@    this.urlsForDebugString = urls;@b@    ArrayList dcopy = new ArrayList();@b@@b@    if (!(LangUtil.isEmpty(dirs)))@b@      dcopy.addAll(Arrays.asList(dirs));@b@@b@    this.dirs = Collections.unmodifiableList(dcopy);@b@  }@b@@b@  public URL getResource(String name)@b@  {@b@    return ClassLoader.getSystemResource(name);@b@  }@b@@b@  public InputStream getResourceAsStream(String name) {@b@    return ClassLoader.getSystemResourceAsStream(name);@b@  }@b@@b@  public synchronized Class loadClass(String name, boolean resolve)@b@    throws ClassNotFoundException@b@  {@b@    ClassNotFoundException thrown = null;@b@    Class result = findLoadedClass(name);@b@    if (null != result)@b@      resolve = false;@b@    else@b@      try {@b@        result = findSystemClass(name);@b@      } catch (ClassNotFoundException e) {@b@        thrown = e;@b@      }@b@@b@    if (null == result) {@b@      try {@b@        result = loadClass(name, resolve);@b@      } catch (ClassNotFoundException e) {@b@        thrown = e;@b@      }@b@      if (null != result)@b@        return result;@b@    }@b@@b@    if (null == result) {@b@      byte[] data = readClass(name);@b@      if (data != null)@b@        result = defineClass(name, data, 0, data.length);@b@@b@    }@b@@b@    if (null == result)@b@      throw new ClassNotFoundException(name);@b@@b@    if (resolve)@b@      resolveClass(result);@b@@b@    return result;@b@  }@b@@b@  private byte[] readClass(String className) throws ClassNotFoundException@b@  {@b@    String fileName = className.replace('.', '/') + ".class";@b@    for (Iterator iter = this.dirs.iterator(); iter.hasNext(); ) {@b@      File file = new File((File)iter.next(), fileName);@b@      if (file.canRead())@b@        return getClassData(file);@b@    }@b@@b@    return null; }@b@@b@  private byte[] getClassData(File f) {@b@    FileInputStream stream;@b@    try {@b@      stream = new FileInputStream(f);@b@      ByteArrayOutputStream out = new ByteArrayOutputStream(1000);@b@      byte[] b = new byte[4096];@b@@b@      while ((n = stream.read(b)) != -1) {@b@        int n;@b@        out.write(b, 0, n);@b@      }@b@      stream.close();@b@      out.close();@b@      return out.toByteArray();@b@    } catch (IOException e) {@b@    }@b@    return null;@b@  }@b@@b@  public String toString()@b@  {@b@    return "UtilClassLoader(urls=" + Arrays.asList(this.urlsForDebugString) + ", dirs=" + this.dirs + ")";@b@  }@b@}

2.LangUtil工具部分

package org.aspectj.util;@b@@b@import java.io.ByteArrayOutputStream;@b@import java.io.File;@b@import java.io.IOException;@b@import java.io.PrintWriter;@b@import java.io.StringWriter;@b@import java.lang.reflect.Array;@b@import java.lang.reflect.InvocationTargetException;@b@import java.security.PrivilegedActionException;@b@import java.sql.SQLException;@b@import java.util.AbstractCollection;@b@import java.util.ArrayList;@b@import java.util.Arrays;@b@import java.util.BitSet;@b@import java.util.Collection;@b@import java.util.Collections;@b@import java.util.LinkedList;@b@import java.util.List;@b@import java.util.StringTokenizer;@b@@b@public class LangUtil@b@{@b@  public static final String EOL;@b@  private static double vmVersion;@b@@b@  public static boolean is13VMOrGreater()@b@  {@b@    return (1.3D <= vmVersion);@b@  }@b@@b@  public static boolean is14VMOrGreater() {@b@    return (1.4D <= vmVersion);@b@  }@b@@b@  public static boolean is15VMOrGreater() {@b@    return (1.5D <= vmVersion);@b@  }@b@@b@  public static boolean is16VMOrGreater() {@b@    return (1.6D <= vmVersion);@b@  }@b@@b@  public static boolean is17VMOrGreater() {@b@    return (1.7D <= vmVersion);@b@  }@b@@b@  public static final void throwIaxIfNull(Object o, String name)@b@  {@b@    if (null == o) {@b@      String message = "null " + ((null == name) ? "input" : name);@b@      throw new IllegalArgumentException(message);@b@    }@b@  }@b@@b@  public static final void throwIaxIfNotAssignable(Object[] ra, Class c, String name)@b@  {@b@    throwIaxIfNull(ra, name);@b@    String label = (null == name) ? "input" : name;@b@    for (int i = 0; i < ra.length; ++i) {@b@      if (null == ra[i]) {@b@        String m = " null " + label + "[" + i + "]";@b@        throw new IllegalArgumentException(m); }@b@      if (null != c) {@b@        Class actualClass = ra[i].getClass();@b@        if (!(c.isAssignableFrom(actualClass))) {@b@          String message = label + " not assignable to " + c.getName();@b@          throw new IllegalArgumentException(message);@b@        }@b@      }@b@    }@b@  }@b@@b@  public static final void throwIaxIfNotAssignable(Object o, Class c, String name)@b@  {@b@    throwIaxIfNull(o, name);@b@    if (null != c) {@b@      Class actualClass = o.getClass();@b@      if (!(c.isAssignableFrom(actualClass))) {@b@        String message = name + " not assignable to " + c.getName();@b@        throw new IllegalArgumentException(message);@b@      }@b@    }@b@  }@b@@b@  public static final void throwIaxIfFalse(boolean test, String message)@b@  {@b@    if (!(test))@b@      throw new IllegalArgumentException(message);@b@  }@b@@b@  public static boolean isEmpty(String s)@b@  {@b@    return ((null == s) || (0 == s.length()));@b@  }@b@@b@  public static boolean isEmpty(Object[] ra)@b@  {@b@    return ((null == ra) || (0 == ra.length));@b@  }@b@@b@  public static boolean isEmpty(Collection collection)@b@  {@b@    return ((null == collection) || (0 == collection.size()));@b@  }@b@@b@  public static String[] split(String text)@b@  {@b@    return ((String[])(String[])strings(text).toArray(new String[0]));@b@  }@b@@b@  public static List commaSplit(String input)@b@  {@b@    return anySplit(input, ",");@b@  }@b@@b@  public static String[] splitClasspath(String classpath)@b@  {@b@    if (isEmpty(classpath))@b@      return new String[0];@b@@b@    StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);@b@    ArrayList result = new ArrayList(st.countTokens());@b@    while (st.hasMoreTokens()) {@b@      String entry = st.nextToken();@b@      if (!(isEmpty(entry)))@b@        result.add(entry);@b@    }@b@@b@    return ((String[])(String[])result.toArray(new String[0]));@b@  }@b@@b@  public static boolean getBoolean(String propertyName, boolean defaultValue)@b@  {@b@    if (null != propertyName)@b@      try {@b@        String value = System.getProperty(propertyName);@b@        if (null != value)@b@          return Boolean.valueOf(value).booleanValue();@b@      }@b@      catch (Throwable t)@b@      {@b@      }@b@@b@    return defaultValue;@b@  }@b@@b@  public static List anySplit(String input, String delim)@b@  {@b@    if (null == input)@b@      return Collections.EMPTY_LIST;@b@@b@    ArrayList result = new ArrayList();@b@@b@    if ((isEmpty(delim)) || (-1 == input.indexOf(delim))) {@b@      result.add(input.trim());@b@    } else {@b@      StringTokenizer st = new StringTokenizer(input, delim);@b@      while (st.hasMoreTokens())@b@        result.add(st.nextToken().trim());@b@    }@b@@b@    return result;@b@  }@b@@b@  public static List strings(String text)@b@  {@b@    if (isEmpty(text))@b@      return Collections.EMPTY_LIST;@b@@b@    List strings = new ArrayList();@b@    StringTokenizer tok = new StringTokenizer(text);@b@    while (tok.hasMoreTokens())@b@      strings.add(tok.nextToken());@b@@b@    return strings;@b@  }@b@@b@  public static List safeList(List list)@b@  {@b@    return ((null == list) ? Collections.EMPTY_LIST : Collections.unmodifiableList(list));@b@  }@b@@b@  public static String[][] copyStrings(String[][] in)@b@  {@b@    String[][] out = new String[in.length][];@b@    for (int i = 0; i < out.length; ++i) {@b@      out[i] = new String[in[i].length];@b@      System.arraycopy(in[i], 0, out[i], 0, out[i].length);@b@    }@b@    return out;@b@  }@b@@b@  public static String[] extractOptions(String[] args, String[][] options)@b@  {@b@    if ((isEmpty(args)) || (isEmpty(options)))@b@      return args;@b@@b@    BitSet foundSet = new BitSet();@b@    String[] result = new String[args.length];@b@    int resultIndex = 0;@b@    for (int j = 0; j < args.length; ++j) {@b@      boolean found = false;@b@      for (int i = 0; (!(found)) && (i < options.length); ++i) {@b@        int k;@b@        String[] option = options[i];@b@        throwIaxIfFalse(!(isEmpty(option)), "options");@b@        String sought = option[0];@b@        found = sought.equals(args[j]);@b@        if (found) {@b@          foundSet.set(i);@b@          int doMore = option.length - 1;@b@          if (0 < doMore) {@b@            int MAX = j + doMore;@b@            if (MAX >= args.length) {@b@              String s = "expecting " + doMore + " args after ";@b@              throw new IllegalArgumentException(s + args[j]);@b@            }@b@            for (k = 1; k < option.length; ++k)@b@              option[k] = args[(++j)];@b@          }@b@        }@b@      }@b@@b@      if (!(found)) {@b@        result[(resultIndex++)] = args[j];@b@      }@b@@b@    }@b@@b@    for (int i = 0; i < options.length; ++i) {@b@      if (!(foundSet.get(i)))@b@        options[i][0] = null;@b@@b@    }@b@@b@    if (resultIndex < args.length) {@b@      String[] temp = new String[resultIndex];@b@      System.arraycopy(result, 0, temp, 0, resultIndex);@b@      args = temp;@b@    }@b@@b@    return args;@b@  }@b@@b@  public static Object[] safeCopy(Object[] source, Object[] sink)@b@  {@b@    int resultSize;@b@    Class sinkType = (null == sink) ? Object.class : sink.getClass().getComponentType();@b@    int sourceLength = (null == source) ? 0 : source.length;@b@    int sinkLength = (null == sink) ? 0 : sink.length;@b@@b@    ArrayList result = null;@b@    if (0 == sourceLength) {@b@      resultSize = 0;@b@    } else {@b@      result = new ArrayList(sourceLength);@b@      for (int i = 0; i < sourceLength; ++i)@b@        if ((null != source[i]) && (sinkType.isAssignableFrom(source[i].getClass())))@b@          result.add(source[i]);@b@@b@@b@      resultSize = result.size();@b@    }@b@    if (resultSize != sinkLength)@b@      sink = (Object[])(Object[])Array.newInstance(sinkType, result.size());@b@@b@    if (0 < resultSize)@b@      sink = result.toArray(sink);@b@@b@    return sink;@b@  }@b@@b@  public static String unqualifiedClassName(Class c)@b@  {@b@    if (null == c)@b@      return "null";@b@@b@    String name = c.getName();@b@    int loc = name.lastIndexOf(".");@b@    if (-1 != loc)@b@      name = name.substring(1 + loc);@b@@b@    return name;@b@  }@b@@b@  public static String unqualifiedClassName(Object o)@b@  {@b@    return unqualifiedClassName((null == o) ? null : o.getClass());@b@  }@b@@b@  public static String replace(String in, String sought, String replace)@b@  {@b@    if ((isEmpty(in)) || (isEmpty(sought)))@b@      return in;@b@@b@    StringBuffer result = new StringBuffer();@b@    int len = sought.length();@b@    int start = 0;@b@@b@    while (-1 != (loc = in.indexOf(sought, start))) {@b@      int loc;@b@      result.append(in.substring(start, loc));@b@      if (!(isEmpty(replace)))@b@        result.append(replace);@b@@b@      start = loc + len;@b@    }@b@    result.append(in.substring(start));@b@    return result.toString();@b@  }@b@@b@  public static String toSizedString(long i, int width)@b@  {@b@    String result = "" + i;@b@    int size = result.length();@b@    if (width > size) {@b@      String pad = "                                              ";@b@      int padLength = "                                              ".length();@b@      if (width > padLength)@b@        width = padLength;@b@@b@      int topad = width - size;@b@      result = "                                              ".substring(0, topad) + result;@b@    }@b@    return result;@b@  }@b@@b@  public static String renderExceptionShort(Throwable e)@b@  {@b@    if (null == e)@b@      return "(Throwable) null";@b@@b@    return "(" + unqualifiedClassName(e) + ") " + e.getMessage();@b@  }@b@@b@  public static String renderException(Throwable t)@b@  {@b@    return renderException(t, true);@b@  }@b@@b@  public static String renderException(Throwable t, boolean elide)@b@  {@b@    if (null == t)@b@      return "null throwable";@b@@b@    t = unwrapException(t);@b@    StringBuffer stack = stackToString(t, false);@b@    if (elide)@b@      elideEndingLines(StringChecker.TEST_PACKAGES, stack, 100);@b@@b@    return stack.toString();@b@  }@b@@b@  static void elideEndingLines(StringChecker checker, StringBuffer stack, int maxLines)@b@  {@b@    if ((null == checker) || (null == stack) || (0 == stack.length()))@b@      return;@b@@b@    LinkedList lines = new LinkedList();@b@    StringTokenizer st = new StringTokenizer(stack.toString(), "\n\r");@b@    while ((st.hasMoreTokens()) && (0 < --maxLines))@b@      lines.add(st.nextToken());@b@@b@    st = null;@b@@b@    int elided = 0;@b@    while (!(lines.isEmpty())) {@b@      String line = (String)lines.getLast();@b@      if (!(checker.acceptString(line)))@b@        break;@b@@b@      ++elided;@b@      lines.removeLast();@b@    }@b@@b@    if ((elided > 0) || (maxLines < 1)) {@b@      int EOL_LEN = EOL.length();@b@      int totalLength = 0;@b@      while (!(lines.isEmpty())) {@b@        totalLength += EOL_LEN + ((String)lines.getFirst()).length();@b@        lines.removeFirst();@b@      }@b@      if (stack.length() > totalLength) {@b@        stack.setLength(totalLength);@b@        if (elided > 0)@b@          stack.append("    (... " + elided + " lines...)");@b@      }@b@    }@b@  }@b@@b@  public static StringBuffer stackToString(Throwable throwable, boolean skipMessage)@b@  {@b@    if (null == throwable)@b@      return new StringBuffer();@b@@b@    StringWriter buf = new StringWriter();@b@    PrintWriter writer = new PrintWriter(buf);@b@    if (!(skipMessage))@b@      writer.println(throwable.getMessage());@b@@b@    throwable.printStackTrace(writer);@b@    try {@b@      buf.close();@b@    } catch (IOException ioe) {@b@    }@b@    return buf.getBuffer();@b@  }@b@@b@  public static Throwable unwrapException(Throwable t)@b@  {@b@    Throwable current = t;@b@    Throwable next = null;@b@    while (current != null)@b@    {@b@      if (current instanceof InvocationTargetException)@b@        next = ((InvocationTargetException)current).getTargetException();@b@      else if (current instanceof ClassNotFoundException)@b@        next = ((ClassNotFoundException)current).getException();@b@      else if (current instanceof ExceptionInInitializerError)@b@        next = ((ExceptionInInitializerError)current).getException();@b@      else if (current instanceof PrivilegedActionException)@b@        next = ((PrivilegedActionException)current).getException();@b@      else if (current instanceof SQLException) {@b@        next = ((SQLException)current).getNextException();@b@      }@b@@b@      if (null == next)@b@        break;@b@@b@      current = next;@b@      next = null;@b@    }@b@@b@    return current;@b@  }@b@@b@  public static List arrayAsList(Object[] array)@b@  {@b@    if ((null == array) || (1 > array.length))@b@      return Collections.EMPTY_LIST;@b@@b@    ArrayList list = new ArrayList();@b@    list.addAll(Arrays.asList(array));@b@    return list;@b@  }@b@@b@  public static String makeClasspath(String bootclasspath, String classpath, String classesDir, String outputJar)@b@  {@b@    StringBuffer sb = new StringBuffer();@b@    addIfNotEmpty(bootclasspath, sb, File.pathSeparator);@b@    addIfNotEmpty(classpath, sb, File.pathSeparator);@b@    if (!(addIfNotEmpty(classesDir, sb, File.pathSeparator)))@b@      addIfNotEmpty(outputJar, sb, File.pathSeparator);@b@@b@    return sb.toString();@b@  }@b@@b@  private static boolean addIfNotEmpty(String input, StringBuffer sink, String delimiter)@b@  {@b@    if ((isEmpty(input)) || (null == sink))@b@      return false;@b@@b@    sink.append(input);@b@    if (!(isEmpty(delimiter)))@b@      sink.append(delimiter);@b@@b@    return true;@b@  }@b@@b@  public static ProcessController makeProcess(ProcessController controller, String classpath, String mainClass, String[] args)@b@  {@b@    File java = getJavaExecutable();@b@    ArrayList cmd = new ArrayList();@b@    cmd.add(java.getAbsolutePath());@b@    cmd.add("-classpath");@b@    cmd.add(classpath);@b@    cmd.add(mainClass);@b@    if (!(isEmpty(args)))@b@      cmd.addAll(Arrays.asList(args));@b@@b@    String[] command = (String[])(String[])cmd.toArray(new String[0]);@b@    if (null == controller)@b@      controller = new ProcessController();@b@@b@    controller.init(command, mainClass);@b@    return controller;@b@  }@b@@b@  public static File getJavaExecutable()@b@  {@b@    File binDir;@b@    String[] execs;@b@    int i;@b@    String javaHome = null;@b@    File result = null;@b@    try@b@    {@b@      javaHome = System.getProperty("java.home");@b@    }@b@    catch (Throwable t) {@b@    }@b@    if (null != javaHome) {@b@      binDir = new File(javaHome, "bin");@b@      if ((binDir.isDirectory()) && (binDir.canRead())) {@b@        execs = new String[] { "java", "java.exe" };@b@        for (i = 0; i < execs.length; ++i) {@b@          result = new File(binDir, execs[i]);@b@          if (result.canRead())@b@            break;@b@        }@b@      }@b@    }@b@@b@    return result;@b@  }@b@@b@  public static boolean sleepUntil(long time)@b@  {@b@    if (time == 0L)@b@      return true;@b@    if (time < 0L) {@b@      throw new IllegalArgumentException("negative: " + time);@b@    }@b@@b@    long curTime = System.currentTimeMillis();@b@    for (int i = 0; (i < 100) && (curTime < time); ++i) {@b@      try {@b@        Thread.sleep(time - curTime);@b@      }@b@      catch (InterruptedException e) {@b@      }@b@      curTime = System.currentTimeMillis();@b@    }@b@    return (curTime >= time);@b@  }@b@@b@  static@b@  {@b@    StringWriter buf = new StringWriter();@b@    PrintWriter writer = new PrintWriter(buf);@b@    writer.println("");@b@    String eol = "\n";@b@    try {@b@      buf.close();@b@      StringBuffer sb = buf.getBuffer();@b@      if (sb != null)@b@        eol = buf.toString();@b@    }@b@    catch (Throwable t) {@b@    }@b@    EOL = eol;@b@    try@b@    {@b@      String vm = System.getProperty("java.version");@b@      if (vm == null)@b@        vm = System.getProperty("java.runtime.version");@b@@b@      if (vm == null)@b@        vm = System.getProperty("java.vm.version");@b@@b@      if (vm == null) {@b@        new RuntimeException("System properties appear damaged, cannot find: java.version/java.runtime.version/java.vm.version").printStackTrace(System.err);@b@@b@        vmVersion = 1.5D;@b@      } else {@b@        try {@b@          String versionString = vm.substring(0, 3);@b@          Double temp = new Double(Double.parseDouble(versionString));@b@          vmVersion = temp.floatValue();@b@        } catch (Exception e) {@b@          vmVersion = 1.4D;@b@        }@b@      }@b@    } catch (Throwable t) {@b@      new RuntimeException("System properties appear damaged, cannot find: java.version/java.runtime.version/java.vm.version", t).printStackTrace(System.err);@b@@b@      vmVersion = 1.5D;@b@    }@b@  }@b@@b@  public static class ProcessController@b@  {@b@    private String[] command;@b@    private String[] envp;@b@    private String label;@b@    private boolean init;@b@    private boolean started;@b@    private boolean completed;@b@    private boolean userStopped;@b@    private Process process;@b@    private FileUtil.Pipe errStream;@b@    private FileUtil.Pipe outStream;@b@    private FileUtil.Pipe inStream;@b@    private ByteArrayOutputStream errSnoop;@b@    private ByteArrayOutputStream outSnoop;@b@    private int result;@b@    private Thrown thrown;@b@@b@    public final void reinit()@b@    {@b@      if (!(this.init))@b@        throw new IllegalStateException("must init(..) before reinit()");@b@@b@      if ((this.started) && (!(this.completed))) {@b@        throw new IllegalStateException("not completed - do stop()");@b@      }@b@@b@      this.started = false;@b@      this.completed = false;@b@      this.result = -2147483648;@b@      this.thrown = null;@b@      this.process = null;@b@      this.errStream = null;@b@      this.outStream = null;@b@      this.inStream = null;@b@    }@b@@b@    public final void init(String classpath, String mainClass, String[] args) {@b@      init(LangUtil.getJavaExecutable(), classpath, mainClass, args);@b@    }@b@@b@    public final void init(File java, String classpath, String mainClass, String[] args) {@b@      LangUtil.throwIaxIfNull(java, "java");@b@      LangUtil.throwIaxIfNull(mainClass, "mainClass");@b@      LangUtil.throwIaxIfNull(args, "args");@b@      ArrayList cmd = new ArrayList();@b@      cmd.add(java.getAbsolutePath());@b@      cmd.add("-classpath");@b@      cmd.add(classpath);@b@      cmd.add(mainClass);@b@      if (!(LangUtil.isEmpty(args)))@b@        cmd.addAll(Arrays.asList(args));@b@@b@      init((String[])(String[])cmd.toArray(new String[0]), mainClass);@b@    }@b@@b@    public final void init(String[] command, String label) {@b@      this.command = ((String[])(String[])LangUtil.safeCopy(command, new String[0]));@b@      if (1 > this.command.length)@b@        throw new IllegalArgumentException("empty command");@b@@b@      this.label = ((LangUtil.isEmpty(label)) ? command[0] : label);@b@      this.init = true;@b@      reinit();@b@    }@b@@b@    public final void setEnvp(String[] envp) {@b@      this.envp = ((String[])(String[])LangUtil.safeCopy(envp, new String[0]));@b@      if (1 > this.envp.length)@b@        throw new IllegalArgumentException("empty envp");@b@    }@b@@b@    public final void setErrSnoop(ByteArrayOutputStream snoop)@b@    {@b@      this.errSnoop = snoop;@b@      if (null != this.errStream)@b@        this.errStream.setSnoop(this.errSnoop);@b@    }@b@@b@    public final void setOutSnoop(ByteArrayOutputStream snoop)@b@    {@b@      this.outSnoop = snoop;@b@      if (null != this.outStream)@b@        this.outStream.setSnoop(this.outSnoop);@b@    }@b@@b@    public final Thread start()@b@    {@b@      if (!(this.init))@b@        throw new IllegalStateException("not initialized");@b@@b@      synchronized (this) {@b@        if (this.started)@b@          throw new IllegalStateException("already started");@b@@b@        this.started = true;@b@      }@b@      try {@b@        this.process = Runtime.getRuntime().exec(this.command);@b@      } catch (IOException e) {@b@        stop(e, -2147483648);@b@        return null;@b@      }@b@      this.errStream = new FileUtil.Pipe(this.process.getErrorStream(), System.err);@b@      if (null != this.errSnoop)@b@        this.errStream.setSnoop(this.errSnoop);@b@@b@      this.outStream = new FileUtil.Pipe(this.process.getInputStream(), System.out);@b@      if (null != this.outSnoop)@b@        this.outStream.setSnoop(this.outSnoop);@b@@b@      this.inStream = new FileUtil.Pipe(System.in, this.process.getOutputStream());@b@@b@      Object processRunner = new Runnable(this) { private final LangUtil.ProcessController this$0;@b@@b@        public void run() { Throwable thrown = null;@b@          int result = -2147483648;@b@          try@b@          {@b@            new Thread(LangUtil.ProcessController.access$000(this.this$0)).start();@b@            new Thread(LangUtil.ProcessController.access$100(this.this$0)).start();@b@            new Thread(LangUtil.ProcessController.access$200(this.this$0)).start();@b@            LangUtil.ProcessController.access$300(this.this$0).waitFor();@b@            result = LangUtil.ProcessController.access$300(this.this$0).exitValue();@b@          } catch (Throwable e) {@b@            thrown = e;@b@          } finally {@b@            LangUtil.ProcessController.access$400(this.this$0, thrown, result);@b@          }@b@        }@b@@b@      };@b@      Thread result = new Thread((Runnable)processRunner, this.label);@b@      result.start();@b@      return ((Thread)result);@b@    }@b@@b@    public final synchronized void stop()@b@    {@b@      if (this.completed)@b@        return;@b@@b@      this.userStopped = true;@b@      stop(null, -2147483648);@b@    }@b@@b@    public final String[] getCommand() {@b@      String[] toCopy = this.command;@b@      if (LangUtil.isEmpty(toCopy))@b@        return new String[0];@b@@b@      String[] result = new String[toCopy.length];@b@      System.arraycopy(toCopy, 0, result, 0, result.length);@b@      return result;@b@    }@b@@b@    public final boolean completed() {@b@      return this.completed;@b@    }@b@@b@    public final boolean started() {@b@      return this.started;@b@    }@b@@b@    public final boolean userStopped() {@b@      return this.userStopped;@b@    }@b@@b@    public final Thrown getThrown()@b@    {@b@      return makeThrown(null);@b@    }@b@@b@    public final int getResult() {@b@      return this.result;@b@    }@b@@b@    protected void doCompleting(Thrown thrown, int result)@b@    {@b@    }@b@@b@    private final synchronized void stop(Throwable thrown, int result)@b@    {@b@      if (this.completed)@b@        throw new IllegalStateException("already completed");@b@      if (null != this.thrown) {@b@        throw new IllegalStateException("already set thrown: " + thrown);@b@      }@b@@b@      this.thrown = makeThrown(thrown);@b@      if (null != this.process)@b@        this.process.destroy();@b@@b@      if (null != this.inStream) {@b@        this.inStream.halt(false, true);@b@        this.inStream = null;@b@      }@b@      if (null != this.outStream) {@b@        this.outStream.halt(true, true);@b@        this.outStream = null;@b@      }@b@      if (null != this.errStream) {@b@        this.errStream.halt(true, true);@b@        this.errStream = null;@b@      }@b@      if (-2147483648 != result)@b@        this.result = result;@b@@b@      this.completed = true;@b@      doCompleting(this.thrown, result);@b@    }@b@@b@    private final synchronized Thrown makeThrown(Throwable processThrown)@b@    {@b@      if (null != this.thrown)@b@        return this.thrown;@b@@b@      return new Thrown(processThrown, this.outStream.getThrown(), this.errStream.getThrown(), this.inStream.getThrown(), null);@b@    }@b@@b@    static FileUtil.Pipe access$000(ProcessController x0)@b@    {@b@      return x0.errStream; } @b@    static FileUtil.Pipe access$100(ProcessController x0) { return x0.outStream; } @b@    static FileUtil.Pipe access$200(ProcessController x0) { return x0.inStream; } @b@    static Process access$300(ProcessController x0) { return x0.process; } @b@    static void access$400(ProcessController x0, Throwable x1, int x2) { x0.stop(x1, x2);@b@    }@b@@b@    public static class Thrown@b@    {@b@      public final Throwable fromProcess;@b@      public final Throwable fromErrPipe;@b@      public final Throwable fromOutPipe;@b@      public final Throwable fromInPipe;@b@      public final boolean thrown;@b@@b@      private Thrown(Throwable fromProcess, Throwable fromOutPipe, Throwable fromErrPipe, Throwable fromInPipe)@b@      {@b@        this.fromProcess = fromProcess;@b@        this.fromErrPipe = fromErrPipe;@b@        this.fromOutPipe = fromOutPipe;@b@        this.fromInPipe = fromInPipe;@b@        this.thrown = ((null != fromProcess) || (null != fromInPipe) || (null != fromOutPipe) || (null != fromErrPipe));@b@      }@b@@b@      public String toString() {@b@        StringBuffer sb = new StringBuffer();@b@        append(sb, this.fromProcess, "process");@b@        append(sb, this.fromOutPipe, " stdout");@b@        append(sb, this.fromErrPipe, " stderr");@b@        append(sb, this.fromInPipe, "  stdin");@b@        if (0 == sb.length())@b@          return "Thrown (none)";@b@@b@        return sb.toString();@b@      }@b@@b@      private void append(StringBuffer sb, Throwable thrown, String label)@b@      {@b@        if (null != thrown) {@b@          sb.append("from " + label + ": ");@b@          sb.append(LangUtil.renderExceptionShort(thrown));@b@          sb.append(LangUtil.EOL);@b@        }@b@      }@b@@b@      Thrown(Throwable x0, Throwable x1, Throwable x2, Throwable x3, LangUtil.1 x4)@b@      {@b@        this(x0, x1, x2, x3);@b@      }@b@    }@b@  }@b@@b@  public static class StringChecker@b@  {@b@    static StringChecker TEST_PACKAGES = new StringChecker(new String[] { "org.aspectj.testing", "org.eclipse.jdt.internal.junit", "junit.framework.", "org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner" });@b@    String[] infixes;@b@@b@    StringChecker(String[] infixes)@b@    {@b@      this.infixes = infixes;@b@    }@b@@b@    public boolean acceptString(String input)@b@    {@b@      int i;@b@      boolean result = false;@b@      if (!(LangUtil.isEmpty(input)))@b@        for (i = 0; (!(result)) && (i < this.infixes.length); ++i)@b@          result = -1 != input.indexOf(this.infixes[i]);@b@@b@@b@      return result;@b@    }@b@  }@b@}