토요일, 1월 12, 2008

BCEL Sample 코드

bcel 홈이나 다른 곳에서 예제가 너무나 빈곤하여 답답하던 차에
틈나는 대로 간단한 예제를 만들어 보기로 하였다.
우선 가장 간단하고 간단한 sample을 소개한다.

참고로 sun jdk 1.6을 사용했고, apache에 있는 bcel 5.2와 같은 것으로 생각됩니다.

public class Test {
public static void main(String[] args) {
System.out.println("BCEL Start...");
String str = "..test bcel...";

System.out.println("Str Value " + str);
}
}
와 같은 코드를 bcel로 만든다면 아래와 같다.

import java.io.IOException;

import com.sun.org.apache.bcel.internal.Constants;
import com.sun.org.apache.bcel.internal.generic.ALOAD;
import com.sun.org.apache.bcel.internal.generic.ASTORE;
import com.sun.org.apache.bcel.internal.generic.ArrayType;
import com.sun.org.apache.bcel.internal.generic.ClassGen;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.InstructionConstants;
import com.sun.org.apache.bcel.internal.generic.InstructionFactory;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.bcel.internal.generic.LocalVariableGen;
import com.sun.org.apache.bcel.internal.generic.MethodGen;
import com.sun.org.apache.bcel.internal.generic.ObjectType;
import com.sun.org.apache.bcel.internal.generic.PUSH;
import com.sun.org.apache.bcel.internal.generic.Type;

/**
* jdk 1.6에 있는 것으로
*
* public class Test { public static void main(String[] args) {
* System.out.println("BCEL Start..."); String str = "..test bcel...";
*
* System.out.println("Str Value " + str); } }
*
* @author hangum
*
*/
public class TestBuilder {
public static void main(String[] args) {
System.out.println("== 작업을 시작했습니다. ");

ClassGen cg = new ClassGen("Test", // class name
"java.lang.Object", // super class
"",
Constants.ACC_PUBLIC | Constants.ACC_SUPER,
null);

ConstantPoolGen cp = cg.getConstantPool();
InstructionList il = new InstructionList();

// method 생성
MethodGen mg = new MethodGen(
Constants.ACC_STATIC | Constants.ACC_PUBLIC,
Type.VOID,
new Type[] {
new ArrayType(Type.STRING, 1)
},
new String[] { "args" },
"main",
"Test",
il,
cp);

InstructionFactory factory = new InstructionFactory(cg);

ObjectType p_stream = new ObjectType("java.io.PrintStream");

il.append(factory.createFieldAccess("java.lang.System", "out",
p_stream, Constants.GETSTATIC));
il.append(new PUSH(cp, "BCEL Start..."));
il.append(factory.createInvoke("java.io.PrintStream", "println",
Type.VOID, new Type[] { Type.STRING },
Constants.INVOKEVIRTUAL));

// 변수 str 생성
LocalVariableGen lvgStr = mg.addLocalVariable("str", Type.STRING, null,
null);
int str = lvgStr.getIndex();
il.append(new PUSH(cp, "..test bcel..."));
lvgStr.setStart(il.append(new ASTORE(str)));

// str Value + str
il.append(factory.createFieldAccess("java.lang.System", "out",
p_stream, Constants.GETSTATIC));
il.append(factory.createNew(Type.STRINGBUFFER));
il.append(InstructionConstants.DUP);
il.append(new PUSH(cp, "Str Value, "));
il.append(factory.createInvoke("java.lang.StringBuffer",
"", Type.VOID, new Type[] { Type.STRING },
Constants.INVOKESPECIAL));
il.append(new ALOAD(str));
il.append(factory.createInvoke("java.lang.StringBuffer", "append",
Type.STRINGBUFFER, new Type[] { Type.STRING },
Constants.INVOKEVIRTUAL));
il.append(factory.createInvoke("java.lang.StringBuffer", "toString",
Type.STRING, Type.NO_ARGS, Constants.INVOKEVIRTUAL));

il.append(factory.createInvoke("java.io.PrintStream", "println",
Type.VOID, new Type[] { Type.STRING },
Constants.INVOKEVIRTUAL));
il.append(InstructionConstants.RETURN);

// return void
il.append(InstructionConstants.RETURN);

mg.setMaxStack();
cg.addMethod(mg.getMethod());

il.dispose();

// construct
cg.addEmptyConstructor(Constants.ACC_PUBLIC);

// 파일생성
try {
cg.getJavaClass().dump("build/Test.class");
} catch (IOException ioe) {
ioe.printStackTrace();
}

System.out.println("== 작업을 끝냈습니다.");
}
}

댓글 없음:

댓글 쓰기