화요일, 4월 22, 2008

bcel을 사용하여 메소드 내용삭제

/**
* 이번 3번째 예제에서는 클래스 메소드 삭제를 해보도록 하겠습니다.
*
* 이번 예제에서는 TestAppendMethodBuild에서 만들었던 TestAppend 클래스의 메소드 private static void
* appendMethod(String str)의 내용을 삭제하는 예제를 만들어 보도록 하겠다.
*
* 3번재 예제에서야 조금 bcel의 면목을 보는듯 하다.
* 사실 위의 예제도 상속을 사용하면 정상적으로 수정가능하겠으나, 지금까지는 예제를 만들고 있으므로 이해해주시기를....
*
* 그럼, 본격적인 예제를 만들어보도록 하자.
*
* 프로그램을 실행하고 난 다음에는 다음과 같은 결과를 예상할 수 있다.
*
* public class TestAppend {
* private static void appendMethod(String str) {
* }
*
* public static void main(String[] args) {
* System.out.println("BCEL Start..."); String str = "..test bcel...";
*
* System.out.println("Str Value " + str);
* appendMethod(str);
* }
* }
*
* 이 예제가 끝나면 TestAppend 예제의 main 메소드를 수정하는 예제를 만들어 보도록 하겠다.



package com.test;

import com.sun.org.apache.bcel.internal.classfile.ClassParser;
import com.sun.org.apache.bcel.internal.classfile.JavaClass;
import com.sun.org.apache.bcel.internal.classfile.Method;
import com.sun.org.apache.bcel.internal.generic.ConstantPoolGen;
import com.sun.org.apache.bcel.internal.generic.Instruction;
import com.sun.org.apache.bcel.internal.generic.InstructionHandle;
import com.sun.org.apache.bcel.internal.generic.InstructionList;
import com.sun.org.apache.bcel.internal.generic.MethodGen;

/**
* 이번 3번째 예제에서는 클래스 메소드 삭제를 해보도록 하겠습니다.
*
* 이번 예제에서는 TestAppendMethodBuild에서 만들었던 TestAppend 클래스의 메소드 private static void
* appendMethod(String str)의 내용을 삭제하는 예제를 만들어 보도록 하겠다.
*
* 3번재 예제에서야 조금 bcel의 면목을 보는듯 하다.
* 사실 위의 예제도 상속을 사용하면 정상적으로 수정가능하겠으나, 지금까지는 예제를 만들고 있으므로 이해해주시기를....
*
* 그럼, 본격적인 예제를 만들어보도록 하자.
*
* 프로그램을 실행하고 난 다음에는 다음과 같은 결과를 예상할 수 있다.
*
public class TestAppend {
* private static void appendMethod(String str) {
* }
*
* public static void main(String[] args) {
* System.out.println("BCEL Start..."); String str = "..test bcel...";
*
* System.out.println("Str Value " + str);
* appendMethod(str);
* }
* }

* 이 예제가 끝나면 TestAppend 예제의 main 메소드를 수정하는 예제를 만들어 보도록 하겠다.
*
* @author hangum
*
*/
public class TestDeleteMethodBuilder {
static String orgClassName = "build/TestAppend.class";

/**
* @param args
*/
public static void main(String[] args) {
// 해당 클래스를 불러온다.
JavaClass classz = null;
try {
classz = new ClassParser(orgClassName).parse();
} catch (Exception e) {
System.out.println(orgClassName + "가 존재 하지 않습니다.");
System.exit(0);
}

Method[] methods = classz.getMethods();
ConstantPoolGen cp = new ConstantPoolGen(classz.getConstantPool());

for (int i = 0; i < methods.length; i++) {
MethodGen mg = new MethodGen(methods[i], classz.getClassName(), cp);

// appendMethod delete
if("appendMethod".equals(methods[i].getName())) {

System.out.println(" ### [작업 method name] " + mg.getName() + " [Signature] " + methods[i].getSignature());

InstructionList il = mg.getInstructionList();
InstructionHandle[] ih = il.getInstructionHandles();

for(int j=0; j < ih.length; j++) {
Instruction inst = ih[j].getInstruction();

try {
if(!"return".equals(inst.getName())) il.delete(inst);
} catch(Exception e) {
System.out.println("==> error rise on [name] " + inst.getName() + " [message] " + e.getMessage());
e.printStackTrace();
}
}

methods[i] = mg.getMethod();
il.dispose();
}
} // end for

/*
* Dump the class to "class name"_.class
*/
String dumpClassName = "c:/temp/" + classz.getClassName() + ".class";
try {
classz.setConstantPool(cp.getFinalConstantPool());
classz.dump(dumpClassName);
} catch (Exception e) {
e.printStackTrace();
}

System.out.println("== 종료했습니다.");
}
}

댓글 없음:

댓글 쓰기