1

I'm trying to dynamically add an annotation to a class at runtime, as in this question: Modify a class definition's annotation string parameter at runtime

However, the 'annotations' field is coming back null. In fact, according to the debugger, everything on the class is coming back null except for "declaredFields" and "name". I'm using Java 7.

Here's my code:

Field field = Class.class.getDeclaredField("annotations");
field.setAccessible(true);
Map<Class<? extends Annotation>, Annotation> annotations = 
    (Map<Class<? extends Annotation>, Annotation>) 
        field.get(clazz);
annotations.put(JsonIdentityInfo.class, newAnnotation);
Community
  • 1
  • 1
wMattDodd
  • 115
  • 1
  • 2
  • 10
  • There is no such field "annotations". Try `MyClass.class.getAnnotations()` – Bohemian Oct 05 '15 at 16:43
  • If I try replacing 'clazz' with 'clazz.getSuperClass()', I get back an immutable empty map, but there should be existing annotations on the class. – wMattDodd Oct 05 '15 at 16:47
  • Are your annotation classes themselves annotated with `@Retention(RetentionPolicy.RUNTIME)`? – Bohemian Oct 05 '15 at 16:48
  • @RealSkeptic he is using Java 7 – wero Oct 05 '15 at 16:53
  • @RealSkeptic I was using Java 8, but I reverted to Java 7 specifically for that reason. – wMattDodd Oct 05 '15 at 16:54
  • @Bohemian Yes they are – wMattDodd Oct 05 '15 at 16:55
  • What do you mean with `I reverted to Java 7`? If you only changed the compiler to be compliant with Java 7 while still using a Java 8 JDK, then there will still be no "annotations" field available. You must install a Java 7 JDK and explicitly use that... – Balder Oct 05 '15 at 16:58
  • @Balder Yes, I changed to using the Java 7 JDK. – wMattDodd Oct 05 '15 at 17:02
  • As already explained [here](http://stackoverflow.com/a/32092952/2711488), you do *not* “dynamically add an annotation”, you are just hacking the internal structure of *one* annotation processing library. Others may not notice your hack. Further, you already learned that this structure is lazily populated. Now imagine what happens, if it is also allowed to get flushed from memory as it can be regenerated from disk again… – Holger Oct 07 '15 at 14:45
  • @Holger I'm open to suggestions as to a better way to add annotations (with per-class dependent info) to over 100 generated classes that may be re-generated later. – wMattDodd Oct 07 '15 at 15:13
  • Sounds like an XY problem. If these classes are generated, then generate them with the appropriate annotation values in the first place. Otherwise, don’t be surprised if your hack breaks again on the next Java version (as it already does today on alternative JREs) – Holger Oct 07 '15 at 15:44

1 Answers1

3

Seems that the class field annotations is lazily built and you first need to force its initialization:

JsonIdentityInfo.class.getAnnotations();

Then proceed with your code.

wero
  • 32,544
  • 3
  • 59
  • 84