简体   繁体   English

如何使用ASM重命名类并保留在同一类加载器中?

[英]How to rename a class with ASM and stay in the same classloader?

I'm trying to rename a class using ASM 4.0 : 我正在尝试使用ASM 4.0重命名类:

ClassReader reader = new ClassReader(
    loader.getResourceAsStream("test/MyClass.class")
);
ClassWriter writer = new ClassWriter(reader, 0);
ClassVisitor visitor = new RemappingClassAdapter(visitor, new Remapper() { /* skipped */ });
reader.accept(visitor, 0);
return new ClassLoader() {
    public Class<?> load(final String name, final byte[] bytes) {
        return this.defineClass(name, bytes, 0, bytes.length);
    }
}.load("test/MyClass", writer.toByteArray());

I skipped the renaming part intentionally. 我故意跳过了重命名部分。 A new class should be an exact copy of the original one. 一个新的类应该是原始类的精确副本。 It is, but it can't be used any more as an old one: 是的,但是不能再用作旧的:

java.lang.ClassCastException: test.MyClass cannot be cast to test.MyClass

How to stay in the same class loader? 如何留在同一个类的加载器中?

In the JVM, each class is identified by it's fully qualified name AND the class loader which loaded the class. 在JVM中,每个类都由其全限定名和加载该类的类加载器标识。 This explains your ClassCastException. 这解释了您的ClassCastException。

Once you rename the class, you should be able to load your renamed class in any classloader. 重命名该类后,您应该能够在任何类加载器中加载重命名的类。 Use reflection to get hold of the "ClassLoader.defineClass()" method and use it to call it on getClass().getClassLoader(); 使用反射来获取“ ClassLoader.defineClass()”方法,并使用它在getClass()。getClassLoader()上对其进行调用;

Method m=ClassLoader.class.getDeclaredMethod("defineClass",
 String.class,byte[].class,int.class,int.class) 
m.setAccessible(true);
m.invoke(getClass().getClassLoader(), ... )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM