3

I am implementing AWS X-Ray in my Java Spring project, and generally speaking, it is working correctly. Log requests and I can see the tracking on the AWS console.

However, in a specific case, it is generating an exception when starting the application.

I debugged the code and the problem is in a task scheduling class, which is annotated with @EnableScheduling. If there is any method in that class with the @Scheduled annotation, the application returns the following error:

2020-12-17 22:50:51.427 ERROR 24379 --- [pool-2-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.

com.amazonaws.xray.exceptions.SubsegmentNotFoundException: Failed to end subsegment: subsegment cannot be found.
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ~[na:1.8.0_265]
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62) ~[na:1.8.0_265]
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45) ~[na:1.8.0_265]
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423) ~[na:1.8.0_265]
    at com.amazonaws.xray.strategy.RuntimeErrorContextMissingStrategy.contextMissing(RuntimeErrorContextMissingStrategy.java:32) ~[aws-xray-recorder-sdk-core-2.8.0.jar:na]
    at com.amazonaws.xray.contexts.ThreadLocalSegmentContext.endSubsegment(ThreadLocalSegmentContext.java:93) ~[aws-xray-recorder-sdk-core-2.8.0.jar:na]
    at com.amazonaws.xray.AWSXRayRecorder.endSubsegment(AWSXRayRecorder.java:627) ~[aws-xray-recorder-sdk-core-2.8.0.jar:na]
    at com.amazonaws.xray.AWSXRay.endSubsegment(AWSXRay.java:125) ~[aws-xray-recorder-sdk-core-2.8.0.jar:na]
    at com.amazonaws.xray.spring.aop.BaseAbstractXRayInterceptor.processXRayTrace(BaseAbstractXRayInterceptor.java:58) ~[aws-xray-recorder-sdk-spring-2.8.0.jar:na]
    at com.amazonaws.xray.spring.aop.BaseAbstractXRayInterceptor.traceAroundMethods(BaseAbstractXRayInterceptor.java:43) ~[aws-xray-recorder-sdk-spring-2.8.0.jar:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_265]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_265]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_265]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_265]
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs(AbstractAspectJAdvice.java:627) ~[spring-aop-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at org.springframework.aop.aspectj.AbstractAspectJAdvice.invokeAdviceMethod(AbstractAspectJAdvice.java:616) ~[spring-aop-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at org.springframework.aop.aspectj.AspectJAroundAdvice.invoke(AspectJAroundAdvice.java:70) ~[spring-aop-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:168) ~[spring-aop-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:671) ~[spring-aop-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at com.domain.common.ToolBox$$EnhancerBySpringCGLIB$$a2712230.convertStackTraceToString(<generated>) ~[classes/:na]
    at com.domain.event.ScheduledEventHandler.runsEvery1Minute(ScheduledEventHandler.java:111) ~[classes/:na]
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_265]
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_265]
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_265]
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_265]
    at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java:65) ~[spring-context-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) ~[spring-context-4.3.19.RELEASE.jar:4.3.19.RELEASE]
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_265]
    at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308) [na:1.8.0_265]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180) [na:1.8.0_265]
    at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294) [na:1.8.0_265]
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_265]
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_265]
    at java.lang.Thread.run(Thread.java:748) [na:1.8.0_265]

I tried to use custom subsegments, as: Generating custom subsegments with the X-Ray SDK for Java and nothing.

The code would look something like this:

@XRayEnabled
@Component
@EnableScheduling
public class ScheduledEventHandler {

    ...
        
    @Scheduled(fixedDelay = 1*60*1000)
    protected void runsEvery1Minute() {
       ...
    }

    ...
}

It seems to me that the @XRayEnabled annotation has some incompatibility with the @Scheduled annotation or there is a specific configuration for this case.

Can anyone help me with this?

Thanks!

Diogo
  • 43
  • 1
  • 4

1 Answers1

0

I have faced with the same issue. You can move scheduled method to the different class which is not annotated with @XRayEnabled. Then you can just add

AWSXRay.beginSegment("youSegmentName");
...
call class annotated with @XRayEnabled
...
AWSXRay.endSegment();
regular
  • 31
  • 4