fuin.org

Small Open Source Java Tools and Libraries

The problem

Javassist bytecode generation is a cool solution that is easy to use:
// Create a cache
ClassPool pool = ClassPool.getDefault();

// Create the class and add an interface
CtClass ctClasz = pool.makeClass("test.ExampleImpl");
ctClasz.addInterface(pool.get(Example.class.getName()));

// Add a method
CtMethod method = CtNewMethod.make("public void sayHello() { System.out.println(\"Hello!\"); }", ctClasz);
ctClasz.addMethod(method);
However, sometimes Javassist displays the all too familiar and annoying error messages. You don't know what's wrong and wish you could see the source! One of Javassist's drawbacks is that it doesn't know anything about source code - not even if you have created classes as explained above.

The solution

To address this issue, we have created a little "wrapper" around Javassist:
// Create a cache
SgClassPool pool = new SgClassPool();

// Create the class and add an interface
SgClass clasz = new SgClass("test", "ExampleImpl");
clasz.addInterface(SgClass.create(pool, Example.class));

// Add a method
SgMethod method = new SgMethod(clasz, "public", SgClass.VOID, "sayHello");
method.addBodyLine("System.out.println(\"Hello!\");");
clasz.addMethod(method);
Looks pretty similar doesn't it?

But here's the difference:

CtClass "System.out.println(ctClasz)":
// CONSOLE OUTPUT

javassist.CtNewClass@1404536[changed public class test.ExampleImpl implements org.fuin.jaddr.srcgen4javassist.examples.Example,  fields= constructors= methods=javassist.CtMethod@9798dee8[public sayHello ()V], ]
Just an ugly dump...

SgClass "System.out.println(class)"
// CONSOLE OUTPUT

package test;

public class ExampleImpl implements org.fuin.jaddr.srcgen4javassist.examples.Example {

    public void sayHello(){
System.out.println("Hello!");
    }

}
You'll get source code from the created class!

Of course you can still create byte code with the "SgClass":
Example example = (Example) (new ByteCodeGenerator()).createInstance(clasz);
example.sayHello();