aws / aws-xray-sdk-java

The official AWS X-Ray Recorder SDK for Java.
Apache License 2.0
94 stars 98 forks source link

ClassNotFoundException: software.amazon.awssdk.core.interceptor.ExecutionInterceptor when including aws-xray-recorder-sdk-aws-sdk-v2-instrumentor #380

Closed verbitan closed 1 year ago

verbitan commented 1 year ago

Hi,

I'm trying to instrument a Spring application which uses the AWS API, however on runtime it fails with the following error.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'AWSClient': Invocation of init method failed
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeInitialization(InitDestroyAnnotationBeanPostProcessor.java:196) ~[spring-beans-6.0.7.jar!/:6.0.7]
...
Caused by: java.lang.NoClassDefFoundError: software/amazon/awssdk/core/interceptor/ExecutionInterceptor
    at jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641) ~[?:?]
...

Below is a snippet of my pom.xml showing that I'm including the relevant dependencies.

...
    <properties>
        <java.version>17</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.0.6</version>
    </parent>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud bill of materials -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>2022.0.2</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- AWS bill of materials -->
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.20.56</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-xray-recorder-sdk-bom</artifactId>
                <version>2.14.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!--SpringFramework dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-aop</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-bootstrap</artifactId>
        </dependency>

        <!-- AWS dependencies -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
        </dependency>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>sns</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-xray-recorder-sdk-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-xray-recorder-sdk-spring</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
        </dependency>
    </dependencies>
...

I can also see the file BOOT-INF/lib/sdk-core-2.20.56.jar on my classpath which contains the file software/amazon/awssdk/core/interceptor/ExecutionInterceptor.class. So I'm not sure what I'm missing!

Any help would be greatly appreciated.

atshaw43 commented 1 year ago

Have you looked at this documentation?

It gives an example of which dependencies to use.

https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html

verbitan commented 1 year ago

Hi @atshaw43,

I have, yes. You can see from my example that I include the aws-xray-recorder-sdk-aws-sdk-v2-instrumentor and aws-xray-recorder-sdk-spring dependencies.

As I mentioned in my original comment, I can see that Maven has added BOOT-INF/lib/sdk-core-2.20.56.jar onto my classpath which does contain the class software/amazon/awssdk/core/interceptor/ExecutionInterceptor.class, which is why I don't understand how I can be getting a Caused by: java.lang.NoClassDefFoundError: software/amazon/awssdk/core/interceptor/ExecutionInterceptor error.

atshaw43 commented 1 year ago

Try adding this dependency: aws-java-sdk-core.

If that does not work, can you give us a sample project with minimal code that reproduces the issue, and more of the stack trace?

Thanks, Adam

verbitan commented 1 year ago

Hi @atshaw43, that didn't solve the issue I'm afraid.

As requested I've created a sample project at https://github.com/verbitan/xray-issue. I just used Spring Initializr to create an empty project, then tried constructing an AWS Batch client in the @RestController.

I've also added a Dockerfile so you can reproduce exactly what I've done with the following commands.

docker build --tag=xray-issue .
docker run -it --rm -p 8080:8080 xray-issue
curl http://localhost:8080

It produces the following log output.

Jun 02, 2023 4:31:42 PM com.amazonaws.xray.agent.runtime.config.XRaySDKConfiguration init                                                                                                                                                                                                                           [35/5805]
INFO: Initializing the X-Ray Agent Recorder

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.0)

2023-06-02T16:31:49.511Z  INFO 1 --- [           main] com.example.springboot.Application       : Starting Application v0.0.1-SNAPSHOT using Java 17.0.7 with PID 1 (/app/libs/spring-boot-0.0.1-SNAPSHOT.jar started by root in /)
2023-06-02T16:31:49.520Z  INFO 1 --- [           main] com.example.springboot.Application       : No active profile set, falling back to 1 default profile: "default"
2023-06-02T16:31:52.792Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-06-02T16:31:52.826Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-06-02T16:31:52.826Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.8]
2023-06-02T16:31:53.227Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-06-02T16:31:53.230Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3522 ms
2023-06-02T16:31:54.245Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-06-02T16:31:54.284Z  INFO 1 --- [           main] com.example.springboot.Application       : Started Application in 6.475 seconds (process running for 13.779)
2023-06-02T16:32:13.659Z  INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-06-02T16:32:13.660Z  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-06-02T16:32:13.661Z  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2023-06-02T16:32:17.658Z ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed: java.lang.NoClassDefFoundError: software/amazon/awssdk/core/interceptor/ExecutionInterceptor] with root
 cause

java.lang.ClassNotFoundException: software.amazon.awssdk.core.interceptor.ExecutionInterceptor                                                                                                                                                                                                                      [10/5806]
        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]
        at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) ~[na:na]
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639) ~[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:574) ~[na:na]
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:149) ~[spring-boot-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
        at software.amazon.awssdk.core.internal.util.ClassLoaderHelper.loadClassViaClasses(ClassLoaderHelper.java:38) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.internal.util.ClassLoaderHelper.loadClass(ClassLoaderHelper.java:105) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.internal.util.ClassLoaderHelper.loadClass(ClassLoaderHelper.java:74) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.createExecutionInterceptor(ClasspathInterceptorChainFactory.java:123) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.createExecutionInterceptorFromResource(ClasspathInterceptorChainFactory.java:95) ~[sdk-core-2.20.56.jar!/:na]
        at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273) ~[na:na]
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.createExecutionInterceptorsFromClasspath(ClasspathInterceptorChainFactory.java:64) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.getGlobalInterceptors(ClasspathInterceptorChainFactory.java:58) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.resolveExecutionInterceptors(SdkDefaultClientBuilder.java:424) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.finalizeConfiguration(SdkDefaultClientBuilder.java:317) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.syncClientConfiguration(SdkDefaultClientBuilder.java:185) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.services.batch.DefaultBatchClientBuilder.buildClient(DefaultBatchClientBuilder.java:39) ~[batch-2.20.56.jar!/:na]
        at software.amazon.awssdk.services.batch.DefaultBatchClientBuilder.buildClient(DefaultBatchClientBuilder.java:27) ~[batch-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.build(SdkDefaultClientBuilder.java:150) ~[sdk-core-2.20.56.jar!/:na]
        at com.example.springboot.controllers.HelloController.index(HelloController.java:16) ~[classes!/:0.0.1-SNAPSHOT]
        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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
atshaw43 commented 1 year ago

I believe you want aws-xray-recorder-sdk-aws-sdk-v2 as you are past AWS SDK version 2.2. It looks like that module is for before AWS SDK version 2.2.

https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-awssdkclients.html

verbitan commented 1 year ago

Hi @atshaw43, based on the link you provided, you're describing manual instrumentation of AWS API calls rather than automatic instrumentation. Relevant quotes from that page are below.

The X-Ray SDK for Java automatically instruments all AWS SDK clients when you include the aws-sdk and an aws-sdk-instrumentor submodules in your build. If you don't include the Instrumentor submodule, you can choose to instrument some clients while excluding others.

To instrument downstream calls to AWS services with AWS SDK for Java 2.2 and later, you can omit the aws-xray-recorder-sdk-aws-sdk-v2-instrumentor module from your build configuration. Include the aws-xray-recorder-sdk-aws-sdk-v2 module instead, then instrument individual clients by configuring them with a TracingInterceptor.

I am after using the automatic instrumentation. If you follow the link to the submodules in the above quote, you'll see that my example is using the correct submodule for automatic instrumentation of 2.2 and above.

aws-xray-recorder-sdk-aws-sdk-v2-instrumentor – With aws-xray-recorder-sdk-aws-sdk-v2, instruments all AWS SDK for Java 2.2 and later clients automatically.

I didn't explicitly include aws-xray-recorder-sdk-aws-sdk-v2 in the pom.xml as it's already a dependency of aws-xray-recorder-sdk-aws-sdk-v2-instrumentor. I manually added it to test, just in case, but it didn't help.

atshaw43 commented 1 year ago

The auto-instrumentation for V2 does not work at the moment. The work around is to use manual instrumentation outline above by using the interceptor in V2 or handler in V1.

My apologies for the confusion that has caused.

verbitan commented 1 year ago

Hi @atshaw43, I updated my example to use manual instrumentation and I'm still getting the issue. You can see my changes on the new branch at https://github.com/verbitan/xray-issue/tree/manual. So it seems I cannot use XRay at all.

Jun 21, 2023 10:57:09 AM com.amazonaws.xray.agent.runtime.config.XRaySDKConfiguration init
INFO: Initializing the X-Ray Agent Recorder

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v3.1.0)

2023-06-21T10:57:17.651Z  INFO 1 --- [           main] com.example.springboot.Application       : Starting Application v0.0.1-SNAPSHOT using Java 17.0.7 with PID 1 (/app/libs/spring-boot-0.0.1-SNAPSHOT.jar started by root in /)
2023-06-21T10:57:17.663Z  INFO 1 --- [           main] com.example.springboot.Application       : No active profile set, falling back to 1 default profile: "default"
2023-06-21T10:57:20.688Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-06-21T10:57:20.721Z  INFO 1 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-06-21T10:57:20.721Z  INFO 1 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.8]
2023-06-21T10:57:21.112Z  INFO 1 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-06-21T10:57:21.115Z  INFO 1 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 3341 ms
2023-06-21T10:57:22.193Z  INFO 1 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-06-21T10:57:22.227Z  INFO 1 --- [           main] com.example.springboot.Application       : Started Application in 6.986 seconds (process running for 13.994)
2023-06-21T10:57:28.560Z  INFO 1 --- [nio-8080-exec-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring DispatcherServlet 'dispatcherServlet'
2023-06-21T10:57:28.561Z  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Initializing Servlet 'dispatcherServlet'
2023-06-21T10:57:28.562Z  INFO 1 --- [nio-8080-exec-1] o.s.web.servlet.DispatcherServlet        : Completed initialization in 1 ms
2023-06-21T10:57:32.603Z ERROR 1 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Handler dispatch failed: java.lang.NoClassDefFoundError: software/amazon/awssdk/core/interceptor/ExecutionInterceptor] with root
 cause

java.lang.ClassNotFoundException: software.amazon.awssdk.core.interceptor.ExecutionInterceptor
        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]
        at java.base/java.lang.ClassLoader.defineClass1(Native Method) ~[na:na]
        at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1012) ~[na:na]
        at java.base/java.security.SecureClassLoader.defineClass(SecureClassLoader.java:150) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.defineClass(BuiltinClassLoader.java:862) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.findClassOnClassPathOrNull(BuiltinClassLoader.java:760) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClassOrNull(BuiltinClassLoader.java:681) ~[na:na]
        at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:639) ~[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:574) ~[na:na]
        at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:149) ~[spring-boot-0.0.1-SNAPSHOT.jar:0.0.1-SNAPSHOT]
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:520) ~[na:na]
        at software.amazon.awssdk.core.internal.util.ClassLoaderHelper.loadClassViaClasses(ClassLoaderHelper.java:38) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.internal.util.ClassLoaderHelper.loadClass(ClassLoaderHelper.java:105) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.internal.util.ClassLoaderHelper.loadClass(ClassLoaderHelper.java:74) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.createExecutionInterceptor(ClasspathInterceptorChainFactory.java:123) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.createExecutionInterceptorFromResource(ClasspathInterceptorChainFactory.java:95) ~[sdk-core-2.20.56.jar!/:na]
        at java.base/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:273) ~[na:na]
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499) ~[na:na]
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921) ~[na:na]
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[na:na]
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682) ~[na:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.createExecutionInterceptorsFromClasspath(ClasspathInterceptorChainFactory.java:64) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.interceptor.ClasspathInterceptorChainFactory.getGlobalInterceptors(ClasspathInterceptorChainFactory.java:58) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.resolveExecutionInterceptors(SdkDefaultClientBuilder.java:424) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.finalizeConfiguration(SdkDefaultClientBuilder.java:317) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.syncClientConfiguration(SdkDefaultClientBuilder.java:185) ~[sdk-core-2.20.56.jar!/:na]
        at software.amazon.awssdk.services.batch.DefaultBatchClientBuilder.buildClient(DefaultBatchClientBuilder.java:39) ~[batch-2.20.56.jar!/:na]
        at software.amazon.awssdk.services.batch.DefaultBatchClientBuilder.buildClient(DefaultBatchClientBuilder.java:27) ~[batch-2.20.56.jar!/:na]
        at software.amazon.awssdk.core.client.builder.SdkDefaultClientBuilder.build(SdkDefaultClientBuilder.java:150) ~[sdk-core-2.20.56.jar!/:na]
        at com.example.springboot.controllers.HelloController.index(HelloController.java:16) ~[classes!/:0.0.1-SNAPSHOT]
        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.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:207) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:152) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:884) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:797) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1081) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:974) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1011) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:564) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885) ~[spring-webmvc-6.0.9.jar!/:6.0.9]
        at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:205) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ~[tomcat-embed-websocket-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116) ~[spring-web-6.0.9.jar!/:6.0.9]
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:174) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:149) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:166) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:341) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:390) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:894) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1741) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-10.1.8.jar!/:na]
        at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na]
wangzlei commented 1 year ago

Tried to reproduce this issue, it works well in my sample application.

AWSXRayRecorder xrayRecorder = AWSXRayRecorderBuilder.defaultRecorder();
        xrayRecorder.beginSegment("test");
        ListObjectsRequest listObjects = ListObjectsRequest
                .builder()
                .bucket("forevidently")
                .build();

        ListObjectsResponse res = s3Client.listObjects(listObjects);

        xrayRecorder.endSegment();
❯ mvn dependency:tree
[INFO] Scanning for projects...
[INFO]
[INFO] -----------------------< org.example:getstarted >-----------------------
[INFO] Building getstarted 1.0-SNAPSHOT
[INFO] --------------------------------[ jar ]---------------------------------
[INFO]
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ getstarted ---
[WARNING] The artifact xml-apis:xml-apis:jar:2.0.2 has been relocated to xml-apis:xml-apis:jar:1.0.b2
[INFO] org.example:getstarted:jar:1.0-SNAPSHOT
[INFO] +- software.amazon.awssdk:s3:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:aws-xml-protocol:jar:2.20.56:compile
[INFO] |  |  \- software.amazon.awssdk:aws-query-protocol:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:protocol-core:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:arns:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:profiles:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:crt-core:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:sdk-core:jar:2.20.56:compile
[INFO] |  |  \- org.reactivestreams:reactive-streams:jar:1.0.3:compile
[INFO] |  +- software.amazon.awssdk:auth:jar:2.20.56:compile
[INFO] |  |  \- software.amazon.eventstream:eventstream:jar:1.0.1:compile
[INFO] |  +- software.amazon.awssdk:http-client-spi:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:regions:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:annotations:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:utils:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:aws-core:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:metrics-spi:jar:2.20.56:compile
[INFO] |  +- software.amazon.awssdk:json-utils:jar:2.20.56:compile
[INFO] |  |  \- software.amazon.awssdk:third-party-jackson-core:jar:2.20.56:compile
[INFO] |  \- software.amazon.awssdk:endpoints-spi:jar:2.20.56:compile
[INFO] +- software.amazon.awssdk:apache-client:jar:2.20.56:compile
[INFO] |  +- org.apache.httpcomponents:httpclient:jar:4.5.13:compile
[INFO] |  +- org.apache.httpcomponents:httpcore:jar:4.4.13:compile
[INFO] |  \- commons-codec:commons-codec:jar:1.15:compile
[INFO] +- com.amazonaws:aws-xray-recorder-sdk-core:jar:2.14.0:compile
[INFO] |  \- com.amazonaws:aws-java-sdk-xray:jar:1.12.228:compile
[INFO] |     +- com.amazonaws:aws-java-sdk-core:jar:1.12.228:compile
[INFO] |     |  +- commons-logging:commons-logging:jar:1.1.3:compile
[INFO] |     |  +- software.amazon.ion:ion-java:jar:1.0.2:compile
[INFO] |     |  +- com.fasterxml.jackson.core:jackson-databind:jar:2.12.6.1:compile
[INFO] |     |  |  +- com.fasterxml.jackson.core:jackson-annotations:jar:2.12.6:compile
[INFO] |     |  |  \- com.fasterxml.jackson.core:jackson-core:jar:2.12.6:compile
[INFO] |     |  +- com.fasterxml.jackson.dataformat:jackson-dataformat-cbor:jar:2.12.6:compile
[INFO] |     |  \- joda-time:joda-time:jar:2.8.1:compile
[INFO] |     \- com.amazonaws:jmespath-java:jar:1.12.228:compile
[INFO] +- com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2-instrumentor:jar:2.14.0:compile
[INFO] |  \- com.amazonaws:aws-xray-recorder-sdk-aws-sdk-v2:jar:2.14.0:runtime
[INFO] |     \- com.amazonaws:aws-xray-recorder-sdk-aws-sdk-core:jar:2.14.0:runtime

My pom is very simple, use the same version as yours:

    <properties>
        <aws.java.sdk.version>2.20.56</aws.java.sdk.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>${aws.java.sdk.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-xray-recorder-sdk-bom</artifactId>
                <version>2.14.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>s3</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>netty-nio-client</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>software.amazon.awssdk</groupId>
                    <artifactId>apache-client</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>apache-client</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-xray-recorder-sdk-core</artifactId>
        </dependency>

        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
        </dependency>

Screenshot 2023-07-06 at 12 23 33 PM

verbitan commented 1 year ago

Hi @wangzlei - does it still work as a Spring application? It’s specifically Spring I’m having an issue with.

wangzlei commented 1 year ago

XRay SDK works regardless spring or not. The exception trace in your logs is AWS SDK v2

java.lang.ClassNotFoundException: software.amazon.awssdk.core.interceptor.ExecutionInterceptor

I notice you initialize aws client in receiving request. https://github.com/verbitan/xray-issue/blob/manual/src/main/java/com/example/springboot/HelloController.java#L16C28-L16C28

Could you move it to constructor?

verbitan commented 1 year ago

Moving to the constructor just means that the ClassNotFoundException is thrown on startup when Spring tries to create the HellpController bean.

Are you able to build my Spring example and see if you are able to reproduce the same issue? Perhaps Spring is messing with the classpath somehow?

wangzlei commented 1 year ago

I ran the spring boot code, there is no xray sdk problem. Please fix your code bug before. Screenshot 2023-07-07 at 2 16 59 PM diff.zip

verbitan commented 1 year ago

You've had to made quite considerable changes to get XRay working, none of which are at all described in the development guide (https://docs.aws.amazon.com/xray/latest/devguide/xray-java.html).

I don't believe that my original code is incorrect, I've followed the AWS documentation accordingly for auto-instrumentation and it hasn't worked. If the changes you've made are required for XRay in Java, shouldn't the documentation be updated to match? Or are you just providing a workaround for now until the auto-instrumentation can be fixed?

wangzlei commented 1 year ago

Please onboard ADOT java auto-instrumentation

verbitan commented 1 year ago

After speaking to AWS today, it turns out this issue is caused by the use of both the DiSCo agent and the Maven module aws-xray-recorder-sdk-aws-sdk-v2-instrumentor being in use in the one project. They are two separate methods of auto-instrumentation, DiSCo auto-instruments numerous things (e.g. the AWS API, SQL calls, etc.) whereas aws-xray-recorder-sdk-aws-sdk-v2-instrumentor only auto-instruments the AWS API.

I've copied the working project below in case any one else stumbles across this issue in the future. This example is just the basic Spring Initializr project that includes a call to AWS Batch client in the @RestController, along with the corresponding pom.xml and Dockerfile.

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Builder Images
# -----------------------------------------------------------------------------
FROM maven:3.9.2 as spring-app
COPY src /home/app/src
COPY pom.xml /home/app/pom.xml
RUN mvn -f /home/app/pom.xml clean package

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Application Image
# -----------------------------------------------------------------------------
FROM amazoncorretto:17

ENV APP_PATH /app
COPY --from=spring-app /home/app/target/spring-boot-*.jar ${APP_PATH}/libs/

CMD java -jar ${APP_PATH}/libs/spring-boot-*.jar
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.0</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.example</groupId>
    <artifactId>spring-boot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>spring-boot</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <!-- AWS bill of materials -->
            <dependency>
                <groupId>software.amazon.awssdk</groupId>
                <artifactId>bom</artifactId>
                <version>2.20.56</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>com.amazonaws</groupId>
                <artifactId>aws-xray-recorder-sdk-bom</artifactId>
                <version>2.14.0</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <!-- SpringFramework dependencies -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- AWS dependencies -->
        <dependency>
            <groupId>software.amazon.awssdk</groupId>
            <artifactId>batch</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-xray-recorder-sdk-core</artifactId>
        </dependency>
        <dependency>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-xray-recorder-sdk-aws-sdk-v2-instrumentor</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
package com.example.springboot.controllers;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.batch.BatchClient;

@RestController
public class HelloController {

    @GetMapping("/")
    public String index() {
        BatchClient batchClient = BatchClient.builder()
                                             .region(Region.of("eu-west-1"))
                                             .build();

        return "Greetings from Spring Boot!";
    }
}