Search code examples
javareflectionmethodsannotationsjavassist

Javassist: Convert CtMethod to java.lang.reflect.Method


I currently need to change the annotation of a java.lang.reflect.Method Object, which should be a clone of the original method so the original one wont get modified. To do so I downloaded the Library Javassist. So, basically, the optimal code to do so would be:

java.lang.reflect.Method myMethod = /*obtain it*/;
java.lang.reflect.Method myMethodClone = myMethod.clone();
myMethodClone.removeAllAnnotations();
myMethodClone.addAnnotation("@MyAnnotation(something=\"something\", etc");

But a code similar to this pseudo-code unfortunately isn't possible. I tried to use javassist to solve my problem, but then I encountered another problem: I can't convert Javassists CtMethod Object into a Method Object, at least not without changing the class where the original method is.

Anyone has an idea how to solve this?


Solution

  • I managed to get my code working by using the default java Annotation & Method class plus some reflection. Here's how I did it (Probably won't help anyone, since my problem was really specific, but you never know...)(Pseudo-Code):

    //Create Annotation
    MyAnnotationOld oldAnnotation;
    MyAnnotation modifiedAnnotation = new MyAnnotation{
    public Class<? extends java.lang.annotation.Annotation> annotationType() {return oldAnnotation.annotationType();}
    public String propertyWhichShallRemainTheSame() {return oldAnnotation.propertyWhichShallRemainTheSame();}
    public String propertyWhichShallBeModified() {return "Modified Thingy";}
    }
    
    //Copy Method
    Method toCopy;
    Method copyMethod = Method.class.getDeclaredMethod("copy", (Class<?>[])null);
    copyMethod.setAccessible(true);
    Method copiedMethod = (Method) copyMethod.invoke(toCopy, (Object[]) null);
    
    //Add annotation to copied method
    Field field = Method.class.getDeclaredField("declaredAnnotations");
    field.setAccessible(true);
    //Intantiate field !!IMPORTANT!! If you don't do this, the field will be null and thus return an error.
    copiedMethod.getAnnotations();
    Map<Class<? extends Annotation>, Annotation> annotations = (Map<Class<? extends Annotation>, Annotation>) field.get(copiedMethod);
    annotations.put(MyAnnotation.class, modifiedAnnotation);