Skip to content

Commit dc59290

Browse files
committed
Undo lazy loading
1 parent fde64f4 commit dc59290

2 files changed

Lines changed: 21 additions & 66 deletions

File tree

dd-java-agent/agent-installer/src/main/java/datadog/trace/agent/tooling/CombiningTransformerBuilder.java

Lines changed: 18 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import java.util.List;
2727
import java.util.Map;
2828
import java.util.Set;
29-
import java.util.function.Supplier;
3029
import net.bytebuddy.agent.builder.AgentBuilder;
3130
import net.bytebuddy.asm.Advice;
3231
import net.bytebuddy.asm.AsmVisitorWrapper;
@@ -131,29 +130,24 @@ private void prepareInstrumentation(InstrumenterModule module, int instrumentati
131130

132131
adviceShader = AdviceShader.with(module);
133132

134-
// Resolve helper names lazily, and capture only GC-neutral values (not the module instance)
135-
// so that the instrumenter can still be unloaded after setup, and load $Muzzle via the
136-
// extended class loader like the muzzle check does.
137-
final String instrumentationClass = module.getClass().getName();
138-
final String[] declaredHelperClassNames = module.helperClassNames();
139-
final boolean injectHelperDependencies = module.injectHelperDependencies();
133+
// Resolve helper names eagerly at install. Only the resolved String[] is captured.
134+
String[] helperClassNames =
135+
InstrumenterModule.loadStaticMuzzleHelperClassNames(
136+
Utils.getExtendedClassLoader(), module.getClass().getName());
137+
if (null == helperClassNames) {
138+
helperClassNames = module.helperClassNames();
139+
}
140+
if (module.injectHelperDependencies()) {
141+
helperClassNames = HelperScanner.withClassDependencies(helperClassNames);
142+
}
140143
helperTransformer =
141-
new HelperTransformer(
142-
module.useAgentCodeSource(),
143-
adviceShader,
144-
module.getClass().getSimpleName(),
145-
() -> {
146-
String[] helperClassNames =
147-
InstrumenterModule.loadStaticMuzzleHelperClassNames(
148-
Utils.getExtendedClassLoader(), instrumentationClass);
149-
if (null == helperClassNames) {
150-
helperClassNames = declaredHelperClassNames;
151-
}
152-
if (injectHelperDependencies) {
153-
helperClassNames = HelperScanner.withClassDependencies(helperClassNames);
154-
}
155-
return helperClassNames;
156-
});
144+
helperClassNames.length > 0
145+
? new HelperTransformer(
146+
module.useAgentCodeSource(),
147+
adviceShader,
148+
module.getClass().getSimpleName(),
149+
helperClassNames)
150+
: null;
157151

158152
postProcessor = module.postProcessor();
159153

@@ -397,7 +391,7 @@ static final class HelperTransformer extends HelperInjector implements AgentBuil
397391
boolean useAgentCodeSource,
398392
AdviceShader adviceShader,
399393
String requestingName,
400-
Supplier<String[]> helperClassNames) {
394+
String... helperClassNames) {
401395
super(useAgentCodeSource, adviceShader, requestingName, helperClassNames);
402396
}
403397
}

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/HelperInjector.java

Lines changed: 3 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
import java.util.Set;
2222
import java.util.WeakHashMap;
2323
import java.util.concurrent.CopyOnWriteArrayList;
24-
import java.util.function.Supplier;
2524
import net.bytebuddy.description.type.TypeDescription;
2625
import net.bytebuddy.dynamic.ClassFileLocator;
2726
import net.bytebuddy.dynamic.DynamicType;
@@ -43,10 +42,7 @@ public class HelperInjector implements Instrumenter.TransformingAdvice {
4342
private final AdviceShader adviceShader;
4443
private final String requestingName;
4544

46-
// Helper names are resolved lazily: when a supplier is provided, resolution is deferred to the
47-
// first transform() so that we don't load the generated $Muzzle class at agent install.
48-
private final Supplier<String[]> helperClassNamesSupplier;
49-
private volatile Set<String> helperClassNames;
45+
private final Set<String> helperClassNames;
5046
private final Map<String, byte[]> dynamicTypeMap = new LinkedHashMap<>();
5147

5248
private final Map<ClassLoader, Boolean> injectedClassLoaders =
@@ -81,27 +77,9 @@ public HelperInjector(
8177
this.requestingName = requestingName;
8278
this.adviceShader = adviceShader;
8379

84-
this.helperClassNamesSupplier = null;
8580
this.helperClassNames = new LinkedHashSet<>(asList(helperClassNames));
8681
}
8782

88-
/**
89-
* Construct HelperInjector whose helper names are resolved lazily on first {@link #transform}, to
90-
* avoid resolving them (which may load the generated {@code $Muzzle} class) at agent install.
91-
*/
92-
public HelperInjector(
93-
final boolean useAgentCodeSource,
94-
final AdviceShader adviceShader,
95-
final String requestingName,
96-
final Supplier<String[]> helperClassNamesSupplier) {
97-
this.useAgentCodeSource = useAgentCodeSource;
98-
this.requestingName = requestingName;
99-
this.adviceShader = adviceShader;
100-
101-
this.helperClassNamesSupplier = helperClassNamesSupplier;
102-
this.helperClassNames = null;
103-
}
104-
10583
public HelperInjector(
10684
final boolean useAgentCodeSource,
10785
final String requestingName,
@@ -110,27 +88,11 @@ public HelperInjector(
11088
this.requestingName = requestingName;
11189
this.adviceShader = null;
11290

113-
this.helperClassNamesSupplier = null;
11491
helperClassNames = helperMap.keySet();
11592
dynamicTypeMap.putAll(helperMap);
11693
}
11794

118-
/** Resolves helper class names, deferring to the supplier when one's provided. */
119-
private Set<String> resolveHelperClassNames() {
120-
Set<String> names = helperClassNames;
121-
if (names == null) {
122-
synchronized (this) {
123-
names = helperClassNames;
124-
if (names == null) {
125-
names = new LinkedHashSet<>(asList(helperClassNamesSupplier.get()));
126-
helperClassNames = names;
127-
}
128-
}
129-
}
130-
return names;
131-
}
132-
133-
private Map<String, byte[]> getHelperMap(final Set<String> helperClassNames) throws IOException {
95+
private Map<String, byte[]> getHelperMap() throws IOException {
13496
if (dynamicTypeMap.isEmpty()) {
13597
final Map<String, byte[]> classnameToBytes = new LinkedHashMap<>();
13698
for (String helperName : helperClassNames) {
@@ -155,7 +117,6 @@ public DynamicType.Builder<?> transform(
155117
ClassLoader classLoader,
156118
final JavaModule module,
157119
final ProtectionDomain pd) {
158-
final Set<String> helperClassNames = resolveHelperClassNames();
159120
if (!helperClassNames.isEmpty()) {
160121
if (classLoader == null) {
161122
throw new UnsupportedOperationException(
@@ -174,7 +135,7 @@ public DynamicType.Builder<?> transform(
174135
String.join(",", helperClassNames));
175136
}
176137

177-
final Map<String, byte[]> classnameToBytes = getHelperMap(helperClassNames);
138+
final Map<String, byte[]> classnameToBytes = getHelperMap();
178139
final Collection<Class<?>> classes = injectClassLoader(classLoader, classnameToBytes);
179140

180141
// all datadog helper classes are in the unnamed module

0 commit comments

Comments
 (0)