Hopefully this is a small working example:
package cloud;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtField;
import javassist.CtMethod;
import javassist.CtNewMethod;
import javassist.Loader;
import javassist.Modifier;
import javassist.NotFoundException;
public class TestBuilder {
private Loader classLoader;
private ClassPool pool;
private CtClass abstractEntityCtClass;
public TestBuilder() {
}
public void buildClass(String name, String msg) {
System.out.println("Building class " + name);
// Create CtClass.
CtClass ctClass = pool.makeClass(name);
// Set superclass to cloud.Entity.
try {
ctClass.setSuperclass(abstractEntityCtClass);
} catch (CannotCompileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
// Add field.
String fieldName = "age";
try {
// Create field.
CtField field = new CtField(CtClass.intType, fieldName, ctClass);
field.setModifiers(Modifier.PUBLIC);
ctClass.addField(field);
String s = "public void say() { System.out.println(\"" + msg + "\");}";
ctClass.addMethod(CtNewMethod.make(
s, ctClass));
} catch (CannotCompileException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return;
}
// Add property.
String getterName = "getAge";
String type = CtClass.intType.getName();
StringBuffer sb = new StringBuffer();
sb.append("public ").append(type).append(" ").append(getterName)
.append("(){").append("return this.").append(fieldName)
.append(";").append("}");
try {
CtMethod method = CtMethod.make(sb.toString(), ctClass);
ctClass.addMethod(method);
} catch (CannotCompileException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
System.out.println("ctClass " + ctClass);
}
public Object createInstance(String name) {
System.out.println("Creating class instance " + name);
Object o = null;
// Create and add to list.
Class<? extends SimpleEntity> newKlass;
try {
newKlass = (Class<? extends SimpleEntity>) classLoader.loadClass(name);
o = newKlass.newInstance();
SimpleEntity e = (SimpleEntity)o;
// objects.add(o);
System.out.println("Created instance " + o);
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
return o;
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return o;
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return o;
}
Method method;
try {
method = o.getClass().getMethod("say");
method.invoke(o, null);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return o;
}
public void build() {
String name = "foo.Bob";
// Create new class pool and loader.
buildPool();
// Build the class.
buildClass(name, "fred");
// Create instance.
Object o = createInstance(name);
// Create new class pool and loader.
buildPool();
// Rebuild the class.
buildClass(name, "bob");
// Create an instance of the rebuilt class.
Object o2 = createInstance(name);
}
private void buildPool() {
// Create class loader and pool.
this.pool = new ClassPool(ClassPool.getDefault());
this.classLoader = new Loader();
this.classLoader.setClassPool(this.pool);
// Get the cloud.AbstractEntity class.
try {
abstractEntityCtClass = ClassPool.getDefault().get(
"cloud.SimpleEntity");
System.out.println("Abstract Entity " + abstractEntityCtClass);
} catch (NotFoundException e) {
e.printStackTrace();
System.exit(-2);
}
}
/**
* @param args
*/
public static void main(String[] args) {
TestBuilder builder = new TestBuilder();
builder.build();
}
}