Annotation Interface Contextual


@Retention(RUNTIME) @Target(FIELD) public @interface Contextual
Event field annotation, specifies that the value carries contextual information.

Contextual information is data that applies to all events happening in the same thread from the beginning to the end of the event with a field annotated with Contextual.

For example, to trace requests or transactions in a system, a trace event can be created to provide context.

@Label("Trace")
@Name("com.example.Trace")
class TraceEvent extends Event {
    @Label("ID")
    @Contextual
    String id;

    @Label("Name")
    @Contextual
    String name;
}

To track details within an order service, an order event can be created where only the order ID provides context.

@Label("Order")
@Name("com.example.Order")
class OrderEvent extends Event {
    @Label("Order ID")
    @Contextual
    long id;

    @Label("Order Date")
    @Timestamp(Timestamp.MILLISECONDS_SINCE_EPOCH)
    long date;

    @Label("Payment Method")
    String paymentMethod;
}

If an order in the order service stalls due to lock contention, a user interface can display contextual information together with the JavaMonitorEnter event to simplify troubleshooting, for example:

  $ jfr print --events JavaMonitorEnter recording.jfr
  jdk.JavaMonitorEnter {
    Context: Trace.id = "00-0af7651916cd43dd8448eb211c80319c-00f067aa0ba902b7-01"
    Context: Trace.name = "POST /checkout/place-order"
    Context: Order.id = 314159
    startTime = 17:51:29.038 (2025-02-07)
    duration = 50.56 ms
    monitorClass = java.util.ArrayDeque (classLoader = bootstrap)
   previousOwner = "Order Thread" (javaThreadId = 56209, virtual = true)
   address = 0x60000232ECB0
   eventThread = "Order Thread" (javaThreadId = 52613, virtual = true)
   stackTrace = [
     java.util.zip.ZipFile$CleanableResource.getInflater() line: 685
     java.util.zip.ZipFile$ZipFileInflaterInputStream.<init>(ZipFile) line: 388
     java.util.zip.ZipFile.getInputStream(ZipEntry) line: 355
     java.util.jar.JarFile.getInputStream(ZipEntry) line: 833
     ...
   ]
  }

The difference between Relational and Contextual annotations is that Relational ties event data together to form a global data structure, similar to a foreign key in a relational database, but Contextual represents a state that applies to all events that happen at the same time, in the same thread. A field can be both contextual and relational at the same time.

A contextual field may incur overhead on a parser reading a recording file, since it must track active context, so it should be used sparingly and only where appropriate.

Since:
25