open-telemetry / opentelemetry-java-instrumentation

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

ClassNotFoundException: io.opentelemetry.api.incubator.trace.ExtendedTracer #11812

Closed hzpz closed 3 weeks ago

hzpz commented 1 month ago

Describe the bug Setting up the OpenTelemetry Spring Boot Starter as described in the documentation using the recently released version 1.40.0 will prevent the Spring Boot context from loading due to a missing class.

Steps to reproduce Create a Spring Boot project with start.spring.io, add the OpenTelemetry dependencies as described in the documentation. For a minimal example see: https://github.com/hzpz/opentelemetry-needs-incubator

What did you expect to see? The Spring Boot context should load.

What did you see instead? The Spring Boot context failed to load.

What version and what artifacts are you using?

Environment Compiler: Temurin 21.0.2 OS: macOS 14.5

Additional context The Spring Boot context loads if I either

Stacktrace

Failed to load ApplicationContext for [MergedContextConfiguration@7d979d34 testClass = com.example.opentelemetry_needs_incubator.OpentelemetryNeedsIncubatorApplicationTests, locations = [], classes = [com.example.opentelemetry_needs_incubator.OpentelemetryNeedsIncubatorApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@6175619b, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@76c7beb3, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@4e76dac, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6c67e137, org.springframework.boot.test.context.SpringBootTestAnnotation@8d9551e1], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
java.lang.IllegalStateException: Failed to load ApplicationContext for [MergedContextConfiguration@7d979d34 testClass = com.example.opentelemetry_needs_incubator.OpentelemetryNeedsIncubatorApplicationTests, locations = [], classes = [com.example.opentelemetry_needs_incubator.OpentelemetryNeedsIncubatorApplication], contextInitializerClasses = [], activeProfiles = [], propertySourceDescriptors = [], propertySourceProperties = ["org.springframework.boot.test.context.SpringBootTestContextBootstrapper=true"], contextCustomizers = [org.springframework.boot.test.autoconfigure.actuate.observability.ObservabilityContextCustomizerFactory$DisableObservabilityContextCustomizer@1f, org.springframework.boot.test.autoconfigure.properties.PropertyMappingContextCustomizer@0, org.springframework.boot.test.autoconfigure.web.servlet.WebDriverContextCustomizer@6175619b, org.springframework.boot.test.context.filter.ExcludeFilterContextCustomizer@76c7beb3, org.springframework.boot.test.json.DuplicateJsonObjectContextCustomizerFactory$DuplicateJsonObjectContextCustomizer@4e76dac, org.springframework.boot.test.mock.mockito.MockitoContextCustomizer@0, org.springframework.boot.test.web.client.TestRestTemplateContextCustomizer@6c67e137, org.springframework.boot.test.context.SpringBootTestAnnotation@8d9551e1], contextLoader = org.springframework.boot.test.context.SpringBootContextLoader, parent = null]
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:180)
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:130)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:142)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:98)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:260)
    at org.springframework.test.context.junit.jupiter.SpringExtension.postProcessTestInstance(SpringExtension.java:163)
    at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
    at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:179)
    at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
    at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
    at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
    at java.base/java.util.stream.StreamSpliterators$WrappingSpliterator.forEachRemaining(StreamSpliterators.java:310)
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:735)
    at java.base/java.util.stream.Streams$ConcatSpliterator.forEachRemaining(Streams.java:734)
    at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
    at java.base/java.util.Optional.orElseGet(Optional.java:364)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'autoConfiguredOpenTelemetrySdk' defined in class path resource [io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig.class]: Failed to instantiate [io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk]: Factory method 'autoConfiguredOpenTelemetrySdk' threw exception with message: io/opentelemetry/api/incubator/trace/ExtendedTracer
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:648)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1337)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1167)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:335)
    at org.springframework.boot.test.context.SpringBootContextLoader.lambda$loadContext$3(SpringBootContextLoader.java:137)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:58)
    at org.springframework.util.function.ThrowingSupplier.get(ThrowingSupplier.java:46)
    at org.springframework.boot.SpringApplication.withHook(SpringApplication.java:1463)
    at org.springframework.boot.test.context.SpringBootContextLoader$ContextLoaderHook.run(SpringBootContextLoader.java:553)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:137)
    at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:108)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:225)
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:152)
    ... 17 more
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/trace/ExtendedTracer
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:177)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:644)
    ... 41 more
Caused by: java.lang.NoClassDefFoundError: io/opentelemetry/api/incubator/trace/ExtendedTracer
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)
    at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150)
    at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862)
    at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681)
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
    at io.opentelemetry.sdk.trace.SdkTracerProvider.<init>(SdkTracerProvider.java:56)
    at io.opentelemetry.sdk.trace.SdkTracerProviderBuilder.build(SdkTracerProviderBuilder.java:204)
    at io.opentelemetry.sdk.OpenTelemetrySdkBuilder.build(OpenTelemetrySdkBuilder.java:101)
    at io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder.build(AutoConfiguredOpenTelemetrySdkBuilder.java:446)
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig.autoConfiguredOpenTelemetrySdk(OpenTelemetryAutoConfiguration.java:107)
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig$$SpringCGLIB$$0.CGLIB$autoConfiguredOpenTelemetrySdk$6(<generated>)
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig$$SpringCGLIB$$FastClass$$1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:258)
    at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:348)
    at io.opentelemetry.instrumentation.spring.autoconfigure.OpenTelemetryAutoConfiguration$OpenTelemetrySdkConfig$$SpringCGLIB$$0.autoConfiguredOpenTelemetrySdk(<generated>)
    at java.base/java.lang.reflect.Method.invoke(Method.java:580)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140)
    ... 42 more
Caused by: java.lang.ClassNotFoundException: io.opentelemetry.api.incubator.trace.ExtendedTracer
    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:526)
    ... 63 more
jkwatson commented 1 month ago

I'm going to move this over to the instrumentation repository, since it involves the functioning of the spring-boot-starter and not the SDK or API themselves.

laurit commented 1 month ago

@zeitlinger could you take a look

zeitlinger commented 1 month ago

@jkwatson it's not really about spring IIUC

this is part of the dependency tree

     |    +--- io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.39.0 -> 1.40.0
     |    |    \--- io.opentelemetry:opentelemetry-sdk:1.40.0
     |    |         +--- io.opentelemetry:opentelemetry-api:1.40.0 (*)
     |    |         +--- io.opentelemetry:opentelemetry-sdk-common:1.40.0 (*)
     |    |         +--- io.opentelemetry:opentelemetry-sdk-trace:1.40.0
     |    |         |    +--- io.opentelemetry:opentelemetry-api-incubator:1.40.0-alpha -> 1.39.0-alpha
jkwatson commented 1 month ago

@jkwatson it's not really about spring IIUC

this is part of the dependency tree

  • SDK needs to have the same version of opentelemetry-api-incubator or bad stuff can happen (like this one)
  • if the user doesn't want to use alpha artifacts, why should they be forced to use the alpha bom?
     |    +--- io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.39.0 -> 1.40.0
     |    |    \--- io.opentelemetry:opentelemetry-sdk:1.40.0
     |    |         +--- io.opentelemetry:opentelemetry-api:1.40.0 (*)
     |    |         +--- io.opentelemetry:opentelemetry-sdk-common:1.40.0 (*)
     |    |         +--- io.opentelemetry:opentelemetry-sdk-trace:1.40.0
     |    |         |    +--- io.opentelemetry:opentelemetry-api-incubator:1.40.0-alpha -> 1.39.0-alpha

What is causing the downgrade of the incubator module?

laurit commented 1 month ago

Try using opentelemetry-instrumentation-bom-alpha 2.6.0-alpha. The issue is that opentelemetry spring boot starter 2.5.0 is compatible with opentelemetry sdk 1.39.0 but here 1.40.0 is used. It is io.opentelemetry.instrumentation:opentelemetry-instrumentation-bom-alpha:2.5.0-alpha that sets opentelemetry-api-incubator version to 1.39.0-alpha. The way I see it we could solve it by changing the documentation to also use opentelemetry-bom-alpha or say that users who who use instrumentation with a different sdk version than what the instrumentation was tested with should figure this and other potential issues out on their own.

zeitlinger commented 1 month ago

The SDK is stable and hence should be backwards compatible. So it SDK depends on the incubator API, then the incubator API should be in the stable BOM IMO.

laurit commented 1 month ago

@jkwatson @jack-berg since opentelemetry-api-incubator is a required dependency of stable sdk components wdyt of also setting its version in opentelemetry-bom?

jack-berg commented 1 month ago

Yeah this is weird.

opentelemetry-sdk is part of opentelemetry-bom and has a transitive dependency on opentelemetry-api-incubator which is not part of opentelemetry-bom. opentelemetry-api-incubator is part of opentelemetry-bom-alpha, which is included in opentelemetry-instrumentation-bom-alpha.

The user has dependencies on opentelemetry-bom and opentelemetry-instrumentation-bom-alpha which are conflicting with each other: opentelemetry-instrumentation-bom-alpha version is 2.5.0, which targets opentelemetry-bom version 1.39.0. But the user also places a direct dependency on opentelemetry-bom version 1.40.0.

Ironically, the fix is to just eliminate the opentelemetry-bom dependency, since that is included automatically already with opentelemetry-instrumentation-bom-alpha.

But it might also be time to consider whether we even want an alpha bom anymore. As of now, there are 4 dependencies in it, two of which will never be stable by design: opentelemetry-opencensus-shim, opentelemetry-api-incubator, opentelemetry-exporter-prometheus, opentelemetry-sdk-extension-incubator.

Maybe its enough to say that we have a single bom, and that you should consult the artifacts table for the stability status of dependencies.

Or we can make it clear to users that a dependency on the instrumentation bom (opentelemetry-instrumentation-bom-alpha) supersedes a dependency on any core repo boms and you should only use one or the other based on your needs.

zeitlinger commented 1 month ago

Discussed in meeting: https://docs.google.com/document/d/1WK9h4p55p8ZjPkxO75-ApI9m0wfea6ENZmMoFRvXSCw/edit#bookmark=id.7oifaq3qamri

srigollamudi commented 1 month ago

I am having the same issue- except for a different class - io/opentelemetry/sdk/autoconfigure/spi/internal/AutoConfigureListener. I have tried to add the below dependency but that didn't resolve the issue

implementation 'io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:1.40.0'

laurit commented 1 month ago

@srigollamudi create a new issue, include stack trace. A minimal application that reproduces the issue would be nice.

srigollamudi commented 1 month ago

Will do. thx!

laurit commented 3 weeks ago

I think this got resolved with a documentation change.