dd-trace-ot 1.67.x: NoClassDefFoundError `ddtrot/dd/trace/api/llmobs/LLMObs` · Issue #12857 · DataDog/dd-trace-java · GitHub
Skip to content

dd-trace-ot 1.67.x: NoClassDefFoundError ddtrot/dd/trace/api/llmobs/LLMObs #12857

Open

Description

@kschwarz1116

Tracer Version(s)

1.67.0+

Java Version(s)

25

JVM Vendor

Oracle JDK

Bug Report

Since 1.67.0, DDTracer.inject(...) from dd-trace-ot throws NoClassDefFoundError for ddtrot/dd/trace/api/llmobs/LLMObs. 1.66.0 is fine. dd-trace-api is on the classpath at the same version as dd-trace-ot.

java.lang.NoClassDefFoundError: ddtrot/dd/trace/api/llmobs/LLMObs
    at ddtrot.dd.trace.core.propagation.DatadogHttpCodec$Injector.inject(DatadogHttpCodec.java:86)
    at ddtrot.dd.trace.core.propagation.HttpCodec$CompoundInjector.inject(HttpCodec.java:194)
    at ddtrot.dd.trace.core.propagation.TracingPropagator.inject(TracingPropagator.java:58)
    at ddtrot.dd.context.propagation.CompositePropagator.inject(CompositePropagator.java:18)
    at datadog.opentracing.DDTracer.inject(DDTracer.java:490)
Caused by: java.lang.ClassNotFoundException: ddtrot.dd.trace.api.llmobs.LLMObs

Analysis

This is a regression from #12416 (9a03e95), which makes DatadogHttpCodec$Injector.inject call LLMObsInternal.propagationValuesFor(...). LLMObsInternal (internal-api) extends LLMObs (dd-trace-api).

In dd-trace-ot/build.gradle.kts, the shadow jar excludes :dd-trace-api and relocates datadog. to ddtrot.dd.. The exclude %regex[datadog/trace/api/(?!Functions|Endpoint)[^/]*] only covers classes directly under datadog/trace/api/, so datadog.trace.api.llmobs.* is relocated. The resulting dd-trace-ot-1.67.1.jar contains ddtrot/dd/trace/api/llmobs/LLMObsInternal.class (superclass ddtrot.dd.trace.api.llmobs.LLMObs) but no LLMObs.class. dd-trace-api only provides the unrelocated datadog/trace/api/llmobs/LLMObs.

Possible fix (untested): add exclude("datadog.trace.api.llmobs.*") to the relocate("datadog.", "ddtrot.dd.") block.

Environment

  • dd-trace-ot and dd-trace-api 1.67.1 (also 1.67.0)
  • JDK 25 (Temurin), OpenTracing 0.32.0

Expected Behavior

DDTracer.inject(...) injects the Datadog headers into the carrier without error, as it does in 1.66.0:

injected headers: {x-datadog-parent-id=..., x-datadog-sampling-priority=1, tracestate=dd=s:1;..., x-datadog-tags=_dd.p.dm=-1,...}

### Reproduction Code

Only `dd-trace-ot` and `dd-trace-api` are needed. Change `dd.version` to `1.66.0` to see it work.

`pom.xml`:

```xml
<project xmlns="http://maven.apache.org/POM/4.0.0">
  <modelVersion>4.0.0</modelVersion>
  <groupId>repro</groupId>
  <artifactId>dd-ot-llmobs-repro</artifactId>
  <version>1.0</version>
  <properties>
    <maven.compiler.release>17</maven.compiler.release>
    <dd.version>1.67.1</dd.version>
  </properties>
  <dependencies>
    <dependency>
      <groupId>com.datadoghq</groupId>
      <artifactId>dd-trace-ot</artifactId>
      <version>${dd.version}</version>
    </dependency>
    <dependency>
      <groupId>com.datadoghq</groupId>
      <artifactId>dd-trace-api</artifactId>
      <version>${dd.version}</version>
    </dependency>
  </dependencies>
</project>

src/main/java/repro/Main.java:

package repro;

import datadog.opentracing.DDTracer;
import io.opentracing.Span;
import io.opentracing.propagation.Format;
import io.opentracing.propagation.TextMapAdapter;
import java.util.HashMap;
import java.util.Map;

public class Main {
  public static void main(String[] args) {
    System.setProperty("dd.writer.type", "LoggingWriter");
    DDTracer tracer = DDTracer.builder().serviceName("repro").build();
    Span span = tracer.buildSpan("op").start();
    Map<String, String> headers = new HashMap<>();
    tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new TextMapAdapter(headers));
    System.out.println("injected headers: " + headers);
    span.finish();
    tracer.close();
  }
}

Run:

mvn -q -B compile
mvn -q -B dependency:build-classpath -Dmdep.outputFile=cp.txt
java -cp target/classes:$(cat cp.txt) repro.Main

(mvn exec:java also fails, but reports LLMObsInternal as the missing class because it wraps the error.)

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions