JavaSsist:toBytecode()抛出异常java.lang.RuntimeException:remaper.by.moofMonkey.Main类已冻结,但him未';t冻结

JavaSsist:toBytecode()抛出异常java.lang.RuntimeException:remaper.by.moofMonkey.Main类已冻结,但him未';t冻结,java,class,javassist,Java,Class,Javassist,如果我在上下文中调用toBytecode()方法,它会抛出 java.lang.RuntimeException:remaper.by.moofMonkey.Main类已冻结 在javassist.CtClassType.checkModify(CtClassType.java:515) 位于javassist.CtClass.getClassFile(CtClass.java:524) 位于com.moofMonkey.Main.writeFile(Main.java:340) 位于com.m

如果我在上下文中调用toBytecode()方法,它会抛出

java.lang.RuntimeException:remaper.by.moofMonkey.Main类已冻结 在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();
}

在调用
toBytecode
的地方不会出现异常,而是在下一个源代码行中调用
getClassFile
。上面说你不能在冻结的类上调用这个

有一个名为
getClassFile2
的方法似乎是为了解决这个问题:

返回该类的类文件(只读)。普通应用程序不需要调用此方法。使用getClassFile()

通过此方法获得的类文件对象是只读的。对该对象的更改可能不会反映在由toBytecode()、toClass()等生成的类文件上

即使isfreeze()为true,此方法也可用。但是,如果类被冻结,它也可能被删除


第一段建议,如果有某种方法可以重新构造代码,使其不需要为冻结的类获取类文件,那么这可能会更好(或者至少Javassist的创建者会更好地考虑)

一旦调用此方法,就不可能再进行进一步修改

如果您将呼叫顺序更改为

String s = cl.getClassFile().getSourceFile();
byte[] bc = cl.toBytecode();

您可以调用
toBytecode

文档不足-请注意:3大多数人喜欢文档,不喜欢复制粘贴。抱歉。@moofMonkey
大多数人都喜欢文档
这些就是自己找到这种解决方案的文档。;-)这很有用:-)重新加载页面:3你在顶部!)问题解决了。特别感谢@SubOptimal
String s = cl.getClassFile().getSourceFile();
byte[] bc = cl.toBytecode();