Skip to content

Commit 0f20c60

Browse files
authored
Merge pull request #3 from laurit/rmi-open
share module opening between indy and inline
2 parents 9c9f775 + 377a301 commit 0f20c60

File tree

9 files changed

+54
-198
lines changed

9 files changed

+54
-198
lines changed

instrumentation/rmi/javaagent/build.gradle.kts

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,5 @@ tasks {
3434
}
3535
withType<Test>().configureEach {
3636
jvmArgs("-Djava.rmi.server.hostname=127.0.0.1")
37-
38-
// Can only export on Java 9+
39-
val testJavaVersion =
40-
gradle.startParameter.projectProperties.get("testJavaVersion")?.let(JavaVersion::toVersion)
41-
?: JavaVersion.current()
42-
if (testJavaVersion.isJava9Compatible) {
43-
jvmArgs("--add-exports=java.rmi/sun.rmi.server=ALL-UNNAMED")
44-
jvmArgs("--add-exports=java.rmi/sun.rmi.transport=ALL-UNNAMED")
45-
}
4637
}
4738
}

instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/RmiContextPropagationInstrumentationModule.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,12 @@
1313
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1414
import io.opentelemetry.javaagent.instrumentation.rmi.context.client.RmiClientContextInstrumentation;
1515
import io.opentelemetry.javaagent.instrumentation.rmi.context.server.RmiServerContextInstrumentation;
16+
import java.rmi.Remote;
1617
import java.util.Arrays;
1718
import java.util.Collections;
1819
import java.util.List;
1920
import java.util.Map;
21+
import net.bytebuddy.utility.JavaModule;
2022

2123
@AutoService(InstrumentationModule.class)
2224
public class RmiContextPropagationInstrumentationModule extends InstrumentationModule
@@ -31,9 +33,8 @@ public List<TypeInstrumentation> typeInstrumentations() {
3133
}
3234

3335
@Override
34-
public Map<String, List<String>> jpmsModulesToOpen() {
35-
String witnessClass = "sun.rmi.transport.StreamRemoteCall";
36+
public Map<JavaModule, List<String>> jpmsModulesToOpen() {
3637
return Collections.singletonMap(
37-
witnessClass, Arrays.asList("sun.rmi.server", "sun.rmi.transport"));
38+
JavaModule.ofType(Remote.class), Arrays.asList("sun.rmi.server", "sun.rmi.transport"));
3839
}
3940
}

instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/client/RmiClientContextInstrumentation.java

Lines changed: 0 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,13 @@
1313
import io.opentelemetry.api.trace.Span;
1414
import io.opentelemetry.context.Context;
1515
import io.opentelemetry.instrumentation.api.util.VirtualField;
16-
import io.opentelemetry.javaagent.bootstrap.AgentClassLoader;
17-
import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder;
1816
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
1917
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
2018
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
21-
import java.lang.instrument.Instrumentation;
2219
import java.rmi.server.ObjID;
23-
import java.util.Collections;
2420
import net.bytebuddy.asm.Advice;
2521
import net.bytebuddy.description.type.TypeDescription;
26-
import net.bytebuddy.dynamic.loading.ClassInjector;
2722
import net.bytebuddy.matcher.ElementMatcher;
28-
import net.bytebuddy.utility.JavaModule;
2923
import sun.rmi.transport.Connection;
3024

3125
/**
@@ -63,30 +57,6 @@ public void transform(TypeTransformer transformer) {
6357
.and(takesArgument(0, named("sun.rmi.transport.Connection")))
6458
.and(takesArgument(1, named("java.rmi.server.ObjID"))),
6559
getClass().getName() + "$StreamRemoteCallConstructorAdvice");
66-
67-
// expose sun.rmi.transport.StreamRemoteCall to helper classes
68-
transformer.applyTransformer(
69-
(builder, typeDescription, classLoader, javaModule, protectionDomain) -> {
70-
if (JavaModule.isSupported()
71-
&& classLoader == null
72-
&& "sun.rmi.transport.StreamRemoteCall".equals(typeDescription.getName())
73-
&& javaModule != null) {
74-
Instrumentation instrumentation = InstrumentationHolder.getInstrumentation();
75-
ClassInjector.UsingInstrumentation.redefineModule(
76-
instrumentation,
77-
javaModule,
78-
Collections.emptySet(),
79-
Collections.emptyMap(),
80-
Collections.singletonMap(
81-
"sun.rmi.transport",
82-
// AgentClassLoader is in unnamed module of the bootstrap class loader which is
83-
// where helper classes are also
84-
Collections.singleton(JavaModule.ofType(AgentClassLoader.class))),
85-
Collections.emptySet(),
86-
Collections.emptyMap());
87-
}
88-
return builder;
89-
});
9060
}
9161

9262
@SuppressWarnings("unused")

instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/ExposeRmiModuleInstrumentation.java

Lines changed: 0 additions & 82 deletions
This file was deleted.

instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/context/jpms/RmiJpmsInstrumentationModule.java

Lines changed: 0 additions & 38 deletions
This file was deleted.

javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/ExperimentalInstrumentationModule.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import java.util.Collections;
1313
import java.util.List;
1414
import java.util.Map;
15+
import net.bytebuddy.utility.JavaModule;
1516

1617
/**
1718
* 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<String> agentPackagesToHide() {
7071
* to get a reference to the module. <br>
7172
* Map value is a list of packages to open in the module
7273
*
73-
* @return map of "witness class" FQN as key, list of packages as value.
74+
* @return map of module to open as key, list of packages as value.
7475
*/
75-
default Map<String, List<String>> jpmsModulesToOpen() {
76+
default Map<JavaModule, List<String>> jpmsModulesToOpen() {
7677
return Collections.emptyMap();
7778
}
7879
}

javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/ModuleOpener.java

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
import static java.util.logging.Level.FINE;
99
import static java.util.logging.Level.WARNING;
1010

11+
import io.opentelemetry.javaagent.bootstrap.AgentClassLoader;
1112
import java.lang.instrument.Instrumentation;
1213
import java.util.Collection;
1314
import java.util.Collections;
1415
import java.util.HashMap;
15-
import java.util.List;
1616
import java.util.Map;
1717
import java.util.Set;
1818
import java.util.logging.Logger;
19+
import net.bytebuddy.description.type.PackageDescription;
20+
import net.bytebuddy.dynamic.loading.ClassInjector;
21+
import net.bytebuddy.utility.JavaModule;
1922

2023
/**
2124
* Module opener provides ability to open JPMS modules and allows instrumentation classloader to
@@ -28,27 +31,30 @@ public class ModuleOpener {
2831

2932
private static final Logger logger = Logger.getLogger(ModuleOpener.class.getName());
3033

34+
// AgentClassLoader is in unnamed module of the bootstrap loader
35+
private static final JavaModule UNNAMED_BOOT_MODULE = JavaModule.ofType(AgentClassLoader.class);
36+
3137
private ModuleOpener() {}
3238

3339
/**
3440
* Opens JPMS module to a class loader unnamed module
3541
*
36-
* @param classFromTargetModule class from target module
37-
* @param openTo class loader to open module for
42+
* @param targetModule target module
43+
* @param openTo class loader to open module for, {@literal null} to use the unnamed module of bootstrap classloader.
3844
* @param packagesToOpen packages to open
3945
*/
4046
public static void open(
4147
Instrumentation instrumentation,
42-
Class<?> classFromTargetModule,
43-
ClassLoader openTo,
48+
JavaModule targetModule,
49+
@Nullable ClassLoader openTo,
4450
Collection<String> packagesToOpen) {
4551

46-
Module targetModule = classFromTargetModule.getModule();
47-
Module openToModule = openTo.getUnnamedModule();
48-
Set<Module> openToModuleSet = Collections.singleton(openToModule);
49-
Map<String, Set<Module>> missingOpens = new HashMap<>();
52+
JavaModule openToModule =
53+
openTo != null ? JavaModule.of(openTo.getUnnamedModule()) : UNNAMED_BOOT_MODULE;
54+
Set<JavaModule> openToModuleSet = Collections.singleton(openToModule);
55+
Map<String, Set<JavaModule>> missingOpens = new HashMap<>();
5056
for (String packageName : packagesToOpen) {
51-
if (!targetModule.isOpen(packageName, openToModule)) {
57+
if (!targetModule.isOpened(new PackageDescription.Simple(packageName), openToModule)) {
5258
missingOpens.put(packageName, openToModuleSet);
5359
logger.log(
5460
FINE,
@@ -60,22 +66,17 @@ public static void open(
6066
return;
6167
}
6268

63-
if (!instrumentation.isModifiableModule(targetModule)) {
64-
logger.log(WARNING, "Module '{0}' can't be modified", targetModule);
65-
return;
66-
}
67-
6869
try {
69-
instrumentation.redefineModule(
70+
ClassInjector.UsingInstrumentation.redefineModule(
71+
instrumentation,
7072
targetModule,
71-
Collections.<Module>emptySet(), // reads
72-
Collections.<String, Set<Module>>emptyMap(), // exports
73-
missingOpens, // opens
74-
Collections.<Class<?>>emptySet(), // uses
75-
Collections.<Class<?>, List<Class<?>>>emptyMap() // provides
76-
);
73+
Collections.emptySet(),
74+
Collections.emptyMap(),
75+
missingOpens,
76+
Collections.emptySet(),
77+
Collections.emptyMap());
7778
} catch (Exception e) {
78-
logger.log(WARNING, "unable to redefine module", e);
79+
logger.log(WARNING, "Failed to redefine module '" + targetModule.getActualName() + "'", e);
7980
}
8081
}
8182
}

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.InjectionMode;
1818
import io.opentelemetry.javaagent.tooling.HelperClassDefinition;
1919
import io.opentelemetry.javaagent.tooling.HelperInjector;
20+
import io.opentelemetry.javaagent.tooling.ModuleOpener;
2021
import io.opentelemetry.javaagent.tooling.TransformSafeLogger;
2122
import io.opentelemetry.javaagent.tooling.Utils;
2223
import io.opentelemetry.javaagent.tooling.bytebuddy.LoggingFailSafeMatcher;
@@ -36,6 +37,7 @@
3637
import java.util.ArrayList;
3738
import java.util.Collections;
3839
import java.util.List;
40+
import java.util.concurrent.atomic.AtomicBoolean;
3941
import java.util.function.Function;
4042
import net.bytebuddy.agent.builder.AgentBuilder;
4143
import net.bytebuddy.description.annotation.AnnotationSource;
@@ -202,13 +204,31 @@ private AgentBuilder installInjectingModule(
202204
VirtualFieldImplementationInstaller contextProvider =
203205
virtualFieldInstallerFactory.create(instrumentationModule);
204206

207+
AtomicBoolean openerRun = new AtomicBoolean();
205208
AgentBuilder agentBuilder = parentAgentBuilder;
206209
for (TypeInstrumentation typeInstrumentation : typeInstrumentations) {
207-
208210
AgentBuilder.Identified.Extendable extendableAgentBuilder =
209211
setTypeMatcher(agentBuilder, instrumentationModule, typeInstrumentation)
210212
.and(muzzleMatcher)
211213
.transform(ConstantAdjuster.instance())
214+
.transform(
215+
(builder, typeDescription, classLoader, module, protectionDomain) -> {
216+
if (instrumentationModule instanceof ExperimentalInstrumentationModule
217+
&& !openerRun.get()) {
218+
ExperimentalInstrumentationModule experimentalModule =
219+
(ExperimentalInstrumentationModule) instrumentationModule;
220+
experimentalModule
221+
.jpmsModulesToOpen()
222+
.forEach(
223+
(javaModule, packages) -> {
224+
ModuleOpener.open(
225+
instrumentation, javaModule, classLoader, packages);
226+
});
227+
openerRun.set(true);
228+
}
229+
230+
return builder;
231+
})
212232
.transform(helperInjector);
213233
extendableAgentBuilder = contextProvider.injectHelperClasses(extendableAgentBuilder);
214234
extendableAgentBuilder = contextProvider.rewriteVirtualFieldsCalls(extendableAgentBuilder);

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/indy/IndyModuleRegistry.java

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -94,16 +94,8 @@ public static InstrumentationModuleClassLoader getInstrumentationClassLoader(
9494
experimentalModule
9595
.jpmsModulesToOpen()
9696
.forEach(
97-
(className, packages) -> {
98-
Class<?> type;
99-
try {
100-
type = Class.forName(className, false, instrumentedClassLoader);
101-
} catch (ClassNotFoundException e) {
102-
throw new IllegalStateException("missing witness class " + className, e);
103-
}
104-
105-
ModuleOpener.open(instrumentation, type, loader, packages);
106-
});
97+
(javaModule, packages) ->
98+
ModuleOpener.open(instrumentation, javaModule, loader, packages));
10799
}
108100
}
109101
return loader;

0 commit comments

Comments
 (0)