JavaSsist:toBytecode()抛出异常java.lang.RuntimeException:remaper.by.moofMonkey.Main类被冻结但是他没有被冻结

时间:2016-05-03 09:55:00

标签: java class javassist

如果我在我的上下文中调用了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

2 个答案:

答案 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的创建者更好地考虑) )。