Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8356224

JFR: Default value of @Registered is ignored

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 25
    • 11, 17, 21, 24
    • hotspot
    • None
    • jfr
    • master

      JFR has three annotations that must be processed before a class is put into the JVM symbol table, which means reflection cannot be used and the bytecode needs to be inspected. Two of those annotations, jdk.jfr.Enabled and jdk.jfr.Registered, have a default value, which happens to be true in both cases, e.g.

          @Target({ ElementType.TYPE })
          @Inherited
          @Retention(RetentionPolicy.RUNTIME)
          public @interface Registered {
            boolean value() default true;
          }

      To find the value of value(), the RuntimeVisibleAnnotations attribute of the event class is checked, and if an annotation is of a known type (Registered or Enabled), the element value pair array is inspected. If the size is 1 and the element name is "value", then the value is returned. This works, but there is a subtle corner case.

      If a user omits setting the value for an annotation in a class, e.g.,

          @Registered
          class Foo extends Event {
          }

      instead of

          @Registered(true)
          class Foo extends Event {
          }

      then the element value pair array in the class file becomes empty, so the annotation is completely ignored. That happens to be fine, since events without an annotation should be registered!

      Now, the issue: If Foo instead inherits from Bar, which is not registered, e.g.,

          @Registered(false)
            class Bar extends Event {
          }

          @Registered
          class Foo extends Bar {
          }

      Foo should be registered and override @Registered(false), but as stated earlier, the element value pair array in the class file of the Registered annotation on Foo is empty, so the annotation is ignored, and Bar gets to set the Foo event to unregistered. The expected behavior is that the default value, true in this case, should be picked from the Registered class, not the annotation on the event.

      There is a similar issue for the Enabled annotation, which leads to the class not being instrumented on class load, but JFR has a mechanism where uninstrumented classes gets retransformed when registered, where the @Enabled annotation is read using reflection, so it works out fine in the end.

      This bug has existed since JDK 11, when JDK Flight Recorder API was introduced.

            egahlin Erik Gahlin
            egahlin Erik Gahlin
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: