open-telemetry / opentelemetry-java-instrumentation

OpenTelemetry auto-instrumentation and instrumentation libraries for Java
https://opentelemetry.io
Apache License 2.0
1.79k stars 782 forks source link

opentelemetry-spring-boot-starter throws ClassNotFoundException: io.opentelemetry.api.incubator.metrics.DoubleGauge #11671

Closed pards closed 3 days ago

pards commented 3 days ago

Describe the bug

opentelemetry-spring-boot-starter throws ClassNotFoundException: io.opentelemetry.api.incubator.metrics.DoubleGauge when importing spring-boot-dependencies instead of setting the parent to spring-boot-starter-parent

This is a standard approach outlined in the Spring documentation.

Steps to reproduce

  1. Unzip otel-demo.zip
  2. Run mvn org.springframework.boot:spring-boot-maven-plugin:run

Expected behavior

Program should run

Actual behavior

$ java -version
openjdk version "17.0.7" 2023-04-18
OpenJDK Runtime Environment Temurin-17.0.7+7 (build 17.0.7+7)
OpenJDK 64-Bit Server VM Temurin-17.0.7+7 (build 17.0.7+7, mixed mode)
$ mvn -version
Apache Maven 3.9.6 (bc0240f3c744dd6b6ec2920b3cd08dcc295161ae)
Maven home: /opt/homebrew/Cellar/maven/3.9.6/libexec
Java version: 17.0.7, vendor: Eclipse Adoptium, runtime: /Library/Java/JavaVirtualMachines/temurin-17.jdk/Contents/Home
Default locale: en_CA, platform encoding: UTF-8
OS name: "mac os x", version: "13.6.4", arch: "aarch64", family: "mac"
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk]: Factory method 'autoConfiguredOpenTelemetrySdk' threw exception with message: io/opentelemetry/api/incubator/metrics/DoubleGauge
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:177) ~[spring-beans-6.1.10.jar:6.1.10]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:644) ~[spring-beans-6.1.10.jar:6.1.10]
    ... 82 common frames omitted
Caused by: java.lang.NoClassDefFoundError: io/opentelemetry/api/incubator/metrics/DoubleGauge
    at io.opentelemetry.sdk.metrics.SdkMeter.gaugeBuilder(SdkMeter.java:111) ~[opentelemetry-sdk-metrics-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.trace.export.BatchSpanProcessor$Worker.<init>(BatchSpanProcessor.java:203) ~[opentelemetry-sdk-trace-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.trace.export.BatchSpanProcessor$Worker.<init>(BatchSpanProcessor.java:162) ~[opentelemetry-sdk-trace-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.trace.export.BatchSpanProcessor.<init>(BatchSpanProcessor.java:87) ~[opentelemetry-sdk-trace-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder.build(BatchSpanProcessorBuilder.java:159) ~[opentelemetry-sdk-trace-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.autoconfigure.TracerProviderConfiguration.configureBatchSpanProcessor(TracerProviderConfiguration.java:126) ~[opentelemetry-sdk-extension-autoconfigure-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.autoconfigure.TracerProviderConfiguration.configureSpanProcessors(TracerProviderConfiguration.java:92) ~[opentelemetry-sdk-extension-autoconfigure-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.autoconfigure.TracerProviderConfiguration.configureTracerProvider(TracerProviderConfiguration.java:62) ~[opentelemetry-sdk-extension-autoconfigure-1.37.0.jar:1.37.0]
    at io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder.build(AutoConfiguredOpenTelemetrySdkBuilder.java:464) ~[opentelemetry-sdk-extension-autoconfigure-1.37.0.jar:1.37.0]
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig.autoConfiguredOpenTelemetrySdk(OpenTelemetryAutoConfiguration.java:107) ~[opentelemetry-spring-boot-2.5.0-alpha.jar:2.5.0-alpha]
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig$$SpringCGLIB$$0.CGLIB$autoConfiguredOpenTelemetrySdk$2(<generated>) ~[opentelemetry-spring-boot-2.5.0-alpha.jar:2.5.0-alpha]
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig$$SpringCGLIB$$FastClass$$1.invoke(<generated>) ~[opentelemetry-spring-boot-2.5.0-alpha.jar:2.5.0-alpha]
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258) ~[spring-core-6.1.10.jar:6.1.10]
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:348) ~[spring-context-6.1.10.jar:6.1.10]
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig$$SpringCGLIB$$0.autoConfiguredOpenTelemetrySdk(<generated>) ~[opentelemetry-spring-boot-2.5.0-alpha.jar:2.5.0-alpha]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
    at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140) ~[spring-beans-6.1.10.jar:6.1.10]
    ... 83 common frames omitted
Caused by: java.lang.ClassNotFoundException: io.opentelemetry.api.incubator.metrics.DoubleGauge
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[na:na]
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188) ~[na:na]
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
    ... 103 common frames omitted

Javaagent or library instrumentation version

v1.39.0

Environment

JDK: 17 OS: Windows 10, and MacOS 13.6.4

Additional context

The attached project runs smoothly when using the spring boot parent (commented out in the pom.xml)

laurit commented 3 days ago

This issue is caused by using opentelemetry api jars from different versions. When you run mvn dependency:tree you'll notice that you have io.opentelemetry:opentelemetry-api:jar:1.37.0:compile and io.opentelemetry:opentelemetry-api-incubator:jar:1.39.0-alpha:runtime. Try moving importing opentelemety boms before importing spring bom in the dependencyManagement section. Otherwise the opentelemetry version set in spring bom will override what is set in the opentelemetry boms.

jeanbisutti commented 3 days ago

@pards Have you followed these instructions related to the dependency management?

laurit commented 3 days ago

@pards Have you followed these instructions related to the dependency management?

@jeanbisutti see the attached sample app. He has added opentelemetry boms to dependencyManagement but what the instructions don't mentions is that the ordering of the boms matters. If you have another bom before opentelemetry boms that sets version for otel artifacts then that bom will win.

pards commented 3 days ago

Re-ordering the imports so that opentelemetry-bom and opentelemetry-instrumentation-bom-alpha appear before spring-boot-dependencies fixed the problem. Thank you