프로그래밍/BCI 썸네일형 리스트형 [Java] ASM EXPAND_FRAMES & SKIP_FRAMES Java 6 에서 스택 맵 프레임이라는 것을 도입했는데, Java 7 에서 부터는 이를 다시 압축해서 저장하기 시작한다. Java 7 에서 컴파일된 바이트 코드를 변환하기 위해 코드를 작성하기 위해서는 ClassReader 인스턴스의 accept 호출 시에 EXPAND_FRAMES 옵션을 주어야 한다. 물론, SKIP_FRAMES 옵션으로 프레임 정보가 완전히 삭제된 바이트 코드를 생성할 수도 있다. 이는, LocalVariablesSorter 라는 지역 변수 생성(코드 참고) 도우미 클래스(물론 이 클래스의 자식들도 포함해서)를 사용 하려고 할 때 적용된다.LocalVariablesSorter 의 부모 클래스인 MethodVisitor를 사용한다면 문제가 되지 않는다. 왜냐하면, 이 MethodVisi.. 더보기 [Java] ASM JSR/RET are not supported with computeFrames option ASM으로 바이트 코드를 변환하다 보면,JSR/RET are not supported with computeFrames option이라는 에러를 볼 수있는데, JSR(Jump to SubRoutine) 과 RET(Return) 을 의미하는 인스트럭션이다. 이는 주로 try {....} finally { } 구문을 위해 사용되었다. 하지만, Jump 가 의미하듯(GOTO 문을 연상해 보자) 코드의 가독성이 떨어진다. 바이트 코드인데 무슨 가독성이냐 하면, 자바의 검증 아키텍쳐에서 코드의 유효성을 검증하기 때문. 이 인스트럭션이 없이도 코드를 만드는 데는 전혀 문제가 없지만, 서브루틴 블럭 만큼의 코드를 인라인으로 복사해야 하기 때문에 코드의 크기가 커질 수 있다. 이런 이유로 코드를 줄이는 툴들이 JSR/.. 더보기 BCI(Byte Code Instrumentation) 자바 바이트 코드를 읽고, 쓰고, 변환 할 수있다. 이는 소스 파일의 변경 없이 원하는 작업을 할 수있다는 것을 의미한다. 오픈 소스 라이브러리BCELASMASM 개요ASM 5 자바 독 바이트 코드의 기본적인 이해 바이트 코드로 변환된 클래스 코드를 이해 하기 위해서는 컴파일된 클래스 구조 및 컴파일된 클래스 내부에서의 타입 및 메소드 표현을 알아야 한다. 이쯤에서 바이트 코드 클래스의 내용을 보고 싶지만 .class 파일은 말 그대로 바이트 코드라 바로 볼 수 있는 뷰어가 없다. 일단 JDK에서 기본으로 제공하는 javap 프로그램을 이용하여 .class파일의 내용을 출력해 보고 위의 내용들이 .class파일에 쓰이고 있다는 것을 확인해 보자. ASM을 이용한 바이트 코드 다루기 ASM 은 ClassV.. 더보기 [Java] ASM으로 메소드 변경하기 ASM으로 메소드 변경하기 메소드의 실행 시간을 알아내는 코드를 삽입하는 작업을 수행한다. 원본 코드로 을 사용한다. 변경을 통해 와 같이 되도록 한다. ASMifier를 통해 어떻게 바뀌어야 하는 지 알아보자. 변경하기 전은 위와 같다. 변경 후는 어떤지 보면 과 를 비교해 보면 mv.visitLdcInsn(new Long(100L));mv.visitMethodInsn(INVOKESTATIC, "java/lang/Thread", "sleep", "(J)V", false); 위 코드를 기준으로 아래 위로 추가된 내용이 보인다. 여기서 어려운 점은, 메소드를 추가 할때와는 달리 기존의 코드 앞뒤에 새로운 코드를 추가해야한다는 것이다. 또한, 메소드 내에서 지역 변수를 하나 사용해야 한다. 이 변수는 메소드.. 더보기 [Java] ASM을 이용한 메소드 추가 하기 ASM으로 메소드 추가 하기 다음과 같은 클래스를 예를 들어보자. 이를 ASM을 이용하여 다음과 같이 바꿔 보자. 우선, 이전 필드 추가 예제를 참고하여 메소드에서 사용할 필드를 추가한다. 완성된 코드는 다음과 같다. 다음 코드로 실행할 수 있다. 더보기 [Java] ASM으로 메소드 생성 하기 ASM으로 메소드 생성 하기 다음과 같은 코드를 생각해 보자. 이를 Textifier를 이용해 보면, 위와 같은 결과가 생성된다. 다음으로 ASMifier를 이용해 보면, 위와 같은 결과가 된다. 보면 알겠지만, 생성하는 좋은 방법은 해당 자바 코드를 작성하고 이를 ASMifier하는 것이다. 더보기 [Java] ASM ClassWriter options ClassWriter options 메소드의 스택 맵 프레임의 계산은 간단하지 않다. 지역 변수나 오퍼랜드 스택도 마찬가지이다. 이를 자동을 계산하도록 하기 위한 ClassWriter의 옵션은 다음과 같다. new ClassWriter(0)자동으로 계산되는 것이 없다.수동으로 모든 것을 계산해야 하기때문에 어려울 수 있지만, 효율적으로 만들 수 있는 여지도 있다.new ClassWriter(ClassWriter.COMPUTE_MAXS)지역 변수 및 오퍼랜드 스택의 크기를 자동 계산한다.여전히 visitMaxs 메소드는 호출해 주어야 한다.호출 시 인자는 어떤 값이 되어도 상관 없다.스택 맵 프레임은 수동으로 계산해야 한다.new ClassWriter(ClassWriter.COMPUTE_FRAMES)모든 .. 더보기 [Java] ASM MethodVisitor ASM MethodVisitor 컴파일된 메소드의 생성이나 변환은 ClassVisitor 클래스의 visitMethod 에서 반환되는 MethodVisitor 추상 클래스를 상속하여 구현된 클래스들에서 이루어진다. 기본적으로 이 클래스는 바이트코드 인스트럭션당 하나의 메소드를 정의한다. 이렇게 정의된 메소드들은 다음 순서에따라 호출되어야 한다. visitAnnotationDefault?( visitAnnotation | visitParameterAnnotation | visitAttribute )*( visitCode( visitTryCatchBlock | visitLabel | visitFrame | visitXxx Insn |visitLocalVariable | visitLineNumber )*vis.. 더보기 [Java] 컴파일된 클래스 내에서의 메소드 개요 컴파일된 클래스에서 메소드는 일련의 바이트코드 인스트럭션들로 저장되어 있다.따라서, 메소드를 변환하거나 생성하기 위해서는 바이트코드 인스트럭션이 어떤 것이고 어떻게 동작하는 지 이해하는 것이 필요하다. 자세한 이해는 JVM 스펙을 참고하고, 여기서는 간단한 변환이나 생성 코딩에 필요한 정도로만 알아보자. 바이트코드 인스트럭션을 이해가기 위해서는 우선 JVM 머신의 실행 모델에 대해 이해할 필요가 있다.자바 코드는 스레드에서 실행되는데, 각각의 스레드는 실행 스택을 가지며, 이는 프레임들로 구성된다. 각각의 프레임은 어떤 하나의 메소드 실행을 나타낸다. 프레임은 두 부분으로 구성된다.로컬 변수 파트랜덤 억세스가 가능한 인덱스를 가지는 변수들로 구성오퍼랜드 스택바이트코드 인스트럭션이 사용할 오퍼랜드 스택St.. 더보기 [Java] ASM Textifier ASM 5 에서 제공하는 유틸리티 클래스이다. .class 파일을 인자로 받아서 바이트코드를 읽을 수 있는 코드로 변환해 출력해준다. 사용법 이전에 만들었던 HelloWorld를 출력한 결과 더보기 이전 1 2 다음 목록 더보기