2013-02-13 4 views
2

Я пытаюсь переименовать класс, используя ASM 4.0:Как переименовать класс с ASM и остаться в одном загрузчике классов?

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()); 

я пропустил переименование части намеренно. Новый класс должен быть точной копией оригинала. Это, но он больше не может использоваться как старый:

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

Как оставаться в этом же загрузчике классов?

ответ

1

В JVM каждый класс идентифицируется его полным именем И загрузчиком класса, который загружал класс. Это объясняет ваше исключение ClassCastException.

Как только вы переименуете класс, вы сможете загрузить свой переименованный класс в любой загрузчик классов. Используйте отражение, чтобы получить метод 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(), ...)