From 9dd11ff60609125a7d1bf61c0bb48c7ab6b37ae2 Mon Sep 17 00:00:00 2001 From: Jonas Kunz Date: Thu, 5 Sep 2024 01:07:13 +0200 Subject: [PATCH] Make OpenTelemetry-API Bridge and dependent instrumentations work with indy (#11578) --- ...KotlinCoroutinesInstrumentationModule.java | 13 +++-- ...OpenTelemetryApiInstrumentationModule.java | 23 ++++++--- ...OpenTelemetryApiInstrumentationModule.java | 12 +++-- ...OpenTelemetryApiInstrumentationModule.java | 12 +++-- ...OpenTelemetryApiInstrumentationModule.java | 12 +++-- ...OpenTelemetryApiInstrumentationModule.java | 14 +++--- ...OpenTelemetryApiInstrumentationModule.java | 12 +++-- ...etryApiIncubatorInstrumentationModule.java | 12 +++-- ...OpenTelemetryApiInstrumentationModule.java | 12 +++-- ...OpenTelemetryApiInstrumentationModule.java | 12 +++-- ...etryApiIncubatorInstrumentationModule.java | 12 +++-- ...OpenTelemetryApiInstrumentationModule.java | 12 +++-- ...ContextExtensionInstrumentationModule.java | 12 +++-- ...strumentationApiInstrumentationModule.java | 12 +++-- .../v3_1/ReactorInstrumentationModule.java | 9 ++-- ...extPropagationOperatorInstrumentation.java | 6 +-- ...pagationOperatorInstrumentationModule.java | 14 +++--- ...gationOperator34InstrumentationModule.java | 10 ++-- .../ExperimentalInstrumentationModule.java | 13 +++++ .../InstrumentationModuleClassLoader.java | 22 ++++++++- .../InstrumentationModuleClassLoaderTest.java | 48 +++++++++++++++++++ 21 files changed, 213 insertions(+), 91 deletions(-) diff --git a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/KotlinCoroutinesInstrumentationModule.java b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/KotlinCoroutinesInstrumentationModule.java index c1a6dbc18677..8ed90c855ccf 100644 --- a/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/KotlinCoroutinesInstrumentationModule.java +++ b/instrumentation/kotlinx-coroutines/kotlinx-coroutines-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/kotlinxcoroutines/KotlinCoroutinesInstrumentationModule.java @@ -10,10 +10,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class KotlinCoroutinesInstrumentationModule extends InstrumentationModule { +public class KotlinCoroutinesInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public KotlinCoroutinesInstrumentationModule() { super("kotlinx-coroutines"); @@ -25,12 +27,9 @@ public boolean isHelperClass(String className) { } @Override - public boolean isIndyModule() { - // java.lang.LinkageError: bad method type alias: (CoroutineContext)Object[] not visible from - // class - // io.opentelemetry.javaagent.instrumentation.kotlinxcoroutines.KotlinCoroutinesInstrumentation$ContextAdvice - // CoroutineContext is loaded from agent class loader not application - return false; + public String getModuleGroup() { + // This module uses the api context bridge helpers, therefore must be in the same classloader + return "opentelemetry-api-bridge"; } @Override 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 02a82acc3ea5..6ce2d6ddcec4 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 @@ -10,19 +10,17 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; +import java.util.Collections; import java.util.List; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.0"); } - @Override - public boolean isIndyModule() { - return false; - } - @Override public List typeInstrumentations() { return asList( @@ -31,4 +29,17 @@ public List typeInstrumentations() { new OpenTelemetryInstrumentation(), new SpanInstrumentation()); } + + @Override + public String getModuleGroup() { + return "opentelemetry-api-bridge"; + } + + @Override + public List agentPackagesToHide() { + // These are helper classes injected by api-version specific instrumentation modules + // We don't want to fall back to accidentally trying to load those from the agent CL + // when they haven't been injected + return Collections.singletonList("io.opentelemetry.javaagent.instrumentation.opentelemetryapi"); + } } 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 436ad0356454..81506ec514d8 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 @@ -10,22 +10,24 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.10"); } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.15/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_15/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.15/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_15/OpenTelemetryApiInstrumentationModule.java index 8fbe6be4dcac..8793787e71b6 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.15/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_15/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.15/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_15/OpenTelemetryApiInstrumentationModule.java @@ -10,21 +10,23 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.15"); } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/OpenTelemetryApiInstrumentationModule.java index 3f5b6b12a753..aed58d617504 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.27/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_27/OpenTelemetryApiInstrumentationModule.java @@ -10,21 +10,23 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.27"); } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } 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 be95027539f0..273bb3b755f2 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 @@ -11,20 +11,17 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.31", "opentelemetry-api-incubator-1.31"); } - @Override - public boolean isIndyModule() { - return false; - } - @Override public List typeInstrumentations() { return singletonList(new OpenTelemetryInstrumentation()); @@ -35,4 +32,9 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed( "application.io.opentelemetry.extension.incubator.metrics.ExtendedDoubleHistogramBuilder"); } + + @Override + public String getModuleGroup() { + return "opentelemetry-api-bridge"; + } } 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 893718fc8e6f..49e8dbd8eed1 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 @@ -12,11 +12,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.32"); } @@ -31,12 +33,12 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } 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 dc20c2596ea6..f4e67fc35fe5 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 @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiIncubatorInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiIncubatorInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiIncubatorInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.32", "opentelemetry-api-incubator-1.32"); } @@ -29,12 +31,12 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryIncubatorInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryIncubatorInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/OpenTelemetryApiInstrumentationModule.java index 991895845fbb..5971d77a6ade 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.37/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_37/incubator/OpenTelemetryApiInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.37", "opentelemetry-api-incubator-1.37"); } @@ -27,12 +29,12 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } 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 b25f135b56b2..fc0d9573a9cf 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 @@ -12,11 +12,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.38"); } @@ -31,12 +33,12 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } 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 0d4c23b6d1d8..a70e8fffbd08 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 @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiIncubatorInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiIncubatorInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiIncubatorInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.38", "opentelemetry-api-incubator-1.38"); } @@ -29,12 +31,12 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryIncubatorInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryIncubatorInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_4/OpenTelemetryApiInstrumentationModule.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_4/OpenTelemetryApiInstrumentationModule.java index 0ac3aafe62f1..de37424b8fbc 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_4/OpenTelemetryApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_4/OpenTelemetryApiInstrumentationModule.java @@ -10,21 +10,23 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule { +public class OpenTelemetryApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public OpenTelemetryApiInstrumentationModule() { super("opentelemetry-api", "opentelemetry-api-1.4"); } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new OpenTelemetryInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new OpenTelemetryInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentationModule.java b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentationModule.java index 98a921e9b830..4d90667c42f1 100644 --- a/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentationModule.java +++ b/instrumentation/opentelemetry-extension-kotlin-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extensionkotlin/ContextExtensionInstrumentationModule.java @@ -10,10 +10,12 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class ContextExtensionInstrumentationModule extends InstrumentationModule { +public class ContextExtensionInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public ContextExtensionInstrumentationModule() { super("opentelemetry-extension-kotlin"); @@ -25,12 +27,12 @@ public boolean isHelperClass(String className) { } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return singletonList(new ContextExtensionInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new ContextExtensionInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/InstrumentationApiInstrumentationModule.java b/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/InstrumentationApiInstrumentationModule.java index 793e33c96676..e6754cb818fe 100644 --- a/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/InstrumentationApiInstrumentationModule.java +++ b/instrumentation/opentelemetry-instrumentation-api/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/instrumentationapi/InstrumentationApiInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class InstrumentationApiInstrumentationModule extends InstrumentationModule { +public class InstrumentationApiInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public InstrumentationApiInstrumentationModule() { super("opentelemetry-instrumentation-api"); @@ -27,12 +29,12 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - return false; + public List typeInstrumentations() { + return asList(new HttpRouteStateInstrumentation(), new SpanKeyInstrumentation()); } @Override - public List typeInstrumentations() { - return asList(new HttpRouteStateInstrumentation(), new SpanKeyInstrumentation()); + public String getModuleGroup() { + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/ReactorInstrumentationModule.java b/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/ReactorInstrumentationModule.java index 2ab1d603c976..22a1571a62d6 100644 --- a/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/ReactorInstrumentationModule.java +++ b/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/ReactorInstrumentationModule.java @@ -10,18 +10,21 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; @AutoService(InstrumentationModule.class) -public class ReactorInstrumentationModule extends InstrumentationModule { +public class ReactorInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public ReactorInstrumentationModule() { super("reactor", "reactor-3.1"); } @Override - public boolean isIndyModule() { - return false; + public String getModuleGroup() { + // needs to be in the same module as ContextPropagationOperatorInstrumentation + return "opentelemetry-api-bridge"; } @Override diff --git a/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentation.java b/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentation.java index 670f63dd2607..cde1a4d4d8c5 100644 --- a/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentation.java +++ b/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentation.java @@ -106,9 +106,9 @@ public static void methodExit( @SuppressWarnings("unused") public static class RunWithAdvice { @Advice.OnMethodEnter - public static void methodEnter( - @Advice.FieldValue(value = "enabled", readOnly = false) boolean enabled) { - enabled = true; + @Advice.AssignReturned.ToFields(@Advice.AssignReturned.ToFields.ToField("enabled")) + public static boolean methodEnter() { + return true; } } } diff --git a/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentationModule.java b/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentationModule.java index f1a179bad238..1f40d19a3f1b 100644 --- a/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentationModule.java +++ b/instrumentation/reactor/reactor-3.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_1/operator/ContextPropagationOperatorInstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class ContextPropagationOperatorInstrumentationModule extends InstrumentationModule { +public class ContextPropagationOperatorInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public ContextPropagationOperatorInstrumentationModule() { super("reactor", "reactor-3.1", "reactor-context-propagation-operator"); @@ -27,13 +29,13 @@ public ElementMatcher.Junction classLoaderMatcher() { } @Override - public boolean isIndyModule() { - // RunWithAdvice uses @Advice.FieldValue - return false; + public List typeInstrumentations() { + return singletonList(new ContextPropagationOperatorInstrumentation()); } @Override - public List typeInstrumentations() { - return singletonList(new ContextPropagationOperatorInstrumentation()); + public String getModuleGroup() { + // This module uses the api context bridge helpers, therefore must be in the same classloader + return "opentelemetry-api-bridge"; } } diff --git a/instrumentation/reactor/reactor-3.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_4/operator/ContextPropagationOperator34InstrumentationModule.java b/instrumentation/reactor/reactor-3.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_4/operator/ContextPropagationOperator34InstrumentationModule.java index d783638f035d..c5fabc4dccbf 100644 --- a/instrumentation/reactor/reactor-3.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_4/operator/ContextPropagationOperator34InstrumentationModule.java +++ b/instrumentation/reactor/reactor-3.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/reactor/v3_4/operator/ContextPropagationOperator34InstrumentationModule.java @@ -11,11 +11,13 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class ContextPropagationOperator34InstrumentationModule extends InstrumentationModule { +public class ContextPropagationOperator34InstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public ContextPropagationOperator34InstrumentationModule() { super("reactor", "reactor-3.4", "reactor-context-propagation-operator"); @@ -33,8 +35,8 @@ public List typeInstrumentations() { } @Override - public boolean isIndyModule() { - // Requires Otel-API bride - return false; + public String getModuleGroup() { + // This module uses the api context bridge helpers, therefore must be in the same classloader + return "opentelemetry-api-bridge"; } } diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java index b2378d752434..af8d33d78659 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java @@ -9,6 +9,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.ClassInjector; +import java.util.Collections; import java.util.List; /** @@ -48,4 +49,16 @@ default List injectedClassNames() { default String getModuleGroup() { return getClass().getName(); } + + /** + * Some instrumentations need to invoke classes which are present both in the agent classloader + * and the instrumented application classloader. By default, the classloader of the + * instrumentation would link those against the class provided by the agent. This setting allows + * to hide packages, so that matching classes are instead used from the application classloader. + * + * @return the list of packages (without trailing dots) + */ + default List agentPackagesToHide() { + return Collections.emptyList(); + } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoader.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoader.java index 3c346823acf8..b4d2477dd57e 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoader.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoader.java @@ -77,6 +77,13 @@ public class InstrumentationModuleClassLoader extends ClassLoader { */ private final ElementMatcher agentClassNamesMatcher; + /** + * Mutable set of packages from the agent classloader to hide. So even if a class matches {@link + * #agentClassNamesMatcher}, it will not be attempted to be loaded from the agent classloader if + * it is from any of these packages. + */ + private final Set hiddenAgentPackages; + private final Set installedModules; public InstrumentationModuleClassLoader( @@ -98,6 +105,7 @@ public InstrumentationModuleClassLoader( this.agentOrExtensionCl = agentOrExtensionCl; this.instrumentedCl = instrumentedCl; this.agentClassNamesMatcher = classesToLoadFromAgentOrExtensionCl; + this.hiddenAgentPackages = Collections.newSetFromMap(new ConcurrentHashMap<>()); } /** @@ -141,6 +149,10 @@ public synchronized void installModule(InstrumentationModule module) { className -> className, className -> BytecodeWithUrl.create(className, agentOrExtensionCl))); installInjectedClasses(classesToInject); + if (module instanceof ExperimentalInstrumentationModule) { + hiddenAgentPackages.addAll( + ((ExperimentalInstrumentationModule) module).agentPackagesToHide()); + } } public synchronized boolean hasModuleInstalled(InstrumentationModule module) { @@ -226,7 +238,15 @@ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundE } private boolean shouldLoadFromAgent(String dotClassName) { - return agentClassNamesMatcher.matches(dotClassName); + if (!agentClassNamesMatcher.matches(dotClassName)) { + return false; + } + for (String packageName : hiddenAgentPackages) { + if (dotClassName.startsWith(packageName)) { + return false; + } + } + return true; } private static Class tryLoad(@Nullable ClassLoader cl, String name) { diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoaderTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoaderTest.java index 5f242fe719c7..9a5c4158914f 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoaderTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/InstrumentationModuleClassLoaderTest.java @@ -8,6 +8,9 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.tooling.BytecodeWithUrl; import io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.Bar; import io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.Foo; @@ -21,8 +24,10 @@ import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarOutputStream; @@ -191,6 +196,49 @@ void checkClassLookupPrecedence(@TempDir Path tempDir) throws Exception { } } + public static class HidingModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { + + List hiddenPackages = new ArrayList<>(); + + public HidingModule() { + super("hiding-module"); + } + + @Override + public List typeInstrumentations() { + return Collections.emptyList(); + } + + @Override + public List agentPackagesToHide() { + return hiddenPackages; + } + } + + @Test + public void testAgentClassHiding() throws ClassNotFoundException { + HidingModule module = new HidingModule(); + + ClassLoader agentCl = HideMe.class.getClassLoader(); + + InstrumentationModuleClassLoader nothingHidden = + new InstrumentationModuleClassLoader(null, agentCl, ElementMatchers.any()); + nothingHidden.installModule(module); + + assertThat(nothingHidden.loadClass(HideMe.class.getName())).isSameAs(HideMe.class); + + module.hiddenPackages.add(HideMe.class.getPackage().getName()); + InstrumentationModuleClassLoader classHidden = + new InstrumentationModuleClassLoader(null, agentCl, ElementMatchers.any()); + classHidden.installModule(module); + + assertThatThrownBy(() -> classHidden.loadClass(HideMe.class.getName())) + .isInstanceOf(ClassNotFoundException.class); + } + + public static class HideMe {} + private static String getClassFile(Class cl) { return cl.getName().replace('.', '/') + ".class"; }