Reputation: 63
I am in need to add an annotation to a method parameter. The method is previously created with javassist like:
CtClass cc2 = pool.makeClass("Dummy");
CtMethod method = CtNewMethod.make("public java.lang.String dummyMethod( java.lang.String oneparam){ return null; }", cc2);
The annotation I want to add is quite simple:
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
/** Name of the parameter */
String name() default "";
}
1) writting the annotation in the method creation throws
javassist.CannotCompileException: [source error] syntax error near "myMethod(@Param
2) found this solution but it is based on a line which in my case returns null:
AttributeInfo paramAtrributeInfo = methodInfo.getAttribute(ParameterAnnotationsAttribute.visibleTag); // or inVisibleTag
I am getting lost on how to accomplish this; has anyone found a way to create a new method and add any annotation to its parameters?
Thanks in advance.
Upvotes: 3
Views: 2556
Reputation: 63
Found a workaround based on the solution I mentioned in the original question. I could not create a class, and add a method to it and insert an annotation to its parameter with javassist. But using a real class as a template, the parameter annotation can be found and edited.
1) First, create a class with a method with the desired annotation
public class TemplateClass {
public String templateMethod(@Param String paramOne) {
return null;
}
}
2) Load it
ClassPool pool = ClassPool.getDefault();
CtClass liveClass = null;
try {
liveClass = pool.get("your.package.path.Dummyclass");
} catch (NotFoundException e) {
logger.error("Template class not found.", e);
}
3) Work it
// -- Get method template
CtMethod dummyMethod = liveClass.getMethods()[2];
// -- Get the annotation
AttributeInfo parameterAttributeInfo = dummyMethod.getMethodInfo().getAttribute(ParameterAnnotationsAttribute.visibleTag);
ConstPool parameterConstPool = parameterAttributeInfo.getConstPool();
ParameterAnnotationsAttribute parameterAtrribute = ((ParameterAnnotationsAttribute) parameterAttributeInfo);
Annotation[][] paramArrays = parameterAtrribute.getAnnotations();
Annotation[] addAnno = paramArrays[0];
//-- Edit the annotation adding values
addAnno[0].addMemberValue("value", new StringMemberValue("This is the value of the annotation", parameterConstPool));
addAnno[0].addMemberValue("required", new BooleanMemberValue(Boolean.TRUE, parameterConstPool));
paramArrays[0] = addAnno;
parameterAtrribute.setAnnotations(paramArrays);
Then change the name of the CtClass and/or CtMethod before building the result class. It is not as flexible as expected, but at least some scenarios can be solved with an approach like this. Any other workaround is welcome!
Upvotes: 1