use of org.fakereplace.data.ClassDataBuilder in project fakereplace by fakereplace.
the class Fakereplace method redefine.
public static void redefine(ClassDefinition[] classes, AddedClass[] addedData, boolean wait) {
try {
for (AddedClass i : addedData) {
ClassFile cf = new ClassFile(new DataInputStream(new ByteArrayInputStream(i.getData())));
mainTransformer.addNewClass(new NewClassData(i.getClassName(), i.getLoader(), cf));
}
for (ClassDefinition i : classes) {
ClassDataStore.instance().markClassReplaced(i.getDefinitionClass());
BaseClassData baseClassData = ClassDataStore.instance().getBaseClassData(i.getDefinitionClass().getClassLoader(), i.getDefinitionClass().getName());
if (baseClassData != null) {
ClassDataStore.instance().saveClassData(i.getDefinitionClass().getClassLoader(), i.getDefinitionClass().getName(), new ClassDataBuilder(baseClassData));
}
}
for (AddedClass c : addedData) {
ClassLookupManager.addClassInfo(c.getClassName(), c.getLoader(), c.getData());
}
inst.redefineClasses(classes);
clearJvmCaches();
if (wait) {
mainTransformer.waitForTasks();
}
} catch (Throwable e) {
try {
// dump the classes to /tmp so we can look at them
for (ClassDefinition d : classes) {
try {
ByteArrayInputStream bin = new ByteArrayInputStream(d.getDefinitionClassFile());
DataInputStream dis = new DataInputStream(bin);
final ClassFile file = new ClassFile(dis);
Transformer.getManipulator().transformClass(file, d.getDefinitionClass().getClassLoader(), true, new HashSet<>());
String dumpDir = AgentOptions.getOption(AgentOption.DUMP_DIR);
if (dumpDir != null) {
FileOutputStream s = new FileOutputStream(dumpDir + '/' + d.getDefinitionClass().getName() + "1.class");
DataOutputStream dos = new DataOutputStream(s);
file.write(dos);
dos.flush();
dos.close();
// s.write(d.getDefinitionClassFile());
s.close();
}
} catch (IOException a) {
a.printStackTrace();
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
throw (new RuntimeException(e));
}
}
Aggregations