바이트 코드 조작

김민지·2022년 10월 20일
0

자바

목록 보기
8/21

Java Agent

위의 예시에서, 바이트 코드 조작부와 조작 대상의 클래스를 사용하는 부분 new Moja().pullOut() 을 동시에 사용할 수 없었다. 이유는, 바이트 코드 조작부에 의하여 빌드된 target 내 Moja.class 는 조작되겠지만, 그 전에 클래스 로더에 의해 조작되기 전 Moja.class 가 메모리에 먼저 올라가기 때문이다. 즉, new Moja().pullOut() 는 메모리에 이미 올라온, 조작되기 전 Moja.class 를 사용하게 된다.

따라서 조작부를 클래스로더가 프로젝트 내 클래스들을 읽기 전에 먼저 실행되게할 필요가 있는데, 이러한 방법 중 하나로 Agent 를 사용할 수 있다. Agent 는 java 에서 지원하는 스펙 중 하나로, 실행 과정에서 클래스 로더에 거치기 전에 Agent 가 먼저 실행된다. 즉 이 Agent 에 바이트 코드 조작부를 넣으면 클래스 로더는 조작된 Moja.class 를 읽게 되는 것이다.

  1. 바이트 코드 조작
  2. 조작된 코드를 메모리에 올려야함
    이래야하는데
    코드는 바이트코드조작 -> 클래스사용 순이지만
    조작되기전 클래스가 메모리에 로드됨 -> 바이트 코드 조작됨 -> 메모리에 로드됐던 클래스를 사용하여 메서드 호출
    이렇게 되기때문에.. 조작된 코드가 실행안된다.
    이를 해결하기 위해서는 메모리에 올리기 전에 바이트 코드를 조작해야한다.
    이걸 가능하게 해주는게 agent

배운내용정리

바이트코드 조작
자바는 .java 를 컴파일해서 .class파일을 만든다
.class파일을 보고 바이트 코드라고 한다
컴파일한뒤에 클래스로더가 class파일을 jvm의 메모리에 올린다 그리고 사용하는 순서이다
그런데 이 과정에서 컴파일된 파일을 수정한다면 어떻게 될까?
나의 파일은 a를 출력하라고하지만 내가 컴파일된파일을 수정하여 b를 출력하라고 한다면
b를 출력하게 할 수 있다.
근데 바이트코드조작을 사용할때 유의 해야할점이 있는데 코드 순서는
1. 바이트 코드 조작
2. 조작된 코드에 대한 메서드 호출
이겠지만 실제로는 바이트코드가 조작되기 전에 클래스가 메모리에로드된다
그리고 바이트 코드는 target하위에 있는 class파일을 조작한다
나는 메모리에 로드된것을 사용하기 때문에 조작된 파일에 대한 메서드출력내용이 보이지 않는다
그래서 2번을 주석해제하고 1번을 실행한 뒤에 2번만 따로 실행해야 그게 가능해진다.
지금 이 상황에서의 문제는 로드가 먼저 된다음에 target하위에있는 클래스를 조작한다는 점이다.
조작을 한 다음에 그 조작한 class파일을 로드해야한다.
이를가능하게 하는게 agent다


출처
https://dailyheumsi.tistory.com/199

profile
안녕하세요!

0개의 댓글