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
----