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

JFR: Default value of @Registered is ignored

XMLWordPrintable

    • Icon: CSR CSR
    • Resolution: Approved
    • Icon: P3 P3
    • 25
    • hotspot
    • None
    • jfr
    • behavioral
    • low
    • Hide
      An event class that is currently unregistered might become registered if the event class participates in a class hierarchy and the user relies on the default value of the jdk.jfr.Registered annotation to override the state of its parent class. No use of the Registered annotation in a hierarchy has been observed in the wild and it's unlikely that the change will lead to an actual problem.
      Show
      An event class that is currently unregistered might become registered if the event class participates in a class hierarchy and the user relies on the default value of the jdk.jfr.Registered annotation to override the state of its parent class. No use of the Registered annotation in a hierarchy has been observed in the wild and it's unlikely that the change will lead to an actual problem.
    • Java API
    • Implementation

      Summary

      The inference mechanism of the Registered annotation in the jdk.jfr package has been modified to behave as if core reflection were used to discover the annotation.

      Problem

      Registration in terms of JDK Flight Recorder (JFR) means that an event class is known to the system and metadata, such as name and description, is written to recording files and exposed over JMX in the EventTypeInfo class.

      By default, event classes are registered when the class initializer is executed, but users can override the behavior by using the jdk.jfr.Registered annotation, which looks like this:

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

      For example,

      @Registered(false)
      class AnimalEvent extends jdk.jfr.Event {
      }

      Users can now instead control registration programmatically using the jdk.jfr.FlightRecorder::register method. This was useful when the Security Manager was in use to ensure that the registration happens in the correct access control context, but could be beneficial in other scenarios as well.

      The problem happens when an event is subclassed and the Registered annotation is overridden, like this:

      @Registered
      class MammalEvent extends AnimalEvent {
      }

      The annotation is ignored, but the event should be registered since the default value is true. If a user specifies true explicitly, e.g., @Registered(true), the annotation works as expected.

      Solution

      The proposed solution is to change the behavior so that Registered behaves as if the implementation had used core reflection:

      Registered r = eventClass.getAnnotation(Registered.class);

      An alternative would be to keep the existing behavior, as it has been available since JDK 11, but it becomes confusing, since further subclassing, e.g.,

      class DogEvent extends MammalEvent {
      }

      will behave as if MammalEvent was registered. The reason for this is that two different mechanisms are involved: inspection of the bytecode and reflection to traverse the hierarchy. The bug only exists when the bytecode is inspected.

      A Google search reveals no use of the annotation in a hierarchy, and it seems unlikely that users would use it without realizing the problem. It's more likely that changing the behavior would make their code work as they expected.

      Specification

      There is no change to the specification, as the behavior is changed to that of core reflection, which is what users expect when the Registered annotation is used in a class hierarchy.

            egahlin Erik Gahlin
            egahlin Erik Gahlin
            Markus Grönlund
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved: