11package datadog .trace .agent .tooling ;
22
33import static datadog .trace .bootstrap .AgentClassLoading .INJECTING_HELPERS ;
4+ import static java .util .Arrays .asList ;
45
56import datadog .trace .bootstrap .instrumentation .api .EagerHelper ;
7+ import datadog .trace .util .JDK9ModuleAccess ;
68import java .io .IOException ;
79import java .lang .ref .WeakReference ;
10+ import java .lang .reflect .AnnotatedElement ;
811import java .security .CodeSource ;
912import java .security .ProtectionDomain ;
10- import java .util .Arrays ;
1113import java .util .Collections ;
14+ import java .util .HashSet ;
1215import java .util .LinkedHashMap ;
1316import java .util .LinkedHashSet ;
1417import java .util .List ;
2023import net .bytebuddy .dynamic .ClassFileLocator ;
2124import net .bytebuddy .dynamic .DynamicType ;
2225import net .bytebuddy .dynamic .loading .ClassInjector ;
23- import net .bytebuddy .dynamic .loading .ClassLoadingStrategy ;
2426import net .bytebuddy .utility .JavaModule ;
2527import org .slf4j .Logger ;
2628import org .slf4j .LoggerFactory ;
@@ -40,9 +42,9 @@ public class HelperInjector implements Instrumenter.TransformingAdvice {
4042 private final Map <String , byte []> dynamicTypeMap = new LinkedHashMap <>();
4143
4244 private final Map <ClassLoader , Boolean > injectedClassLoaders =
43- Collections .synchronizedMap (new WeakHashMap <ClassLoader , Boolean >());
45+ Collections .synchronizedMap (new WeakHashMap <>());
4446
45- private final List <WeakReference <Object >> helperModules = new CopyOnWriteArrayList <>();
47+ private final List <WeakReference <AnnotatedElement >> helperModules = new CopyOnWriteArrayList <>();
4648
4749 /**
4850 * Construct HelperInjector.
@@ -71,7 +73,7 @@ public HelperInjector(
7173 this .requestingName = requestingName ;
7274 this .adviceShader = adviceShader ;
7375
74- this .helperClassNames = new LinkedHashSet <>(Arrays . asList (helperClassNames ));
76+ this .helperClassNames = new LinkedHashSet <>(asList (helperClassNames ));
7577 }
7678
7779 public HelperInjector (
@@ -132,12 +134,10 @@ public DynamicType.Builder<?> transform(
132134 final Map <String , byte []> classnameToBytes = getHelperMap ();
133135 final Map <String , Class <?>> classes = injectClassLoader (classLoader , classnameToBytes );
134136
135- // All datadog helper classes are in the unnamed module
136- // And there's exactly one unnamed module per classloader
137- // Use the module of the first class for convenience
137+ // all datadog helper classes are in the unnamed module
138+ // and there's exactly one unnamed module per classloader
138139 if (JavaModule .isSupported ()) {
139- final JavaModule javaModule = JavaModule .ofType (classes .values ().iterator ().next ());
140- helperModules .add (new WeakReference <>(javaModule .unwrap ()));
140+ helperModules .add (new WeakReference <>(JDK9ModuleAccess .getUnnamedModule (classLoader )));
141141 }
142142
143143 // forcibly initialize any eager helpers
@@ -177,43 +177,42 @@ private Map<String, Class<?>> injectClassLoader(
177177 final ClassLoader classLoader , final Map <String , byte []> classnameToBytes ) {
178178 INJECTING_HELPERS .begin ();
179179 try {
180- ProtectionDomain protectionDomain = createProtectionDomain (classLoader );
181- return new ClassInjector .UsingReflection (classLoader , protectionDomain )
182- .injectRaw (classnameToBytes );
180+ if (useAgentCodeSource ) {
181+ ProtectionDomain protectionDomain = createProtectionDomain (classLoader );
182+ return new ClassInjector .UsingReflection (classLoader , protectionDomain )
183+ .injectRaw (classnameToBytes );
184+ } else {
185+ return new ClassInjector .UsingReflection (classLoader ).injectRaw (classnameToBytes );
186+ }
183187 } finally {
184188 INJECTING_HELPERS .end ();
185189 }
186190 }
187191
188192 private ProtectionDomain createProtectionDomain (final ClassLoader classLoader ) {
189- if (useAgentCodeSource ) {
190- CodeSource codeSource = HelperInjector .class .getProtectionDomain ().getCodeSource ();
191- return new ProtectionDomain (codeSource , null , classLoader , null );
192- } else {
193- return ClassLoadingStrategy .NO_PROTECTION_DOMAIN ;
194- }
193+ CodeSource codeSource = HelperInjector .class .getProtectionDomain ().getCodeSource ();
194+ return new ProtectionDomain (codeSource , null , classLoader , null );
195195 }
196196
197197 private void ensureModuleCanReadHelperModules (final JavaModule target ) {
198198 if (JavaModule .isSupported () && target != JavaModule .UNSUPPORTED && target .isNamed ()) {
199- for (final WeakReference <Object > helperModuleReference : helperModules ) {
200- final Object realModule = helperModuleReference .get ();
201- if (realModule != null ) {
202- final JavaModule helperModule = JavaModule .of (realModule );
203-
204- if (!target .canRead (helperModule )) {
205- log .debug ("Adding module read from {} to {}" , target , helperModule );
206- ClassInjector .UsingInstrumentation .redefineModule (
207- Utils .getInstrumentation (),
208- target ,
209- Collections .singleton (helperModule ),
210- Collections .<String , Set <JavaModule >>emptyMap (),
211- Collections .<String , Set <JavaModule >>emptyMap (),
212- Collections .<Class <?>>emptySet (),
213- Collections .<Class <?>, List <Class <?>>>emptyMap ());
199+ AnnotatedElement targetModule = (AnnotatedElement ) target .unwrap ();
200+ Set <AnnotatedElement > extraReads = null ;
201+ for (final WeakReference <AnnotatedElement > helperModuleReference : helperModules ) {
202+ final AnnotatedElement helperModule = helperModuleReference .get ();
203+ if (helperModule != null ) {
204+ if (!JDK9ModuleAccess .canRead (targetModule , helperModule )) {
205+ if (extraReads == null ) {
206+ extraReads = new HashSet <>();
207+ }
208+ extraReads .add (helperModule );
214209 }
215210 }
216211 }
212+ if (extraReads != null ) {
213+ log .debug ("Adding module reads from {} to {}" , targetModule , extraReads );
214+ JDK9ModuleAccess .addModuleReads (Utils .getInstrumentation (), targetModule , extraReads );
215+ }
217216 }
218217 }
219218}
0 commit comments