Description
See #46229 (comment) for some background. In addition to management.opentelemetry.resource-attributes
affecting the resource attributes that are included when exported metrics over OTLP, we also have a problem with conditions at the moment.
With these three dependencies:
implementation 'org.springframework.boot:spring-boot-starter'
implementation 'org.springframework.boot:spring-boot-metrics'
runtimeOnly 'io.micrometer:micrometer-registry-otlp'
An app will fail to start with the following exception:
java.lang.IllegalArgumentException: Could not find class [org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetryProperties]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:353) ~[spring-core-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.core.annotation.TypeMappedAnnotation.adapt(TypeMappedAnnotation.java:451) ~[spring-core-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.core.annotation.TypeMappedAnnotation.getValue(TypeMappedAnnotation.java:384) ~[spring-core-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.core.annotation.TypeMappedAnnotation.asMap(TypeMappedAnnotation.java:273) ~[spring-core-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.core.annotation.AbstractMergedAnnotation.asAnnotationAttributes(AbstractMergedAnnotation.java:191) ~[spring-core-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.annotation.AnnotationBeanNameGenerator.determineBeanNameFromAnnotation(AnnotationBeanNameGenerator.java:143) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.annotation.AnnotationBeanNameGenerator.generateBeanName(AnnotationBeanNameGenerator.java:110) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.registerBeanDefinitionForImportedConfigurationClass(ConfigurationClassBeanDefinitionReader.java:167) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:147) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:126) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:446) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:306) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:781) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:599) ~[spring-context-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:737) ~[spring-boot-4.0.0-SNAPSHOT.jar:4.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:435) ~[spring-boot-4.0.0-SNAPSHOT.jar:4.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[spring-boot-4.0.0-SNAPSHOT.jar:4.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1344) ~[spring-boot-4.0.0-SNAPSHOT.jar:4.0.0-SNAPSHOT]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1333) ~[spring-boot-4.0.0-SNAPSHOT.jar:4.0.0-SNAPSHOT]
at com.example.gh_46229.Gh46229Application.main(Gh46229Application.java:10) ~[main/:na]
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.opentelemetry.autoconfigure.OpenTelemetryProperties
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:526) ~[na:na]
at java.base/java.lang.Class.forName0(Native Method) ~[na:na]
at java.base/java.lang.Class.forName(Class.java:534) ~[na:na]
at java.base/java.lang.Class.forName(Class.java:513) ~[na:na]
at org.springframework.util.ClassUtils.forName(ClassUtils.java:302) ~[spring-core-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
at org.springframework.util.ClassUtils.resolveClassName(ClassUtils.java:343) ~[spring-core-7.0.0-SNAPSHOT.jar:7.0.0-SNAPSHOT]
... 21 common frames omitted
The code in spring-boot-metrics
that deals with OTLP currently assumes that spring-boot-opentelemetry
will also be on the classpath but that may not be the case. Making it a required dependency would require introducing a new module as spring-boot-metrics
itself should not have a required dependency on spring-boot-opentelemetry
. Leaving it optional but with appropriate conditions in place would address the CNFE above but may add to the confusion about the different between OTLP and OpenTelemetry and when the management.opentelemetry
properties will and will not have an effect.