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.
- csr of
-
JDK-8356224 JFR: Default value of @Registered is ignored
-
- Resolved
-