0

I wanted to enable tracing in a Java Spring Boot project using Spring Sleuth and OpenTelemetry. The traces need to be exported to Lightstep. I added spring-cloud-starter-sleuth, spring-cloud-sleuth-otel-autoconfigure, opentelemetry-exporter-otlp-trace and grpc-okhttp dependencies. I added the following in the pom.xml.

<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2021.0.4</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-sleuth-otel-dependencies</artifactId>
                <version>1.1.0</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-sleuth -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-sleuth-brave</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-sleuth-otel-autoconfigure -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-sleuth-otel-autoconfigure</artifactId>
<!--            <version>1.0.0-M5</version>-->
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.opentelemetry/opentelemetry-exporter-otlp-trace -->
        <dependency>
            <groupId>io.opentelemetry</groupId>
            <artifactId>opentelemetry-exporter-otlp-trace</artifactId>
            <version>1.14.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.grpc/grpc-okhttp -->
        <dependency>
            <groupId>io.grpc</groupId>
            <artifactId>grpc-okhttp</artifactId>
            <version>1.42.1</version>
        </dependency>

Added the following properties in application.properties file.

spring.sleuth.propagation.type=W3C
spring.sleuth.otel.exporter.otlp.endpoint=${OTEL_EXPORTER_OTLP_TRACES_ENDPOINT}

When I run the application I get the following exception.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'otelHttpServerHandler' defined in class path resource [org/springframework/cloud/sleuth/autoconfig/otel/OtelBridgeConfiguration$TraceOtelHttpBridgeConfiguration.class]: Unsatisfied dependency expressed through method 'otelHttpServerHandler' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'otel' defined in class path resource [org/springframework/cloud/sleuth/autoconfig/otel/OtelAutoConfiguration.class]: Unsatisfied dependency expressed through method 'otel' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'otelTracerProvider' defined in class path resource [org/springframework/cloud/sleuth/autoconfig/otel/OtelAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.opentelemetry.sdk.trace.SdkTracerProvider]: Factory method 'otelTracerProvider' threw exception; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'otelOtlpGrpcSpanExporter' defined in class path resource [org/springframework/cloud/sleuth/autoconfig/otel/OtelExporterConfiguration$OtlpExporterConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter]: Factory method 'otelOtlpGrpcSpanExporter' threw exception; nested exception is java.lang.NoSuchMethodError: 'io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder io.opentelemetry.exporter.internal.grpc.GrpcExporter.builder(java.lang.String, long, java.net.URI, java.util.function.Supplier, java.lang.String, java.lang.String)'
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:233) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1282) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveNamedBean(DefaultListableBeanFactory.java:1243) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveBean(DefaultListableBeanFactory.java:494) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:349) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342) ~[spring-beans-5.3.18.jar:5.3.18]
    at org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebServletConfiguration$LazyTracingFilter.tracingFilter(TraceWebServletConfiguration.java:142) ~[spring-cloud-sleuth-autoconfigure-3.1.4.jar:3.1.4]
    at org.springframework.cloud.sleuth.autoconfig.instrument.web.TraceWebServletConfiguration$LazyTracingFilter.init(TraceWebServletConfiguration.java:125) ~[spring-cloud-sleuth-autoconfigure-3.1.4.jar:3.1.4]
    at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:272) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:106) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4613) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5256) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:835) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1396) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1386) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) ~[na:na]
    at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145) ~[na:na]
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:919) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:263) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:432) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:927) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.apache.catalina.startup.Tomcat.start(Tomcat.java:486) ~[tomcat-embed-core-9.0.60.jar:9.0.60]
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.initialize(TomcatWebServer.java:123) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.web.embedded.tomcat.TomcatWebServer.<init>(TomcatWebServer.java:104) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getTomcatWebServer(TomcatServletWebServerFactory.java:478) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory.getWebServer(TomcatServletWebServerFactory.java:211) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.createWebServer(ServletWebServerApplicationContext.java:182) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.onRefresh(ServletWebServerApplicationContext.java:160) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:577) ~[spring-context-5.3.18.jar:5.3.18]
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:145) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:740) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:415) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1312) ~[spring-boot-2.6.6.jar:2.6.6]
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1301) ~[spring-boot-2.6.6.jar:2.6.6]
    at com.cognite.tracker.ConsumptionTrackerApplication.main(ConsumptionTrackerApplication.java:10) ~[classes/:na]

When I check the dependency tree I get the following output.

|  +- io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:jar:1.16.0:compile
[INFO] |  +- io.opentelemetry.instrumentation:opentelemetry-instrumentation-api:jar:1.18.0:compile
[INFO] |  \- io.opentelemetry:opentelemetry-extension-trace-propagators:jar:1.16.0:compile
[INFO] +- io.opentelemetry:opentelemetry-exporter-otlp-trace:jar:1.14.0:compile
[INFO] |  \- io.opentelemetry:opentelemetry-exporter-otlp-common:jar:1.16.0:runtime
[INFO] |     \- com.squareup.okhttp3:okhttp:jar:3.14.9:runtime

Appreciate if someone has a clue on what's going on :D.

1 Answers1

0

looks like spring-cloud-sleuth-otel-autoconfigure pulls in io.opentelemetry:opentelemetry-exporter-otlp-common:1.16 as transient dependency which has a different constructor than the one in version 1.14

nested exception is java.lang.NoSuchMethodError: 'io.opentelemetry.exporter.internal.grpc.GrpcExporterBuilder io.opentelemetry.exporter.internal.grpc.GrpcExporter.builder(java.lang.String, long, java.net.URI, java.util.function.Supplier, java.lang.String, java.lang.String)

if you pin the version of the transient dependency io.opentelemetry:opentelemetry-exporter-otlp-common to 1.14 it should work.

    <dependency>
        <groupId>io.opentelemetry</groupId>
        <artifactId>io.opentelemetry:opentelemetry-exporter-otlp-common</artifactId>
        <version>1.14.0</version>
    </dependency>

add this to your import section. I also used a more recent version of org.springframework.cloud:spring-cloud-sleuth-otel-dependencies:1.1.0-M7

For testing i used this config

spring:
  sleuth:
    otel:
      sdk:
        disabled: false
    metrics: ""
    logs: ""
    exporter:
      otlp:
        enabled: true
        endpoint: http://localhost:4317

i hope this helps