From 6948ca08ae02417df48d1aef3c30adc3be553514 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 20 May 2026 17:35:37 +0200 Subject: [PATCH 01/21] add common CL --- .../indy/IndyModuleRegistry.java | 14 ++- .../InstrumentationModuleClassLoader.java | 113 +++++++++++++++++- .../InstrumentationModuleClassLoaderTest.java | 35 ++++-- 3 files changed, 148 insertions(+), 14 deletions(-) diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/IndyModuleRegistry.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/IndyModuleRegistry.java index f55ac321a2eb..4be65176b743 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/IndyModuleRegistry.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/IndyModuleRegistry.java @@ -34,6 +34,9 @@ private IndyModuleRegistry() {} private static final ClassLoaderValue> instrumentationClassLoaders = new ClassLoaderValue<>(); + private static final ClassLoaderValue + instrumentationCommonClassLoader = new ClassLoaderValue<>(); + public static InstrumentationModuleClassLoader getInstrumentationClassLoader( String moduleClassName, ClassLoader instrumentedClassLoader) { InstrumentationModule instrumentationModule = modulesByClassName.get(moduleClassName); @@ -100,7 +103,7 @@ public static InstrumentationModuleClassLoader createInstrumentationClassLoaderF // TODO: remove this method and replace usages with a custom TypePool implementation instead ClassLoader agentOrExtensionCl = module.getClass().getClassLoader(); InstrumentationModuleClassLoader cl = - new InstrumentationModuleClassLoader(instrumentedClassLoader, agentOrExtensionCl); + new InstrumentationModuleClassLoader(instrumentedClassLoader, agentOrExtensionCl, null); cl.installModule(module, true); return cl; } @@ -127,12 +130,19 @@ private static void initializeModuleLoaderForClassLoader( String groupName = getModuleGroup(module); + InstrumentationModuleClassLoader commonCl = + instrumentationCommonClassLoader.computeIfAbsent( + classLoader, + () -> new InstrumentationModuleClassLoader(classLoader, agentOrExtensionCl, null)); + InstrumentationModuleClassLoader moduleCl = instrumentationClassLoaders .computeIfAbsent(classLoader, ConcurrentHashMap::new) .computeIfAbsent( groupName, - unused -> new InstrumentationModuleClassLoader(classLoader, agentOrExtensionCl)); + unused -> + new InstrumentationModuleClassLoader( + classLoader, agentOrExtensionCl, commonCl)); moduleCl.installModule(module); } 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 7f2215f9640c..3eb1c0c0162d 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 @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.tooling.instrumentation.indy; +import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; @@ -27,6 +28,7 @@ import java.security.ProtectionDomain; import java.util.Collections; import java.util.Enumeration; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -74,6 +76,7 @@ public class InstrumentationModuleClassLoader extends ClassLoader { private final Map additionalInjectedClasses; private final ClassLoader agentOrExtensionCl; + @Nullable private final InstrumentationModuleClassLoader commonCl; private volatile MethodHandles.Lookup cachedLookup; @Nullable private final ClassLoader instrumentedCl; @@ -85,6 +88,8 @@ public class InstrumentationModuleClassLoader extends ClassLoader { */ private final ElementMatcher agentClassNamesMatcher; + private final ElementMatcher agentCommonClassNamesMatcher; + /** * 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 @@ -95,17 +100,23 @@ public class InstrumentationModuleClassLoader extends ClassLoader { private final Set installedModules; public InstrumentationModuleClassLoader( - ClassLoader instrumentedCl, ClassLoader agentOrExtensionCl) { + ClassLoader instrumentedCl, + ClassLoader agentOrExtensionCl, + @Nullable InstrumentationModuleClassLoader commonCl) { this( instrumentedCl, agentOrExtensionCl, - new StringMatcher("io.opentelemetry.javaagent", StringMatcher.Mode.STARTS_WITH)); + new StringMatcher("io.opentelemetry.javaagent", StringMatcher.Mode.STARTS_WITH), + commonCl, + new StringMatcher("disabled-for-now", StringMatcher.Mode.STARTS_WITH)); } InstrumentationModuleClassLoader( @Nullable ClassLoader instrumentedCl, ClassLoader agentOrExtensionCl, - ElementMatcher classesToLoadFromAgentOrExtensionCl) { + ElementMatcher classesToLoadFromAgentOrExtensionCl, + @Nullable InstrumentationModuleClassLoader commonCl, + ElementMatcher classesToLoadFromCommonCl) { // agent/extension-class loader is "main"-parent, but class lookup is overridden super(agentOrExtensionCl); additionalInjectedClasses = new ConcurrentHashMap<>(); @@ -114,6 +125,8 @@ public InstrumentationModuleClassLoader( this.instrumentedCl = instrumentedCl; this.agentClassNamesMatcher = classesToLoadFromAgentOrExtensionCl; this.hiddenAgentPackages = Collections.newSetFromMap(new ConcurrentHashMap<>()); + this.commonCl = commonCl; + this.agentCommonClassNamesMatcher = classesToLoadFromCommonCl; } /** @@ -161,7 +174,9 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC toMap( className -> className, className -> BytecodeWithUrl.create(className, agentOrExtensionCl))); + installInjectedClasses(classesToInject); + if (module instanceof ExperimentalInstrumentationModule) { ExperimentalInstrumentationModule experimentalModule = (ExperimentalInstrumentationModule) module; @@ -184,13 +199,96 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC } } + /** + * Determines if injected class should be loaded in a shared class loader or not. + * + * @param className class name + * @return true if class should be loaded in shared class loader, false otherwise (default) + */ + boolean useCommonClassLoader(String className) { + if (agentCommonClassNamesMatcher.matches(className)) { + return true; + } + // TODO: we can replace this name-based heuristic with proper annotation + // or we can also make the instrumentation modules provide a dedicated API to provide a + // list/pattern + for (String part : commonPackageHeuristic) { + // instrumentation, not shaded + String normalized = normalize(part, "io.opentelemetry.javaagent.instrumentation."); + // library, not shaded + normalized = normalize(normalized, "io.opentelemetry.instrumentation."); + if (className.contains(normalized + ".")) { + return true; + } + } + return false; + } + + private static String normalize(String value, String prefix) { + if (value.startsWith(prefix)) { + return value.substring(prefix.length()); + } + return value; + } + + // TODO temporary heuristic to validate the idea that a single shared CL is valid + // if this approach is valid, then we should probably find a better way, for example by using an + // annotation in the packages themselves to indicate they should be shared. + private static final Set commonPackageHeuristic = + new HashSet<>( + asList( + "io.opentelemetry.javaagent.instrumentation.hibernate.common.v3_3", + "io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.common.v5_0", + "io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal", + "io.opentelemetry.instrumentation.netty.common.internal", + "io.opentelemetry.javaagent.instrumentation.netty.common.v4_0", + "io.opentelemetry.instrumentation.netty.common.v4_0.internal", + "io.opentelemetry.instrumentation.netty.v4_1.internal", + "io.opentelemetry.javaagent.instrumentation.couchbase.common.v2_0", + // for pekko, we should refactor to help simplify this + "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0", + "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.route", + "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.server", + "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.tapir", + // for akka, we should refactor to help simplify this + "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0", + "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server", + "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server.route", + // aws sdk 1.x library + "io.opentelemetry.instrumentation.awssdk.v1_11", + // aws sdk 2.x library internals: refactor needed to avoid relying on internals + "io.opentelemetry.instrumentation.awssdk.v2_2.internal", + // aws sdk 2.x instrumentation + "io.opentelemetry.javaagent.instrumentation.awssdk.v2_2")); + public synchronized boolean hasModuleInstalled(InstrumentationModule module) { return installedModules.contains(module); } + /** + * Injects classes into this module classloader and delegates injection to the common classloader + * as-needed + * + * @param classesToInject classes to inject + */ // Visible for testing synchronized void installInjectedClasses(Map classesToInject) { - classesToInject.forEach(additionalInjectedClasses::putIfAbsent); + if (commonCl == null) { + classesToInject.forEach(additionalInjectedClasses::putIfAbsent); + } else { + Map common = new HashMap<>(); + Map injected = new HashMap<>(); + classesToInject.forEach( + (className, bytecode) -> { + if (useCommonClassLoader(className)) { + common.putIfAbsent(className, bytecode); + } else { + injected.putIfAbsent(className, bytecode); + } + }); + commonCl.installInjectedClasses(common); + injected.forEach(additionalInjectedClasses::putIfAbsent); + } } private static Set getClassesToInject(InstrumentationModule module) { @@ -240,7 +338,12 @@ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundE synchronized (getClassLoadingLock(name)) { Class result = findLoadedClass(name); - // This CL is self-first: Injected class are loaded BEFORE a parent lookup + // Common classes delegation is first to ensure they are only loaded in the common CL + if (result == null && commonCl != null && useCommonClassLoader(name)) { + result = tryLoad(commonCl, name); + } + + // Injected class are loaded BEFORE a parent lookup if (result == null) { BytecodeWithUrl injected = getInjectedClass(name); if (injected != null) { 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 ab92c3514da4..89f230fa94e1 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 @@ -36,6 +36,7 @@ import net.bytebuddy.ByteBuddy; import net.bytebuddy.dynamic.ClassFileLocator; import net.bytebuddy.implementation.FixedValue; +import net.bytebuddy.matcher.StringMatcher; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.condition.OS; import org.junit.jupiter.api.io.TempDir; @@ -66,11 +67,11 @@ void checkLookup() throws Throwable { ClassLoader dummyParent = new URLClassLoader(new URL[] {}, null); InstrumentationModuleClassLoader m1 = - new InstrumentationModuleClassLoader(dummyParent, dummyParent, any()); + new InstrumentationModuleClassLoader(dummyParent, dummyParent, any(), null, any()); m1.installInjectedClasses(toInject); InstrumentationModuleClassLoader m2 = - new InstrumentationModuleClassLoader(dummyParent, dummyParent, any()); + new InstrumentationModuleClassLoader(dummyParent, dummyParent, any(), null, any()); m2.installInjectedClasses(toInject); // MethodHandles.publicLookup() always succeeds on the first invocation @@ -105,7 +106,7 @@ void checkInjectedClassesHavePackage() throws Throwable { ClassLoader dummyParent = new URLClassLoader(new URL[] {}, null); InstrumentationModuleClassLoader m1 = - new InstrumentationModuleClassLoader(dummyParent, dummyParent, any()); + new InstrumentationModuleClassLoader(dummyParent, dummyParent, any(), null, any()); m1.installInjectedClasses(toInject); Class injected = Class.forName(A.class.getName(), true, m1); @@ -127,7 +128,7 @@ void checkClassLookupPrecedence(@TempDir Path tempDir) throws Exception { Map appClasses = copyClassesWithMarker("app-cl", A.class, B.class, C.class); Map agentClasses = copyClassesWithMarker("agent-cl", B.class, C.class); Map moduleClasses = - copyClassesWithMarker("module-cl", A.class, B.class, C.class, D.class); + copyClassesWithMarker("module-cl", A.class, B.class, C.class, D.class, E.class); Path appJar = tempDir.resolve("dummy-app.jar"); createJar(appClasses, appJar); @@ -144,10 +145,23 @@ void checkClassLookupPrecedence(@TempDir Path tempDir) throws Exception { try { Map toInject = new HashMap<>(); + // a copy of C is injected into module CL, thus the module CL should load it toInject.put(C.class.getName(), BytecodeWithUrl.create(C.class.getName(), moduleSourceCl)); + // a copy of E is injected into common module CL, thus the module CL should delegate loading + // to the common CL. + toInject.put(E.class.getName(), BytecodeWithUrl.create(E.class.getName(), moduleSourceCl)); + InstrumentationModuleClassLoader moduleCommonCl = + new InstrumentationModuleClassLoader(appCl, agentCl, any(), null, null); InstrumentationModuleClassLoader moduleCl = - new InstrumentationModuleClassLoader(appCl, agentCl, any()); + new InstrumentationModuleClassLoader( + appCl, + agentCl, + any(), + moduleCommonCl, + new StringMatcher("E", StringMatcher.Mode.ENDS_WITH)); + + // this will delegate injection into common CL as-needed moduleCl.installInjectedClasses(toInject); // Verify precedence for classloading @@ -167,6 +181,11 @@ void checkClassLookupPrecedence(@TempDir Path tempDir) throws Exception { assertThatThrownBy(() -> moduleCl.loadClass(D.class.getName())) .isInstanceOf(ClassNotFoundException.class); + Class clE = moduleCl.loadClass(E.class.getName()); + // marker remains the same as in the module CL. + assertThat(getMarkerValue(clE)).isEqualTo("module-cl"); + assertThat(clE.getClassLoader()).isSameAs(moduleCommonCl); + // Verify precedence for looking up .class resources URL resourceA = moduleCl.getResource(getClassFile(A.class)); assertThat(resourceA.toString()).startsWith("jar:" + appJar.toUri().toURL()); @@ -247,14 +266,14 @@ public void testAgentClassHiding() throws ClassNotFoundException { ClassLoader agentCl = HideMe.class.getClassLoader(); InstrumentationModuleClassLoader nothingHidden = - new InstrumentationModuleClassLoader(null, agentCl, any()); + new InstrumentationModuleClassLoader(null, agentCl, any(), null, 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, any()); + new InstrumentationModuleClassLoader(null, agentCl, any(), null, any()); classHidden.installModule(module); assertThatThrownBy(() -> classHidden.loadClass(HideMe.class.getName())) @@ -315,4 +334,6 @@ public static class B {} public static class C {} public static class D {} + + public static class E {} } From 8f7a058661781257febabc48f3ef40ad0696742d Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 20 May 2026 17:36:04 +0200 Subject: [PATCH 02/21] hibernate --- .../hibernate/v3_3/HibernateInstrumentationModule.java | 9 +-------- .../hibernate/v4_0/HibernateInstrumentationModule.java | 9 +-------- .../hibernate/v6_0/HibernateInstrumentationModule.java | 9 +-------- .../call/v4_3/HibernateInstrumentationModule.java | 9 +-------- 4 files changed, 4 insertions(+), 32 deletions(-) diff --git a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java index cafd0c85f3f4..6ca1c19b15bb 100644 --- a/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v3_3/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ 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 HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-3.3"); @@ -32,11 +30,6 @@ public ElementMatcher.Junction classLoaderMatcher() { "org.hibernate.transaction.JBossTransactionManagerLookup"); } - @Override - public String getModuleGroup() { - return "hibernate"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java index 9b5baf389d90..81e5e766e903 100644 --- a/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v4_0/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ 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 HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-4.0"); @@ -32,11 +30,6 @@ public ElementMatcher.Junction classLoaderMatcher() { "org.hibernate.Criteria"); } - @Override - public String getModuleGroup() { - return "hibernate"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java index 388afd0ce37c..e754419ab459 100644 --- a/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-6.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/v6_0/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ 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 HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate", "hibernate-6.0"); @@ -29,11 +27,6 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.hibernate.query.spi.SqmQuery"); } - @Override - public String getModuleGroup() { - return "hibernate"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/procedure/call/v4_3/HibernateInstrumentationModule.java b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/procedure/call/v4_3/HibernateInstrumentationModule.java index a24f4923fbd4..c424b2682770 100644 --- a/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/procedure/call/v4_3/HibernateInstrumentationModule.java +++ b/instrumentation/hibernate/hibernate-procedure-call-4.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/procedure/call/v4_3/HibernateInstrumentationModule.java @@ -11,13 +11,11 @@ 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 HibernateInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class HibernateInstrumentationModule extends InstrumentationModule { public HibernateInstrumentationModule() { super("hibernate-procedure-call", "hibernate-procedure-call-4.3", "hibernate"); } @@ -28,11 +26,6 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.hibernate.procedure.ProcedureCall"); } - @Override - public String getModuleGroup() { - return "hibernate"; - } - @Override public List typeInstrumentations() { return asList(new ProcedureCallInstrumentation(), new SessionInstrumentation()); From 913308f98a5eca2832a6a354583cde79a946d362 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 20 May 2026 17:36:21 +0200 Subject: [PATCH 03/21] elasticsearch --- .../ElasticsearchApiClientInstrumentationModule.java | 9 +-------- .../v7_0/ElasticsearchRest7InstrumentationModule.java | 9 +-------- 2 files changed, 2 insertions(+), 16 deletions(-) diff --git a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/api/client/v7_16/ElasticsearchApiClientInstrumentationModule.java b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/api/client/v7_16/ElasticsearchApiClientInstrumentationModule.java index 8f089d7ac70a..4d5be8959784 100644 --- a/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/api/client/v7_16/ElasticsearchApiClientInstrumentationModule.java +++ b/instrumentation/elasticsearch/elasticsearch-api-client-7.16/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/api/client/v7_16/ElasticsearchApiClientInstrumentationModule.java @@ -12,13 +12,11 @@ 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 ElasticsearchApiClientInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class ElasticsearchApiClientInstrumentationModule extends InstrumentationModule { public ElasticsearchApiClientInstrumentationModule() { super("elasticsearch-api-client", "elasticsearch-api-client-7.16", "elasticsearch"); } @@ -32,11 +30,6 @@ public ElementMatcher.Junction classLoaderMatcher() { .and(not(hasClassesNamed("co.elastic.clients.transport.instrumentation.Instrumentation"))); } - @Override - public String getModuleGroup() { - return "elasticsearch"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java index 44263ee21ccb..0f971fdde59d 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java +++ b/instrumentation/elasticsearch/elasticsearch-rest-7.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/v7_0/ElasticsearchRest7InstrumentationModule.java @@ -12,13 +12,11 @@ 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 ElasticsearchRest7InstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class ElasticsearchRest7InstrumentationModule extends InstrumentationModule { public ElasticsearchRest7InstrumentationModule() { super("elasticsearch-rest", "elasticsearch-rest-7.0", "elasticsearch"); } @@ -32,11 +30,6 @@ public ElementMatcher.Junction classLoaderMatcher() { .and(not(hasClassesNamed("co.elastic.clients.transport.instrumentation.Instrumentation"))); } - @Override - public String getModuleGroup() { - return "elasticsearch"; - } - @Override public List typeInstrumentations() { return singletonList(new RestClientInstrumentation()); From df903749a24314fba1ff71834fa5aad4bee3eab2 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 20 May 2026 17:36:52 +0200 Subject: [PATCH 04/21] couchbase --- .../couchbase/v2_0/CouchbaseInstrumentationModule.java | 5 ----- .../couchbase/v2_6/CouchbaseInstrumentationModule.java | 9 +-------- 2 files changed, 1 insertion(+), 13 deletions(-) diff --git a/instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseInstrumentationModule.java b/instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseInstrumentationModule.java index a84dedfd5168..54cf73c67f37 100644 --- a/instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseInstrumentationModule.java +++ b/instrumentation/couchbase/couchbase-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_0/CouchbaseInstrumentationModule.java @@ -34,11 +34,6 @@ public List typeInstrumentations() { return asList(new CouchbaseBucketInstrumentation(), new CouchbaseClusterInstrumentation()); } - @Override - public String getModuleGroup() { - return "couchbase"; - } - @Override public List injectedClassNames() { return singletonList("rx.OpenTelemetryTracingUtil"); diff --git a/instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseInstrumentationModule.java b/instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseInstrumentationModule.java index 639d9e06b5dc..7e6dad346415 100644 --- a/instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseInstrumentationModule.java +++ b/instrumentation/couchbase/couchbase-2.6/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/v2_6/CouchbaseInstrumentationModule.java @@ -11,13 +11,11 @@ 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 CouchbaseInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class CouchbaseInstrumentationModule extends InstrumentationModule { public CouchbaseInstrumentationModule() { super("couchbase", "couchbase-2.6"); @@ -33,9 +31,4 @@ public ElementMatcher.Junction classLoaderMatcher() { public List typeInstrumentations() { return asList(new CouchbaseCoreInstrumentation(), new CouchbaseNetworkInstrumentation()); } - - @Override - public String getModuleGroup() { - return "couchbase"; - } } From 43d64685495b3c3b68f2be1ed640ca40b4a072b8 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 20 May 2026 17:37:34 +0200 Subject: [PATCH 05/21] netty --- .../v23_11/FinagleHttpInstrumentationModule.java | 6 ------ .../netty/v3_8/NettyInstrumentationModule.java | 9 +-------- .../netty/v4_0/NettyInstrumentationModule.java | 9 +-------- .../netty/v4_1/NettyInstrumentationModule.java | 9 +-------- .../ratpack/v1_4/RatpackInstrumentationModule.java | 10 +--------- .../ratpack/v1_7/RatpackInstrumentationModule.java | 10 +--------- .../gateway/v2_0/GatewayInstrumentationModule.java | 10 +--------- .../ReactorNettyInstrumentationModule.java | 10 +--------- 8 files changed, 7 insertions(+), 66 deletions(-) diff --git a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java index 81658c6ca854..325c6b2cf44a 100644 --- a/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java +++ b/instrumentation/finagle-http-23.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/finaglehttp/v23_11/FinagleHttpInstrumentationModule.java @@ -30,12 +30,6 @@ public List typeInstrumentations() { new H2StreamChannelInitInstrumentation()); } - @Override - public String getModuleGroup() { - // relies on netty and needs access to common netty instrumentation classes - return "netty"; - } - @Override public List injectedClassNames() { // these are injected so that they can access package-private members diff --git a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java index 40c92d0083f8..db5c9bb15687 100644 --- a/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-3.8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v3_8/NettyInstrumentationModule.java @@ -11,13 +11,11 @@ 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 NettyInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-3.8"); } @@ -28,11 +26,6 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.jboss.netty.handler.codec.http.HttpMessage"); } - @Override - public String getModuleGroup() { - return "netty"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java index d8dbe58f08ff..fb5149b28634 100644 --- a/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_0/NettyInstrumentationModule.java @@ -12,14 +12,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 io.opentelemetry.javaagent.instrumentation.netty.common.v4_0.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.0"); } @@ -32,11 +30,6 @@ public ElementMatcher.Junction classLoaderMatcher() { .and(not(hasClassesNamed("io.netty.handler.codec.http.CombinedHttpHeaders"))); } - @Override - public String getModuleGroup() { - return "netty"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java index 9b1ced016ebf..1d2b37ff693d 100644 --- a/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java +++ b/instrumentation/netty/netty-4.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/v4_1/NettyInstrumentationModule.java @@ -11,14 +11,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 io.opentelemetry.javaagent.instrumentation.netty.common.v4_0.NettyFutureInstrumentation; import java.util.List; import net.bytebuddy.matcher.ElementMatcher; @AutoService(InstrumentationModule.class) -public class NettyInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class NettyInstrumentationModule extends InstrumentationModule { public NettyInstrumentationModule() { super("netty", "netty-4.1"); } @@ -29,11 +27,6 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("io.netty.handler.codec.http.CombinedHttpHeaders"); } - @Override - public String getModuleGroup() { - return "netty"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/RatpackInstrumentationModule.java b/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/RatpackInstrumentationModule.java index 5a0aa9efb721..192abd721dda 100644 --- a/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/RatpackInstrumentationModule.java +++ b/instrumentation/ratpack/ratpack-1.4/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_4/RatpackInstrumentationModule.java @@ -10,22 +10,14 @@ 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 RatpackInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class RatpackInstrumentationModule extends InstrumentationModule { public RatpackInstrumentationModule() { super("ratpack", "ratpack-1.4"); } - @Override - public String getModuleGroup() { - // relies on netty - return "netty"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/ratpack/ratpack-1.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_7/RatpackInstrumentationModule.java b/instrumentation/ratpack/ratpack-1.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_7/RatpackInstrumentationModule.java index b60e1bb219e4..a84f79ec1a56 100644 --- a/instrumentation/ratpack/ratpack-1.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_7/RatpackInstrumentationModule.java +++ b/instrumentation/ratpack/ratpack-1.7/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/ratpack/v1_7/RatpackInstrumentationModule.java @@ -11,23 +11,15 @@ 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 RatpackInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class RatpackInstrumentationModule extends InstrumentationModule { public RatpackInstrumentationModule() { super("ratpack", "ratpack-1.7"); } - @Override - public String getModuleGroup() { - // relies on netty - return "netty"; - } - @Override public ElementMatcher.Junction classLoaderMatcher() { // added in 1.7.0 diff --git a/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/gateway/v2_0/GatewayInstrumentationModule.java b/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/gateway/v2_0/GatewayInstrumentationModule.java index e144489141e1..fd9440cabac8 100644 --- a/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/gateway/v2_0/GatewayInstrumentationModule.java +++ b/instrumentation/spring/spring-cloud-gateway/spring-cloud-gateway-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/gateway/v2_0/GatewayInstrumentationModule.java @@ -10,12 +10,10 @@ 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 GatewayInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class GatewayInstrumentationModule extends InstrumentationModule { public GatewayInstrumentationModule() { super("spring-cloud-gateway", "spring-cloud-gateway-2.0"); @@ -26,12 +24,6 @@ public List typeInstrumentations() { return singletonList(new HandlerAdapterInstrumentation()); } - @Override - public String getModuleGroup() { - // relies on netty - return "netty"; - } - @Override public int order() { // Later than Spring Webflux. diff --git a/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java b/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java index d6a9ccf44397..e2e26007b701 100644 --- a/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java +++ b/instrumentation/spring/spring-webflux/spring-webflux-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/webflux/v5_0/server/reactornetty/ReactorNettyInstrumentationModule.java @@ -10,23 +10,15 @@ 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 ReactorNettyInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class ReactorNettyInstrumentationModule extends InstrumentationModule { public ReactorNettyInstrumentationModule() { super("spring-webflux", "spring-webflux-5.0", "reactor-netty", "reactor-netty-server"); } - @Override - public String getModuleGroup() { - // relies on netty - return "netty"; - } - @Override public List typeInstrumentations() { return asList(new HttpTrafficHandlerInstrumentation(), new ContextHandlerInstrumentation()); From 65768794603bf3c499b9d426d35d30949f415852 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 20 May 2026 17:38:07 +0200 Subject: [PATCH 06/21] akka + pekko --- .../server/AkkaHttpServerInstrumentationModule.java | 5 ----- .../route/AkkaHttpServerRouteInstrumentationModule.java | 5 ----- .../server/PekkoHttpServerInstrumentationModule.java | 9 +-------- .../route/PekkoHttpServerRouteInstrumentationModule.java | 9 +-------- .../TapirPekkoHttpServerRouteInstrumentationModule.java | 9 +-------- 5 files changed, 3 insertions(+), 34 deletions(-) diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/AkkaHttpServerInstrumentationModule.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/AkkaHttpServerInstrumentationModule.java index 4773e687a369..fde8e1008991 100644 --- a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/AkkaHttpServerInstrumentationModule.java +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/AkkaHttpServerInstrumentationModule.java @@ -22,11 +22,6 @@ public AkkaHttpServerInstrumentationModule() { super("akka-http", "akka-http-10.0", "akka-http-server"); } - @Override - public String getModuleGroup() { - return "akka-http"; - } - @Override public ElementMatcher.Junction classLoaderMatcher() { // in GraphInterpreterInstrumentation we instrument a class that belongs to akka-streams, make diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/AkkaHttpServerRouteInstrumentationModule.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/AkkaHttpServerRouteInstrumentationModule.java index 72de95f90253..7bf2e3bd5bc4 100644 --- a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/AkkaHttpServerRouteInstrumentationModule.java +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/AkkaHttpServerRouteInstrumentationModule.java @@ -24,11 +24,6 @@ public AkkaHttpServerRouteInstrumentationModule() { super("akka-http", "akka-http-10.0", "akka-http-server", "akka-http-server-route"); } - @Override - public String getModuleGroup() { - return "akka-http"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/PekkoHttpServerInstrumentationModule.java b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/PekkoHttpServerInstrumentationModule.java index 79bee8d34166..d5bd39ac247b 100644 --- a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/PekkoHttpServerInstrumentationModule.java +++ b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/PekkoHttpServerInstrumentationModule.java @@ -11,13 +11,11 @@ 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 PekkoHttpServerInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class PekkoHttpServerInstrumentationModule extends InstrumentationModule { public PekkoHttpServerInstrumentationModule() { super("pekko-http", "pekko-http-1.0", "pekko-http-server"); } @@ -30,11 +28,6 @@ public ElementMatcher.Junction classLoaderMatcher() { return hasClassesNamed("org.apache.pekko.http.scaladsl.HttpExt"); } - @Override - public String getModuleGroup() { - return "pekko-server"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/route/PekkoHttpServerRouteInstrumentationModule.java b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/route/PekkoHttpServerRouteInstrumentationModule.java index 77b3b0d81955..323b38c532c6 100644 --- a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/route/PekkoHttpServerRouteInstrumentationModule.java +++ b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/route/PekkoHttpServerRouteInstrumentationModule.java @@ -10,7 +10,6 @@ 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; /** @@ -18,17 +17,11 @@ * PekkoHttpServerInstrumentationModule applies to classes in pekko-http-core.jar */ @AutoService(InstrumentationModule.class) -public class PekkoHttpServerRouteInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class PekkoHttpServerRouteInstrumentationModule extends InstrumentationModule { public PekkoHttpServerRouteInstrumentationModule() { super("pekko-http", "pekko-http-1.0", "pekko-http-server", "pekko-http-server-route"); } - @Override - public String getModuleGroup() { - return "pekko-server"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/TapirPekkoHttpServerRouteInstrumentationModule.java b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/TapirPekkoHttpServerRouteInstrumentationModule.java index 8998e62b3191..2f73e4f08efd 100644 --- a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/TapirPekkoHttpServerRouteInstrumentationModule.java +++ b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/TapirPekkoHttpServerRouteInstrumentationModule.java @@ -10,12 +10,10 @@ 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 TapirPekkoHttpServerRouteInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class TapirPekkoHttpServerRouteInstrumentationModule extends InstrumentationModule { public TapirPekkoHttpServerRouteInstrumentationModule() { super( "pekko-http", @@ -26,11 +24,6 @@ public TapirPekkoHttpServerRouteInstrumentationModule() { "tapir-pekko-http-server-route"); } - @Override - public String getModuleGroup() { - return "pekko-server"; - } - @Override public List typeInstrumentations() { return singletonList(new TapirPathInstrumentation()); From 823a8c6fdbec8be673eecaae448c5937c76d57ce Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 20 May 2026 17:38:21 +0200 Subject: [PATCH 07/21] aws sdk --- .../v1_11/AbstractAwsSdkInstrumentationModule.java | 9 +-------- .../awssdk/v1_11/AwsSdkInstrumentationModule.java | 9 +-------- .../awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java | 5 ----- .../aws/v3_0/SpringAwsSqsInstrumentationModule.java | 5 ----- 4 files changed, 2 insertions(+), 26 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java index c8aa58a1cfd6..62d7913909e0 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AbstractAwsSdkInstrumentationModule.java @@ -12,14 +12,12 @@ import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; -import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import java.util.List; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; // TODO: Copy & paste with only trivial adaptions from v2 -abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +abstract class AbstractAwsSdkInstrumentationModule extends InstrumentationModule { protected AbstractAwsSdkInstrumentationModule(String additionalInstrumentationName) { super("aws-sdk", "aws-sdk-1.11", additionalInstrumentationName); @@ -30,11 +28,6 @@ public boolean isHelperClass(String className) { return className.startsWith("io.opentelemetry.contrib.awsxray."); } - @Override - public String getModuleGroup() { - return "aws-sdk"; - } - @Override public ElementMatcher.Junction classLoaderMatcher() { // added in 1.10.33 diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java index 89a4a6c8f673..048bbdfc41a6 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v1_11/AwsSdkInstrumentationModule.java @@ -10,12 +10,10 @@ 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 AwsSdkInstrumentationModule extends InstrumentationModule - implements ExperimentalInstrumentationModule { +public class AwsSdkInstrumentationModule extends InstrumentationModule { public AwsSdkInstrumentationModule() { super("aws-sdk", "aws-sdk-1.11", "aws-sdk-1.11-core"); } @@ -25,11 +23,6 @@ public boolean isHelperClass(String className) { return className.startsWith("io.opentelemetry.contrib.awsxray."); } - @Override - public String getModuleGroup() { - return "aws-sdk"; - } - @Override public List typeInstrumentations() { return asList( diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java index 646873f066a9..848bc31d0448 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AbstractAwsSdkInstrumentationModule.java @@ -24,11 +24,6 @@ protected AbstractAwsSdkInstrumentationModule(String additionalInstrumentationNa super("aws-sdk", "aws-sdk-2.2", additionalInstrumentationName); } - @Override - public String getModuleGroup() { - return "aws-sdk-v2"; - } - @Override public boolean isHelperClass(String className) { return className.startsWith("io.opentelemetry.contrib.awsxray."); diff --git a/instrumentation/spring/spring-cloud-aws-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/aws/v3_0/SpringAwsSqsInstrumentationModule.java b/instrumentation/spring/spring-cloud-aws-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/aws/v3_0/SpringAwsSqsInstrumentationModule.java index c4831aa8a336..8603ff5f653d 100644 --- a/instrumentation/spring/spring-cloud-aws-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/aws/v3_0/SpringAwsSqsInstrumentationModule.java +++ b/instrumentation/spring/spring-cloud-aws-3.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/spring/cloud/aws/v3_0/SpringAwsSqsInstrumentationModule.java @@ -26,11 +26,6 @@ public boolean isHelperClass(String className) { return className.startsWith("io.opentelemetry.contrib.awsxray."); } - @Override - public String getModuleGroup() { - return "aws-sdk-v2"; - } - @Override public List typeInstrumentations() { return asList( From 1597e6af3fe617fd13d832cc2ca8adcb69619b9b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 12:05:35 +0200 Subject: [PATCH 08/21] add annotation for CL target --- .../internal/ClassLoadingStrategy.java | 32 ++++++++ .../internal/ClassLoadingTarget.java | 33 ++++++++ .../indy/ClassLoadingTargetUtil.java | 55 +++++++++++++ .../indy/ClassLoadingTargetUtilTest.java | 78 +++++++++++++++++++ .../indy/dummies/targetcl/package-info.java | 5 ++ 5 files changed, 203 insertions(+) create mode 100644 javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingStrategy.java create mode 100644 javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingTarget.java create mode 100644 javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java create mode 100644 javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java create mode 100644 javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/package-info.java diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingStrategy.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingStrategy.java new file mode 100644 index 000000000000..7daca65232fc --- /dev/null +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingStrategy.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.extension.instrumentation.internal; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time.
+ * Explicitly defines the classloader that needs to be used to load classes. + * + *
    + *
  • when using inline instrumentation, this is ignored and behavior is equivalent to {@link + * ClassLoadingTarget#INSTRUMENTATION_TARGET} as classes are injected into the instrumented CL + *
  • when using indy instrumentation and not explicitly set, the behavior is equivalent to an + * explicit {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} + *
  • when using indy and classes/packages need to be shared across multiple isolated + * classloaders, the {@link ClassLoadingTarget#INSTRUMENTATION_SHARED} should be used + *
+ */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.TYPE, ElementType.PACKAGE}) +public @interface ClassLoadingStrategy { + + ClassLoadingTarget value() default ClassLoadingTarget.INSTRUMENTATION_ISOLATED; +} diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingTarget.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingTarget.java new file mode 100644 index 000000000000..ed63a24b155e --- /dev/null +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ClassLoadingTarget.java @@ -0,0 +1,33 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.extension.instrumentation.internal; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time.
+ */ +public enum ClassLoadingTarget { + /** + * Class or package will be injected into the instrumented classloader, as if the class was + * present in the application classpath. When referenced directly from instrumentation advice or + * helper classes, it should never be loaded in the instrumentation module or agent classloader. + */ + INSTRUMENTATION_TARGET, + /** + * Class or package will be injected into an isolated instrumentation module classloader when + * using InvokeDynamic instrumentation. This is the default for most instrumentation classes as + * they need to be isolated from the instrumented application.
+ * When using inlined instrumentation, this is equivalent to {@link #INSTRUMENTATION_TARGET}. + */ + INSTRUMENTATION_ISOLATED, + /** + * Class or package will be injected into a shared instrumentation module classloader when using + * InvokeDynamic instrumentation. This should be used for shared libraries classes and classes + * that are used across multiple instrumentation modules.
+ * When using inlined instrumentation, this is equivalent to {@link #INSTRUMENTATION_TARGET}. + */ + INSTRUMENTATION_SHARED +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java new file mode 100644 index 000000000000..6c2e1e8b263e --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.instrumentation.indy; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; +import org.objectweb.asm.ClassReader; +import org.objectweb.asm.Type; +import org.objectweb.asm.tree.AnnotationNode; +import org.objectweb.asm.tree.ClassNode; + +/** Utility to help with class-loading indy modules */ +public class ClassLoadingTargetUtil { + + private static final Type STRATEGY_ANNOTATION = Type.getType(ClassLoadingStrategy.class); + private static final Type TARGET_ENUM = Type.getType(ClassLoadingTarget.class); + + private ClassLoadingTargetUtil() {} + + /** + * Reads the class class-loading strategy from class (or package) bytecode + * + * @param bytecode class or package bytecode + * @return class loading strategy, defaults to {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} + * if annotation is not present. + */ + // package-protected for testing + static ClassLoadingTarget getTarget(byte[] bytecode) { + ClassReader cr = new ClassReader(bytecode); + ClassNode classNode = new ClassNode(); + cr.accept(classNode, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); + if (classNode.visibleAnnotations != null) { + for (AnnotationNode annotation : classNode.visibleAnnotations) { + if (Type.getType(annotation.desc).equals(STRATEGY_ANNOTATION)) { + for (Object value : annotation.values) { + if (value instanceof String[]) { + String[] array = (String[]) value; + if (array.length == 2 && Type.getType(array[0]).equals(TARGET_ENUM)) { + return ClassLoadingTarget.valueOf(array[1]); + } + } + } + } + } + } + return ClassLoadingTarget.INSTRUMENTATION_ISOLATED; + } + + public static ClassLoadingTarget getTarget(String className, ClassLoader classLoader) { + return null; + } +} diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java new file mode 100644 index 000000000000..81ee354efa4c --- /dev/null +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java @@ -0,0 +1,78 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.instrumentation.indy; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; +import java.io.IOException; +import java.io.InputStream; +import net.bytebuddy.utility.StreamDrainer; +import org.junit.jupiter.api.Test; + +public class ClassLoadingTargetUtilTest { + + @Test + void checkTarget() { + // isolated by default when not explicitly set + testStrategy(AClass.class, ClassLoadingTarget.INSTRUMENTATION_ISOLATED); + + // explicitly set at class level + testExplicitAnnotation(BClass.class, ClassLoadingTarget.INSTRUMENTATION_ISOLATED); + testExplicitAnnotation(CClass.class, ClassLoadingTarget.INSTRUMENTATION_SHARED); + testExplicitAnnotation(DClass.class, ClassLoadingTarget.INSTRUMENTATION_TARGET); + + // explicitly set at package level, we test only once as the implementation is same as class + byte[] packageByteCode = + getPackageByteCode( + "io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl"); + assertThat(ClassLoadingTargetUtil.getTarget(packageByteCode)) + .isEqualTo(ClassLoadingTarget.INSTRUMENTATION_SHARED); + } + + private void testStrategy(Class type, ClassLoadingTarget expected) { + byte[] bytecode = getClassByteCode(type); + assertThat(ClassLoadingTargetUtil.getTarget(bytecode)).isEqualTo(expected); + } + + private void testExplicitAnnotation(Class type, ClassLoadingTarget expected) { + ClassLoadingStrategy annotation = type.getAnnotation(ClassLoadingStrategy.class); + assertThat(annotation).isNotNull(); + assertThat(annotation.value()).isEqualTo(expected); + testStrategy(type, expected); + } + + private byte[] getClassByteCode(Class type) { + String classFileName = type.getName().replace('.', '/') + ".class"; + return getByteCode(classFileName); + } + + private byte[] getByteCode(String resourcePath) { + try (InputStream input = getClass().getClassLoader().getResourceAsStream(resourcePath)) { + assertThat(input).isNotNull(); + return StreamDrainer.DEFAULT.drain(input); + } catch (IOException e) { + throw new IllegalStateException(e); + } + } + + private byte[] getPackageByteCode(String packageName) { + String packageFileName = packageName.replace('.', '/') + "/package-info.class"; + return getByteCode(packageFileName); + } + + private static class AClass {} + + @ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_ISOLATED) + private static class BClass {} + + @ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) + private static class CClass {} + + @ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_TARGET) + private static class DClass {} +} diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/package-info.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/package-info.java new file mode 100644 index 000000000000..502ff1ab6afe --- /dev/null +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; From 3187a96dc29d5ae5913db190913df9881a54f4b1 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 13:51:00 +0200 Subject: [PATCH 09/21] add fallback + improve API --- .../indy/ClassLoadingTargetUtil.java | 59 ++++++++++++++++++- .../indy/ClassLoadingTargetUtilTest.java | 57 +++++++++--------- .../indy/dummies/targetcl/DummyInherit.java | 8 +++ .../indy/dummies/targetcl/DummyOverride.java | 12 ++++ 4 files changed, 104 insertions(+), 32 deletions(-) create mode 100644 javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyInherit.java create mode 100644 javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyOverride.java diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java index 6c2e1e8b263e..c883c32f05c5 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java @@ -7,6 +7,10 @@ import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; +import java.io.IOException; +import java.io.InputStream; +import javax.annotation.Nullable; +import net.bytebuddy.utility.StreamDrainer; import org.objectweb.asm.ClassReader; import org.objectweb.asm.Type; import org.objectweb.asm.tree.AnnotationNode; @@ -28,7 +32,8 @@ private ClassLoadingTargetUtil() {} * if annotation is not present. */ // package-protected for testing - static ClassLoadingTarget getTarget(byte[] bytecode) { + @Nullable + private static ClassLoadingTarget getTarget(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); ClassNode classNode = new ClassNode(); cr.accept(classNode, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); @@ -46,10 +51,58 @@ static ClassLoadingTarget getTarget(byte[] bytecode) { } } } + return null; + } + + /** + * Get class target with fallback on package target. + * + * @param className class name + * @param classLoader class loader to load class/package bytecode + * @return class loading target, defaults to {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} + * if annotation is not present + */ + public static ClassLoadingTarget getClassTarget(String className, ClassLoader classLoader) { + ClassLoadingTarget classTarget = classTarget(className, classLoader); + if (null != classTarget) { + return classTarget; + } + String packageName = className.substring(0, className.lastIndexOf('.')); + ClassLoadingTarget packageTarget = packageTarget(packageName, classLoader); + if (packageTarget != null) { + return packageTarget; + } return ClassLoadingTarget.INSTRUMENTATION_ISOLATED; } - public static ClassLoadingTarget getTarget(String className, ClassLoader classLoader) { - return null; + // package-private for testing + @Nullable + static ClassLoadingTarget packageTarget(String packageName, ClassLoader classLoader) { + String packagePath = packageName.replace(".", "/") + "/package-info.class"; + byte[] byteCode = getByteCode(packagePath, classLoader); + return byteCode == null ? null : getTarget(byteCode); + } + + // package-private for testing + @Nullable + static ClassLoadingTarget classTarget(String className, ClassLoader classLoader) { + String classPath = className.replace(".", "/") + ".class"; + byte[] byteCode = getByteCode(classPath, classLoader); + if (byteCode == null) { + throw new IllegalArgumentException("missing class: " + classPath); + } + return getTarget(byteCode); + } + + @Nullable + private static byte[] getByteCode(String resourcePath, ClassLoader classLoader) { + try (InputStream input = classLoader.getResourceAsStream(resourcePath)) { + if (input == null) { + return null; + } + return StreamDrainer.DEFAULT.drain(input); + } catch (IOException e) { + throw new IllegalStateException(e); + } } } diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java index 81ee354efa4c..4b7f34731dad 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java @@ -6,12 +6,12 @@ package io.opentelemetry.javaagent.tooling.instrumentation.indy; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; -import java.io.IOException; -import java.io.InputStream; -import net.bytebuddy.utility.StreamDrainer; +import io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl.DummyInherit; +import io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl.DummyOverride; import org.junit.jupiter.api.Test; public class ClassLoadingTargetUtilTest { @@ -26,17 +26,35 @@ void checkTarget() { testExplicitAnnotation(CClass.class, ClassLoadingTarget.INSTRUMENTATION_SHARED); testExplicitAnnotation(DClass.class, ClassLoadingTarget.INSTRUMENTATION_TARGET); - // explicitly set at package level, we test only once as the implementation is same as class - byte[] packageByteCode = - getPackageByteCode( - "io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl"); - assertThat(ClassLoadingTargetUtil.getTarget(packageByteCode)) + // explicitly set at package level + String packageName = "io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl"; + assertThat(ClassLoadingTargetUtil.packageTarget(packageName, getClass().getClassLoader())) .isEqualTo(ClassLoadingTarget.INSTRUMENTATION_SHARED); + + // package defines values inherited on class + assertThat(DummyInherit.class.getAnnotation(ClassLoadingStrategy.class)) + .describedAs("no annotation is present on class") + .isNull(); + assertThat( + ClassLoadingTargetUtil.getClassTarget( + DummyInherit.class.getName(), getClass().getClassLoader())) + .describedAs("package annotation is applied for class lookup") + .isEqualTo(ClassLoadingTarget.INSTRUMENTATION_SHARED); + + // class lookup has priority over package when defined on both + testExplicitAnnotation(DummyOverride.class, ClassLoadingTarget.INSTRUMENTATION_ISOLATED); + + // should defend against non-existing class + assertThatThrownBy( + () -> + ClassLoadingTargetUtil.getClassTarget( + "this.class.does.not.Exists", getClass().getClassLoader())) + .isInstanceOf(IllegalArgumentException.class); } private void testStrategy(Class type, ClassLoadingTarget expected) { - byte[] bytecode = getClassByteCode(type); - assertThat(ClassLoadingTargetUtil.getTarget(bytecode)).isEqualTo(expected); + assertThat(ClassLoadingTargetUtil.getClassTarget(type.getName(), getClass().getClassLoader())) + .isEqualTo(expected); } private void testExplicitAnnotation(Class type, ClassLoadingTarget expected) { @@ -46,25 +64,6 @@ private void testExplicitAnnotation(Class type, ClassLoadingTarget expected) testStrategy(type, expected); } - private byte[] getClassByteCode(Class type) { - String classFileName = type.getName().replace('.', '/') + ".class"; - return getByteCode(classFileName); - } - - private byte[] getByteCode(String resourcePath) { - try (InputStream input = getClass().getClassLoader().getResourceAsStream(resourcePath)) { - assertThat(input).isNotNull(); - return StreamDrainer.DEFAULT.drain(input); - } catch (IOException e) { - throw new IllegalStateException(e); - } - } - - private byte[] getPackageByteCode(String packageName) { - String packageFileName = packageName.replace('.', '/') + "/package-info.class"; - return getByteCode(packageFileName); - } - private static class AClass {} @ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_ISOLATED) diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyInherit.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyInherit.java new file mode 100644 index 000000000000..0dcbfa8d6963 --- /dev/null +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyInherit.java @@ -0,0 +1,8 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl; + +public class DummyInherit {} diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyOverride.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyOverride.java new file mode 100644 index 000000000000..dabf14e99e8c --- /dev/null +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/dummies/targetcl/DummyOverride.java @@ -0,0 +1,12 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.instrumentation.indy.dummies.targetcl; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; + +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_ISOLATED) +public class DummyOverride {} From ac797231fa124e8ea4d1225709c04e9fa8f7deda Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 14:17:20 +0200 Subject: [PATCH 10/21] remove bogus comment --- .../tooling/instrumentation/indy/ClassLoadingTargetUtil.java | 1 - 1 file changed, 1 deletion(-) diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java index c883c32f05c5..09c0a24d95ec 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java @@ -31,7 +31,6 @@ private ClassLoadingTargetUtil() {} * @return class loading strategy, defaults to {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} * if annotation is not present. */ - // package-protected for testing @Nullable private static ClassLoadingTarget getTarget(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); From ea776a36c6a2a530b7b7301535f150028f29edc2 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 14:42:55 +0200 Subject: [PATCH 11/21] make it work for hibernate-3.3 --- .../hibernate/common/v3_3/package-info.java | 5 + .../indy/ClassLoadingTargetUtil.java | 28 ++-- .../InstrumentationModuleClassLoader.java | 144 +++++++----------- 3 files changed, 70 insertions(+), 107 deletions(-) create mode 100644 instrumentation/hibernate/hibernate-common-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/common/v3_3/package-info.java diff --git a/instrumentation/hibernate/hibernate-common-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/common/v3_3/package-info.java b/instrumentation/hibernate/hibernate-common-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/common/v3_3/package-info.java new file mode 100644 index 000000000000..80e4091e587d --- /dev/null +++ b/instrumentation/hibernate/hibernate-common-3.3/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/hibernate/common/v3_3/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.hibernate.common.v3_3; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java index c883c32f05c5..e246897705b5 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java @@ -31,9 +31,8 @@ private ClassLoadingTargetUtil() {} * @return class loading strategy, defaults to {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} * if annotation is not present. */ - // package-protected for testing @Nullable - private static ClassLoadingTarget getTarget(byte[] bytecode) { + static ClassLoadingTarget getTarget(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); ClassNode classNode = new ClassNode(); cr.accept(classNode, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); @@ -59,11 +58,17 @@ private static ClassLoadingTarget getTarget(byte[] bytecode) { * * @param className class name * @param classLoader class loader to load class/package bytecode - * @return class loading target, defaults to {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} - * if annotation is not present + * @return class loading target, {@literal null} if class is not present in class loader or target + * is not defined */ + @Nullable public static ClassLoadingTarget getClassTarget(String className, ClassLoader classLoader) { - ClassLoadingTarget classTarget = classTarget(className, classLoader); + String classPath = className.replace(".", "/") + ".class"; + byte[] byteCode = getByteCode(classPath, classLoader); + if (byteCode == null) { + return null; + } + ClassLoadingTarget classTarget = getTarget(byteCode); if (null != classTarget) { return classTarget; } @@ -72,7 +77,7 @@ public static ClassLoadingTarget getClassTarget(String className, ClassLoader cl if (packageTarget != null) { return packageTarget; } - return ClassLoadingTarget.INSTRUMENTATION_ISOLATED; + return null; } // package-private for testing @@ -83,17 +88,6 @@ static ClassLoadingTarget packageTarget(String packageName, ClassLoader classLoa return byteCode == null ? null : getTarget(byteCode); } - // package-private for testing - @Nullable - static ClassLoadingTarget classTarget(String className, ClassLoader classLoader) { - String classPath = className.replace(".", "/") + ".class"; - byte[] byteCode = getByteCode(classPath, classLoader); - if (byteCode == null) { - throw new IllegalArgumentException("missing class: " + classPath); - } - return getTarget(byteCode); - } - @Nullable private static byte[] getByteCode(String resourcePath, ClassLoader classLoader) { try (InputStream input = classLoader.getResourceAsStream(resourcePath)) { 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 3eb1c0c0162d..fb78c2257f93 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 @@ -5,15 +5,14 @@ package io.opentelemetry.javaagent.tooling.instrumentation.indy; -import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; import static java.util.Collections.singletonMap; -import static java.util.stream.Collectors.toMap; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.tooling.BytecodeWithUrl; import io.opentelemetry.javaagent.tooling.HelperInjector; @@ -88,8 +87,6 @@ public class InstrumentationModuleClassLoader extends ClassLoader { */ private final ElementMatcher agentClassNamesMatcher; - private final ElementMatcher agentCommonClassNamesMatcher; - /** * 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 @@ -126,7 +123,6 @@ public InstrumentationModuleClassLoader( this.agentClassNamesMatcher = classesToLoadFromAgentOrExtensionCl; this.hiddenAgentPackages = Collections.newSetFromMap(new ConcurrentHashMap<>()); this.commonCl = commonCl; - this.agentCommonClassNamesMatcher = classesToLoadFromCommonCl; } /** @@ -168,14 +164,31 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC if (!installedModules.add(module)) { return; } - Map classesToInject = - getClassesToInject(module).stream() - .collect( - toMap( - className -> className, - className -> BytecodeWithUrl.create(className, agentOrExtensionCl))); + + Map commonClassesToInject = new HashMap<>(); + Map classesToInject = new HashMap<>(); + + getClassesToInject(module) + .forEach( + name -> { + + // TODO: this makes reading bytecode twice, we should find ways to optimize this, for + // example by + // making BytecodeWithUrl trigger the target detection + ClassLoadingTarget target = + ClassLoadingTargetUtil.getClassTarget(name, agentOrExtensionCl); + BytecodeWithUrl bytecodeWithUrl = BytecodeWithUrl.create(name, agentOrExtensionCl); + if (target == ClassLoadingTarget.INSTRUMENTATION_SHARED) { + commonClassesToInject.put(name, bytecodeWithUrl); + } else { + classesToInject.put(name, bytecodeWithUrl); + } + }); installInjectedClasses(classesToInject); + if (!commonClassesToInject.isEmpty()) { + installInjectedClasses(commonClassesToInject); + } if (module instanceof ExperimentalInstrumentationModule) { ExperimentalInstrumentationModule experimentalModule = @@ -199,67 +212,29 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC } } - /** - * Determines if injected class should be loaded in a shared class loader or not. - * - * @param className class name - * @return true if class should be loaded in shared class loader, false otherwise (default) - */ - boolean useCommonClassLoader(String className) { - if (agentCommonClassNamesMatcher.matches(className)) { - return true; - } - // TODO: we can replace this name-based heuristic with proper annotation - // or we can also make the instrumentation modules provide a dedicated API to provide a - // list/pattern - for (String part : commonPackageHeuristic) { - // instrumentation, not shaded - String normalized = normalize(part, "io.opentelemetry.javaagent.instrumentation."); - // library, not shaded - normalized = normalize(normalized, "io.opentelemetry.instrumentation."); - if (className.contains(normalized + ".")) { - return true; - } - } - return false; - } - - private static String normalize(String value, String prefix) { - if (value.startsWith(prefix)) { - return value.substring(prefix.length()); - } - return value; - } - - // TODO temporary heuristic to validate the idea that a single shared CL is valid - // if this approach is valid, then we should probably find a better way, for example by using an - // annotation in the packages themselves to indicate they should be shared. - private static final Set commonPackageHeuristic = - new HashSet<>( - asList( - "io.opentelemetry.javaagent.instrumentation.hibernate.common.v3_3", - "io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.common.v5_0", - "io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal", - "io.opentelemetry.instrumentation.netty.common.internal", - "io.opentelemetry.javaagent.instrumentation.netty.common.v4_0", - "io.opentelemetry.instrumentation.netty.common.v4_0.internal", - "io.opentelemetry.instrumentation.netty.v4_1.internal", - "io.opentelemetry.javaagent.instrumentation.couchbase.common.v2_0", - // for pekko, we should refactor to help simplify this - "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0", - "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.route", - "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.server", - "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.tapir", - // for akka, we should refactor to help simplify this - "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0", - "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server", - "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server.route", - // aws sdk 1.x library - "io.opentelemetry.instrumentation.awssdk.v1_11", - // aws sdk 2.x library internals: refactor needed to avoid relying on internals - "io.opentelemetry.instrumentation.awssdk.v2_2.internal", - // aws sdk 2.x instrumentation - "io.opentelemetry.javaagent.instrumentation.awssdk.v2_2")); + // "io.opentelemetry.javaagent.instrumentation.hibernate.common.v3_3", + // "io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.common.v5_0", + // "io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal", + // "io.opentelemetry.instrumentation.netty.common.internal", + // "io.opentelemetry.javaagent.instrumentation.netty.common.v4_0", + // "io.opentelemetry.instrumentation.netty.common.v4_0.internal", + // "io.opentelemetry.instrumentation.netty.v4_1.internal", + // "io.opentelemetry.javaagent.instrumentation.couchbase.common.v2_0", + // // for pekko, we should refactor to help simplify this + // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0", + // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.route", + // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.server", + // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.tapir", + // // for akka, we should refactor to help simplify this + // "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0", + // "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server", + // "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server.route", + // // aws sdk 1.x library + // "io.opentelemetry.instrumentation.awssdk.v1_11", + // // aws sdk 2.x library internals: refactor needed to avoid relying on internals + // "io.opentelemetry.instrumentation.awssdk.v2_2.internal", + // // aws sdk 2.x instrumentation + // "io.opentelemetry.javaagent.instrumentation.awssdk.v2_2" public synchronized boolean hasModuleInstalled(InstrumentationModule module) { return installedModules.contains(module); @@ -273,22 +248,7 @@ public synchronized boolean hasModuleInstalled(InstrumentationModule module) { */ // Visible for testing synchronized void installInjectedClasses(Map classesToInject) { - if (commonCl == null) { - classesToInject.forEach(additionalInjectedClasses::putIfAbsent); - } else { - Map common = new HashMap<>(); - Map injected = new HashMap<>(); - classesToInject.forEach( - (className, bytecode) -> { - if (useCommonClassLoader(className)) { - common.putIfAbsent(className, bytecode); - } else { - injected.putIfAbsent(className, bytecode); - } - }); - commonCl.installInjectedClasses(common); - injected.forEach(additionalInjectedClasses::putIfAbsent); - } + classesToInject.forEach(additionalInjectedClasses::putIfAbsent); } private static Set getClassesToInject(InstrumentationModule module) { @@ -339,8 +299,12 @@ protected Class loadClass(String name, boolean resolve) throws ClassNotFoundE Class result = findLoadedClass(name); // Common classes delegation is first to ensure they are only loaded in the common CL - if (result == null && commonCl != null && useCommonClassLoader(name)) { - result = tryLoad(commonCl, name); + if (result == null && commonCl != null) { + ClassLoadingTarget classTarget = + ClassLoadingTargetUtil.getClassTarget(name, agentOrExtensionCl); + if (classTarget == ClassLoadingTarget.INSTRUMENTATION_SHARED) { + result = tryLoad(commonCl, name); + } } // Injected class are loaded BEFORE a parent lookup From dcae0f0cc6da680b95e9d732fa8412daa1023283 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 15:03:57 +0200 Subject: [PATCH 12/21] fix things --- .../indy/InstrumentationModuleClassLoader.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) 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 fb78c2257f93..eb59f9a165f7 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 @@ -168,10 +168,10 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC Map commonClassesToInject = new HashMap<>(); Map classesToInject = new HashMap<>(); + getClassesToInject(module) .forEach( name -> { - // TODO: this makes reading bytecode twice, we should find ways to optimize this, for // example by // making BytecodeWithUrl trigger the target detection @@ -186,7 +186,10 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC }); installInjectedClasses(classesToInject); - if (!commonClassesToInject.isEmpty()) { + if (commonCl != null) { + commonCl.installInjectedClasses(commonClassesToInject); + } else { + // when there is no common CL, default to load everything in module CL installInjectedClasses(commonClassesToInject); } @@ -212,9 +215,9 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC } } - // "io.opentelemetry.javaagent.instrumentation.hibernate.common.v3_3", // "io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.common.v5_0", // "io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal", + // "io.opentelemetry.instrumentation.netty.common.internal", // "io.opentelemetry.javaagent.instrumentation.netty.common.v4_0", // "io.opentelemetry.instrumentation.netty.common.v4_0.internal", From 2204f47281d06d0e8081e3a6ac82ca5a50f23dff Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 15:04:25 +0200 Subject: [PATCH 13/21] elasticsearch --- .../v5_0/ElasticsearchRestJavaagentInstrumenterFactory.java | 3 +++ .../elasticsearch-rest-common-5.0/library/build.gradle.kts | 2 ++ .../rest/common/v5_0/internal/package-info.java | 5 +++++ 3 files changed, 10 insertions(+) create mode 100644 instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/src/main/java/io/opentelemetry/instrumentation/elasticsearch/rest/common/v5_0/internal/package-info.java diff --git a/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/common/v5_0/ElasticsearchRestJavaagentInstrumenterFactory.java b/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/common/v5_0/ElasticsearchRestJavaagentInstrumenterFactory.java index 7c4ecf74f213..a2f9d3c645a9 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/common/v5_0/ElasticsearchRestJavaagentInstrumenterFactory.java +++ b/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/elasticsearch/rest/common/v5_0/ElasticsearchRestJavaagentInstrumenterFactory.java @@ -13,9 +13,12 @@ import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchRestInstrumenterFactory; import io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal.ElasticsearchRestRequest; import io.opentelemetry.javaagent.bootstrap.internal.AgentCommonConfig; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; import java.util.function.Function; import org.elasticsearch.client.Response; +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) public class ElasticsearchRestJavaagentInstrumenterFactory { private static final boolean CAPTURE_SEARCH_QUERY = diff --git a/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/build.gradle.kts b/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/build.gradle.kts index 667d2ae3ae34..dca3f9d866d3 100644 --- a/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/build.gradle.kts +++ b/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/build.gradle.kts @@ -7,4 +7,6 @@ dependencies { compileOnly("com.google.auto.value:auto-value-annotations") annotationProcessor("com.google.auto.value:auto-value") + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") } diff --git a/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/src/main/java/io/opentelemetry/instrumentation/elasticsearch/rest/common/v5_0/internal/package-info.java b/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/src/main/java/io/opentelemetry/instrumentation/elasticsearch/rest/common/v5_0/internal/package-info.java new file mode 100644 index 000000000000..a14449a8658c --- /dev/null +++ b/instrumentation/elasticsearch/elasticsearch-rest-common-5.0/library/src/main/java/io/opentelemetry/instrumentation/elasticsearch/rest/common/v5_0/internal/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; From 36b815c4141280a5bf038966e98caeee087389e8 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 15:21:22 +0200 Subject: [PATCH 14/21] netty --- .../netty/netty-4.1/library/build.gradle.kts | 2 ++ .../netty/v4_1/internal/package-info.java | 5 ++++ .../netty/common/v4_0/package-info.java | 5 ++++ .../netty-common-4.0/library/build.gradle.kts | 2 ++ .../common/v4_0/internal/package-info.java | 5 ++++ .../netty-common/library/build.gradle.kts | 2 ++ .../netty/common/internal/package-info.java | 5 ++++ .../indy/ClassLoadingTargetUtil.java | 27 +++++++++++-------- .../InstrumentationModuleClassLoader.java | 8 ------ 9 files changed, 42 insertions(+), 19 deletions(-) create mode 100644 instrumentation/netty/netty-4.1/library/src/main/java/io/opentelemetry/instrumentation/netty/v4_1/internal/package-info.java create mode 100644 instrumentation/netty/netty-common-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/v4_0/package-info.java create mode 100644 instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/package-info.java create mode 100644 instrumentation/netty/netty-common/library/src/main/java/io/opentelemetry/instrumentation/netty/common/internal/package-info.java diff --git a/instrumentation/netty/netty-4.1/library/build.gradle.kts b/instrumentation/netty/netty-4.1/library/build.gradle.kts index 5c06edc56238..111dd5b663cf 100644 --- a/instrumentation/netty/netty-4.1/library/build.gradle.kts +++ b/instrumentation/netty/netty-4.1/library/build.gradle.kts @@ -11,6 +11,8 @@ dependencies { annotationProcessor("com.google.auto.value:auto-value") testImplementation(project(":instrumentation:netty:netty-4.1:testing")) + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") } tasks { diff --git a/instrumentation/netty/netty-4.1/library/src/main/java/io/opentelemetry/instrumentation/netty/v4_1/internal/package-info.java b/instrumentation/netty/netty-4.1/library/src/main/java/io/opentelemetry/instrumentation/netty/v4_1/internal/package-info.java new file mode 100644 index 000000000000..a283cd69798b --- /dev/null +++ b/instrumentation/netty/netty-4.1/library/src/main/java/io/opentelemetry/instrumentation/netty/v4_1/internal/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.netty.v4_1.internal; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/netty/netty-common-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/v4_0/package-info.java b/instrumentation/netty/netty-common-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/v4_0/package-info.java new file mode 100644 index 000000000000..a4fb05175467 --- /dev/null +++ b/instrumentation/netty/netty-common-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/netty/common/v4_0/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.netty.common.v4_0; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/netty/netty-common-4.0/library/build.gradle.kts b/instrumentation/netty/netty-common-4.0/library/build.gradle.kts index feefae65cfe1..c6a6bd0cb3eb 100644 --- a/instrumentation/netty/netty-common-4.0/library/build.gradle.kts +++ b/instrumentation/netty/netty-common-4.0/library/build.gradle.kts @@ -9,4 +9,6 @@ dependencies { implementation(project(":instrumentation:netty:netty-common:library")) compileOnly("io.netty:netty-codec-http:4.0.0.Final") + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") } diff --git a/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/package-info.java b/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/package-info.java new file mode 100644 index 000000000000..a5bc9253eec1 --- /dev/null +++ b/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.netty.common.v4_0.internal; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/netty/netty-common/library/build.gradle.kts b/instrumentation/netty/netty-common/library/build.gradle.kts index 8f6b7c537697..3d17d445fe6a 100644 --- a/instrumentation/netty/netty-common/library/build.gradle.kts +++ b/instrumentation/netty/netty-common/library/build.gradle.kts @@ -5,4 +5,6 @@ plugins { dependencies { compileOnly("com.google.auto.value:auto-value-annotations") annotationProcessor("com.google.auto.value:auto-value") + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") } diff --git a/instrumentation/netty/netty-common/library/src/main/java/io/opentelemetry/instrumentation/netty/common/internal/package-info.java b/instrumentation/netty/netty-common/library/src/main/java/io/opentelemetry/instrumentation/netty/common/internal/package-info.java new file mode 100644 index 000000000000..6ed2a496f0a0 --- /dev/null +++ b/instrumentation/netty/netty-common/library/src/main/java/io/opentelemetry/instrumentation/netty/common/internal/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.netty.common.internal; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java index e246897705b5..09c0a24d95ec 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java @@ -32,7 +32,7 @@ private ClassLoadingTargetUtil() {} * if annotation is not present. */ @Nullable - static ClassLoadingTarget getTarget(byte[] bytecode) { + private static ClassLoadingTarget getTarget(byte[] bytecode) { ClassReader cr = new ClassReader(bytecode); ClassNode classNode = new ClassNode(); cr.accept(classNode, ClassReader.SKIP_FRAMES | ClassReader.SKIP_DEBUG); @@ -58,17 +58,11 @@ static ClassLoadingTarget getTarget(byte[] bytecode) { * * @param className class name * @param classLoader class loader to load class/package bytecode - * @return class loading target, {@literal null} if class is not present in class loader or target - * is not defined + * @return class loading target, defaults to {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} + * if annotation is not present */ - @Nullable public static ClassLoadingTarget getClassTarget(String className, ClassLoader classLoader) { - String classPath = className.replace(".", "/") + ".class"; - byte[] byteCode = getByteCode(classPath, classLoader); - if (byteCode == null) { - return null; - } - ClassLoadingTarget classTarget = getTarget(byteCode); + ClassLoadingTarget classTarget = classTarget(className, classLoader); if (null != classTarget) { return classTarget; } @@ -77,7 +71,7 @@ public static ClassLoadingTarget getClassTarget(String className, ClassLoader cl if (packageTarget != null) { return packageTarget; } - return null; + return ClassLoadingTarget.INSTRUMENTATION_ISOLATED; } // package-private for testing @@ -88,6 +82,17 @@ static ClassLoadingTarget packageTarget(String packageName, ClassLoader classLoa return byteCode == null ? null : getTarget(byteCode); } + // package-private for testing + @Nullable + static ClassLoadingTarget classTarget(String className, ClassLoader classLoader) { + String classPath = className.replace(".", "/") + ".class"; + byte[] byteCode = getByteCode(classPath, classLoader); + if (byteCode == null) { + throw new IllegalArgumentException("missing class: " + classPath); + } + return getTarget(byteCode); + } + @Nullable private static byte[] getByteCode(String resourcePath, ClassLoader classLoader) { try (InputStream input = classLoader.getResourceAsStream(resourcePath)) { 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 eb59f9a165f7..3ea88cdaa1a5 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 @@ -168,7 +168,6 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC Map commonClassesToInject = new HashMap<>(); Map classesToInject = new HashMap<>(); - getClassesToInject(module) .forEach( name -> { @@ -215,13 +214,6 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC } } - // "io.opentelemetry.javaagent.instrumentation.elasticsearch.rest.common.v5_0", - // "io.opentelemetry.instrumentation.elasticsearch.rest.common.v5_0.internal", - - // "io.opentelemetry.instrumentation.netty.common.internal", - // "io.opentelemetry.javaagent.instrumentation.netty.common.v4_0", - // "io.opentelemetry.instrumentation.netty.common.v4_0.internal", - // "io.opentelemetry.instrumentation.netty.v4_1.internal", // "io.opentelemetry.javaagent.instrumentation.couchbase.common.v2_0", // // for pekko, we should refactor to help simplify this // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0", From c9932ccb3f04b349a6e4c6dad9d71f17a69ccef7 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 15:38:18 +0200 Subject: [PATCH 15/21] better deal with missing classes --- .../indy/ClassLoadingTargetUtil.java | 16 +++++++++++----- .../indy/ClassLoadingTargetUtilTest.java | 16 +++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java index 09c0a24d95ec..6b818aa51f07 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtil.java @@ -58,11 +58,17 @@ private static ClassLoadingTarget getTarget(byte[] bytecode) { * * @param className class name * @param classLoader class loader to load class/package bytecode - * @return class loading target, defaults to {@link ClassLoadingTarget#INSTRUMENTATION_ISOLATED} - * if annotation is not present + * @return class loading target, or {@literal null} of no annotation is present */ + @Nullable public static ClassLoadingTarget getClassTarget(String className, ClassLoader classLoader) { - ClassLoadingTarget classTarget = classTarget(className, classLoader); + String classPath = className.replace(".", "/") + ".class"; + byte[] byteCode = getByteCode(classPath, classLoader); + if (byteCode == null) { + // class is not present in this CL + return null; + } + ClassLoadingTarget classTarget = getTarget(byteCode); if (null != classTarget) { return classTarget; } @@ -71,7 +77,7 @@ public static ClassLoadingTarget getClassTarget(String className, ClassLoader cl if (packageTarget != null) { return packageTarget; } - return ClassLoadingTarget.INSTRUMENTATION_ISOLATED; + return null; } // package-private for testing @@ -88,7 +94,7 @@ static ClassLoadingTarget classTarget(String className, ClassLoader classLoader) String classPath = className.replace(".", "/") + ".class"; byte[] byteCode = getByteCode(classPath, classLoader); if (byteCode == null) { - throw new IllegalArgumentException("missing class: " + classPath); + return null; } return getTarget(byteCode); } diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java index 4b7f34731dad..d3c7c7007028 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/ClassLoadingTargetUtilTest.java @@ -6,7 +6,6 @@ package io.opentelemetry.javaagent.tooling.instrumentation.indy; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; @@ -18,8 +17,8 @@ public class ClassLoadingTargetUtilTest { @Test void checkTarget() { - // isolated by default when not explicitly set - testStrategy(AClass.class, ClassLoadingTarget.INSTRUMENTATION_ISOLATED); + // not defined at class nor package level + testStrategy(AClass.class, null); // explicitly set at class level testExplicitAnnotation(BClass.class, ClassLoadingTarget.INSTRUMENTATION_ISOLATED); @@ -31,7 +30,7 @@ void checkTarget() { assertThat(ClassLoadingTargetUtil.packageTarget(packageName, getClass().getClassLoader())) .isEqualTo(ClassLoadingTarget.INSTRUMENTATION_SHARED); - // package defines values inherited on class + // package defined values inherited on class assertThat(DummyInherit.class.getAnnotation(ClassLoadingStrategy.class)) .describedAs("no annotation is present on class") .isNull(); @@ -45,11 +44,10 @@ void checkTarget() { testExplicitAnnotation(DummyOverride.class, ClassLoadingTarget.INSTRUMENTATION_ISOLATED); // should defend against non-existing class - assertThatThrownBy( - () -> - ClassLoadingTargetUtil.getClassTarget( - "this.class.does.not.Exists", getClass().getClassLoader())) - .isInstanceOf(IllegalArgumentException.class); + assertThat( + ClassLoadingTargetUtil.getClassTarget( + "this.class.does.not.Exists", getClass().getClassLoader())) + .isNull(); } private void testStrategy(Class type, ClassLoadingTarget expected) { From e766cb3edff531c865cbc23a1232c0b73cc3f73b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 15:44:03 +0200 Subject: [PATCH 16/21] couchbase --- .../instrumentation/couchbase/common/v2_0/package-info.java | 5 +++++ .../indy/InstrumentationModuleClassLoader.java | 1 - 2 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 instrumentation/couchbase/couchbase-common-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/common/v2_0/package-info.java diff --git a/instrumentation/couchbase/couchbase-common-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/common/v2_0/package-info.java b/instrumentation/couchbase/couchbase-common-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/common/v2_0/package-info.java new file mode 100644 index 000000000000..9f7e9d7912ad --- /dev/null +++ b/instrumentation/couchbase/couchbase-common-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/couchbase/common/v2_0/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.couchbase.common.v2_0; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; 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 3ea88cdaa1a5..1ff468b1f3c7 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 @@ -214,7 +214,6 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC } } - // "io.opentelemetry.javaagent.instrumentation.couchbase.common.v2_0", // // for pekko, we should refactor to help simplify this // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0", // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.route", From 0bcb87f8eb249b60bef645b3ab77e5e078122fa2 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 15:45:56 +0200 Subject: [PATCH 17/21] pekko --- .../instrumentation/pekkohttp/v1_0/client/package-info.java | 5 +++++ .../instrumentation/pekkohttp/v1_0/package-info.java | 5 +++++ .../instrumentation/pekkohttp/v1_0/server/package-info.java | 5 +++++ .../pekkohttp/v1_0/server/tapir/package-info.java | 5 +++++ 4 files changed, 20 insertions(+) create mode 100644 instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/client/package-info.java create mode 100644 instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/package-info.java create mode 100644 instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/package-info.java create mode 100644 instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/package-info.java diff --git a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/client/package-info.java b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/client/package-info.java new file mode 100644 index 000000000000..333793762f3d --- /dev/null +++ b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/client/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.client; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/package-info.java b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/package-info.java new file mode 100644 index 000000000000..2cfe80d09d64 --- /dev/null +++ b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/package-info.java b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/package-info.java new file mode 100644 index 000000000000..2383aa6c2701 --- /dev/null +++ b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.server; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/package-info.java b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/package-info.java new file mode 100644 index 000000000000..911c42c41414 --- /dev/null +++ b/instrumentation/pekko/pekko-http-1.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/pekkohttp/v1_0/server/tapir/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.server.tapir; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; From 1e1511043aa35a70510e1731fd7d389db4279267 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 15:56:25 +0200 Subject: [PATCH 18/21] finish migration --- .../akkahttp/v10_0/package-info.java | 5 +++++ .../akkahttp/v10_0/server/package-info.java | 5 +++++ .../v10_0/server/route/package-info.java | 5 +++++ .../aws-sdk-1.11/library/build.gradle.kts | 2 ++ .../awssdk/v1_11/package-info.java | 4 ++++ .../awssdk/v2_2/package-info.java | 5 +++++ .../aws-sdk/aws-sdk-2.2/library/build.gradle.kts | 2 ++ .../awssdk/v2_2/internal/package-info.java | 5 +++++ .../indy/InstrumentationModuleClassLoader.java | 16 ---------------- 9 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/package-info.java create mode 100644 instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/package-info.java create mode 100644 instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/package-info.java create mode 100644 instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java create mode 100644 instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/package-info.java create mode 100644 instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/package-info.java diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/package-info.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/package-info.java new file mode 100644 index 000000000000..367efb19a412 --- /dev/null +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/package-info.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/package-info.java new file mode 100644 index 000000000000..dea939f311dd --- /dev/null +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/package-info.java b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/package-info.java new file mode 100644 index 000000000000..1a01021a7326 --- /dev/null +++ b/instrumentation/akka/akka-http-10.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/akkahttp/v10_0/server/route/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server.route; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library/build.gradle.kts b/instrumentation/aws-sdk/aws-sdk-1.11/library/build.gradle.kts index a383ff0fa7fc..6e8772df19f3 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library/build.gradle.kts +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library/build.gradle.kts @@ -19,6 +19,8 @@ dependencies { testLibrary("com.amazonaws:aws-java-sdk-s3:1.11.106") testLibrary("com.amazonaws:aws-java-sdk-sns:1.11.106") testLibrary("com.amazonaws:aws-java-sdk-stepfunctions:1.11.106") + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") } if (!otelProps.testLatestDeps) { diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java b/instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java new file mode 100644 index 000000000000..e9f88de4fc44 --- /dev/null +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java @@ -0,0 +1,4 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.awssdk.v1_11; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/package-info.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/package-info.java new file mode 100644 index 000000000000..a36c2811a8aa --- /dev/null +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.javaagent.instrumentation.awssdk.v2_2; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts b/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts index f4ff61e2af88..40c72833063f 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/build.gradle.kts @@ -30,6 +30,8 @@ dependencies { testLibrary("software.amazon.awssdk:secretsmanager:2.2.0") testLibrary("software.amazon.awssdk:ses:2.2.0") testLibrary("software.amazon.awssdk:sfn:2.2.0") + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") } testing { diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/package-info.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/package-info.java new file mode 100644 index 000000000000..bc9ef1d0e92d --- /dev/null +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.awssdk.v2_2.internal; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; 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 1ff468b1f3c7..043ead45e966 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 @@ -214,22 +214,6 @@ synchronized void installModule(InstrumentationModule module, boolean forMuzzleC } } - // // for pekko, we should refactor to help simplify this - // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0", - // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.route", - // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.server", - // "io.opentelemetry.javaagent.instrumentation.pekkohttp.v1_0.tapir", - // // for akka, we should refactor to help simplify this - // "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0", - // "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server", - // "io.opentelemetry.javaagent.instrumentation.akkahttp.v10_0.server.route", - // // aws sdk 1.x library - // "io.opentelemetry.instrumentation.awssdk.v1_11", - // // aws sdk 2.x library internals: refactor needed to avoid relying on internals - // "io.opentelemetry.instrumentation.awssdk.v2_2.internal", - // // aws sdk 2.x instrumentation - // "io.opentelemetry.javaagent.instrumentation.awssdk.v2_2" - public synchronized boolean hasModuleInstalled(InstrumentationModule module) { return installedModules.contains(module); } From a76b0a2cf2ff76c5fae45ffe271cafe8797c3fad Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 22 May 2026 16:18:37 +0200 Subject: [PATCH 19/21] fix pebkc --- .../opentelemetry/instrumentation/awssdk/v1_11/package-info.java | 1 + 1 file changed, 1 insertion(+) diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java b/instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java index e9f88de4fc44..e85eb2bbbaf1 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/package-info.java @@ -2,3 +2,4 @@ package io.opentelemetry.instrumentation.awssdk.v1_11; import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; From 85767d0a9ba8737496c9afb9fc4dce2a10cccfbc Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 25 May 2026 13:53:50 +0200 Subject: [PATCH 20/21] add missing dependency --- .../aws-sdk/aws-sdk-1.11/library-autoconfigure/build.gradle.kts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/build.gradle.kts b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/build.gradle.kts index 43ad1a1ec123..f06efe858431 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/build.gradle.kts +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/build.gradle.kts @@ -18,6 +18,8 @@ dependencies { testLibrary("com.amazonaws:aws-java-sdk-dynamodb:1.11.106") testLibrary("com.amazonaws:aws-java-sdk-sns:1.11.106") testLibrary("com.amazonaws:aws-java-sdk-sqs:1.11.106") + + compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api") } tasks { From 1ccf859909f152bba1d093395a8521e3b16060fe Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 25 May 2026 14:15:25 +0200 Subject: [PATCH 21/21] fix some netty stuff --- .../netty/common/v4_0/internal/client/package-info.java | 5 +++++ .../netty/common/v4_0/internal/server/package-info.java | 5 +++++ 2 files changed, 10 insertions(+) create mode 100644 instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/client/package-info.java create mode 100644 instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/server/package-info.java diff --git a/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/client/package-info.java b/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/client/package-info.java new file mode 100644 index 000000000000..ede97dc52454 --- /dev/null +++ b/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/client/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.netty.common.v4_0.internal.client; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget; diff --git a/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/server/package-info.java b/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/server/package-info.java new file mode 100644 index 000000000000..453946f0f483 --- /dev/null +++ b/instrumentation/netty/netty-common-4.0/library/src/main/java/io/opentelemetry/instrumentation/netty/common/v4_0/internal/server/package-info.java @@ -0,0 +1,5 @@ +@ClassLoadingStrategy(ClassLoadingTarget.INSTRUMENTATION_SHARED) +package io.opentelemetry.instrumentation.netty.common.v4_0.internal.server; + +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingStrategy; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ClassLoadingTarget;