package ariba.awreload;
import java.io.File;
import ariba.util.core.Assert;
import ariba.util.core.ClassUtil;
import ariba.ui.aribaweb.util.AWResource;
import java.util.List;
import java.lang.instrument.ClassDefinition;
import java.lang.reflect.Method;
import java.lang.reflect.InvocationTargetException;
public class HotSwapFactory
{
// hotswap (ClassDefinition[] defns, Boolean[]succeeded)
public static final String HotSwapMethodName = "hotswap";
public static final Class[] HotSwapMethodParams = new Class[]{ClassDefinition[].class, Boolean[].class};
public static class ClassSpec {
public Class _cls;
public byte[] _bytecode;
public File _file;
public ClassSpec (Class cls, byte[] bytecode, File f)
{
_cls = cls;
_bytecode = bytecode;
_file = f;
}
}
private static final String JVMTI_RELOADER_CLASS_NAME =
"ariba.awreload.jmti.JVMTIClient";
/**
* Try first with JDK 5 and failover on Java 1.4 HotSwap (requires native module)
*/
private static Object _Instance = null;
private static Method _Method = null;
public static Object instance()
{
if (_Instance == null) {
try {
Class redefinerClass = Class.forName(JVMTI_RELOADER_CLASS_NAME);
_Instance = redefinerClass.newInstance();
_Method = redefinerClass.getMethod(HotSwapMethodName, HotSwapMethodParams);
Assert.that(_Method != null, "Can't find hotswap method on class %s", redefinerClass);
} catch (Throwable t) {
System.out.println("Exception initializing AWRelaod: " + t);
}
}
return _Instance;
}
public static void hotswap (List<ClassSpec> classSpecs)
{
if (_Method == null) return;
ClassDefinition[] changes = new ClassDefinition[classSpecs.size()];
for (int i=0; i<classSpecs.size(); i++) {
ClassSpec spec = classSpecs.get(i);
changes[i] = new ClassDefinition(spec._cls, spec._bytecode);
}
Boolean[] succeeded = new Boolean[classSpecs.size()];
try {
_Method.invoke(_Instance, changes, succeeded);
} catch (IllegalAccessException e) {
e.printStackTrace();
return;
} catch (InvocationTargetException e) {
e.printStackTrace();
return;
}
JavaReloadClassLoader loader = (JavaReloadClassLoader)ClassUtil.getClassFactory();
for (int i=0; i<classSpecs.size(); i++) {
ClassSpec spec = classSpecs.get(i);
if (succeeded[i]) {
loader.loadSucceeded(spec);
} else {
loader.loadFailed(spec);
}
}
}
}