如果我在我的上下文中调用了Baycode()方法,它会抛出
java.lang.RuntimeException:remaper.by.moofMonkey.Main类被冻结 at javassist.CtClassType.checkModify(CtClassType.java:515) 在javassist.CtClass.getClassFile(CtClass.java:524) 在com.moofMonkey.Main.writeFile(Main.java:340) 在com.moofMonkey.Main.saveClasses(Main.java:324) 在com.moofMonkey.Main.main(Main.java:309)
我的背景:
.....
for (CtClass cl : modClasses) {
cl.stopPruning(true);
writeFile(cl, "./ModifiedClasses"); //cl.writeFile("./ModifiedClasses");
cl.stopPruning(false);
}
.....
public static void writeFile(CtClass cl, String directoryName) throws Throwable {
System.out.println(">> " + cl.getName());
byte[] bc = cl.toBytecode();
String s = cl.getClassFile().getSourceFile();
int index = new String(bc).indexOf(s);
for(int i = 0; i < s.length(); i++) //KILL SOURCEFILE (c) moofMonkey
bc[index + i] = '-';
DataOutputStream out = cl.makeFileOutput(directoryName);
out.write(bc);
out.flush();
out.close();
}
但是......如果我调用writeFile()的模拟 - cl.writeFile() - 一切正常!
我可以这样做:
1. Save File
2. Read bytes from him
3. Dp what I need
4. Save File
答案 0 :(得分:2)
查看CtClass的javadoc揭示了
调用此方法后,无法进一步修改。
如果您将通话顺序更改为
DeserializationContext ctxt = spy(mapper.getDeserializationContext());
doReturn(true).when(ctxt).isEnabled(any(MapperFeature.class));
你可以致电String s = cl.getClassFile().getSourceFile();
byte[] bc = cl.toBytecode();
。
答案 1 :(得分:0)
例外情况不会发生在您拨打toBytecode
的情况下,而是在您呼叫getClassFile
的下一个来源行中。 documentation表示不允许你在冻结的课程上调用它。
有一种名为getClassFile2
的方法似乎可以解决这个问题:
返回此类的类文件(只读)。普通应用程序不需要调用此方法。使用getClassFile()。
此方法获取的ClassFile对象是只读的。对此对象的更改可能不会反映在由toBytecode(),toClass()等生成的类文件中。
即使isFrozen()为true,此方法也可用。但是,如果课程被冻结,它也可能会被修剪。
第一段建议如果有一些方法可以重构你的代码,这样就不需要为冻结的类获取一个类文件,那可能会更好(或者至少是Javassist的创建者更好地考虑) )。