2013-02-13 2 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(), ...) 
관련 문제