Java Dynamic Instrumentation #2
Continuing from Java Dynamic Instrumentation #1, this post will cover some more advanced features of the Javassist API.
In the previous post, we went over the ClassPool
, CtClass
, and CtMethod
classes and how to add code to the beginning and end of a method. In this post, we will cover the dynamic creation and addition of classes, methods, and fields.
In this post, we are going to start with a fairly complex piece of code, and I will then break it down into steps.
HelloWorld.java:
{% highlight java %}
public class HelloWorld {
public void do1() {
System.out.println("Hello World!");
}
public void do2(String tosay){
System.out.println(tosay);
}
}
{% endhighlight %}
Inst3.java:
{% highlight java %}
import javassist.*;
public class Inst3 {
public static void main(String[] args) throws Exception {
ClassPool pool = ClassPool.getDefault();
CtClass hw_ctc = pool.get("HelloWorld");
CtClass nhw_ctc = pool.makeClass("NewHelloWorld");
nhw_ctc.setSuperclass(hw_ctc);
CtField f1 = CtField.make("private String name;", nhw_ctc);
nhw_ctc.addField(f1);
CtConstructor c = CtNewConstructor.make("public NewHelloWorld(){\n" +
"\tname = \"TestName\";" +
"}\n", nhw_ctc);
nhw_ctc.addConstructor(c);
CtMethod m1 = CtNewMethod.make("public void do3(){\n" +
"\tSystem.out.println(name);\n" +
"}\n", nhw_ctc);
nhw_ctc.addMethod(m1);
CtMethod m2 = CtNewMethod.make("public void do1(){\n" +
"\tSystem.out.println(\"Hello New World\");\n" +
"\tdo3();\n" +
"}\n", nhw_ctc);
nhw_ctc.addMethod(m2);
Class hw_class = hw_ctc.toClass();
Class nhw_class = nhw_ctc.toClass();
HelloWorld hw = (HelloWorld)hw_class.newInstance();
HelloWorld nhw = (HelloWorld)nhw_class.newInstance();
hw.do1();
hw.do2("Goodbye world");
System.out.println("-------");
nhw.do1();
}
}
{% endhighlight %}
$ javac -classpath /path/to/javassist.jar: Inst3.java HelloWorld.java
$ java -cp /path/to/javassist.jar: Inst3
Hello World!
Goodbye world
----