内部类使用ASM重命名时出现NoClassDefFoundError

问题描述 投票:0回答:1

我正在尝试使用ASM重命名类,然后再将其写到JAR文件中,然后稍后将其重新加载。我已经实现了我的ASM重新映射器,如下所示:

private static class MyClassRemapper extends Remapper {
    private final String className;

    public MyClassRemapper(Class cls) {
        className = cls.getCanonicalName().replace(".", "/");
    }

    @Override public String map(String internalName) {
        if (internalName.startsWith(className))
            return internalName.replace(className, "New" + className);
        return super.map(internalName);
    }
}

如果我给它喂一些OuterClass,一切都很好。但是,如果我随后将内部类InnerClass添加到OuterClass,则当我尝试在NewOuterClass实例上调用方法(如果需要的话,通过反射)重新加载JAR之后,我会收到错误消息: >

java.lang.NoClassDefFoundError: com/.../NewOuterClass$InnerClass
    at java.base/java.lang.Class.getDeclaredMethods0(Native Method)
    at java.base/java.lang.Class.privateGetDeclaredMethods(Class.java:3139)
    at java.base/java.lang.Class.getMethodsRecursive(Class.java:3280)
    at java.base/java.lang.Class.getMethod0(Class.java:3266)
    at java.base/java.lang.Class.getMethod(Class.java:2063)
    at ...

从错误中可以明显看出,ASM已成功重命名了对InnerClass的某些引用,但显然不是类定义本身。我已经看过实现mapInnerClassName了,但是我很确定我不需要这样做,因为那会改变InnerClass本身。有人有什么想法吗?

编辑

:如果将map功能更改为;
    @Override public String map(String internalName) {
        if (internalName == className)
            return internalName.replace(className, "New" + className);
        return super.map(internalName);
    }

以便只重命名顶级类,然后在尝试运行内部类构造函数时遇到另一个错误:

NoSuchMethodError: com.(...).OuterClass$InnerClass.<init>(Lcom/.../NewOuterClass)V

这表明内部类的方法无法正确重命名。

我正在尝试使用ASM重命名类,然后再将其写到JAR文件中,然后稍后将其重新加载。我已经实现了我的ASM重新映射器,如下所示:私有静态类MyClassRemapper ...

java-bytecode-asm
1个回答
0
投票

Holger在他的评论中提供了解决方案。问题是我只是重新映射外部类的源文件。但是,内部类也有其自己的源文件。解决方案是将MyClassRemapper应用于此并将其写出。

© www.soinside.com 2019 - 2024. All rights reserved.