[java] Javassist를 활용한 특정 클래스의 추적 기능

특정 클래스의 메소드 호출 및 필드 접근을 추적하고 싶을 때, Javassist라는 라이브러리를 활용할 수 있습니다. Javassist는 자바 바이트코드를 수정하고 조작하는 데 사용되는 강력한 도구입니다. 이를 통해 우리는 런타임에 클래스의 동작을 변경하거나 수정할 수 있습니다.

이번 예제에서는 특정 클래스에서 메소드 호출을 추적하는 방법을 살펴보겠습니다.

Javassist 설치

Javassist를 사용하기 위해 먼저 라이브러리를 다운로드해야 합니다. 다음 Maven 종속성을 프로젝트의 pom.xml 파일에 추가하여 Javassist를 설치할 수 있습니다.

<dependency>
    <groupId>org.javassist</groupId>
    <artifactId>javassist</artifactId>
    <version>3.27.0-GA</version>
</dependency>

추적 기능 구현

다음은 추적 기능을 구현하는 예제 코드입니다.

import javassist.*;
import java.lang.instrument.*;

public class MethodTracerAgent {
    public static void premain(String agentArgs, Instrumentation inst) {
        ClassFileTransformer transformer = (ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) -> {
            if (className.equals("com.example.MyClass")) {
                try {
                    CtClass ctClass = ClassPool.getDefault().get(className.replace("/", "."));
                    
                    for (CtMethod method : ctClass.getDeclaredMethods()) {
                        method.insertBefore("{ System.out.println(\"Entering method: " + method.getName() + "\"); }");
                        method.insertAfter("{ System.out.println(\"Exiting method: " + method.getName() + "\"); }");
                    }
                    
                    byte[] byteCode = ctClass.toBytecode();
                    ctClass.detach();
                    
                    return byteCode;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            
            return null;
        };
        
        inst.addTransformer(transformer);
    }
}

위 코드에서 com.example.MyClass 클래스에서 메소드 호출을 추적하고, 해당 메소드의 진입 및 종료를 출력하도록 하였습니다.

agent 설정

Agent를 사용할 경우, jar 파일을 만들어 JVM 옵션으로 지정해주어야 합니다. 다음은 MANIFEST.MF 파일의 내용입니다.

Manifest-Version: 1.0
Premain-Class: MethodTracerAgent

다음 명령어로 jar 파일을 생성할 수 있습니다.

jar -cvfm method-tracer-agent.jar MANIFEST.MF MethodTracerAgent.class

추적 기능 실행

아래 명령어를 통해 추적 기능을 실행할 수 있습니다.

java -javaagent:path/to/method-tracer-agent.jar -cp path/to/your-classpath com.example.Main

path/to/method-tracer-agent.jarcom.example.Main은 각각 생성한 jar 파일과 추적하고자 하는 메인 클래스로 변경해야 합니다.

결론

이번 예제를 통해 Javassist를 활용하여 특정 클래스의 메소드 호출을 추적하는 기능을 구현하는 방법을 알아보았습니다. Javassist는 자바 바이트코드 조작에 강력한 도구이며, 이를 통해 프로그램의 동작을 유연하게 수정할 수 있습니다.