[Java] 바이트코드 조작 ①

홍정완·2022년 7월 28일
0

Java

목록 보기
18/25
post-thumbnail

바이트 코드 조작 라이브러리


바이트 코드 조작 라이브러리는 3가지가 주로 사용된다.


  • ASM
    • 가장 고전적이고, 널리 쓰이는 라이브러리
    • Visitor, Adapter Pattern을 잘 알고 있어야 하며, 학습 비용이 높다.
    • ASM


  • ByteBuddy

    • 위 라이브러리보다 문서가 잘 정리되어 있고, 학습하기 편하다.
    • 성능 우수
    • ByteBuddy API 사용할 줄 알면 쉽게 바이트코드 조작 가능
    • ByteBuddy



pom.xml dependency 추가

	<dependency>
            <groupId>net.bytebuddy</groupId>
            <artifactId>byte-buddy</artifactId>
            <version>1.10.1</version>
    </dependency>

Moja Class

public class Moja {

    public String pullOut() {
        return "";
    }
}

Masulsa Class

public class Masulsa {

    public static void main(String[] args) throws IOException {
    
        System.out.println(new Moja().pullOut());
    }
}

위 코드는 Masulsa Class에서 Moja Class를 호출해도 빈 문자열을 출력한다.


Moja Class의 변경 없이 출력되는 값을 바꿀 수 없을까?


ByteBuddy를 사용해 빈 문자열이 아닌 'Rabbit'을 출력해 보자.



재정의된 Masulsa Class

public class Masulsa {

    public static void main(String[] args) throws IOException {
        try {
            new ByteBuddy().redefine(Moja.class)
                    .method(named("pullOut")).intercept(FixedValue.value("Rabbit"))
                    .make().saveIn(new File("/Users/Hong/Desktop/java 8/HongJungWan-Java8-Java/target/classes/"));
        } catch (IOException e) {
            e.printStackTrace();
        }

//        System.out.println(new Moja().pullOut());
    }
}

  • redefine

    • 어떤 클래스를 재정의한다는 메서드

  • Moja 클래스의 pullOut 메서드를 가로챈 다음 Rabbit이라는 문자열을 리턴하도록 변경

  • 변경된 Moja 클래스를 해당 프로젝트의 target/classes 폴더로 저장

  • ByteBuddy로 작업을 미리 한 뒤, pullOut 메서드를 실행

    • main이 실행되기 전에 클래스 로딩 시 Moja가 로딩이 되어버린다



이전 실행에서는 빈 문자열을 출력했지만, Rabbit이라는 문자열을 리턴하도록 변경된다.


✅ ByteBuddy를 이용해 바이트 코드를 수정

profile
습관이 전부다.

0개의 댓글