package com.rc.retroweaver;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.JarURLConnection;
import java.net.URL;
import java.util.jar.Attributes;
public class WeaveRunner {
private RetroWeaver retroWeaver;
private RetroWeaverClassLoader classLoader;
public WeaveRunner(String classPath) {
// use the current JVM version as the target
String version = System.getProperty("java.version");
int target;
switch (version.charAt(2)) {
case '2':
target = Weaver.VERSION_1_2;
break;
case '3':
target = Weaver.VERSION_1_3;
break;
case '4':
target = Weaver.VERSION_1_4;
break;
case '5':
target = Weaver.VERSION_1_5;
break;
default:
throw new RetroWeaverException("Unsupported JVM version: " + version);
}
retroWeaver = new RetroWeaver(target);
retroWeaver.setLazy(true);
classLoader = new RetroWeaverClassLoader();
classLoader.setClassPath(classPath);
classLoader.setWeaver(retroWeaver);
}
public void run(String className, String[] args)
throws ClassNotFoundException, NoSuchMethodException {
Class clazz = classLoader.loadClass(className);
Method m = clazz.getMethod("main", new Class[] { args.getClass() });
m.setAccessible(true);
int mods = m.getModifiers();
if (m.getReturnType() != void.class || !Modifier.isStatic(mods)
|| !Modifier.isPublic(mods)) {
throw new NoSuchMethodException("main");
}
try {
m.invoke(null, new Object[] { args });
} catch (IllegalAccessException e) {
} catch (InvocationTargetException ite) {
throw new RetroWeaverException(ite);
}
}
public void executeJar(String jarFileName, String[] args)
throws ClassNotFoundException, NoSuchMethodException {
// add jar to class path
classLoader.addJarClassPathElement(jarFileName);
// get class name from MANIFEST
String className = null;
try {
URL u = new URL("jar:file:" + jarFileName + "!/");
JarURLConnection uc = (JarURLConnection) u.openConnection();
Attributes attr = uc.getMainAttributes();
if (attr != null)
className = attr.getValue(Attributes.Name.MAIN_CLASS);
} catch (IOException ioe) {
}
if (className == null) {
System.err.println("No " + Attributes.Name.MAIN_CLASS
+ " specified in jar file " + jarFileName);
} else {
run(className, args);
}
}
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException {
String classPath = null;
String mainClass = null;
String jarFileName = null;
int argIndex = 0;
while (argIndex < args.length) {
String command = args[argIndex++];
if (command.equals("-cp") || command.equals("-classpath")) {
classPath = args[argIndex++];
} else if (command.equals("-jar")) {
jarFileName = args[argIndex++];
break;
} else {
mainClass = command;
break;
}
}
if (jarFileName == null) {
String errorMsg = null;
if (classPath == null)
errorMsg = "Missing class path";
if (mainClass == null)
errorMsg = "Missing main class or jar option";
if (errorMsg != null) {
System.out.println(errorMsg);
System.out.println();
usage();
return;
}
}
String[] realArgs = new String[args.length - argIndex];
System.arraycopy(args, argIndex, realArgs, 0, args.length - argIndex);
WeaveRunner runner = new WeaveRunner(classPath);
if (jarFileName != null)
runner.executeJar(jarFileName, realArgs);
else
runner.run(mainClass, realArgs);
}
private static final String nl = System.getProperty("line.separator");
private static void usage() {
String msg = "Usage: WeaveRunner [-options] class [args...]"
+ nl
+ "\t\t(to execute a class)"
+ nl
+ "\tor WeaveRunner [-options] -jar jarfile [args...]"
+ nl
+ "\t\t(to execute a jar file)"
+ nl
+ nl
+ "where options include:"
+ nl
+ "\t-cp <class search path of directories and zip/jar files>"
+ nl
+ "\t-classpath <class search path of directories and zip/jar files>"
+ nl + "\t\tA " + File.pathSeparatorChar
+ " separated list of directories, JAR archives," + nl
+ "\t\tand ZIP archives to search for class files." + nl;
System.out.println(msg);
}
}