BCI ( Byte Code Instrumentation )์„ ์œ„ํ•œ ASM 5.0 ํ”„๋ ˆ์ž„ ์›Œํฌ์— ๋Œ€ํ•ด์„œ ๊ณต๋ถ€ํ•ด๋ณผ ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

ASM์— ๋Œ€ํ•œ ์‚ฌ์šฉ์ž๋ฉ”๋‰ด์–ผ ๋ฐ ๊ฐœ๋ฐœ์ž๊ฐ€์ด๋“œ๋Š” http://asm.ow2.org/index.html ์ด๊ณณ์—์„œ ์‰ฝ๊ฒŒ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

์˜ค๋Š˜์€ ๊ทธ ์ฒซ ์‹œ๊ฐ„. ์‚ฌ์šฉ์ž ๋ฉ”๋‰ด์–ผ์„ ์ฝ์–ด๊ฐ€๋ฉด์„œ ์กฐ๊ธˆ์”ฉ ์กฐ๊ธˆ์”ฉ ์ •๋ฆฌํ•ด์„œ ๋ธ”๋กœ๊ทธ์— ์˜ฌ๋ฆด ์˜ˆ์ •์ž…๋‹ˆ๋‹ค.

์˜ค๋Š˜์€ ํด๋ž˜์Šค ํŒŒ์ผ ์ฝ์–ด์„œ ์ •๋ณด ์–ป์–ด์˜ค๋Š” ๋ถ€๋ถ„๋งŒ ์•Œ์•„๋ณด๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์šฐ์„  ์ดํด๋ฆฝ์Šค์— ASM 5.0 ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.  

 

http://forge.ow2.org/project/showfiles.php?group_id=23

 

์œ„ ๋งํฌ์— ๊ฐ€์‹œ๋ฉด ๋ฒ„์ „๋ณ„๋กœ zip ํŒŒ์ผ์„ ๋‹ค์šด๋กœ๋“œ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.( ๋งํฌ๊ฐ€ ๊นจ์งˆ ๊ฒƒ์„ ์—ผ๋ คํ•˜์—ฌ ์ตœ์‹  ๋ฒ„์ „ 5.0.3์„ ์ฒจ๋ถ€ํ•˜์˜€์Šต๋‹ˆ๋‹ค )

 

๋‹ค์šด๋กœ๋“œ ๋ฐ›์€ zipํŒŒ์ผ์„ ์••์ถ•ํ•ด์ œ๋ฅผ ํ•ฉ๋‹ˆ๋‹ค.

 

์ด์ œ ์ดํด๋ฆฝ์Šค๋ฅผ ์‹คํ–‰์‹œํ‚ค๊ณ  ํ”„๋กœ์ ํŠธ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ๊ธฐ๋งŒํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

configure build pathํ•˜์…”์„œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ถ”๊ฐ€ํ•˜๋ฉด ์„ค์น˜ ์™„๋ฃŒ!

 

์ž ์ด์ œ ํ”„๋ ˆ์ž„์›Œํฌ๋ฅผ ์„ค์น˜ํ–ˆ์œผ๋‹ˆ ์‚ฌ์šฉํ•ด๋ณด๊ธฐ๋กœ ํ•˜์ฃ .

 

BCITestํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ณ  ๊ทธ ๋ฐ‘์— ์„ธ ๊ฐœ์˜ ํด๋ž˜์Šค ํŒŒ์ผ์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค.

 

BCITest.java
HelloWorld.java
MyClassVisitor.java

 

// BCITest.java ์†Œ์Šค ( JUnit Test๋ฅผ ์ด์šฉํ–ˆ์Šต๋‹ˆ๋‹ค ) 


package BCItest;

import java.io.IOException;
import org.junit.Test;
import org.objectweb.asm.ClassReader;

public class BCITest {
    @Test
    public void test() throws IOException {
        MyClassVisitor cv = new MyClassVisitor(327680);    // ASM5 = 327680
        ClassReader cr = new ClassReader("BCITest.HelloWorld");       // ๋Œ€์†Œ๋ฌธ์ž ๊ตฌ๋ถ„ X ( bcitest.helloworld ๋ผ๊ณ ํ•ด๋„ ์‹คํ–‰๋จ )
        cr.accept(cv, 2);
    }

 

ํ…Œ์ŠคํŠธ ํ•ด๋ณด์‹ค ๋•Œ์—๋Š” BCITest.HelloWorld ๋Œ€์‹ ์— ๋‹ค๋ฅธ ์ž„์˜์˜ ํด๋ž˜์Šค๋ฅผ ๋„ฃ์–ด๋ณด์‹œ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด java.lang.String์ด๋ผ๋“ ๊ฐ€ java.lang.Exception์ด๋ผ๋“ ๊ฐ€ ํ•˜๋Š” ํด๋ž˜์Šค๋“ค ๋ง์ด์ฃ .

 

// HelloWorld.java ์†Œ์Šค

 

package BCItest;

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!!");
    }
}

 

// MyClassVisitor.java ์†Œ์Šค

package BCItest;

import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.TypePath;

public class MyClassVisitor extends ClassVisitor {

    public MyClassVisitor(int arg0) {
        super(arg0);
    }
    @Override
    public void visit(int version, int access, String name,
            String signature, String superName, String[] interfaces) {
        super.visit(version, access, name, signature, superName, interfaces);
        System.out.println(name + " extends " + superName + " {");
    }
    @Override
    public void visitEnd() {
        super.visitEnd();
        System.out.println("}");
    }
    @Override
    public FieldVisitor visitField(int access, String name, String desc,
            String signature, Object value) {
        System.out.println(" " + desc + " " + name);
        return super.visitField(access, name, desc, signature, value);
    }
    @Override
    public MethodVisitor visitMethod(int access, String name,
            String desc, String signature, String[] exceptions) {
        System.out.println(" " + name + desc);
        return super.visitMethod(access, name, desc, signature, exceptions);
    }
}
 

์œ„์—์„œ MyClassVisitor๋Š” ClassVisitor๋ฅผ ์ƒ์†ํ•œ ๋’ค ๋ช‡๋ช‡ ๋ฉ”์†Œ๋“œ๋งŒ ์˜ค๋ฒ„๋ผ์ด๋“œ ํ–ˆ์Šต๋‹ˆ๋‹ค.

 

์šฐ์„  ์ œ๊ฐ€ ์ œ๊ณตํ•ด๋“œ๋ฆฐ ์†Œ์Šค๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•˜๋ฉด ์•„๋ž˜์™€ ๊ฐ™์€ ๊ฒฐ๊ณผ๊ฐ€ ๋‚˜์˜ต๋‹ˆ๋‹ค.

 

BCItest/HelloWorld extends java/lang/Object {
 <init>()V
 main([Ljava/lang/String;)V

 

์—ฌ๊ธฐ์„œ <init>์€ ์ƒ์„ฑ์ž๋ฅผ ๋งํ•˜๊ณ  ๋งˆ์ง€๋ง‰์˜ V๋Š” void๋ฅผ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.  

 

์–ด๋–ค๊ฐ€์š”? ์–ด๋ ต์ง€ ์•Š์ฃ ?   

 

HelloWorld ํด๋ž˜์Šค์— ๋ฉ”์†Œ๋“œ๋ฅผ ๋” ๋„ฃ์–ด๋ณด๊ณ  ( ๋ฆฌํ„ด ํƒ€์ž…์ด๋‚˜ ํŒŒ๋ผ๋ฏธํ„ฐ ๊ฐœ์ˆ˜, ์ข…๋ฅ˜๋ฅผ ๋‹ค๋ฅด๊ฒŒ ํ•ด์„œ ) ํ…Œ์ŠคํŠธํ•ด๋ณด์„ธ์š”~ 


์ฐธ๊ณ ๋กœ ์•„๋ž˜๋Š” Type Descriptor ์™€ Method descriptor ์ž…๋‹ˆ๋‹ค.  

 

๋ญ๊ฐ€ ๋ญ˜ ์˜๋ฏธํ•˜๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด์ฃผ๋Š” ๊ฑฐ๋‹ˆ๊นŒ ์ด๊ฑฐ๋Š” ์™ธ์šฐ์‹œ๋Š”๊ฒŒ ์ข‹์„๊ฑฐ์—์š”~







์ฐธ๊ณ ๋กœ ํด๋ž˜์Šค๋ฅผ ์ฝ์–ด๋“ค์ด๋Š” ๋ฐฉ๋ฒ•์€ BCITestํด๋ž˜์Šค์—์„œ ClassReader์ƒ์„ฑํ•  ๋•Œ ์ด๋ฆ„์„ ์ฃผ๋Š” ๋ฐฉ๋ฒ• ์™ธ์— ๋‹ค๋ฅธ ๋ฐฉ๋ฒ•๋„ ์žˆ์Šต๋‹ˆ๋‹ค.

์‚ฌ ์šฉ์ž ๋ฉ”๋‰ด์–ผ์—๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค๋ช…์ด ๋˜์–ด์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฆ„, ๊ฐ’, byte array, input stream์„ ์ด์šฉํ•ด์„œ ์ฝ์–ด๋“ค์ผ ์ˆ˜ ์žˆ๋Š”๋ฐ input stream์„ ์ด์šฉํ•ด์„œ ํด๋ž˜์Šค๋ฅผ ์ฝ์–ด๋“ค์ผ ๋•Œ๋Š” ํด๋ž˜์Šค ๋กœ๋”์˜ getResourceAsStream ๋ฉ”์†Œ๋“œ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์˜ˆ์ œ๊ฐ€ ๋ฐ”๋กœ ๋ฐ‘์— ๋‚˜์™€์žˆ์ฃ ?


The class that must be read can be specified by name, as above, or by value, as a byte array or as an InputStream. An input stream to read the content of a class can be obtained with the ClassLoaderโ€™s getResourceAsStream method with:

 

cl.getResourceAsStream(classname.replace(โ€™.โ€™, โ€™/โ€™) + ".class");

 

์ž, ํด๋ž˜์Šค ํŒŒ์ผ ์ฝ๊ธฐ๋Š” ์ด์ฏค์—์„œ ๋๋‚ด๊ฒ ์Šต๋‹ˆ๋‹ค. ์„ค๋ช…์ด ๊ธธ๋ฉด ๋จธ๋ฆฌ๋งŒ ์•„ํ”„์ฃ .

 

๋‹ค์Œ ์‹œ๊ฐ„์—๋Š” ๊ธฐ์กด์˜ ํด๋ž˜์Šค๋ฅผ ์ฝ๋Š”๊ฒƒ์ด ์•„๋‹ˆ๋ผ ํด๋ž˜์Šค๋ฅผ ์ƒ์„ฑํ•ด๋ณด๋„๋ก ํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค~

 

๊ทธ๋Ÿผ ์˜ค๋Š˜์€ ์—ฌ๊ธฐ์„œ ์ด๋งŒ~ 

 

 ์ถœ์ฒ˜ : ASM 4 ์‚ฌ์šฉ์ž ๊ฐ€์ด๋“œ ( ํ…Œ์ŠคํŠธ๋Š” ASM 5 ๋กœ ํ–ˆ์Šต๋‹ˆ๋‹ค. )