This content has been marked as final.
Show 2 replies
-
1. Re: loading a modified class directly from a ClassFile
chiba Nov 23, 2005 11:02 PM (in response to johncoleman)I think it would be better to use ClassPool, CtClass, etc.
Your problem is that you added an interface but did not
change your class to be an abstract class (your class does
not implement all methods from the interface.) -
2. Re: loading a modified class directly from a ClassFile
johncoleman Nov 27, 2005 10:06 AM (in response to johncoleman)"chiba" wrote:
I think it would be better to use ClassPool, CtClass, etc.
Your problem is that you added an interface but did not
change your class to be an abstract class (your class does
not implement all methods from the interface.)
You are correct. I tried using ClassPool before but kept getting duplicate class exceptions. I have tried again and have everything working perfectly. This is my code to implement an interface and create getters and setters to inherit from a superclass if required....
CtClass ptc = pool.get(className);
CtClass pti = pool.get(interfaceName);
CtMethod[] ptims = pti.getDeclaredMethods();
if (!pti.isInterface()) {
log.fatal("The class " + interfaceName
+ " is not an interface.");
return;
}
for (int m = 0; m < ptims.length; m++) {
// see if class defines the method when method is get or set
if (ptims[m].getMethodInfo().isMethod()
&& (ptims[m].getName().startsWith("get") || ptims[m]
.getName().startsWith("set"))) {
try {
// see if method already declared in class
CtMethod ptcm = ptc.getDeclaredMethod(ptims[m]
.getName(), ptims[m].getParameterTypes());
} catch (NotFoundException ex1) {
// the method is not declared and needs to be added
// if not in superclass then a problem!
boolean inSuper;
try {
CtMethod ptcm = ptc.getMethod(ptims[m].getName(),
ptims[m].getSignature());
inSuper = true;
} catch (NotFoundException ex2) {
inSuper = false;
}
// quit if method unavailable from superclass
if (!inSuper) {
log.fatal("Method " + ptims[m].getName()
+ " not available in " + className
+ " class.");
return;
}
// class does not define method so add it
if (ptims[m].getName().startsWith("get")) {
String body = "public "
+ ptims[m].getReturnType().getName() + " "
+ ptims[m].getName() + "() { return super."
+ ptims[m].getName() + "(); }";
log.debug("add " + body + " to class " + className);
CtMethod nm = CtNewMethod.make(body, ptc);
ptc.addMethod(nm);
}
if (ptims[m].getName().startsWith("set")) {
String type = ptims[m].getParameterTypes()[0]
.getName();
String body = "public void " + ptims[m].getName()
+ "(" + type + " x" + ") { super."
+ ptims[m].getName() + "(x); }";
log.debug("add " + body + " to class " + className);
CtMethod nm = CtNewMethod.make(body, ptc);
ptc.addMethod(nm);
}
}
}
}
ptc.addInterface(pti);
// force the class loader to load the modified class
ptc.toClass(getClass().getClassLoader());