2017-05-23 1 views
1

사용 사례를내가 자바 SE8 <code>ClassFileTransformer</code> 구현을 작성하려고 해요

을 실행하지 ClassTransformer를. 이것의 목표는 디버깅입니다. 나는 BTrace에 대해 잘 알고 있지만, 실제로하려고하는 것에 대한 청구서에 맞지 않습니다. 즉, 내부 메서드 수준 검사입니다. BTrace는 중단 점을 입력/종료로 제한합니다. 나는 이것에 대해 자세히 알고 싶었다.

그래서 지금은 ASM으로이 작업을 직접 수행 할 수 있다고 생각했습니다.

그래서 나는 간단한 ClassFileTransformer를 정의하여 시작


문제 (ASM는 ByteBuddy 및 BTrace 사용하는 바이트 코드 조작 라이브러리입니다).

public class PreMainInjection { 
    public static void premain(String agentArgs, 
      Instrumentation inst) { 
     inst.addTransformer(new EntryPoint(), true); 
    } 
} 

public class EntryPoint implements ClassFileTransformer { 
    public EntryPoint() { } 
    @Override 
    public byte[] transform(ClassLoader classloader, String name, 
      Class<?> clazz, ProtectionDomain prot, byte[] data) { 
     System.out.printf("Loaded: %s\n", name); 
    } 
} 

그리고 완벽하게 작동했습니다. D 모든 클래스의 목록이 내가 조사 할 응용 프로그램으로 표시됩니다.

이제 ASM을 가져옵니다.

public class PreMainInjection { 
    public static void premain(String agentArgs, 
      Instrumentation inst) { 
     inst.addTransformer(new EntryPoint(), true); 
    } 
} 

public class EntryPoint implements ClassFileTransformer { 
    public EntryPoint() { } 
    @Override 
    public byte[] transform(ClassLoader classloader, String name, 
      Class<?> clazz, ProtectionDomain prot, byte[] data) { 
     ClassReader reader = new ClassReader(bytes); 
     ClassNode node = new ClassNode(); 
     ClassWriter writer = new ClassWriter(
      ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); 
     reader.accept(node, ClassReader.EXPAND_FRAMES); 
     System.out.printf("Name: %s", node.name); 
     node.accept(writer); 
     return writer.toByteArray(); 
    } 
} 

이것은 작동합니다 ... 지금까지 내 앱이 중단되지 않습니다. 하지만 단일 디버그 출력을 보지 못했습니다.

그럼 어떻게 될까요? 내 에이전트가 그냥 응용 프로그램은 여전히 ​​작동

System.out.printf("Loaded %s\n", name); 
return null; 

않는 경우

더 확장하려면 내가 출력을 볼 수 있습니다. 그래서 나는 매우 혼란 스럽다.

+0

'ASM'이란 무엇입니까? –

+0

@MarkStewart https://en.wikipedia.org/wiki/ObjectWeb_ASM? –

+0

ASM : http://asm.ow2.org/ 자바 바이트 코드 조작 라이브러리. OP를 업데이트하여이를 반영하고 더 나은 참조를 제공하십시오. –

답변

0

ASM이 얼마나 어려울 수 있는지에 대한 첫 번째 질문에 대답하십시오. 매우 어렵습니다.

실제로 말하면 인쇄 결과에 도달하기 전에 예외가 발생했을 수 있습니다. 클래스 파일 변환기를 사용하면 transform 메서드에서 벗어날 경우 예외가 표시되지 않습니다. try-catch 블록에 코드를 래핑하여 예외가 발생했는지 확인하려고 했습니까?

또한 ASM을 에이전트에 묶지 않았을 가능성이 있습니다. 이 경우 변압기가 실행되는 동안 예외가 아닌 오류가 발생합니다. 마지막으로, 문제의 원인이 될 수있는 참조 된 모든 클래스 파일에 대한 액세스가 필요하기 때문에 프레임 계산없이 에이전트를 시험해 보겠습니다.

0

그래서 나는 ClassReader의 전체 방문이 실시 된 후

ClassNode의 내부 필드는 인스턴스화 이상한 가장자리 경우 타격을 한 것으로 나타났습니다. 그렇기 때문에 정적으로 증명할 수 있습니다. System.out.printf("Name: %s", node.name);은 컴파일시 항상 NullPointerException을 반환합니다.

그래서 JVM이 단순히 내 ClassFileTransformer을로드하지 않는다고 생각합니다.

어느 쪽이든 나는 시스템을 작동시키고있다.

관련 문제