We are building a tool (for internal use) that only works if the javax.persistence.GeneratedValue annotation is removed from our source code (we are setting the Id in the tool, which is rejected due to the GeneratedValue annotation)... but for normal operations, we require this annotation.
How do you remove a Java Annotation at Runtime (probably using Reflection)?
This is my class:
@Entity
public class PersistentClass{
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
// ... Other data
}
This is what I would like to be able to change it to, at runtime:
@Entity
public class PersistentClass{
@Id
private long id;
// ... Other data
}
It is possible to do this on the class itself:
// for some reason this for-loop is required or an Exception is thrown
for (Annotation annotation : PersistentClass.class.getAnnotations()) {
System.out.println("Annotation: " + annotation);
}
Field field = Class.class.getDeclaredField("annotations");
field.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> annotations = (Map<Class<? extends Annotation>, Annotation>) field.get(PersistentClass.class);
System.out.println("Annotations size: " + annotations.size());
annotations.remove(Entity.class);
System.out.println("Annotations size: " + annotations.size());
If you can get the annotations map from a field, then the same solution would apply.
You can remove annotations in your source code by using the Annotations view. You can remove annotations in your source code by directly deleting the annotation in the Java editor or by using the Annotations view.
If annotations specify a retention policy of RUNTIME, then they can be queried at run time by any Java program through the use of reflection. Reflection is the feature that enables information about a class to be obtained at run time.
With Java reflection, we can inspect constructors of any class and even create class objects at runtime. This is made possible by the java. lang.
Reflection is a feature in the Java programming language. It allows an executing Java program to examine or "introspect" upon itself, and manipulate internal properties of the program. For example, it's possible for a Java class to obtain the names of all its members and display them.
You can't remove an annotation at runtime. Reflection only inspects code.
What you can do is:
You can remove the annotations used string hacking tools like Perl or SED. These would probably be pretty reliable but the actual commands you use to do this might be pretty cryptic.
If you can to make modified versions of source code in a principled way, you can use a program transformation system (PTS) These are tools that parse source to compiler data structures, let you specify (structured) "transforms" to be applied to the code, applies the transforms to the structures in a reliable way, and then regenerates (valid) source code for the changed program.
A good PTS will let you specify such transforms in terms of surface syntax:
if you see *this* pattern, replace it by *that* pattern
where the pattern is essentially a fragment of the target language code (e.g., Java).
(I happen to build one of these PTSes). A specific rule (for my PTS) might look like:
rule remove_Generated_value(a: annotations, e: expression):
annotations -> annotations =
" \a @GeneratedValue(strategy = \e) " -> " \a ";
This says, "if you find a list of annotations containing a GeneratedValue annotation with a 'strategy' property of any value", replace that (->) annotation by the list without the annotation". [This works because the annotation list is commutative so we can always act as if an interesting member was the last member of the list.] (The " marks are metaquotes; they distinguish the syntax for the rule langauge from the syntax for Java in the patterns.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With