Fly
Fly

Reputation: 862

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?

Upvotes: 2

Views: 1062

Answers (2)

Fly
Fly

Reputation: 862

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);

Upvotes: 3

Luca Basso Ricci
Luca Basso Ricci

Reputation: 18403

javassist uses his own class hierarchy,not the Java one. If you want to use javassist start reading official doc and how it works.

About your question: conversion Method <-> CtMethod is impossible. In addiction, what do you intend to do with cloned method? If you want to "duplicate" a method in which class will it live? In the same of the original method? Impossible, because you will receive a "method already present" (or similar).

javassist can solve your problem but a full answer if not possible because the question is pretty vague. My advice is to start from official doc or using this tutorial

Upvotes: 3

Related Questions