我正在尝试使用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 ...
Holger在他的评论中提供了解决方案。问题是我只是重新映射外部类的源文件。但是,内部类也有其自己的源文件。解决方案是将MyClassRemapper
应用于此并将其写出。