Skip to content

Commit 4874d2b

Browse files
committed
Provide means to ensure a JPMS module can read dynamically defined classes
1 parent 871a3a1 commit 4874d2b

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2025-Present Datadog, Inc.
5+
*/
6+
7+
package datadog.instrument.utils;
8+
9+
import static datadog.instrument.utils.JVM.atLeastJava;
10+
import static java.util.Collections.emptyMap;
11+
import static java.util.Collections.emptySet;
12+
13+
import java.lang.instrument.Instrumentation;
14+
import java.util.HashSet;
15+
import java.util.Set;
16+
17+
/** Methods for managing <a href="https://openjdk.org/projects/jigsaw/spec/">JPMS</a> modules. */
18+
public final class Modules {
19+
20+
/**
21+
* Ensures the module has read access to classes dynamically defined in the given class-loaders.
22+
*
23+
* @param inst the instrumentation that can redefine modules
24+
* @param module the module that should be able to read the classes
25+
* @param classLoaders the class-loaders defining classes to read
26+
*/
27+
@SuppressWarnings({"Since15"})
28+
public static void ensureReadability(
29+
Instrumentation inst, Object module, Iterable<ClassLoader> classLoaders) {
30+
if (atLeastJava(9)) { // JPMS is only available on Java 9+
31+
if (!(module instanceof java.lang.Module)) {
32+
return; // argument is not a real module
33+
}
34+
java.lang.Module theModule = (java.lang.Module) module;
35+
if (!theModule.isNamed()) {
36+
return; // unnamed modules can read each other
37+
}
38+
Set<java.lang.Module> extraReads = new HashSet<>();
39+
for (ClassLoader cl : classLoaders) {
40+
java.lang.Module unnamedModule = cl.getUnnamedModule();
41+
if (!theModule.canRead(unnamedModule)) {
42+
extraReads.add(unnamedModule);
43+
}
44+
}
45+
if (!extraReads.isEmpty()) {
46+
inst.redefineModule(theModule, extraReads, emptyMap(), emptyMap(), emptySet(), emptyMap());
47+
}
48+
}
49+
}
50+
}

0 commit comments

Comments
 (0)