Skip to content

Commit 0e1d307

Browse files
committed
Add support for non-visitor based class parsing (via dd-instrument-java)
1 parent 1128695 commit 0e1d307

File tree

6 files changed

+63
-11
lines changed

6 files changed

+63
-11
lines changed

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/AnnotationOutline.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,17 @@ final class AnnotationOutline extends WithName implements AnnotationDescription
1717
private static final Map<String, AnnotationDescription> annotationOutlines = new HashMap<>();
1818

1919
static void prepareAnnotationOutline(String name) {
20-
String descriptor = 'L' + name.replace('.', '/') + ';';
21-
annotationOutlines.put(descriptor, new AnnotationOutline(name));
20+
// only a few annotation outlines get prepared - we register them under
21+
// both their internal name and descriptor to support different callers
22+
AnnotationOutline annotationOutline = new AnnotationOutline(name);
23+
String internalName = name.replace('.', '/');
24+
annotationOutlines.put('L' + internalName + ';', annotationOutline);
25+
annotationOutlines.put(internalName, annotationOutline);
2226
}
2327

2428
/** Only provide outlines of annotations of interest used for matching. */
25-
static AnnotationDescription annotationOutline(String descriptor) {
26-
return annotationOutlines.get(descriptor);
29+
static AnnotationDescription annotationOutline(String internalNameOrDescriptor) {
30+
return annotationOutlines.get(internalNameOrDescriptor);
2731
}
2832

2933
private AnnotationOutline(String name) {

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/OutlineTypeParser.java

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
import static net.bytebuddy.jar.asm.ClassReader.SKIP_CODE;
55
import static net.bytebuddy.jar.asm.ClassReader.SKIP_DEBUG;
66

7+
import datadog.instrument.classmatch.ClassFile;
8+
import datadog.trace.api.InstrumenterConfig;
79
import java.lang.annotation.Annotation;
810
import java.lang.reflect.Field;
911
import java.lang.reflect.Method;
@@ -18,13 +20,19 @@
1820

1921
/** Attempts a minimal parse of just the named elements we need for matching. */
2022
final class OutlineTypeParser implements TypeParser {
23+
private static final boolean visitorClassParsing =
24+
InstrumenterConfig.get().isVisitorClassParsing();
2125

2226
@Override
2327
public TypeDescription parse(byte[] bytecode) {
24-
ClassReader classReader = OpenedClassReader.of(bytecode);
25-
OutlineTypeExtractor typeExtractor = new OutlineTypeExtractor();
26-
classReader.accept(typeExtractor, SKIP_CODE | SKIP_DEBUG);
27-
return typeExtractor.typeOutline;
28+
if (visitorClassParsing) {
29+
ClassReader classReader = OpenedClassReader.of(bytecode);
30+
OutlineTypeExtractor typeExtractor = new OutlineTypeExtractor();
31+
classReader.accept(typeExtractor, SKIP_CODE | SKIP_DEBUG);
32+
return typeExtractor.typeOutline;
33+
} else {
34+
return new TypeOutline(ClassFile.outline(bytecode));
35+
}
2836
}
2937

3038
@Override
@@ -39,7 +47,7 @@ public TypeDescription parse(Class<?> loadedType) {
3947
extractTypeNames(loadedType.getInterfaces()));
4048

4149
for (Annotation a : loadedType.getDeclaredAnnotations()) {
42-
typeOutline.declare(annotationOutline(Type.getDescriptor(a.annotationType())));
50+
typeOutline.declare(annotationOutline(Type.getInternalName(a.annotationType())));
4351
}
4452

4553
for (Field field : loadedType.getDeclaredFields()) {
@@ -50,7 +58,7 @@ public TypeDescription parse(Class<?> loadedType) {
5058
field.getName(),
5159
Type.getDescriptor(field.getType()));
5260
for (Annotation a : field.getDeclaredAnnotations()) {
53-
fieldOutline.declare(annotationOutline(Type.getDescriptor(a.annotationType())));
61+
fieldOutline.declare(annotationOutline(Type.getInternalName(a.annotationType())));
5462
}
5563
typeOutline.declare(fieldOutline);
5664
}
@@ -63,7 +71,7 @@ public TypeDescription parse(Class<?> loadedType) {
6371
method.getName(),
6472
Type.getMethodDescriptor(method));
6573
for (Annotation a : method.getDeclaredAnnotations()) {
66-
methodOutline.declare(annotationOutline(Type.getDescriptor(a.annotationType())));
74+
methodOutline.declare(annotationOutline(Type.getInternalName(a.annotationType())));
6775
}
6876
typeOutline.declare(methodOutline);
6977
}

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypeOutline.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package datadog.trace.agent.tooling.bytebuddy.outline;
22

3+
import static datadog.trace.agent.tooling.bytebuddy.outline.AnnotationOutline.annotationOutline;
34
import static datadog.trace.agent.tooling.bytebuddy.outline.TypeFactory.findType;
45

6+
import datadog.instrument.classmatch.ClassOutline;
57
import java.util.ArrayList;
68
import java.util.List;
79
import net.bytebuddy.description.annotation.AnnotationDescription;
@@ -42,6 +44,29 @@ final class TypeOutline extends WithName {
4244
this.interfaces = interfaces;
4345
}
4446

47+
public TypeOutline(ClassOutline outline) {
48+
super(outline.className.replace('/', '.'));
49+
this.modifiers = outline.access & ALLOWED_TYPE_MODIFIERS;
50+
this.superName = outline.superName;
51+
this.interfaces = outline.interfaces;
52+
53+
for (String annotation : outline.annotations) {
54+
declare(annotationOutline(annotation));
55+
}
56+
57+
for (datadog.instrument.classmatch.FieldOutline f : outline.fields) {
58+
declare(new FieldOutline(this, f.access, f.fieldName, f.descriptor));
59+
}
60+
61+
for (datadog.instrument.classmatch.MethodOutline m : outline.methods) {
62+
MethodOutline method = new MethodOutline(this, m.access, m.methodName, m.descriptor);
63+
for (String annotation : m.annotations) {
64+
method.declare(annotationOutline(annotation));
65+
}
66+
declare(method);
67+
}
68+
}
69+
4570
@Override
4671
protected TypeDescription delegate() {
4772
throw new IllegalStateException("Not available in outline for " + name);

dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/bytebuddy/outline/TypePoolFacade.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import static datadog.trace.agent.tooling.bytebuddy.outline.TypeFactory.findType;
55
import static datadog.trace.agent.tooling.bytebuddy.outline.TypeFactory.typeFactory;
66

7+
import datadog.instrument.classmatch.ClassFile;
78
import datadog.trace.agent.tooling.bytebuddy.SharedTypePools;
89
import datadog.trace.agent.tooling.bytebuddy.memoize.Memoizer;
910
import datadog.trace.api.InstrumenterConfig;
@@ -36,6 +37,9 @@ public static ClassLoader currentContext() {
3637

3738
@Override
3839
public void annotationOfInterest(String name) {
40+
if (!InstrumenterConfig.get().isVisitorClassParsing()) {
41+
ClassFile.annotationOfInterest(name.replace('.', '/'));
42+
}
3943
AnnotationOutline.prepareAnnotationOutline(name);
4044
}
4145

dd-trace-api/src/main/java/datadog/trace/api/config/TraceInstrumentationConfig.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,9 @@ public final class TraceInstrumentationConfig {
159159
public static final String RESOLVER_USE_URL_CACHES = "resolver.use.url.caches";
160160
public static final String RESOLVER_RESET_INTERVAL = "resolver.reset.interval";
161161
public static final String RESOLVER_NAMES_ARE_UNIQUE = "resolver.names.are.unique";
162+
163+
public static final String VISITOR_CLASS_PARSING = "visitor.class.parsing";
164+
162165
public static final String CASSANDRA_KEYSPACE_STATEMENT_EXTRACTION_ENABLED =
163166
"trace.cassandra.keyspace.statement.extraction.enabled";
164167
public static final String COUCHBASE_INTERNAL_SPANS_ENABLED =

internal-api/src/main/java/datadog/trace/api/InstrumenterConfig.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@
7373
import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_PEKKO_SCHEDULER_ENABLED;
7474
import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_THREAD_POOL_EXECUTORS_EXCLUDE;
7575
import static datadog.trace.api.config.TraceInstrumentationConfig.TRACE_WEBSOCKET_MESSAGES_ENABLED;
76+
import static datadog.trace.api.config.TraceInstrumentationConfig.VISITOR_CLASS_PARSING;
7677
import static datadog.trace.api.config.UsmConfig.USM_ENABLED;
7778
import static datadog.trace.util.CollectionUtils.tryMakeImmutableList;
7879
import static datadog.trace.util.CollectionUtils.tryMakeImmutableSet;
@@ -161,6 +162,7 @@ public class InstrumenterConfig {
161162
private final boolean resolverUseLoadClass;
162163
private final Boolean resolverUseUrlCaches;
163164
private final int resolverResetInterval;
165+
private final boolean visitorClassParsing;
164166

165167
private final boolean runtimeContextFieldInjection;
166168
private final boolean serialVersionUIDFieldInjection;
@@ -280,6 +282,8 @@ private InstrumenterConfig() {
280282
? 0
281283
: configProvider.getInteger(RESOLVER_RESET_INTERVAL, DEFAULT_RESOLVER_RESET_INTERVAL);
282284

285+
visitorClassParsing = configProvider.getBoolean(VISITOR_CLASS_PARSING, false);
286+
283287
runtimeContextFieldInjection =
284288
configProvider.getBoolean(
285289
RUNTIME_CONTEXT_FIELD_INJECTION, DEFAULT_RUNTIME_CONTEXT_FIELD_INJECTION);
@@ -505,6 +509,10 @@ public String getResolverCacheDir() {
505509
return resolverCacheDir;
506510
}
507511

512+
public boolean isVisitorClassParsing() {
513+
return visitorClassParsing;
514+
}
515+
508516
public String getInstrumentationConfigId() {
509517
return instrumentationConfigId;
510518
}

0 commit comments

Comments
 (0)