Skip to content

Queueing-time profiler aborts the whole instrumentation install under a JDK 24+ AOT cache (zero spans); disabling that one feature is enough #12540

Description

@gibKim

Tracer Version(s)

1.65.1, 1.66.0

Java Version(s)

25

JVM Vendor

Eclipse Adoptium / Temurin

Bug Report

TL;DR: with a JDK 25 AOT cache, the queueing-time profiler's failed retransformation batch silently aborts the entire instrumentation install (zero spans). Disabling that single feature — -Ddd.profiling.queueing.time.enabled=false — restores all spans and keeps every other profiling capability. Fully disabling the profiler is not necessary.

Behavior

With -XX:AOTCache enabled (jib containerizingMode=packaged, Spring Boot, JDK 25):

  • The tracer starts normally, prints its configuration, reports agent_error: false.
  • Not a single span is produced. No warnings at default log level.
  • Only -Ddd.trace.debug=true reveals: Exception while retransforming 574 classes.

Identical behaviour on 1.65.1 and 1.66.0, so not a recent regression.

Root cause

UnwrappingVisitor (queueing-time profiling) adds the TaskWrapper interface to the classes it instruments. Adding an interface is a structural change, which the JVM rejects on retransformation. Normally this works because the agent installs before those classes load — but a JDK 24+ AOT cache (JEP 483) materializes them before premain.

Since no BatchAllocator is configured, that is the single batch holding every class, and RedefinitionStrategy aborts the whole install. One unusable profiler feature takes all instrumentation down with it.

Why this is filed separately from #10479

#10479 covers partial span loss via the context-store weak-map fallback (addressed by #12105). This is a different mechanism with a total, silent loss — and a much narrower fix surface.

Expected Behavior

A retransformation failure of one optional profiling feature should not abort the entire instrumentation install, and the degradation should be visible at default log level.

Workaround

-Ddd.profiling.queueing.time.enabled=false — all spans return, all other profiling features (CPU, allocation, lock, IO, …) keep working.

Fix

#12506 retries the failed batch without the interface change, dropping only queueing-time profiling and logging the degradation once at info. With that fix the workaround flag is no longer needed.

Reproduction Code

  1. Spring Boot app, jib containerizingMode=packaged, JDK 25 (Temurin).
  2. Training run: -XX:AOTCacheOutput=app.aot with the agent attached, then run with -XX:AOTCache=app.aot -javaagent:dd-java-agent.jar.
  3. Send requests: zero spans. Add -Ddd.profiling.queueing.time.enabled=false: all spans appear (245 spans in our 20-request measurement, identical to no-AOT baseline — table in Fix instrumentation being dropped when a JDK AOT cache is used #12506).

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions