From dff511424534e7e94d3628a531da3def425ca217 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:43:33 +0200 Subject: [PATCH 01/10] make instrumentation modules indy ready --- .../OpenTelemetryApiInstrumentationModule.java | 5 +++++ .../opentelemetryapi/TestInstrumentationModule.java | 5 +++++ .../v1_10/OpenTelemetryApiInstrumentationModule.java | 5 +++++ .../incubator/OpenTelemetryApiInstrumentationModule.java | 5 +++++ .../v1_32/OpenTelemetryApiInstrumentationModule.java | 5 +++++ .../OpenTelemetryApiIncubatorInstrumentationModule.java | 5 +++++ .../v1_38/OpenTelemetryApiInstrumentationModule.java | 5 +++++ .../OpenTelemetryApiIncubatorInstrumentationModule.java | 5 +++++ .../OpenTelemetryApiIncubatorInstrumentationModule.java | 5 +++++ .../OpenTelemetryApiIncubatorInstrumentationModule.java | 5 +++++ 10 files changed, 50 insertions(+) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryApiInstrumentationModule.java index f0fb67e48f56..d07f92724571 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryApiInstrumentationModule.java @@ -43,4 +43,9 @@ public List agentPackagesToHide() { // when they haven't been injected return Collections.singletonList("io.opentelemetry.javaagent.instrumentation.opentelemetryapi"); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentationModule.java index c3a158a059b6..8d645c5e039d 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentationModule.java @@ -29,4 +29,9 @@ public String getModuleGroup() { public List typeInstrumentations() { return singletonList(new TestInstrumentation()); } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/OpenTelemetryApiInstrumentationModule.java index 256f5527abb9..00338f637562 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.10/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_10/OpenTelemetryApiInstrumentationModule.java @@ -37,4 +37,9 @@ public ElementMatcher.Junction classLoaderMatcher() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/incubator/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/incubator/OpenTelemetryApiInstrumentationModule.java index 273bb3b755f2..9dbe8d2fbddf 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/incubator/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.31/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_31/incubator/OpenTelemetryApiInstrumentationModule.java @@ -37,4 +37,9 @@ public ElementMatcher.Junction classLoaderMatcher() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java index 92bd112db90c..fefa28aa76cb 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/OpenTelemetryApiInstrumentationModule.java @@ -43,4 +43,9 @@ public List typeInstrumentations() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java index f4e67fc35fe5..c62ac006af59 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.32/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_32/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java @@ -39,4 +39,9 @@ public List typeInstrumentations() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/OpenTelemetryApiInstrumentationModule.java index 7385e5677dfe..93e45ca132ff 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/OpenTelemetryApiInstrumentationModule.java @@ -43,4 +43,9 @@ public List typeInstrumentations() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java index 752ac424f66d..3b07855edf64 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.38/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_38/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java @@ -40,4 +40,9 @@ public List typeInstrumentations() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.40/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_40/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.40/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_40/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java index 92b8cf886c7d..93fca86e9b21 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.40/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_40/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.40/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_40/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java @@ -40,4 +40,9 @@ public List typeInstrumentations() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.47/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_47/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.47/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_47/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java index da3fdc2de6ac..d00b92691861 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.47/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_47/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.47/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_47/incubator/OpenTelemetryApiIncubatorInstrumentationModule.java @@ -43,4 +43,9 @@ public List typeInstrumentations() { public String getModuleGroup() { return "opentelemetry-api-bridge"; } + + @Override + public boolean isIndyReady() { + return true; + } } From 3b47a854e55cdc301e78e23dfaad2823412ebded Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 17 Sep 2025 10:50:24 +0200 Subject: [PATCH 02/10] make opentelemetry-api indy-ready --- .../opentelemetryapi/ContextInstrumentation.java | 6 ++++-- .../ContextStorageWrappersInstrumentation.java | 10 +++++++--- .../InstrumentationUtilInstrumentation.java | 10 +++++----- .../OpenTelemetryInstrumentation.java | 8 ++++---- .../opentelemetryapi/SpanInstrumentation.java | 11 +++++------ .../opentelemetryapi/TestInstrumentation.java | 10 +++++----- 6 files changed, 30 insertions(+), 25 deletions(-) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextInstrumentation.java index c4beb21b9df8..912af97f9439 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextInstrumentation.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextInstrumentation.java @@ -15,6 +15,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -41,9 +42,10 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class WrapRootAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void methodExit(@Advice.Return(readOnly = false) Context root) { - root = AgentContextStorage.wrapRootContext(root); + public static Context methodExit(@Advice.Return Context root) { + return AgentContextStorage.wrapRootContext(root); } } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java index 9f958249a392..66ab53906c4d 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java @@ -15,6 +15,7 @@ import java.util.List; import java.util.function.Function; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -41,13 +42,16 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class AddWrapperAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void methodExit( - @Advice.Return(readOnly = false) - List> wrappers) { + public static List> methodExit( + @Advice.Return + List> originalWrappers) { + List> wrappers = originalWrappers; wrappers = new ArrayList<>(wrappers); // AgentContextStorage wrapper doesn't delegate, so needs to be the innermost wrapper wrappers.add(0, AgentContextStorage.wrap()); + return wrappers; } } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/InstrumentationUtilInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/InstrumentationUtilInstrumentation.java index 8d76b334e5dd..b0e69ec38fe5 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/InstrumentationUtilInstrumentation.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/InstrumentationUtilInstrumentation.java @@ -15,6 +15,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -44,12 +45,11 @@ public static boolean methodEnter() { return true; } + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void methodExit( - @Advice.Argument(0) Context context, @Advice.Return(readOnly = false) boolean result) { - result = - InstrumentationUtil.shouldSuppressInstrumentation( - AgentContextStorage.getAgentContext(context)); + public static boolean methodExit(@Advice.Argument(0) Context context) { + return InstrumentationUtil.shouldSuppressInstrumentation( + AgentContextStorage.getAgentContext(context)); } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryInstrumentation.java index b4b5ef760d54..467e10a270dd 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryInstrumentation.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/OpenTelemetryInstrumentation.java @@ -17,6 +17,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import java.util.logging.Logger; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -58,11 +59,10 @@ public static Object onEnter() { return null; } + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void methodExit( - @Advice.Return(readOnly = false) - application.io.opentelemetry.api.OpenTelemetry openTelemetry) { - openTelemetry = ApplicationOpenTelemetry.INSTANCE; + public static application.io.opentelemetry.api.OpenTelemetry methodExit() { + return ApplicationOpenTelemetry.INSTANCE; } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/SpanInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/SpanInstrumentation.java index 90de611f1262..9e4dd11645b7 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/SpanInstrumentation.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/SpanInstrumentation.java @@ -15,6 +15,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -40,13 +41,11 @@ public static boolean methodEnter() { return false; } + @AssignReturned.ToReturned @Advice.OnMethodExit - public static void methodExit( - @Advice.Argument(0) SpanContext applicationSpanContext, - @Advice.Return(readOnly = false) Span applicationSpan) { - applicationSpan = - Bridging.toApplication( - io.opentelemetry.api.trace.Span.wrap(Bridging.toAgent(applicationSpanContext))); + public static Span methodExit(@Advice.Argument(0) SpanContext applicationSpanContext) { + return Bridging.toApplication( + io.opentelemetry.api.trace.Span.wrap(Bridging.toAgent(applicationSpanContext))); } } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentation.java index 46d5ec170e2d..2db0412045f0 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentation.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/TestInstrumentation.java @@ -13,6 +13,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -31,12 +32,11 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class TestAdvice { + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void onExit( - @Advice.Argument(0) Context context, @Advice.Return(readOnly = false) boolean result) { - result = - InstrumentationUtil.shouldSuppressInstrumentation( - AgentContextStorage.getAgentContext(context)); + public static boolean onExit(@Advice.Argument(0) Context context) { + return InstrumentationUtil.shouldSuppressInstrumentation( + AgentContextStorage.getAgentContext(context)); } } } From b61acff698559e0062270754cd55e112be656255 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 17 Sep 2025 12:05:36 +0200 Subject: [PATCH 03/10] other opentelemetry components --- .../WithSpanInstrumentation.java | 155 +++++++++++------- .../ContextExtensionInstrumentation.java | 27 ++- .../WithSpanInstrumentation.java | 148 ++++++++++------- .../SpanKeyInstrumentation.java | 16 +- .../AgentSpanTestingInstrumentation.java | 53 +++--- 5 files changed, 245 insertions(+), 154 deletions(-) diff --git a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java index 0891e1f9e297..b339f881765c 100644 --- a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java @@ -21,7 +21,6 @@ import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; @@ -29,7 +28,9 @@ import java.lang.reflect.Method; import java.util.Map; import java.util.Set; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.ByteCodeElement; import net.bytebuddy.description.annotation.AnnotationSource; import net.bytebuddy.description.method.MethodDescription; @@ -119,89 +120,117 @@ static ElementMatcher.Junction configureExcludedMethods() { @SuppressWarnings("unused") public static class WithSpanAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Origin Method originMethod, - @Advice.Local("otelMethod") Method method, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it - // to local variable so that there would be only one call to Class.getMethod. - method = originMethod; + public static class AdviceScope { + private final Method method; + private final Context context; + private final Scope scope; + + private AdviceScope(Method method, Context context, Scope scope) { + this.method = method; + this.context = context; + this.scope = scope; + } - Instrumenter instrumenter = WithSpanSingletons.instrumenter(); - Context current = Java8BytecodeBridge.currentContext(); + @Nullable + public static AdviceScope start(Method method) { + Instrumenter instrumenter = WithSpanSingletons.instrumenter(); + Context current = Context.current(); + if (!instrumenter.shouldStart(current, method)) { + return null; + } + Context context = instrumenter.start(current, method); + return new AdviceScope(method, context, context.makeCurrent()); + } - if (instrumenter.shouldStart(current, method)) { - context = instrumenter.start(current, method); - scope = context.makeCurrent(); + public Object end(Object returnValue, @Nullable Throwable throwable) { + scope.close(); + AsyncOperationEndSupport operationEndSupport = + AsyncOperationEndSupport.create( + WithSpanSingletons.instrumenter(), Object.class, method.getReturnType()); + return operationEndSupport.asyncEnd(context, method, returnValue, throwable); } } + @Nullable + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope onEnter(@Advice.Origin Method originMethod) { + // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it + // to local variable so that there would be only one call to Class.getMethod. + return AdviceScope.start(originMethod); + } + + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void stopSpan( - @Advice.Local("otelMethod") Method method, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, - @Advice.Thrown Throwable throwable) { - if (scope == null) { - return; + public static Object stopSpan( + @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Enter @Nullable AdviceScope adviceScope) { + if (adviceScope != null) { + return adviceScope.end(returnValue, throwable); } - scope.close(); - - AsyncOperationEndSupport operationEndSupport = - AsyncOperationEndSupport.create( - WithSpanSingletons.instrumenter(), Object.class, method.getReturnType()); - returnValue = operationEndSupport.asyncEnd(context, method, returnValue, throwable); + return returnValue; } } @SuppressWarnings("unused") public static class WithSpanAttributesAdvice { + public static class AdviceScope { + private final Method method; + private final MethodRequest request; + private final Context context; + private final Scope scope; + + private AdviceScope(Method method, MethodRequest request, Context context, Scope scope) { + this.method = method; + this.request = request; + this.context = context; + this.scope = scope; + } + + @Nullable + public static AdviceScope start(Method method, MethodRequest request) { + Instrumenter instrumenter = + WithSpanSingletons.instrumenterWithAttributes(); + Context current = Context.current(); + if (!instrumenter.shouldStart(current, request)) { + return null; + } + Context context = instrumenter.start(current, request); + return new AdviceScope(method, request, context, context.makeCurrent()); + } + + public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { + scope.close(); + AsyncOperationEndSupport operationEndSupport = + AsyncOperationEndSupport.create( + WithSpanSingletons.instrumenterWithAttributes(), + Object.class, + method.getReturnType()); + return operationEndSupport.asyncEnd(context, request, returnValue, throwable); + } + } + @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( + public static AdviceScope onEnter( @Advice.Origin Method originMethod, - @Advice.Local("otelMethod") Method method, - @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, - @Advice.Local("otelRequest") MethodRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - + @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to local variable so that there would be only one call to Class.getMethod. - method = originMethod; - - Instrumenter instrumenter = - WithSpanSingletons.instrumenterWithAttributes(); - Context current = Java8BytecodeBridge.currentContext(); - request = new MethodRequest(method, args); - - if (instrumenter.shouldStart(current, request)) { - context = instrumenter.start(current, request); - scope = context.makeCurrent(); - } + MethodRequest request = new MethodRequest(originMethod, args); + return AdviceScope.start(originMethod, request); } + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void stopSpan( - @Advice.Local("otelMethod") Method method, - @Advice.Local("otelRequest") MethodRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, - @Advice.Thrown Throwable throwable) { - if (scope == null) { - return; + public static Object stopSpan( + @Advice.Return @Nullable Object returnValue, + @Advice.Thrown Throwable throwable, + @Advice.Enter AdviceScope adviceScope) { + if (adviceScope != null) { + return adviceScope.end(returnValue, throwable); } - scope.close(); - AsyncOperationEndSupport operationEndSupport = - AsyncOperationEndSupport.create( - WithSpanSingletons.instrumenterWithAttributes(), - Object.class, - method.getReturnType()); - returnValue = operationEndSupport.asyncEnd(context, request, returnValue, throwable); + return returnValue; } } } diff --git a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java index 71b10907ce73..99d3820a82e7 100644 --- a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java +++ b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java @@ -15,6 +15,7 @@ import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage; import kotlin.coroutines.CoroutineContext; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -50,6 +51,7 @@ public static class ContextAdvice { @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static CoroutineContext enter(@Advice.Argument(0) Context applicationContext) { + if (applicationContext != null) { io.opentelemetry.context.Context agentContext = AgentContextStorage.getAgentContext(applicationContext); @@ -58,13 +60,16 @@ public static CoroutineContext enter(@Advice.Argument(0) Context applicationCont return null; } + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class) - public static void onExit( - @Advice.Return(readOnly = false) CoroutineContext result, + public static CoroutineContext onExit( + @Advice.Return CoroutineContext originalResult, @Advice.Enter CoroutineContext coroutineContext) { + CoroutineContext result = originalResult; if (coroutineContext != null) { result = coroutineContext; } + return result; } } @@ -75,22 +80,28 @@ public static class ImplicitContextKeyedAdvice { public static CoroutineContext enter( @Advice.Argument(0) application.io.opentelemetry.context.ImplicitContextKeyed implicitContextKeyed) { + if (implicitContextKeyed != null) { Context applicationContext = Context.current().with(implicitContextKeyed); io.opentelemetry.context.Context agentContext = AgentContextStorage.getAgentContext(applicationContext); + return ContextExtensionsKt.asContextElement(agentContext); } + return null; } + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class) - public static void onExit( - @Advice.Return(readOnly = false) CoroutineContext result, + public static CoroutineContext onExit( + @Advice.Return CoroutineContext originalResult, @Advice.Enter CoroutineContext coroutineContext) { + CoroutineContext result = originalResult; if (coroutineContext != null) { result = coroutineContext; } + return result; } } @@ -99,6 +110,7 @@ public static class GetOpenTelemetryContextAdvice { @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static Context enter(@Advice.Argument(0) CoroutineContext coroutineContext) { + if (coroutineContext != null) { io.opentelemetry.context.Context agentContext = ContextExtensionsKt.getOpenTelemetryContext(coroutineContext); @@ -107,12 +119,15 @@ public static Context enter(@Advice.Argument(0) CoroutineContext coroutineContex return null; } + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class) - public static void onExit( - @Advice.Return(readOnly = false) Context result, @Advice.Enter Context context) { + public static Context onExit( + @Advice.Return Context originalResult, @Advice.Enter Context context) { + Context result = originalResult; if (context != null) { result = context; } + return result; } } } diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java index 975b4d866132..6e5050a2a951 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java @@ -23,7 +23,9 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import java.lang.reflect.Method; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.annotation.AnnotationSource; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.description.type.TypeDescription; @@ -80,85 +82,115 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class WithSpanAdvice { - @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Origin Method originMethod, - @Advice.Local("otelMethod") Method method, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it - // to local variable so that there would be only one call to Class.getMethod. - method = originMethod; + public static class AdviceScope { + private final Method method; + private final Context context; + private final Scope scope; - Instrumenter instrumenter = instrumenter(); - Context current = AnnotationSingletons.getContextForMethod(method); + public AdviceScope(Method method, Context context, Scope scope) { + this.method = method; + this.context = context; + this.scope = scope; + } + + @Nullable + public static AdviceScope start(Method method) { + Instrumenter instrumenter = instrumenter(); + Context current = AnnotationSingletons.getContextForMethod(method); + if (!instrumenter.shouldStart(current, method)) { + return null; + } + Context context = instrumenter.start(current, method); + return new AdviceScope(method, context, context.makeCurrent()); + } - if (instrumenter.shouldStart(current, method)) { - context = instrumenter.start(current, method); - scope = context.makeCurrent(); + public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { + scope.close(); + AsyncOperationEndSupport operationEndSupport = + AsyncOperationEndSupport.create(instrumenter(), Object.class, method.getReturnType()); + return operationEndSupport.asyncEnd(context, method, returnValue, throwable); } } + @Nullable + @Advice.OnMethodEnter(suppress = Throwable.class) + public static AdviceScope onEnter(@Advice.Origin Method originMethod) { + // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it + // to advice scope so that there would be only one call to Class.getMethod. + return AdviceScope.start(originMethod); + } + + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void stopSpan( - @Advice.Local("otelMethod") Method method, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, - @Advice.Thrown Throwable throwable) { - if (scope == null) { - return; + public static Object stopSpan( + @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, + @Advice.Thrown @Nullable Throwable throwable, + @Advice.Enter @Nullable AdviceScope adviceScope) { + if (adviceScope != null) { + return adviceScope.end(returnValue, throwable); } - scope.close(); - - AsyncOperationEndSupport operationEndSupport = - AsyncOperationEndSupport.create(instrumenter(), Object.class, method.getReturnType()); - returnValue = operationEndSupport.asyncEnd(context, method, returnValue, throwable); + return returnValue; } } @SuppressWarnings("unused") public static class WithSpanAttributesAdvice { + public static class AdviceScope { + private final Method method; + private final MethodRequest request; + private final Context context; + private final Scope scope; + + public AdviceScope(Method method, MethodRequest request, Context context, Scope scope) { + this.method = method; + this.request = request; + this.context = context; + this.scope = scope; + } + + @Nullable + public static AdviceScope start(Method method, Object[] args) { + Instrumenter instrumenter = instrumenterWithAttributes(); + Context current = AnnotationSingletons.getContextForMethod(method); + MethodRequest request = new MethodRequest(method, args); + if (!instrumenter.shouldStart(current, request)) { + return null; + } + Context context = instrumenter.start(current, request); + return new AdviceScope(method, request, context, context.makeCurrent()); + } + + public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { + scope.close(); + AsyncOperationEndSupport operationEndSupport = + AsyncOperationEndSupport.create( + instrumenterWithAttributes(), Object.class, method.getReturnType()); + return operationEndSupport.asyncEnd(context, request, returnValue, throwable); + } + } + + @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( + public static AdviceScope onEnter( @Advice.Origin Method originMethod, - @Advice.Local("otelMethod") Method method, - @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args, - @Advice.Local("otelRequest") MethodRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { + @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it - // to local variable so that there would be only one call to Class.getMethod. - method = originMethod; - - Instrumenter instrumenter = instrumenterWithAttributes(); - Context current = AnnotationSingletons.getContextForMethod(method); - request = new MethodRequest(method, args); - - if (instrumenter.shouldStart(current, request)) { - context = instrumenter.start(current, request); - scope = context.makeCurrent(); - } + // to advice scope so that there would be only one call to Class.getMethod. + return AdviceScope.start(originMethod, args); } + @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) - public static void stopSpan( - @Advice.Local("otelMethod") Method method, - @Advice.Local("otelRequest") MethodRequest request, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope, - @Advice.Return(typing = Assigner.Typing.DYNAMIC, readOnly = false) Object returnValue, - @Advice.Thrown Throwable throwable) { - if (scope == null) { - return; + public static Object stopSpan( + @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, + @Advice.Thrown Throwable throwable, + @Advice.Enter AdviceScope adviceScope) { + if (adviceScope != null) { + return adviceScope.end(returnValue, throwable); } - scope.close(); - AsyncOperationEndSupport operationEndSupport = - AsyncOperationEndSupport.create( - instrumenterWithAttributes(), Object.class, method.getReturnType()); - returnValue = operationEndSupport.asyncEnd(context, request, returnValue, throwable); + return returnValue; } } } diff --git a/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java b/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java index b8cc4ea99f40..fe691ad9f239 100644 --- a/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java @@ -16,6 +16,7 @@ import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging; import net.bytebuddy.asm.Advice; +import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -70,14 +71,16 @@ public static Context onEnter( return AgentContextStorage.toApplicationContext(newAgentContext); } + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void onExit( - @Advice.Enter Context newApplicationContext, - @Advice.Return(readOnly = false) Context result) { + public static Context onExit( + @Advice.Return Context originalResult, @Advice.Enter Context newApplicationContext) { + Context result = originalResult; if (newApplicationContext != null) { result = newApplicationContext; } + return result; } } @@ -106,13 +109,16 @@ public static Span onEnter( return Bridging.toApplication(agentSpan); } + @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) - public static void onExit( - @Advice.Enter Span applicationSpan, @Advice.Return(readOnly = false) Span result) { + public static Span onExit( + @Advice.Return Span originalResult, @Advice.Enter Span applicationSpan) { + Span result = originalResult; if (applicationSpan != null) { result = applicationSpan; } + return result; } } } diff --git a/instrumentation/opentelemetry-instrumentation-api/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/testing/AgentSpanTestingInstrumentation.java b/instrumentation/opentelemetry-instrumentation-api/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/testing/AgentSpanTestingInstrumentation.java index ffd71eb9e7a7..91c556272096 100644 --- a/instrumentation/opentelemetry-instrumentation-api/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/testing/AgentSpanTestingInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-api/testing/src/main/java/io/opentelemetry/javaagent/instrumentation/testing/AgentSpanTestingInstrumentation.java @@ -11,6 +11,7 @@ import io.opentelemetry.context.Scope; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; @@ -30,25 +31,38 @@ public void transform(TypeTransformer transformer) { named("runWithAllSpanKeys"), this.getClass().getName() + "$RunWithAllSpanKeysAdvice"); } + public static class AdviceScope { + private final Context context; + private final Scope scope; + + public AdviceScope(Context context, Scope scope) { + this.context = context; + this.scope = scope; + } + + public Context getContext() { + return context; + } + + public void end() { + scope.close(); + } + } + @SuppressWarnings("unused") public static class RunWithHttpServerSpanAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Argument(0) String spanName, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - context = AgentSpanTestingInstrumenter.startHttpServerSpan(spanName); - scope = context.makeCurrent(); + public static AdviceScope onEnter(@Advice.Argument(0) String spanName) { + Context context = AgentSpanTestingInstrumenter.startHttpServerSpan(spanName); + return new AdviceScope(context, context.makeCurrent()); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - scope.close(); - AgentSpanTestingInstrumenter.endHttpServer(context, throwable); + @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter AdviceScope adviceScope) { + adviceScope.end(); + AgentSpanTestingInstrumenter.endHttpServer(adviceScope.getContext(), throwable); } } @@ -56,21 +70,16 @@ public static void onExit( public static class RunWithAllSpanKeysAdvice { @Advice.OnMethodEnter(suppress = Throwable.class) - public static void onEnter( - @Advice.Argument(0) String spanName, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - context = AgentSpanTestingInstrumenter.startSpanWithAllKeys(spanName); - scope = context.makeCurrent(); + public static AdviceScope onEnter(@Advice.Argument(0) String spanName) { + Context context = AgentSpanTestingInstrumenter.startSpanWithAllKeys(spanName); + return new AdviceScope(context, context.makeCurrent()); } @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static void onExit( - @Advice.Thrown Throwable throwable, - @Advice.Local("otelContext") Context context, - @Advice.Local("otelScope") Scope scope) { - scope.close(); - AgentSpanTestingInstrumenter.end(context, throwable); + @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter AdviceScope adviceScope) { + adviceScope.end(); + AgentSpanTestingInstrumenter.end(adviceScope.getContext(), throwable); } } } From 0f57d390d09e62f8a7b380891f2d1bbeb2118384 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 17 Sep 2025 21:21:54 +0200 Subject: [PATCH 04/10] rename things to make linter happy --- .../WithSpanInstrumentation.java | 28 +++++++++--------- .../WithSpanInstrumentation.java | 29 ++++++++++--------- 2 files changed, 29 insertions(+), 28 deletions(-) diff --git a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java index b339f881765c..ec8732ec06b8 100644 --- a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java @@ -120,26 +120,26 @@ static ElementMatcher.Junction configureExcludedMethods() { @SuppressWarnings("unused") public static class WithSpanAdvice { - public static class AdviceScope { + public static class WithSpanAdviceScope { private final Method method; private final Context context; private final Scope scope; - private AdviceScope(Method method, Context context, Scope scope) { + private WithSpanAdviceScope(Method method, Context context, Scope scope) { this.method = method; this.context = context; this.scope = scope; } @Nullable - public static AdviceScope start(Method method) { + public static WithSpanAdviceScope start(Method method) { Instrumenter instrumenter = WithSpanSingletons.instrumenter(); Context current = Context.current(); if (!instrumenter.shouldStart(current, method)) { return null; } Context context = instrumenter.start(current, method); - return new AdviceScope(method, context, context.makeCurrent()); + return new WithSpanAdviceScope(method, context, context.makeCurrent()); } public Object end(Object returnValue, @Nullable Throwable throwable) { @@ -153,10 +153,10 @@ public Object end(Object returnValue, @Nullable Throwable throwable) { @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static AdviceScope onEnter(@Advice.Origin Method originMethod) { + public static WithSpanAdviceScope onEnter(@Advice.Origin Method originMethod) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to local variable so that there would be only one call to Class.getMethod. - return AdviceScope.start(originMethod); + return WithSpanAdviceScope.start(originMethod); } @AssignReturned.ToReturned @@ -164,7 +164,7 @@ public static AdviceScope onEnter(@Advice.Origin Method originMethod) { public static Object stopSpan( @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, @Advice.Thrown @Nullable Throwable throwable, - @Advice.Enter @Nullable AdviceScope adviceScope) { + @Advice.Enter @Nullable WithSpanAdviceScope adviceScope) { if (adviceScope != null) { return adviceScope.end(returnValue, throwable); } @@ -175,13 +175,13 @@ public static Object stopSpan( @SuppressWarnings("unused") public static class WithSpanAttributesAdvice { - public static class AdviceScope { + public static class WithSpanAttributesAdviceScope { private final Method method; private final MethodRequest request; private final Context context; private final Scope scope; - private AdviceScope(Method method, MethodRequest request, Context context, Scope scope) { + private WithSpanAttributesAdviceScope(Method method, MethodRequest request, Context context, Scope scope) { this.method = method; this.request = request; this.context = context; @@ -189,7 +189,7 @@ private AdviceScope(Method method, MethodRequest request, Context context, Scope } @Nullable - public static AdviceScope start(Method method, MethodRequest request) { + public static WithSpanAttributesAdviceScope start(Method method, MethodRequest request) { Instrumenter instrumenter = WithSpanSingletons.instrumenterWithAttributes(); Context current = Context.current(); @@ -197,7 +197,7 @@ public static AdviceScope start(Method method, MethodRequest request) { return null; } Context context = instrumenter.start(current, request); - return new AdviceScope(method, request, context, context.makeCurrent()); + return new WithSpanAttributesAdviceScope(method, request, context, context.makeCurrent()); } public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { @@ -212,13 +212,13 @@ public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { } @Advice.OnMethodEnter(suppress = Throwable.class) - public static AdviceScope onEnter( + public static WithSpanAttributesAdviceScope onEnter( @Advice.Origin Method originMethod, @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to local variable so that there would be only one call to Class.getMethod. MethodRequest request = new MethodRequest(originMethod, args); - return AdviceScope.start(originMethod, request); + return WithSpanAttributesAdviceScope.start(originMethod, request); } @AssignReturned.ToReturned @@ -226,7 +226,7 @@ public static AdviceScope onEnter( public static Object stopSpan( @Advice.Return @Nullable Object returnValue, @Advice.Thrown Throwable throwable, - @Advice.Enter AdviceScope adviceScope) { + @Advice.Enter WithSpanAttributesAdviceScope adviceScope) { if (adviceScope != null) { return adviceScope.end(returnValue, throwable); } diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java index 6e5050a2a951..39403a1b59a0 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java @@ -82,26 +82,26 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class WithSpanAdvice { - public static class AdviceScope { + public static class WithSpanAdviceScope { private final Method method; private final Context context; private final Scope scope; - public AdviceScope(Method method, Context context, Scope scope) { + public WithSpanAdviceScope(Method method, Context context, Scope scope) { this.method = method; this.context = context; this.scope = scope; } @Nullable - public static AdviceScope start(Method method) { + public static WithSpanAdviceScope start(Method method) { Instrumenter instrumenter = instrumenter(); Context current = AnnotationSingletons.getContextForMethod(method); if (!instrumenter.shouldStart(current, method)) { return null; } Context context = instrumenter.start(current, method); - return new AdviceScope(method, context, context.makeCurrent()); + return new WithSpanAdviceScope(method, context, context.makeCurrent()); } public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { @@ -114,10 +114,10 @@ public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static AdviceScope onEnter(@Advice.Origin Method originMethod) { + public static WithSpanAdviceScope onEnter(@Advice.Origin Method originMethod) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to advice scope so that there would be only one call to Class.getMethod. - return AdviceScope.start(originMethod); + return WithSpanAdviceScope.start(originMethod); } @AssignReturned.ToReturned @@ -125,7 +125,7 @@ public static AdviceScope onEnter(@Advice.Origin Method originMethod) { public static Object stopSpan( @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, @Advice.Thrown @Nullable Throwable throwable, - @Advice.Enter @Nullable AdviceScope adviceScope) { + @Advice.Enter @Nullable WithSpanAdviceScope adviceScope) { if (adviceScope != null) { return adviceScope.end(returnValue, throwable); } @@ -136,13 +136,14 @@ public static Object stopSpan( @SuppressWarnings("unused") public static class WithSpanAttributesAdvice { - public static class AdviceScope { + public static class WithSpanAttributesAdviceScope { private final Method method; private final MethodRequest request; private final Context context; private final Scope scope; - public AdviceScope(Method method, MethodRequest request, Context context, Scope scope) { + public WithSpanAttributesAdviceScope( + Method method, MethodRequest request, Context context, Scope scope) { this.method = method; this.request = request; this.context = context; @@ -150,7 +151,7 @@ public AdviceScope(Method method, MethodRequest request, Context context, Scope } @Nullable - public static AdviceScope start(Method method, Object[] args) { + public static WithSpanAttributesAdviceScope start(Method method, Object[] args) { Instrumenter instrumenter = instrumenterWithAttributes(); Context current = AnnotationSingletons.getContextForMethod(method); MethodRequest request = new MethodRequest(method, args); @@ -158,7 +159,7 @@ public static AdviceScope start(Method method, Object[] args) { return null; } Context context = instrumenter.start(current, request); - return new AdviceScope(method, request, context, context.makeCurrent()); + return new WithSpanAttributesAdviceScope(method, request, context, context.makeCurrent()); } public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { @@ -172,13 +173,13 @@ public Object end(@Nullable Object returnValue, @Nullable Throwable throwable) { @Nullable @Advice.OnMethodEnter(suppress = Throwable.class) - public static AdviceScope onEnter( + public static WithSpanAttributesAdviceScope onEnter( @Advice.Origin Method originMethod, @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to advice scope so that there would be only one call to Class.getMethod. - return AdviceScope.start(originMethod, args); + return WithSpanAttributesAdviceScope.start(originMethod, args); } @AssignReturned.ToReturned @@ -186,7 +187,7 @@ public static AdviceScope onEnter( public static Object stopSpan( @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, @Advice.Thrown Throwable throwable, - @Advice.Enter AdviceScope adviceScope) { + @Advice.Enter WithSpanAttributesAdviceScope adviceScope) { if (adviceScope != null) { return adviceScope.end(returnValue, throwable); } From 19a3cbafa5f06732edf249e5ab125281d53fdd08 Mon Sep 17 00:00:00 2001 From: otelbot <197425009+otelbot@users.noreply.github.com> Date: Wed, 17 Sep 2025 19:34:11 +0000 Subject: [PATCH 05/10] ./gradlew spotlessApply --- .../extensionannotations/WithSpanInstrumentation.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java index ec8732ec06b8..7a3779fb5fe1 100644 --- a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java @@ -181,7 +181,8 @@ public static class WithSpanAttributesAdviceScope { private final Context context; private final Scope scope; - private WithSpanAttributesAdviceScope(Method method, MethodRequest request, Context context, Scope scope) { + private WithSpanAttributesAdviceScope( + Method method, MethodRequest request, Context context, Scope scope) { this.method = method; this.request = request; this.context = context; From 1e57881bac5d657854750778f0a0a56efffb9663 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 18 Sep 2025 09:56:59 +0200 Subject: [PATCH 06/10] minor cleanup --- .../extensionannotations/WithSpanInstrumentation.java | 3 ++- .../extensionkotlin/ContextExtensionInstrumentation.java | 5 ----- .../instrumentationannotations/WithSpanInstrumentation.java | 2 +- 3 files changed, 3 insertions(+), 7 deletions(-) diff --git a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java index ec8732ec06b8..7a3779fb5fe1 100644 --- a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java @@ -181,7 +181,8 @@ public static class WithSpanAttributesAdviceScope { private final Context context; private final Scope scope; - private WithSpanAttributesAdviceScope(Method method, MethodRequest request, Context context, Scope scope) { + private WithSpanAttributesAdviceScope( + Method method, MethodRequest request, Context context, Scope scope) { this.method = method; this.request = request; this.context = context; diff --git a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java index 99d3820a82e7..b98e973434bd 100644 --- a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java +++ b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java @@ -51,7 +51,6 @@ public static class ContextAdvice { @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static CoroutineContext enter(@Advice.Argument(0) Context applicationContext) { - if (applicationContext != null) { io.opentelemetry.context.Context agentContext = AgentContextStorage.getAgentContext(applicationContext); @@ -80,15 +79,12 @@ public static class ImplicitContextKeyedAdvice { public static CoroutineContext enter( @Advice.Argument(0) application.io.opentelemetry.context.ImplicitContextKeyed implicitContextKeyed) { - if (implicitContextKeyed != null) { Context applicationContext = Context.current().with(implicitContextKeyed); io.opentelemetry.context.Context agentContext = AgentContextStorage.getAgentContext(applicationContext); - return ContextExtensionsKt.asContextElement(agentContext); } - return null; } @@ -110,7 +106,6 @@ public static class GetOpenTelemetryContextAdvice { @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static Context enter(@Advice.Argument(0) CoroutineContext coroutineContext) { - if (coroutineContext != null) { io.opentelemetry.context.Context agentContext = ContextExtensionsKt.getOpenTelemetryContext(coroutineContext); diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java index 39403a1b59a0..a769a82c0981 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java @@ -142,7 +142,7 @@ public static class WithSpanAttributesAdviceScope { private final Context context; private final Scope scope; - public WithSpanAttributesAdviceScope( + private WithSpanAttributesAdviceScope( Method method, MethodRequest request, Context context, Scope scope) { this.method = method; this.request = request; From 414c367639457490123fa1a6101a5a8f72dc78c4 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:05:50 +0200 Subject: [PATCH 07/10] add few missing annotations --- .../extensionannotations/WithSpanInstrumentation.java | 2 +- .../instrumentationannotations/WithSpanInstrumentation.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java index 7a3779fb5fe1..1f5e3f9b72d0 100644 --- a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java @@ -226,7 +226,7 @@ public static WithSpanAttributesAdviceScope onEnter( @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static Object stopSpan( @Advice.Return @Nullable Object returnValue, - @Advice.Thrown Throwable throwable, + @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter WithSpanAttributesAdviceScope adviceScope) { if (adviceScope != null) { return adviceScope.end(returnValue, throwable); diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java index a769a82c0981..c9f6c9adfb6f 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java @@ -185,8 +185,8 @@ public static WithSpanAttributesAdviceScope onEnter( @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) public static Object stopSpan( - @Advice.Return(typing = Assigner.Typing.DYNAMIC) Object returnValue, - @Advice.Thrown Throwable throwable, + @Advice.Return(typing = Assigner.Typing.DYNAMIC) @Nullable Object returnValue, + @Advice.Thrown @Nullable Throwable throwable, @Advice.Enter WithSpanAttributesAdviceScope adviceScope) { if (adviceScope != null) { return adviceScope.end(returnValue, throwable); From 98095683d42ed5e41ceed2d3fc0696409b0dff4d Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 18 Sep 2025 10:09:30 +0200 Subject: [PATCH 08/10] fix minor things and comments --- .../extensionannotations/WithSpanInstrumentation.java | 4 ++-- .../instrumentationannotations/WithSpanInstrumentation.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java index 1f5e3f9b72d0..147b69f6339e 100644 --- a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java @@ -155,7 +155,7 @@ public Object end(Object returnValue, @Nullable Throwable throwable) { @Advice.OnMethodEnter(suppress = Throwable.class) public static WithSpanAdviceScope onEnter(@Advice.Origin Method originMethod) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it - // to local variable so that there would be only one call to Class.getMethod. + // to advice scope so that there would be only one call to Class.getMethod. return WithSpanAdviceScope.start(originMethod); } @@ -217,7 +217,7 @@ public static WithSpanAttributesAdviceScope onEnter( @Advice.Origin Method originMethod, @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it - // to local variable so that there would be only one call to Class.getMethod. + // to advice scope so that there would be only one call to Class.getMethod. MethodRequest request = new MethodRequest(originMethod, args); return WithSpanAttributesAdviceScope.start(originMethod, request); } diff --git a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java index c9f6c9adfb6f..2ed57433e1d3 100644 --- a/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-annotations-1.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationannotations/WithSpanInstrumentation.java @@ -87,7 +87,7 @@ public static class WithSpanAdviceScope { private final Context context; private final Scope scope; - public WithSpanAdviceScope(Method method, Context context, Scope scope) { + private WithSpanAdviceScope(Method method, Context context, Scope scope) { this.method = method; this.context = context; this.scope = scope; From 6742102661ff75f9039059b647e5a1036dc6b7ec Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 26 Sep 2025 13:45:39 +0200 Subject: [PATCH 09/10] post-review changes --- ...ContextStorageWrappersInstrumentation.java | 4 +-- .../WithSpanInstrumentation.java | 6 ++-- .../ContextExtensionInstrumentation.java | 29 +++++++------------ 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java index 66ab53906c4d..d034412cda49 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/ContextStorageWrappersInstrumentation.java @@ -47,8 +47,8 @@ public static class AddWrapperAdvice { public static List> methodExit( @Advice.Return List> originalWrappers) { - List> wrappers = originalWrappers; - wrappers = new ArrayList<>(wrappers); + List> wrappers = + new ArrayList<>(originalWrappers); // AgentContextStorage wrapper doesn't delegate, so needs to be the innermost wrapper wrappers.add(0, AgentContextStorage.wrap()); return wrappers; diff --git a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java index 147b69f6339e..c6b8fc0c83de 100644 --- a/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java +++ b/instrumentation/opentelemetry-extension-annotations-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionannotations/WithSpanInstrumentation.java @@ -190,7 +190,8 @@ private WithSpanAttributesAdviceScope( } @Nullable - public static WithSpanAttributesAdviceScope start(Method method, MethodRequest request) { + public static WithSpanAttributesAdviceScope start(Method method, Object[] args) { + MethodRequest request = new MethodRequest(method, args); Instrumenter instrumenter = WithSpanSingletons.instrumenterWithAttributes(); Context current = Context.current(); @@ -218,8 +219,7 @@ public static WithSpanAttributesAdviceScope onEnter( @Advice.AllArguments(typing = Assigner.Typing.DYNAMIC) Object[] args) { // Every usage of @Advice.Origin Method is replaced with a call to Class.getMethod, copy it // to advice scope so that there would be only one call to Class.getMethod. - MethodRequest request = new MethodRequest(originMethod, args); - return WithSpanAttributesAdviceScope.start(originMethod, request); + return WithSpanAttributesAdviceScope.start(originMethod, args); } @AssignReturned.ToReturned diff --git a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java index b98e973434bd..3aacf0be171c 100644 --- a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java +++ b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentation.java @@ -13,6 +13,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage; +import javax.annotation.Nullable; import kotlin.coroutines.CoroutineContext; import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice.AssignReturned; @@ -49,6 +50,7 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class ContextAdvice { + @Nullable @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static CoroutineContext enter(@Advice.Argument(0) Context applicationContext) { if (applicationContext != null) { @@ -63,18 +65,15 @@ public static CoroutineContext enter(@Advice.Argument(0) Context applicationCont @Advice.OnMethodExit(onThrowable = Throwable.class) public static CoroutineContext onExit( @Advice.Return CoroutineContext originalResult, - @Advice.Enter CoroutineContext coroutineContext) { - CoroutineContext result = originalResult; - if (coroutineContext != null) { - result = coroutineContext; - } - return result; + @Advice.Enter @Nullable CoroutineContext coroutineContext) { + return coroutineContext != null ? coroutineContext : originalResult; } } @SuppressWarnings("unused") public static class ImplicitContextKeyedAdvice { + @Nullable @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static CoroutineContext enter( @Advice.Argument(0) @@ -92,18 +91,15 @@ public static CoroutineContext enter( @Advice.OnMethodExit(onThrowable = Throwable.class) public static CoroutineContext onExit( @Advice.Return CoroutineContext originalResult, - @Advice.Enter CoroutineContext coroutineContext) { - CoroutineContext result = originalResult; - if (coroutineContext != null) { - result = coroutineContext; - } - return result; + @Advice.Enter @Nullable CoroutineContext coroutineContext) { + return coroutineContext != null ? coroutineContext : originalResult; } } @SuppressWarnings("unused") public static class GetOpenTelemetryContextAdvice { + @Nullable @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static Context enter(@Advice.Argument(0) CoroutineContext coroutineContext) { if (coroutineContext != null) { @@ -114,15 +110,12 @@ public static Context enter(@Advice.Argument(0) CoroutineContext coroutineContex return null; } + @Nullable @AssignReturned.ToReturned @Advice.OnMethodExit(onThrowable = Throwable.class) public static Context onExit( - @Advice.Return Context originalResult, @Advice.Enter Context context) { - Context result = originalResult; - if (context != null) { - result = context; - } - return result; + @Advice.Return Context originalResult, @Advice.Enter @Nullable Context context) { + return context != null ? context : originalResult; } } } From 3fff6673d1562e4a80a8b68e1c49f0aece4595d1 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 26 Sep 2025 14:01:51 +0200 Subject: [PATCH 10/10] post-review changes --- .../SpanKeyInstrumentation.java | 24 ++++++++----------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java b/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java index fe691ad9f239..786961e088eb 100644 --- a/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java +++ b/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/SpanKeyInstrumentation.java @@ -15,6 +15,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.context.AgentContextStorage; import io.opentelemetry.javaagent.instrumentation.opentelemetryapi.trace.Bridging; +import javax.annotation.Nullable; import net.bytebuddy.asm.Advice; import net.bytebuddy.asm.Advice.AssignReturned; import net.bytebuddy.description.type.TypeDescription; @@ -42,6 +43,8 @@ public void transform(TypeTransformer transformer) { @SuppressWarnings("unused") public static class StoreInContextAdvice { + + @Nullable @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static Context onEnter( @Advice.This SpanKey applicationSpanKey, @@ -74,18 +77,16 @@ public static Context onEnter( @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) public static Context onExit( - @Advice.Return Context originalResult, @Advice.Enter Context newApplicationContext) { - Context result = originalResult; - - if (newApplicationContext != null) { - result = newApplicationContext; - } - return result; + @Advice.Return Context originalResult, + @Advice.Enter @Nullable Context newApplicationContext) { + return newApplicationContext != null ? newApplicationContext : originalResult; } } @SuppressWarnings("unused") public static class FromContextOrNullAdvice { + + @Nullable @Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class) public static Span onEnter( @Advice.This SpanKey applicationSpanKey, @Advice.Argument(0) Context applicationContext) { @@ -112,13 +113,8 @@ public static Span onEnter( @AssignReturned.ToReturned @Advice.OnMethodExit(suppress = Throwable.class) public static Span onExit( - @Advice.Return Span originalResult, @Advice.Enter Span applicationSpan) { - Span result = originalResult; - - if (applicationSpan != null) { - result = applicationSpan; - } - return result; + @Advice.Return Span originalResult, @Advice.Enter @Nullable Span applicationSpan) { + return applicationSpan != null ? applicationSpan : originalResult; } } }