|
| 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