Skip to content

Commit 39767bb

Browse files
authored
Remove legacy agent installer (#6797)
1 parent 4fa5f84 commit 39767bb

File tree

6 files changed

+120
-346
lines changed

6 files changed

+120
-346
lines changed

dd-java-agent/agent-builder/src/main/java/datadog/trace/agent/tooling/AbstractTransformerBuilder.java

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

dd-java-agent/agent-builder/src/main/java/datadog/trace/agent/tooling/AgentInstaller.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -189,12 +189,8 @@ public static ClassFileTransformer installBytebuddyAgent(
189189
}
190190
}
191191

192-
AbstractTransformerBuilder transformerBuilder;
193-
if (InstrumenterConfig.get().isLegacyInstallerEnabled()) {
194-
transformerBuilder = new LegacyTransformerBuilder(agentBuilder);
195-
} else {
196-
transformerBuilder = new CombiningTransformerBuilder(agentBuilder, maxInstrumentationId);
197-
}
192+
CombiningTransformerBuilder transformerBuilder =
193+
new CombiningTransformerBuilder(agentBuilder, maxInstrumentationId);
198194

199195
int installedCount = 0;
200196
for (Instrumenter instrumenter : instrumenters) {

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

Lines changed: 118 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import static datadog.trace.agent.tooling.bytebuddy.DDTransformers.defaultTransformers;
44
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.ANY_CLASS_LOADER;
5+
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.hasClassNamed;
6+
import static datadog.trace.agent.tooling.bytebuddy.matcher.ClassLoaderMatchers.hasClassNamedOneOf;
7+
import static datadog.trace.agent.tooling.bytebuddy.matcher.HierarchyMatchers.declaresAnnotation;
58
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf;
69
import static net.bytebuddy.matcher.ElementMatchers.not;
710

@@ -14,19 +17,38 @@
1417
import datadog.trace.api.InstrumenterConfig;
1518
import java.lang.instrument.ClassFileTransformer;
1619
import java.lang.instrument.Instrumentation;
20+
import java.security.ProtectionDomain;
1721
import java.util.ArrayList;
1822
import java.util.Arrays;
1923
import java.util.BitSet;
2024
import java.util.Collection;
25+
import java.util.HashMap;
2126
import java.util.List;
2227
import java.util.Map;
2328
import net.bytebuddy.agent.builder.AgentBuilder;
2429
import net.bytebuddy.asm.Advice;
30+
import net.bytebuddy.asm.AsmVisitorWrapper;
2531
import net.bytebuddy.description.method.MethodDescription;
32+
import net.bytebuddy.description.type.TypeDescription;
33+
import net.bytebuddy.dynamic.DynamicType;
2634
import net.bytebuddy.matcher.ElementMatcher;
35+
import net.bytebuddy.utility.JavaModule;
2736

2837
/** Builds multiple instrumentations into a single combining-matcher and splitting-transformer. */
29-
public final class CombiningTransformerBuilder extends AbstractTransformerBuilder {
38+
public final class CombiningTransformerBuilder
39+
implements Instrumenter.TypeTransformer, Instrumenter.MethodTransformer {
40+
41+
// Added here instead of byte-buddy's ignores because it's relatively
42+
// expensive. https://github.com/DataDog/dd-trace-java/pull/1045
43+
private static final ElementMatcher.Junction<TypeDescription> NOT_DECORATOR_MATCHER =
44+
not(
45+
declaresAnnotation(
46+
namedOneOf("javax.decorator.Decorator", "jakarta.decorator.Decorator")));
47+
48+
/** Associates context stores with the class-loader matchers to activate them. */
49+
private final Map<Map.Entry<String, String>, ElementMatcher<ClassLoader>> contextStoreInjection =
50+
new HashMap<>();
51+
3052
private final AgentBuilder agentBuilder;
3153

3254
private final List<MatchRecorder> matchers = new ArrayList<>();
@@ -52,8 +74,21 @@ public CombiningTransformerBuilder(AgentBuilder agentBuilder, int maxInstrumenta
5274
this.nextSupplementaryId = maxInstrumentationId + 1;
5375
}
5476

55-
@Override
56-
protected void buildInstrumentation(InstrumenterModule module, Instrumenter member) {
77+
public void applyInstrumentation(Instrumenter instrumenter) {
78+
if (instrumenter instanceof InstrumenterModule) {
79+
InstrumenterModule module = (InstrumenterModule) instrumenter;
80+
if (module.isEnabled()) {
81+
InstrumenterState.registerInstrumentation(module);
82+
for (Instrumenter member : module.typeInstrumentations()) {
83+
buildInstrumentation(module, member);
84+
}
85+
}
86+
} else {
87+
throw new IllegalArgumentException("Unexpected Instrumenter type");
88+
}
89+
}
90+
91+
private void buildInstrumentation(InstrumenterModule module, Instrumenter member) {
5792

5893
int id = module.instrumentationId();
5994
if (module != member) {
@@ -161,8 +196,51 @@ public void applyAdvice(ElementMatcher<? super MethodDescription> matcher, Strin
161196
.advice(not(ignoredMethods).and(matcher), className));
162197
}
163198

164-
@Override
165-
protected void applyContextStoreInjection(
199+
/** Counts the number of distinct context store injections registered with this builder. */
200+
private int contextStoreCount() {
201+
return contextStoreInjection.size();
202+
}
203+
204+
/** Applies each context store injection, guarded by the associated class-loader matcher. */
205+
private void applyContextStoreInjection() {
206+
contextStoreInjection.forEach(this::applyContextStoreInjection);
207+
}
208+
209+
/** Tracks which class-loader matchers are associated with each store request. */
210+
private void registerContextStoreInjection(
211+
InstrumenterModule module, Instrumenter member, Map<String, String> contextStore) {
212+
ElementMatcher<ClassLoader> activation;
213+
214+
if (member instanceof Instrumenter.ForBootstrap) {
215+
activation = ANY_CLASS_LOADER;
216+
} else if (member instanceof Instrumenter.ForTypeHierarchy) {
217+
String hierarchyHint = ((Instrumenter.ForTypeHierarchy) member).hierarchyMarkerType();
218+
activation = null != hierarchyHint ? hasClassNamed(hierarchyHint) : ANY_CLASS_LOADER;
219+
} else if (member instanceof Instrumenter.ForSingleType) {
220+
activation = hasClassNamed(((Instrumenter.ForSingleType) member).instrumentedType());
221+
} else if (member instanceof Instrumenter.ForKnownTypes) {
222+
activation = hasClassNamedOneOf(((Instrumenter.ForKnownTypes) member).knownMatchingTypes());
223+
} else {
224+
activation = ANY_CLASS_LOADER;
225+
}
226+
227+
activation = requireBoth(activation, module.classLoaderMatcher());
228+
229+
for (Map.Entry<String, String> storeEntry : contextStore.entrySet()) {
230+
ElementMatcher<ClassLoader> oldActivation = contextStoreInjection.get(storeEntry);
231+
// optimization: treat 'any' as if there wasn't an old matcher
232+
if (null == oldActivation || ANY_CLASS_LOADER == activation) {
233+
contextStoreInjection.put(storeEntry, activation);
234+
} else if (ANY_CLASS_LOADER != oldActivation) {
235+
// store can be activated by either the old OR new matcher
236+
contextStoreInjection.put(
237+
storeEntry, new ElementMatcher.Junction.Disjunction<>(oldActivation, activation));
238+
}
239+
}
240+
}
241+
242+
/** Arranges for a context value field to be injected into types extending the context key. */
243+
private void applyContextStoreInjection(
166244
Map.Entry<String, String> contextStore, ElementMatcher<ClassLoader> activation) {
167245
String keyClassName = contextStore.getKey();
168246
String contextClassName = contextStore.getValue();
@@ -178,7 +256,6 @@ protected void applyContextStoreInjection(
178256
transformers[id] = new AdviceStack(new VisitingTransformer(contextAdvice));
179257
}
180258

181-
@Override
182259
public ClassFileTransformer installOn(Instrumentation instrumentation) {
183260
if (InstrumenterConfig.get().isRuntimeContextFieldInjection()) {
184261
// expand so we have enough space for a context injecting transformer for each store
@@ -193,4 +270,39 @@ public ClassFileTransformer installOn(Instrumentation instrumentation) {
193270
.transform(new SplittingTransformer(transformers))
194271
.installOn(instrumentation);
195272
}
273+
274+
static final class VisitingTransformer implements AgentBuilder.Transformer {
275+
private final AsmVisitorWrapper visitor;
276+
277+
VisitingTransformer(AsmVisitorWrapper visitor) {
278+
this.visitor = visitor;
279+
}
280+
281+
@Override
282+
public DynamicType.Builder<?> transform(
283+
DynamicType.Builder<?> builder,
284+
TypeDescription typeDescription,
285+
ClassLoader classLoader,
286+
JavaModule module,
287+
ProtectionDomain pd) {
288+
return builder.visit(visitor);
289+
}
290+
}
291+
292+
static final class HelperTransformer extends HelperInjector implements AgentBuilder.Transformer {
293+
HelperTransformer(String requestingName, String... helperClassNames) {
294+
super(requestingName, helperClassNames);
295+
}
296+
}
297+
298+
static ElementMatcher<ClassLoader> requireBoth(
299+
ElementMatcher<ClassLoader> lhs, ElementMatcher<ClassLoader> rhs) {
300+
if (ANY_CLASS_LOADER == lhs) {
301+
return rhs;
302+
} else if (ANY_CLASS_LOADER == rhs) {
303+
return lhs;
304+
} else {
305+
return new ElementMatcher.Junction.Conjunction<>(lhs, rhs);
306+
}
307+
}
196308
}

0 commit comments

Comments
 (0)