반응형
메이븐 Bytebuddy 설정
<dependency>
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.11.0</version>
</dependency>
Moja.java
public class Moja {
public String pullOut() {
return "";
}
}
Moja.class 바이트 코드 조작하기
public class Masulsa {
public static void main(String[] args) {
try {
new ByteBuddy().redefine(Moja.class)
.method(named("pullOut")).intercept(FixedValue.value("Rabbit!"))
.make().saveIn(new File("F:\\classloader-sample\\target\\classes\\"));
} catch (IOException e) {
e.printStackTrace();
}
// System.out.println(new Moja().pullOut());
}
}
기존 Moja.class
public class Moja {
public Moja() {
}
public String pullOut() {
return "";
}
}
조작된 Moja.class
public class Moja {
public Moja() {
}
public String pullOut() {
return "Rabbit!";
}
}
- Bytebuddy를 이용해서 Moja.class를 재정의한다.
- Moja에 있는 pullOut 메소드를 가로채서 고정된 값인 Rabbit!을 출력하도록 설정하고 클래스 파일이 존재하는 폴더 위치를 지정해주면 해당 코드 실행 시 바이트 코드가 변경이 된다.
- System.out.println과 동시에 사용하면 바이트코드 조작이 먹히지 않는다. 그 이유는 실행을 하게 되면, Masulsa.class, Moja.class로 컴파일되고 클래스로딩 과정에서 메소드 영역에 해당 클래스와 메소드와 관련된 정보들이 저장된다. 그 이후에 Bytebuddy통해서 Moja.class 파일을 조작한다고해도 이미 로딩된 클래스 정보(메소드 영역에 있는)를 보고 값을 출력하고있기 때문에 Rabbit!이 표시되지않는다.
- 처음 실행할때는 위와 같은 이유로 Rabbit! 문구가 표시가 되지않지만 두 번째 실행부터는 별도로 Moja.java 파일을 다시 컴파일 하지 않는다면 Bytebuddy가 Moja.class 파일을 조작한 상태이기 때문에 Rabbit! 문구가 표시된다.
반응형
'Java > 기본' 카테고리의 다른 글
자바 리플렉션(Java Reflection) API - 클래스 정보 조회 (0) | 2021.05.29 |
---|---|
자바(Java) 바이트 코드 조작관련 - 자바 에이전트 (0) | 2021.05.29 |
자바(Java) 바이트 코드 조작관련 - 코드 커버리지 (0) | 2021.05.26 |
자바(Java) - 클래스 로더 시스템 구조 이해하기 (0) | 2021.05.25 |
자바(Java) - JVM 구조 이해하기 (0) | 2021.05.24 |
[참고자료]
더 자바, 코드를 조작하는 다양한 방법, 백기선