Skip to content

java.lang.NoClassDefFoundError: datadog/opentelemetry/shim/trace/OtelSpanEvent #8017

@krosen040

Description

@krosen040

Description

When running an application with the Java agent and support for OpenTelemetry enabled (dd.trace.otel.enabled=true) and calling addEvent or recordException on an io.opentelemetry.api.trace.Span (support for this added in #7408), in certain cases it fails with the following error:

Exception in thread "main" java.lang.NoClassDefFoundError: datadog/opentelemetry/shim/trace/OtelSpanEvent
        at datadog.opentelemetry.shim.trace.OtelSpan.addEvent(OtelSpan.java:85)
        at io.opentelemetry.api.trace.Span.addEvent(Span.java:198)
        at org.example.App.thisThrows(App.java:18)
        at org.example.App.main(App.java:11)
Caused by: java.lang.ClassNotFoundException: datadog.opentelemetry.shim.trace.OtelSpanEvent
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
        at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
        ... 4 more

Tested using the following versions:

  • Java:
$ java -version
openjdk version "17.0.8" 2023-07-18 LTS
OpenJDK Runtime Environment Zulu17.44+15-CA (build 17.0.8+7-LTS)
OpenJDK 64-Bit Server VM Zulu17.44+15-CA (build 17.0.8+7-LTS, mixed mode, sharing)
  • dd-trace-java: 1.43.0

Example

A minimal example that reproduces the error can be found below.

In the example, I use @WithSpan because it's an easy way to make the Java agent create a span (so that Span.current() doesn't return a no-op span), however we're seeing the same problem in other scenarios as well.

It should be noted that if thisThrows is called after thisWorks, no exception is thrown.

App.java

package org.example;

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.annotations.WithSpan;

public class App {
    public static void main(String[] args) {
        thisThrows();
        thisWorks();
    }

    @WithSpan
    static void thisThrows() {
        Span span = Span.current();
        span.addEvent("test");
    }

    static void thisWorks() {
        Tracer tracer = GlobalOpenTelemetry.getTracer("scope");
        Span span = tracer.spanBuilder("span").startSpan();

        try (Scope scope = span.makeCurrent()) {
            span.addEvent("test");
        } finally {
            span.end();
        }
    }
}

build.gradle

plugins {
    id 'application'
}

repositories {
    mavenCentral()
}

dependencies {
    implementation 'io.opentelemetry:opentelemetry-api:1.44.1'
    implementation 'io.opentelemetry.instrumentation:opentelemetry-instrumentation-annotations:2.10.0'
}

java {
    toolchain {
        languageVersion = JavaLanguageVersion.of(17)
    }
}

application {
    mainClass = 'org.example.App'
    applicationDefaultJvmArgs = ["-javaagent:../dd-java-agent-1.43.0.jar", "-Ddd.trace.otel.enabled=true", "-Ddd.writer.type=LoggingWriter"]
}

Metadata

Metadata

Assignees

Labels

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions