From a7fdf1a33111c79201d490f4d6dc3bdb9de2c8c7 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 7 Nov 2024 14:29:44 +0100 Subject: [PATCH 01/15] make rmi instrumentation indy-compatible --- .../RmiContextPropagationInstrumentationModule.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java index 20317582d5c8..bd09178336e8 100644 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java +++ b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java @@ -20,13 +20,6 @@ public RmiContextPropagationInstrumentationModule() { super("rmi", "rmi-context-propagation"); } - @Override - public boolean isIndyModule() { - // java.lang.IllegalAccessError: class - // io.opentelemetry.javaagent.instrumentation.rmi.context.client.RmiClientContextInstrumentation$StreamRemoteCallConstructorAdvice (in unnamed module @0x740ee00f) cannot access class sun.rmi.transport.Connection (in module java.rmi) because module java.rmi does not export sun.rmi.transport to unnamed module @0x740ee00f - return false; - } - @Override public List typeInstrumentations() { return asList(new RmiClientContextInstrumentation(), new RmiServerContextInstrumentation()); From 1a9a687ff64722a61702489f59ae734c6c3eb810 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 13 Dec 2024 18:19:00 +0100 Subject: [PATCH 02/15] add module opener --- ...ntextPropagationInstrumentationModule.java | 14 +++- .../ExperimentalInstrumentationModule.java | 15 ++++ .../javaagent/tooling/ModuleOpener.java | 76 +++++++++++++++++++ .../indy/IndyModuleRegistry.java | 37 +++++++++ 4 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java index bd09178336e8..deadedc02875 100644 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java +++ b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java @@ -10,12 +10,17 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.instrumentation.rmi.context.client.RmiClientContextInstrumentation; import io.opentelemetry.javaagent.instrumentation.rmi.context.server.RmiServerContextInstrumentation; +import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; @AutoService(InstrumentationModule.class) -public class RmiContextPropagationInstrumentationModule extends InstrumentationModule { +public class RmiContextPropagationInstrumentationModule extends InstrumentationModule + implements ExperimentalInstrumentationModule { public RmiContextPropagationInstrumentationModule() { super("rmi", "rmi-context-propagation"); } @@ -24,4 +29,11 @@ public RmiContextPropagationInstrumentationModule() { public List typeInstrumentations() { return asList(new RmiClientContextInstrumentation(), new RmiServerContextInstrumentation()); } + + @Override + public Map> jpmsModulesToOpen() { + String witnessClass = "sun.rmi.transport.StreamRemoteCall"; + return Collections.singletonMap( + witnessClass, Arrays.asList("sun.rmi.server", "sun.rmi.transport")); + } } diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java index af8d33d78659..3c404aa5e2c7 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java @@ -11,6 +11,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.ClassInjector; import java.util.Collections; import java.util.List; +import java.util.Map; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -61,4 +62,18 @@ default String getModuleGroup() { default List agentPackagesToHide() { return Collections.emptyList(); } + + /** + * Some instrumentation need to access JPMS modules that are not accessible by default, this + * method provides a way to access those classes like the "--add-opens" JVM command.
+ * Map key is the name of a "witness class" belonging to the module that will be loaded and used + * to get a reference to the module.
+ * Map value is a list of packages to open in the module + * + * @return map of "witness class" name as key, list of packages as value. + */ + // TODO: copy the javadoc of the original implementation + default Map> jpmsModulesToOpen() { + return Collections.emptyMap(); + } } diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java new file mode 100644 index 000000000000..81ce0e0a1398 --- /dev/null +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -0,0 +1,76 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling; + +import static java.util.logging.Level.FINE; +import static java.util.logging.Level.WARNING; + +import java.lang.instrument.Instrumentation; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.logging.Logger; + +public class ModuleOpener { + + private static final Logger logger = Logger.getLogger(ModuleOpener.class.getName()); + + private ModuleOpener() {} + + /** + * Opens JPMS module to a class loader unnamed module + * + * @param classFromTargetModule class from target module + * @param openTo class loader to open module for + * @param packagesToOpen packages to open + */ + public static void open( + Instrumentation instrumentation, + Class classFromTargetModule, + ClassLoader openTo, + Collection packagesToOpen) { + + Module targetModule = classFromTargetModule.getModule(); + Module openToModule = openTo.getUnnamedModule(); + Set openToModuleSet = Collections.singleton(openToModule); + Map> missingOpens = new HashMap<>(); + for (String packageName : packagesToOpen) { + if (!targetModule.isOpen(packageName, openToModule)) { + missingOpens.put(packageName, openToModuleSet); + logger.log( + FINE, + () -> + String.format( + "Exposing package '%s' in module '%s' to module '%s'", + packageName, targetModule, openToModule)); + } + } + if (missingOpens.isEmpty()) { + return; + } + + if (!instrumentation.isModifiableModule(targetModule)) { + logger.log(WARNING, "Module '{}' can't be modified", targetModule); + return; + } + + try { + instrumentation.redefineModule( + targetModule, + Collections.emptySet(), // reads + Collections.>emptyMap(), // exports + missingOpens, // opens + Collections.>emptySet(), // uses + Collections., List>>emptyMap() // provides + ); + } catch (Exception e) { + logger.log(WARNING, "unable to redefine module", e); + } + } +} 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 7eaf7f3511b6..94129855cea4 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 @@ -5,9 +5,12 @@ package io.opentelemetry.javaagent.tooling.instrumentation.indy; +import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; +import io.opentelemetry.javaagent.tooling.ModuleOpener; import io.opentelemetry.javaagent.tooling.util.ClassLoaderValue; +import java.lang.instrument.Instrumentation; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.bytebuddy.agent.builder.AgentBuilder; @@ -65,6 +68,40 @@ public static InstrumentationModuleClassLoader getInstrumentationClassLoader( + " yet"); } + if (module instanceof ExperimentalInstrumentationModule) { + ExperimentalInstrumentationModule experimentalModule = + (ExperimentalInstrumentationModule) module; + + // Opening JPMS modules requires to use a 'witness class' in the target module to get a + // reference to the module, which means we have to eagerly load the class. + // + // However, this code here triggered when the advice is being executed for the first time so + // this only creates a very small eager loading that is unlikely to have impact on the + // application. + // + // Also, using a class that is already loaded like the one that is being instrumented or a + // related one would increase the likeliness of not having an effect on application class + // loading. + + Instrumentation instrumentation = InstrumentationHolder.getInstrumentation(); + if (instrumentation == null) { + throw new IllegalStateException("global instrumentation not available"); + } + + experimentalModule + .jpmsModulesToOpen() + .forEach( + (className, packages) -> { + Class type; + try { + type = Class.forName(className, false, instrumentedClassLoader); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("missing witness class " + className, e); + } + + ModuleOpener.open(instrumentation, type, loader, packages); + }); + } return loader; } From 31fb5c21cf613d5f7b5beaf93d848247ba6fcdd5 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Fri, 13 Dec 2024 18:29:32 +0100 Subject: [PATCH 03/15] enhance javadoc --- .../internal/ExperimentalInstrumentationModule.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java index 3c404aa5e2c7..eb5ce6041f8e 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java @@ -70,9 +70,8 @@ default List agentPackagesToHide() { * to get a reference to the module.
* Map value is a list of packages to open in the module * - * @return map of "witness class" name as key, list of packages as value. + * @return map of "witness class" FQN as key, list of packages as value. */ - // TODO: copy the javadoc of the original implementation default Map> jpmsModulesToOpen() { return Collections.emptyMap(); } From 6e4614052028db70286431b1a304c06c4abc8e3b Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:33:35 +0100 Subject: [PATCH 04/15] add TODO for current module open impl. --- .../rmi/context/jpms/RmiJpmsInstrumentationModule.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java index 6baf3baad0e0..dbcc4ff1271f 100644 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java +++ b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java @@ -21,6 +21,12 @@ @AutoService(InstrumentationModule.class) public class RmiJpmsInstrumentationModule extends InstrumentationModule { + // TODO: this instrumentation is only kept for inlined advices and will be removed once migration + // to indy instrumentation is complete. + // + // For Indy instrumentation, this is replaced with + // ExperimentalInstrumentationModule#jpmsModulesToOpen + public RmiJpmsInstrumentationModule() { super("rmi", "rmi-jpms"); } From 101710d071f3dfd031c095dbf802d93a4add953c Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:39:03 +0100 Subject: [PATCH 05/15] fix logging --- .../io/opentelemetry/javaagent/tooling/ModuleOpener.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index 81ce0e0a1398..3278ada40f0b 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -45,10 +45,8 @@ public static void open( missingOpens.put(packageName, openToModuleSet); logger.log( FINE, - () -> - String.format( - "Exposing package '%s' in module '%s' to module '%s'", - packageName, targetModule, openToModule)); + "Exposing package '{0}' in module '{1}' to module '{2}'", + new Object[] {packageName, targetModule, openToModule}); } } if (missingOpens.isEmpty()) { @@ -56,7 +54,7 @@ public static void open( } if (!instrumentation.isModifiableModule(targetModule)) { - logger.log(WARNING, "Module '{}' can't be modified", targetModule); + logger.log(WARNING, "Module '{0}' can't be modified", targetModule); return; } From 9c251f0464045d17dabb4142ca0d3515ae938933 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 19 Dec 2024 10:52:49 +0100 Subject: [PATCH 06/15] use module opener only when supported --- .../javaagent/tooling/ModuleOpener.java | 7 +++++ .../indy/IndyModuleRegistry.java | 30 +++++++++++-------- 2 files changed, 24 insertions(+), 13 deletions(-) diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index 3278ada40f0b..af5b311e7d41 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -17,6 +17,13 @@ import java.util.Set; import java.util.logging.Logger; +/** + * Module opener provides ability to open JPMS modules and allows instrumentation classloader to + * access module contents without requiring JVM arguments modification.
+ * Usage of this class must be guarded with an {@code net.bytebuddy.utility.JavaModule#isSupported} + * check as it's compiled for Java 9+, otherwise an {@link UnsupportedClassVersionError} will be + * thrown for java 8. + */ public class ModuleOpener { private static final Logger logger = Logger.getLogger(ModuleOpener.class.getName()); 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 94129855cea4..1f1203d023fa 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 @@ -14,6 +14,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import net.bytebuddy.agent.builder.AgentBuilder; +import net.bytebuddy.utility.JavaModule; public class IndyModuleRegistry { @@ -88,19 +89,22 @@ public static InstrumentationModuleClassLoader getInstrumentationClassLoader( throw new IllegalStateException("global instrumentation not available"); } - experimentalModule - .jpmsModulesToOpen() - .forEach( - (className, packages) -> { - Class type; - try { - type = Class.forName(className, false, instrumentedClassLoader); - } catch (ClassNotFoundException e) { - throw new IllegalStateException("missing witness class " + className, e); - } - - ModuleOpener.open(instrumentation, type, loader, packages); - }); + if (JavaModule.isSupported()) { + // module opener only usable for java 9+ + experimentalModule + .jpmsModulesToOpen() + .forEach( + (className, packages) -> { + Class type; + try { + type = Class.forName(className, false, instrumentedClassLoader); + } catch (ClassNotFoundException e) { + throw new IllegalStateException("missing witness class " + className, e); + } + + ModuleOpener.open(instrumentation, type, loader, packages); + }); + } } return loader; } From de48095888684ae50f3b9a82e15581d16103b065 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Fri, 10 Jan 2025 16:20:09 +0200 Subject: [PATCH 07/15] share module opening between indy and inline --- .../rmi/javaagent/build.gradle.kts | 9 -- ...ntextPropagationInstrumentationModule.java | 7 +- .../RmiClientContextInstrumentation.java | 30 ------- .../jpms/ExposeRmiModuleInstrumentation.java | 82 ------------------- .../jpms/RmiJpmsInstrumentationModule.java | 38 --------- .../ExperimentalInstrumentationModule.java | 5 +- .../javaagent/tooling/ModuleOpener.java | 43 +++++----- .../InstrumentationModuleInstaller.java | 22 ++++- .../indy/IndyModuleRegistry.java | 12 +-- 9 files changed, 52 insertions(+), 196 deletions(-) delete mode 100644 instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/ExposeRmiModuleInstrumentation.java delete mode 100644 instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java diff --git a/instrumentation/rmi/javaagent/build.gradle.kts b/instrumentation/rmi/javaagent/build.gradle.kts index 5007588c1273..fbd584f7d293 100644 --- a/instrumentation/rmi/javaagent/build.gradle.kts +++ b/instrumentation/rmi/javaagent/build.gradle.kts @@ -34,14 +34,5 @@ tasks { } withType().configureEach { jvmArgs("-Djava.rmi.server.hostname=127.0.0.1") - - // Can only export on Java 9+ - val testJavaVersion = - gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion) - ?: JavaVersion.current() - if (testJavaVersion.isJava9Compatible) { - jvmArgs("--add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED") - jvmArgs("--add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED") - } } } diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java index deadedc02875..03043bb0a426 100644 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java +++ b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java @@ -13,10 +13,12 @@ import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.instrumentation.rmi.context.client.RmiClientContextInstrumentation; import io.opentelemetry.javaagent.instrumentation.rmi.context.server.RmiServerContextInstrumentation; +import java.rmi.Remote; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import net.bytebuddy.utility.JavaModule; @AutoService(InstrumentationModule.class) public class RmiContextPropagationInstrumentationModule extends InstrumentationModule @@ -31,9 +33,8 @@ public List typeInstrumentations() { } @Override - public Map> jpmsModulesToOpen() { - String witnessClass = "sun.rmi.transport.StreamRemoteCall"; + public Map> jpmsModulesToOpen() { return Collections.singletonMap( - witnessClass, Arrays.asList("sun.rmi.server", "sun.rmi.transport")); + JavaModule.ofType(Remote.class), Arrays.asList("sun.rmi.server", "sun.rmi.transport")); } } diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/client/RmiClientContextInstrumentation.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/client/RmiClientContextInstrumentation.java index bacfd1e70d5a..7436e2afee8b 100644 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/client/RmiClientContextInstrumentation.java +++ b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/client/RmiClientContextInstrumentation.java @@ -13,19 +13,13 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.util.VirtualField; -import io.opentelemetry.javaagent.bootstrap.AgentClassLoader; -import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder; import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; -import java.lang.instrument.Instrumentation; import java.rmi.server.ObjID; -import java.util.Collections; import net.bytebuddy.asm.Advice; import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.matcher.ElementMatcher; -import net.bytebuddy.utility.JavaModule; import sun.rmi.transport.Connection; /** @@ -63,30 +57,6 @@ public void transform(TypeTransformer transformer) { .and(takesArgument(0, named("sun.rmi.transport.Connection"))) .and(takesArgument(1, named("java.rmi.server.ObjID"))), getClass().getName() + "$StreamRemoteCallConstructorAdvice"); - - // expose sun.rmi.transport.StreamRemoteCall to helper classes - transformer.applyTransformer( - (builder, typeDescription, classLoader, javaModule, protectionDomain) -> { - if (JavaModule.isSupported() - && classLoader == null - && "sun.rmi.transport.StreamRemoteCall".equals(typeDescription.getName()) - && javaModule != null) { - Instrumentation instrumentation = InstrumentationHolder.getInstrumentation(); - ClassInjector.UsingInstrumentation.redefineModule( - instrumentation, - javaModule, - Collections.emptySet(), - Collections.emptyMap(), - Collections.singletonMap( - "sun.rmi.transport", - // AgentClassLoader is in unnamed module of the bootstrap class loader which is - // where helper classes are also - Collections.singleton(JavaModule.ofType(AgentClassLoader.class))), - Collections.emptySet(), - Collections.emptyMap()); - } - return builder; - }); } @SuppressWarnings("unused") diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/ExposeRmiModuleInstrumentation.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/ExposeRmiModuleInstrumentation.java deleted file mode 100644 index e82c4786f286..000000000000 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/ExposeRmiModuleInstrumentation.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.rmi.context.jpms; - -import static java.util.logging.Level.FINE; -import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith; - -import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder; -import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge; -import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; -import java.util.Collections; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.logging.Logger; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.dynamic.loading.ClassInjector; -import net.bytebuddy.matcher.ElementMatcher; -import net.bytebuddy.utility.JavaModule; - -public class ExposeRmiModuleInstrumentation implements TypeInstrumentation { - private static final Logger logger = - Logger.getLogger(ExposeRmiModuleInstrumentation.class.getName()); - - private final AtomicBoolean instrumented = new AtomicBoolean(); - - @Override - public ElementMatcher typeMatcher() { - ElementMatcher.Junction notInstrumented = - new ElementMatcher.Junction.AbstractBase() { - - @Override - public boolean matches(TypeDescription target) { - return !instrumented.get(); - } - }; - - return notInstrumented.and(nameStartsWith("sun.rmi")); - } - - @Override - public ElementMatcher classLoaderOptimization() { - return new ElementMatcher.Junction.AbstractBase() { - - @Override - public boolean matches(ClassLoader target) { - // runs only in bootstrap class loader - return JavaModule.isSupported() && target == null; - } - }; - } - - @Override - public void transform(TypeTransformer transformer) { - transformer.applyTransformer( - (builder, typeDescription, classLoader, javaModule, protectionDomain) -> { - if (javaModule != null && javaModule.isNamed()) { - // using Java8BytecodeBridge because it's in the unnamed module in the bootstrap - // loader, and that's where the rmi instrumentation helper classes will end up - JavaModule helperModule = JavaModule.ofType(Java8BytecodeBridge.class); - // expose sun.rmi.server package to unnamed module - ClassInjector.UsingInstrumentation.redefineModule( - InstrumentationHolder.getInstrumentation(), - javaModule, - Collections.emptySet(), - Collections.singletonMap("sun.rmi.server", Collections.singleton(helperModule)), - Collections.emptyMap(), - Collections.emptySet(), - Collections.emptyMap()); - - instrumented.set(true); - logger.log( - FINE, - "Exposed package \"sun.rmi.server\" in module {0} to unnamed module", - javaModule); - } - return builder; - }); - } -} diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java deleted file mode 100644 index dbcc4ff1271f..000000000000 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.instrumentation.rmi.context.jpms; - -import static java.util.Collections.singletonList; - -import com.google.auto.service.AutoService; -import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; -import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; -import io.opentelemetry.javaagent.instrumentation.rmi.context.server.ContextDispatcher; -import java.util.List; - -/** - * RMI server instrumentation class {@link ContextDispatcher} implements an internal interface that - * is not exported by java module system. This is not allowed on jdk17. This instrumentation module - * exposes JDK internal classes for RMI server instrumentation. - */ -@AutoService(InstrumentationModule.class) -public class RmiJpmsInstrumentationModule extends InstrumentationModule { - - // TODO: this instrumentation is only kept for inlined advices and will be removed once migration - // to indy instrumentation is complete. - // - // For Indy instrumentation, this is replaced with - // ExperimentalInstrumentationModule#jpmsModulesToOpen - - public RmiJpmsInstrumentationModule() { - super("rmi", "rmi-jpms"); - } - - @Override - public List typeInstrumentations() { - return singletonList(new ExposeRmiModuleInstrumentation()); - } -} diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java index eb5ce6041f8e..9bc7345210a2 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java @@ -12,6 +12,7 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import net.bytebuddy.utility.JavaModule; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -70,9 +71,9 @@ default List agentPackagesToHide() { * to get a reference to the module.
* Map value is a list of packages to open in the module * - * @return map of "witness class" FQN as key, list of packages as value. + * @return map of module to open as key, list of packages as value. */ - default Map> jpmsModulesToOpen() { + default Map> jpmsModulesToOpen() { return Collections.emptyMap(); } } diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index af5b311e7d41..64cf7292c070 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -8,14 +8,17 @@ import static java.util.logging.Level.FINE; import static java.util.logging.Level.WARNING; +import io.opentelemetry.javaagent.bootstrap.AgentClassLoader; import java.lang.instrument.Instrumentation; import java.util.Collection; import java.util.Collections; import java.util.HashMap; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.logging.Logger; +import net.bytebuddy.description.type.PackageDescription; +import net.bytebuddy.dynamic.loading.ClassInjector; +import net.bytebuddy.utility.JavaModule; /** * Module opener provides ability to open JPMS modules and allows instrumentation classloader to @@ -28,27 +31,30 @@ public class ModuleOpener { private static final Logger logger = Logger.getLogger(ModuleOpener.class.getName()); + // AgentClassLoader is in unnamed module of the bootstrap loader + private static final JavaModule UNNAMED_BOOT_MODULE = JavaModule.ofType(AgentClassLoader.class); + private ModuleOpener() {} /** * Opens JPMS module to a class loader unnamed module * - * @param classFromTargetModule class from target module + * @param targetModule target module * @param openTo class loader to open module for * @param packagesToOpen packages to open */ public static void open( Instrumentation instrumentation, - Class classFromTargetModule, + JavaModule targetModule, ClassLoader openTo, Collection packagesToOpen) { - Module targetModule = classFromTargetModule.getModule(); - Module openToModule = openTo.getUnnamedModule(); - Set openToModuleSet = Collections.singleton(openToModule); - Map> missingOpens = new HashMap<>(); + JavaModule openToModule = + openTo != null ? JavaModule.of(openTo.getUnnamedModule()) : UNNAMED_BOOT_MODULE; + Set openToModuleSet = Collections.singleton(openToModule); + Map> missingOpens = new HashMap<>(); for (String packageName : packagesToOpen) { - if (!targetModule.isOpen(packageName, openToModule)) { + if (!targetModule.isOpened(new PackageDescription.Simple(packageName), openToModule)) { missingOpens.put(packageName, openToModuleSet); logger.log( FINE, @@ -60,22 +66,17 @@ public static void open( return; } - if (!instrumentation.isModifiableModule(targetModule)) { - logger.log(WARNING, "Module '{0}' can't be modified", targetModule); - return; - } - try { - instrumentation.redefineModule( + ClassInjector.UsingInstrumentation.redefineModule( + instrumentation, targetModule, - Collections.emptySet(), // reads - Collections.>emptyMap(), // exports - missingOpens, // opens - Collections.>emptySet(), // uses - Collections., List>>emptyMap() // provides - ); + Collections.emptySet(), + Collections.emptyMap(), + missingOpens, + Collections.emptySet(), + Collections.emptyMap()); } catch (Exception e) { - logger.log(WARNING, "unable to redefine module", e); + logger.log(WARNING, "Failed to redefine module '" + targetModule.getActualName() + "'", e); } } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java index 09bc519812a9..ef45ac208226 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java @@ -17,6 +17,7 @@ import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.InjectionMode; import io.opentelemetry.javaagent.tooling.HelperClassDefinition; import io.opentelemetry.javaagent.tooling.HelperInjector; +import io.opentelemetry.javaagent.tooling.ModuleOpener; import io.opentelemetry.javaagent.tooling.TransformSafeLogger; import io.opentelemetry.javaagent.tooling.Utils; import io.opentelemetry.javaagent.tooling.bytebuddy.LoggingFailSafeMatcher; @@ -36,6 +37,7 @@ import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Function; import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.description.annotation.AnnotationSource; @@ -202,13 +204,31 @@ private AgentBuilder installInjectingModule( VirtualFieldImplementationInstaller contextProvider = virtualFieldInstallerFactory.create(instrumentationModule); + AtomicBoolean openerRun = new AtomicBoolean(); AgentBuilder agentBuilder = parentAgentBuilder; for (TypeInstrumentation typeInstrumentation : typeInstrumentations) { - AgentBuilder.Identified.Extendable extendableAgentBuilder = setTypeMatcher(agentBuilder, instrumentationModule, typeInstrumentation) .and(muzzleMatcher) .transform(ConstantAdjuster.instance()) + .transform( + (builder, typeDescription, classLoader, module, protectionDomain) -> { + if (instrumentationModule instanceof ExperimentalInstrumentationModule + && !openerRun.get()) { + ExperimentalInstrumentationModule experimentalModule = + (ExperimentalInstrumentationModule) instrumentationModule; + experimentalModule + .jpmsModulesToOpen() + .forEach( + (javaModule, packages) -> { + ModuleOpener.open( + instrumentation, javaModule, classLoader, packages); + }); + openerRun.set(true); + } + + return builder; + }) .transform(helperInjector); extendableAgentBuilder = contextProvider.injectHelperClasses(extendableAgentBuilder); extendableAgentBuilder = contextProvider.rewriteVirtualFieldsCalls(extendableAgentBuilder); 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 1f1203d023fa..e0492a386033 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 @@ -94,16 +94,8 @@ public static InstrumentationModuleClassLoader getInstrumentationClassLoader( experimentalModule .jpmsModulesToOpen() .forEach( - (className, packages) -> { - Class type; - try { - type = Class.forName(className, false, instrumentedClassLoader); - } catch (ClassNotFoundException e) { - throw new IllegalStateException("missing witness class " + className, e); - } - - ModuleOpener.open(instrumentation, type, loader, packages); - }); + (javaModule, packages) -> + ModuleOpener.open(instrumentation, javaModule, loader, packages)); } } return loader; From d64d5fd8a891f2ee305318eb762203ad580bd3b7 Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 14 Jan 2025 15:26:07 +0200 Subject: [PATCH 08/15] Update javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java Co-authored-by: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> --- .../java/io/opentelemetry/javaagent/tooling/ModuleOpener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index 64cf7292c070..70228e4ec752 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -46,7 +46,7 @@ private ModuleOpener() {} public static void open( Instrumentation instrumentation, JavaModule targetModule, - ClassLoader openTo, + @Nullable ClassLoader openTo, Collection packagesToOpen) { JavaModule openToModule = From 377a30195da48ef354e4c26defd5e6f773a330eb Mon Sep 17 00:00:00 2001 From: Lauri Tulmin Date: Tue, 14 Jan 2025 15:26:32 +0200 Subject: [PATCH 09/15] Update javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java Co-authored-by: SylvainJuge <763082+SylvainJuge@users.noreply.github.com> --- .../java/io/opentelemetry/javaagent/tooling/ModuleOpener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index 70228e4ec752..01c3d3cf094b 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -40,7 +40,7 @@ private ModuleOpener() {} * Opens JPMS module to a class loader unnamed module * * @param targetModule target module - * @param openTo class loader to open module for + * @param openTo class loader to open module for, {@literal null} to use the unnamed module of bootstrap classloader. * @param packagesToOpen packages to open */ public static void open( From bd70195e6d100f9afd5fcb500756038295a78a00 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:12:08 +0100 Subject: [PATCH 10/15] add TODO + spotless reformat --- .../internal/ExperimentalInstrumentationModule.java | 2 ++ .../java/io/opentelemetry/javaagent/tooling/ModuleOpener.java | 3 ++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java index 9bc7345210a2..262a35dd441b 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java @@ -73,6 +73,8 @@ default List agentPackagesToHide() { * * @return map of module to open as key, list of packages as value. */ + // TODO: when moving this method outside of experimental API, we need to decide using JavaModule + // instance or a class FQN in the map entry, as it could lead to some limitations default Map> jpmsModulesToOpen() { return Collections.emptyMap(); } diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index 01c3d3cf094b..473e90045482 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -40,7 +40,8 @@ private ModuleOpener() {} * Opens JPMS module to a class loader unnamed module * * @param targetModule target module - * @param openTo class loader to open module for, {@literal null} to use the unnamed module of bootstrap classloader. + * @param openTo class loader to open module for, {@literal null} to use the unnamed module of + * bootstrap classloader. * @param packagesToOpen packages to open */ public static void open( From b14f5e037f2633cc75749d89616be224741446dd Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 14 Jan 2025 15:29:12 +0100 Subject: [PATCH 11/15] compile before push I should --- .../java/io/opentelemetry/javaagent/tooling/ModuleOpener.java | 1 + 1 file changed, 1 insertion(+) diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index 473e90045482..b77339216ef0 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -19,6 +19,7 @@ import net.bytebuddy.description.type.PackageDescription; import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.utility.JavaModule; +import javax.annotation.Nullable; /** * Module opener provides ability to open JPMS modules and allows instrumentation classloader to From ab4662cb441c6c5ac6fbd79abf8549e3df4b7af1 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 14 Jan 2025 16:29:51 +0100 Subject: [PATCH 12/15] spotless again --- .../java/io/opentelemetry/javaagent/tooling/ModuleOpener.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java index b77339216ef0..5f5327f56ba7 100644 --- a/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java +++ b/javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java @@ -16,10 +16,10 @@ import java.util.Map; import java.util.Set; import java.util.logging.Logger; +import javax.annotation.Nullable; import net.bytebuddy.description.type.PackageDescription; import net.bytebuddy.dynamic.loading.ClassInjector; import net.bytebuddy.utility.JavaModule; -import javax.annotation.Nullable; /** * Module opener provides ability to open JPMS modules and allows instrumentation classloader to From 3235f3a3fb84bf4bb3b0b9679d126aeb03499756 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Tue, 14 Jan 2025 17:01:29 +0100 Subject: [PATCH 13/15] do not use module opener for java < 9 --- .../instrumentation/InstrumentationModuleInstaller.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java index ef45ac208226..a0924738e44b 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java @@ -43,6 +43,7 @@ import net.bytebuddy.description.annotation.AnnotationSource; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.matcher.ElementMatcher; +import net.bytebuddy.utility.JavaModule; public final class InstrumentationModuleInstaller { @@ -213,7 +214,8 @@ private AgentBuilder installInjectingModule( .transform(ConstantAdjuster.instance()) .transform( (builder, typeDescription, classLoader, module, protectionDomain) -> { - if (instrumentationModule instanceof ExperimentalInstrumentationModule + if (JavaModule.isSupported() + && instrumentationModule instanceof ExperimentalInstrumentationModule && !openerRun.get()) { ExperimentalInstrumentationModule experimentalModule = (ExperimentalInstrumentationModule) instrumentationModule; From aa23db016ce9d7fbfec446454c045fbcbded7bd7 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Wed, 15 Jan 2025 14:28:39 +0100 Subject: [PATCH 14/15] remove obsolete comment --- .../instrumentation/indy/IndyModuleRegistry.java | 11 ----------- 1 file changed, 11 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 e0492a386033..611bf419326e 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 @@ -73,17 +73,6 @@ public static InstrumentationModuleClassLoader getInstrumentationClassLoader( ExperimentalInstrumentationModule experimentalModule = (ExperimentalInstrumentationModule) module; - // Opening JPMS modules requires to use a 'witness class' in the target module to get a - // reference to the module, which means we have to eagerly load the class. - // - // However, this code here triggered when the advice is being executed for the first time so - // this only creates a very small eager loading that is unlikely to have impact on the - // application. - // - // Also, using a class that is already loaded like the one that is being instrumented or a - // related one would increase the likeliness of not having an effect on application class - // loading. - Instrumentation instrumentation = InstrumentationHolder.getInstrumentation(); if (instrumentation == null) { throw new IllegalStateException("global instrumentation not available"); From 66cc354772b74b91f446ccc30dbc900680a06364 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Thu, 16 Jan 2025 09:56:47 +0100 Subject: [PATCH 15/15] remove obsolete comment --- .../internal/ExperimentalInstrumentationModule.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java index 262a35dd441b..ab791a23e1e9 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java @@ -66,10 +66,7 @@ default List agentPackagesToHide() { /** * Some instrumentation need to access JPMS modules that are not accessible by default, this - * method provides a way to access those classes like the "--add-opens" JVM command.
- * Map key is the name of a "witness class" belonging to the module that will be loaded and used - * to get a reference to the module.
- * Map value is a list of packages to open in the module + * method provides a way to access those classes like the "--add-opens" JVM command. * * @return map of module to open as key, list of packages as value. */