@@ -25,10 +25,15 @@ index a6b89d253d..e62d30eddb 100644
2525       if (!functionInstrumenter().shouldStart(parentContext, otelInput)) {
2626         return;
2727diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts 
28- index df605add2f..b2f01d9d4d  100644
28+ index df605add2f..e16c736990  100644
2929--- a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts 
3030+++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/build.gradle.kts 
31- @@ -9,7 +9,7 @@  dependencies {
31+ @@ -5,11 +5,12 @@  plugins {
32+  dependencies {
33+    compileOnly("io.opentelemetry:opentelemetry-sdk")
34+    compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
35+ +   compileOnly(project(":muzzle"))
36+  
3237   compileOnly("com.google.auto.value:auto-value-annotations")
3338   annotationProcessor("com.google.auto.value:auto-value")
3439
@@ -37,7 +42,7 @@ index df605add2f..b2f01d9d4d 100644
3742
3843   // We do lightweight parsing of JSON to extract HTTP headers from requests for propagation.
3944   // This will be commonly needed even for users that don't use events, but luckily it's not too big.
40- @@ -26,6 +26 ,7 @@  dependencies {
45+ @@ -26,6 +27 ,7 @@  dependencies {
4146
4247   testImplementation(project(":instrumentation:aws-lambda:aws-lambda-core-1.0:testing"))
4348   testImplementation("uk.org.webcompere:system-stubs-jupiter")
@@ -147,10 +152,10 @@ index 9341bf6f79..f719c1ea93 100644
147152 }
148153diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractor.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractor.java 
149154new file mode 100644
150- index 0000000000..e711558e05 
155+ index 0000000000..6349d1bb29 
151156--- /dev/null 
152157+++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/main/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractor.java 
153- @@ -0,0 +1,68  @@ 
158+ @@ -0,0 +1,85  @@ 
154159+ /*
155160+  * Copyright The OpenTelemetry Authors
156161+  * SPDX-License-Identifier: Apache-2.0
@@ -162,19 +167,23 @@ index 0000000000..e711558e05
162167+ 
163168+ import io.opentelemetry.context.Context;
164169+ import io.opentelemetry.context.propagation.TextMapGetter;
170+ + import io.opentelemetry.javaagent.tooling.muzzle.NoMuzzle;
165171+ import java.util.Locale;
166172+ import java.util.Map;
173+ + import java.util.logging.Logger;
167174+ 
168175+ /**
169176+  * This class is internal and is hence not for public use. Its APIs are unstable and can change at
170177+  * any time.
171178+  */
172179+ public final class ParentContextExtractor {
173180+ 
181+ +   private static final Logger logger = Logger.getLogger(ParentContextExtractor.class.getName());
174182+   private static final String AWS_TRACE_HEADER_ENV_KEY = "_X_AMZN_TRACE_ID";
175183+   private static final String AWS_TRACE_HEADER_PROP = "com.amazonaws.xray.traceHeader";
176184+   // lower-case map getter used for extraction
177185+   static final String AWS_TRACE_HEADER_PROPAGATOR_KEY = "x-amzn-trace-id";
186+ +   static boolean getXrayTraceIdMethodExists = true;
178187+ 
179188+   static Context extract(
180189+       Map<String, String> headers,
@@ -188,9 +197,22 @@ index 0000000000..e711558e05
188197+     return instrumenter.extract(mergedHeaders, MapGetter.INSTANCE);
189198+   }
190199+ 
200+ +   @NoMuzzle
191201+   private static String getTraceHeader(
192202+       com.amazonaws.services.lambda.runtime.Context lambdaContext) {
193- +     String traceHeader = lambdaContext.getXrayTraceId();
203+ +     String traceHeader = null;
204+ + 
205+ +     // Lambda Core dependency that is actually used by Lambda Runtime may be on an older version
206+ +     // that does not have the `getXrayTraceId` method. If `NoSuchMethodError` occurs, we do not
207+ +     // attempt invoking `getXrayTraceId` again.
208+ +     if (getXrayTraceIdMethodExists) {
209+ +       try {
210+ +         traceHeader = lambdaContext.getXrayTraceId();
211+ +       } catch (NoSuchMethodError e) {
212+ +         logger.fine("Failed to get X-Ray trace ID from lambdaContext: " + e);
213+ +         getXrayTraceIdMethodExists = false;
214+ +       }
215+ +     }
194216+     if (traceHeader != null && !traceHeader.isEmpty()) {
195217+       return traceHeader;
196218+     }
@@ -234,10 +256,10 @@ index cb19d1e568..12ed174bb2 100644
234256     assertThat(spanContext.getSpanId()).isEqualTo("00f067aa0ba902b7");
235257diff --git a/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractorTest.java b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractorTest.java 
236258new file mode 100644
237- index 0000000000..76fc823a65 
259+ index 0000000000..4b0f354769 
238260--- /dev/null 
239261+++ b/instrumentation/aws-lambda/aws-lambda-core-1.0/library/src/test/java/io/opentelemetry/instrumentation/awslambdacore/v1_0/internal/ParentContextExtractorTest.java 
240- @@ -0,0 +1,337  @@ 
262+ @@ -0,0 +1,375  @@ 
241263+ /*
242264+  * Copyright The OpenTelemetry Authors
243265+  * SPDX-License-Identifier: Apache-2.0
@@ -247,6 +269,8 @@ index 0000000000..76fc823a65
247269+ 
248270+ import static org.assertj.core.api.Assertions.assertThat;
249271+ import static org.mockito.Mockito.mock;
272+ + import static org.mockito.Mockito.times;
273+ + import static org.mockito.Mockito.verify;
250274+ import static org.mockito.Mockito.when;
251275+ 
252276+ import com.amazonaws.services.lambda.runtime.Context;
@@ -574,6 +598,42 @@ index 0000000000..76fc823a65
574598+     assertThat(spanContext.getSpanId()).isEqualTo("0000000000000789");
575599+     assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa7");
576600+   }
601+ + 
602+ +   @Test
603+ +   void shouldFallbackToSystemPropertyWhenNoSuchMethodErrorThrown() {
604+ +     // given
605+ +     Map<String, String> headers = ImmutableMap.of();
606+ +     Context mockLambdaContextWithNoSuchMethodError = mock(Context.class);
607+ +     when(mockLambdaContextWithNoSuchMethodError.getXrayTraceId())
608+ +         .thenThrow(new NoSuchMethodError("getXrayTraceId method not found"));
609+ +     systemProperties.set(
610+ +         "com.amazonaws.xray.traceHeader",
611+ +         "Root=1-8a3c60f7-d188f8fa79d48a391a778fa7;Parent=0000000000000789;Sampled=1");
612+ + 
613+ +     // Reset the static flag to ensure the method is attempted
614+ +     ParentContextExtractor.getXrayTraceIdMethodExists = true;
615+ + 
616+ +     // when - call extract
617+ +     io.opentelemetry.context.Context context =
618+ +         ParentContextExtractor.extract(
619+ +             headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithNoSuchMethodError);
620+ + 
621+ +     // then
622+ +     Span span = Span.fromContext(context);
623+ +     SpanContext spanContext = span.getSpanContext();
624+ +     assertThat(spanContext.isValid()).isTrue();
625+ +     assertThat(spanContext.getSpanId()).isEqualTo("0000000000000789");
626+ +     assertThat(spanContext.getTraceId()).isEqualTo("8a3c60f7d188f8fa79d48a391a778fa7");
627+ +     // Verify getXrayTraceId was called only once
628+ +     assertThat(ParentContextExtractor.getXrayTraceIdMethodExists).isFalse();
629+ +     verify(mockLambdaContextWithNoSuchMethodError, times(1)).getXrayTraceId();
630+ + 
631+ +     // when - call extract again
632+ +     ParentContextExtractor.extract(
633+ +         headers, INSTRUMENTER_WITH_B3_XRAY_PROPAGATORS, mockLambdaContextWithNoSuchMethodError);
634+ +     // Verify the call count of getXrayTraceId is still 1
635+ +     verify(mockLambdaContextWithNoSuchMethodError, times(1)).getXrayTraceId();
636+ +   }
577637+ }
578638diff --git a/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestHandlerInstrumentation.java b/instrumentation/aws-lambda/aws-lambda-events-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awslambdaevents/v2_2/AwsLambdaRequestHandlerInstrumentation.java 
579639index e059250807..1fa80c3735 100644
@@ -614,7 +674,7 @@ index 4cd11fc0c4..7b7d62755c 100644
614674   }
615675
616676diff --git a/version.gradle.kts b/version.gradle.kts 
617- index 7900c9a4d9..80383d7c22  100644
677+ index ec9690086c..b267166804  100644
618678--- a/version.gradle.kts 
619679+++ b/version.gradle.kts 
620680@@ -1,5 +1,5 @@ 
0 commit comments