i think you need to call setMethodAt, replaceMethod, or setMethods.
http://jakarta.apache.org/bcel/apidocs/org/apache/bcel/generic/ClassGen.html#setMethodAt(org.apache.bcel.classfile.Method,%20int)
btw, your printing technique will only work for a very specialized subset of methods:
- single return at end of method and
- no exceptions and
- no finally
you really want to add this code to method 1 (with code M1):
System.out.println("start");
try { M1 }
finally {System.out.println("end"); }you should see how that compiles (using javap or something) and replicate it using bcel.
Koduru, Rajendra Kumar Reddy wrote:
Hi,
I just started using BCEL, I want to instrument methods in my class
with system.out.println at start and end of methods
Ex:
[1]
public class HelloBCEL {
public static void main(String[] argv) { String name = null;
try { System.out.print("Please enter your name> "); name = in.readLine(); } catch(IOException e) { return; } System.out.println("Hello, " + name); } }
I want to instrument all the methods of above class with system.out.println("starting") at the start and system.out.println("ending") at the end, that is something which looks like this
[2]
public static void main(String[] argv) { System.out.println("starting");
String name = null;
try { System.out.print("Please enter your name> "); name = in.readLine(); } catch(IOException e) { return; } System.out.println("Hello, " + name); } System.out.println("ending");
}
So i have used BCEL and written a clas which updates the class [1] into class [2], The BCEL code written to insert statements is written as follows
import java.io.*; import org.apache.bcel.*; import org.apache.bcel.classfile.*; import org.apache.bcel.generic.*;
public class insertBCEL{
public static ObjectType p_stream = null;
public static void main( String args[] ) throws IOException {
ClassParser cparse = new ClassParser("HelloBCEL.class");
JavaClass clazz = cparse.parse();
ClassGen cg = new ClassGen(clazz);
ConstantPool cp1 = clazz.getConstantPool();
ConstantPoolGen cp = new ConstantPoolGen(cp1);
InstructionFactory factory = new
InstructionFactory(cp);
p_stream = new ObjectType("java.io.PrintStream");
Method[] meths = clazz.getMethods();
for(int i = 0; i< meths.length; i++ ){
Code code = meths[i].getCode();
if(code != null) System.out.println(code);
System.out.println(meths[i]);
meths[i] = instrumentMeths(clazz,meths[i],cp,factory);
Code code1 = meths[i].getCode();
if(code1 != null)
System.out.println(code1); }
try {
cg.getJavaClass().dump("HelloBCEL.class");
}catch(Exception e){System.out.println(e);} }
public static Method instrumentMeths(JavaClass clazz, Method method ,ConstantPoolGen cp, InstructionFactory factory){
MethodGen mg = new MethodGen(method,clazz.getClassName(),cp);
InstructionList il = mg.getInstructionList();
InstructionHandle[] ihans =
il.getInstructionHandles();
InstructionHandle ihs = il.getStart();
InstructionHandle ihe = il.getEnd();
InstructionList ils = new InstructionList();
InstructionList ile = new InstructionList();
ils.append(factory.createFieldAccess("java.lang.System","out",p_stream,C
onstants.GETSTATIC));
ils.append(new PUSH(cp,"starting"));
ils.append(factory.createInvoke("java.io.PrintStream", "println",
Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL));
ile.append(factory.createFieldAccess("java.lang.System","out",p_stream,C
onstants.GETSTATIC));
ile.append(new PUSH(cp,"ending"));
ile.append(factory.createInvoke("java.io.PrintStream", "println",
Type.VOID, new Type[] { Type.STRING }, Constants.INVOKEVIRTUAL)); InstructionHandle ihss = il.insert(ihs,ils);
il.redirectBranches(ihs, ihss); InstructionHandle ihee = il.insert(ihe,ile);
il.redirectBranches(ihe, ihee); mg.setMaxStack();
return mg.getMethod();
}
}
Then i tried to execute the instrumented class java HelloBCEL , but it doesnot instrument the strings "starting" and "ending" for the class, pLease let me know if i am wrong somewhere in the above code.
Hope that you can help me in this regard.
Thank you in advance, Reddy.
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
