Using X-Ray throws ClassCastExceptions for Subsegments, documentation unclear
- Dominant language
- Java
- Stars
- 100
- Forks
- 100
- PR merge metrics
- No merged PRs in 30d
Description
The documentation around using X-Ray in Java with Lambda is (IMO) very unclear. I keep getting a `ClassCastException` when trying to do what I think should be a simple task: instrument my code with segments/subsegments.
I've created a very simple [example repo](https://github.com/shearn89/simpleJavaXray) to demonstrate the issue. If you build and invoke locally, you get the same exception as deploying and calling via the CLI:
```
java.lang.ClassCastException: class com.amazonaws.xray.entities.SegmentImpl cannot be cast to class com.amazonaws.xray.entities.Subsegment (com.amazonaws.xray.entities.SegmentImpl and com.amazonaws.xray.entities.Subsegment are in unnamed module of loader lambdainternal.CustomerClassLoader @433c675d)
at com.amazonaws.xray.contexts.LambdaSegmentContext.beginSubsegment(LambdaSegmentContext.java:80)
at com.amazonaws.xray.AWSXRayRecorder.beginSubsegment(AWSXRayRecorder.java:616)
at com.amazonaws.xray.AWSXRay.beginSubsegment(AWSXRay.java:121)
at helloworld.App.doSomething(App.java:31)
at helloworld.App.handleRequest(App.java:25)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.base/java.lang.reflect.Method.invoke(Unknown Source)
```
The lambda is trivial:
```
package helloworld;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.xray.AWSXRay;
import com.amazonaws.xray.AWSXRayRecorderBuilder;
import com.amazonaws.xray.entities.Subsegment;
import com.amazonaws.xray.strategy.sampling.NoSamplingStrategy;
import java.util.Map;
/**
* Handler for requests to Lambda function.
*/
public class App implements RequestHandler, String> {
public App() {
AWSXRayRecorderBuilder builder = AWSXRayRecorderBuilder.standard();
builder.withSamplingStrategy(new NoSamplingStrategy());
AWSXRay.setGlobalRecorder(builder.build());
}
public String handleRequest(Map input, final Context context) {
AWSXRay.beginSegment("simpleJavaXrayTest");
String output = doSomething();
AWSXRay.endSegment();
return output;
}
private String doSomething() {
Subsegment subsegment = AWSXRay.beginSubsegment("doSomething");
try {
thrower();
} catch (Exception e) {
subsegment.addException(e);
}
AWSXRay.endSubsegment();
return "here we are";
}
private void thrower() throws Exception {
throw new Exception("oops");
}
}
```
As per [this page](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java.html), first paragraph (emphasis mine):
> The X-Ray SDK for Java is a set of libraries for Java web applications that provide classes and methods for generating and sending trace data to the X-Ray daemon. Trace data includes information about incoming HTTP requests served by the application, and calls that the application makes to downstream services using the AWS SDK, HTTP clients, or an SQL database connector. **You can also create segments manually and add debug information in annotations and metadata.**
There's also a whole page on [custom subsegments in Java](https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-java-subsegments.html), but I'm still stumped.
I had to come to GitHub to find [this message](https://github.com/aws/aws-xray-sdk-java/issues/245#issuecomment-749063904) which seems to say that I can't use Segments in my Lambda. The actual code I'm working on does a couple of different things with binary data, so I'd like to add segments/subsegments to time and trace the various sections of the code (read/store/process). It's a little frustrating that there doesn't seem to be a simple example of doing this, and lots of the java docs reference Servlets which are irrelevant to my application!
**TL;DR** - the exception thrown is unclear and unhelpful to the uninitiated. It doesn't tell you what you're doing wrong, and the documentation doesn't seem to say I'm doing something incorrect. The [troubleshooting](https://docs.aws.amazon.com/xray/latest/devguide/xray-troubleshooting.html) page has nothing that would tell me what to do next.
Contributor guide
Assessment
This issue has not been assessed yet.