바이트 코드 조작
바이트 코드 조작
라이브러리
ASM
visitor 패턴, adapter 패턴을 이해해야 사용하기 쉽다.
Javaassist
ByteBuddy
가장 간단하게 바이트 코드를 조작할 수 있다.
조작 예제
아래와 같이 빈 문자열을 반환하는 메서드를 가진 Moja 클래스의 바이트코드를 조작하여 Rabbit을 반환하도록 만들 수 있다.
자바 에이전트
소개
클래스 로딩 시 자바 에이전트를 거쳐 변경된 바이트 코드가 메모리에 저장되어 사용된다.
모델
premain 모델
애플리케이션 구동 시 옵션을 주어 에이전트를 연동하는 방식
agent 모델
구동중인 프로세스에 에이전트를 연동하는 방식
속성
Can-Redefine-Classes
에이전트에 의해 클래스를 재정의할 수 있는지 여부 설정
can-Retransform-Classes
에이전트에 의해 클래스를 변형할 수 있는지 여부 설정
실습
bytebuddy에 대한 의존성을 등록해주고 아래와 같이 AgentBuilder를 통해 에이전트 클래스를 생성한다.
아래와 같이 premain 클래스를 등록하고 redifine, retransform 속성을 활성화한다.
./gradlew build
를 통해 생성된 agent jar 파일을 사용해 애플리케이션을 실행하면 클래스로딩 시 에이전트에 의해 변경된 바이트 코드가 애플리케이션에서 사용된다. 이 때 클래스 파일이 변경되지는 않는다.
바이트 코드 조작 활용
프로그램 분석
코드에서 버그를 찾거나 복잡도를 계산하는 툴에서 사용할 수 있다.
클래스 파일 생성
프록시 클래스 생성, 특정 API 호출 접근 제한, 스칼라 등 JVM 언어의 컴파일러에서 사용할 수 있다.
Mockito, Pinpoint 등 프로파일러, 최적화, 로깅 등 다양한 경우에 사용된다.
스프링의 컴포넌트 스캔에서도 후보 클래스 정보를 찾는 데에 ASM 라이브러리가 사용된다.
ClassPathScanningCandidateComponentProvider 클래스를 통해 컴포넌트 스캔이 진행되며, SimpleMetadataReader 클래스에서 ClassReader와 Visitor를 사용해 클래스에 있는 메타 정보를 읽어온다.
Last updated