错误修改使用JavaAssist现有类

时间:2019-02-01 23:39:50

标签: java bytecode-manipulation java-assist

我正在应对以下CodeWars挑战:

https://www.codewars.com/kata/hack-22/train/java

下面就是我写的:

public static Yossarian loophole() throws Throwable {
    ClassPool pool = ClassPool.getDefault();
    //Loader cl = new Loader(pool);
    CtClass yossarianClass = pool.get("Yossarian");
    int modifiers = yossarianClass.getDeclaredMethod("isCrazy").getModifiers();
    if(Modifier.isFinal(modifiers)) {
        System.out.println("Removing Final");
        int notFinalModifier = Modifier.clear(modifiers, Modifier.FINAL);
        yossarianClass.getDeclaredMethod("isCrazy").setModifiers(notFinalModifier);
        yossarianClass.rebuildClassFile();
    }
    final CtClass saneYossarianClass = ClassPool.getDefault().makeClass("SaneYossarian");
    saneYossarianClass.setSuperclass(yossarianClass);
    final CtMethod overrideMethod = CtNewMethod.make("public boolean isCrazy() { return true; }", saneYossarianClass);
    saneYossarianClass.addMethod(overrideMethod);
    final Class<?> aClass = saneYossarianClass.toClass(Yossarian.class.getClassLoader(), Yossarian.class.getProtectionDomain());
    return (Yossarian) aClass.newInstance();
}

,我收到以下错误:

线程“ main”中的异常javassist.CannotCompileException:由java.lang.ClassFormatError:类SaneYossarian覆盖了最终方法isCrazy。()Z

这是没有意义的!我正是使用JavaAssist来修改原始类。我不是在寻找解决挑战的方法,而只是想了解在修改课程的步骤中我做错了什么。任何帮助表示赞赏。

UPDATE :我还尝试直接修改基类中的方法以返回true,

1 个答案:

答案 0 :(得分:1)

代替

bootstrap = False

使用

final Class<?> aClass = saneYossarianClass.toClass(Yossarian.class.getClassLoader(), Yossarian.class.getProtectionDomain());

出于某些原因,这对我有用:

 final Class<?> aClass = saneYossarianClass.toClass();

并且:

public final class SomeClassHavingFinals {

    public final void sayHelloBoy() {
        System.out.println("I am saying hello original");
    }
}

输出

  

我被覆盖

因此它似乎正在工作。 IDK内部,但似乎toClass()导致文件定义被重建。