Skip to content

Commit bb3eabd

Browse files
committed
Introduce marker mechanism for eagerly initializing helpers, and use it to register AsyncResultExtensions
1 parent 207f770 commit bb3eabd

File tree

12 files changed

+55
-54
lines changed

12 files changed

+55
-54
lines changed

dd-java-agent/agent-bootstrap/src/main/java/datadog/trace/bootstrap/instrumentation/java/concurrent/AsyncResultExtensions.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static java.util.Collections.singletonList;
44

5+
import datadog.trace.api.Platform;
56
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
67
import java.util.List;
78
import java.util.concurrent.CompletableFuture;
@@ -22,6 +23,15 @@ public final class AsyncResultExtensions {
2223
*/
2324
public static void register(AsyncResultExtension extension) {
2425
if (extension != null) {
26+
if (Platform.isNativeImageBuilder()
27+
&& extension
28+
.getClass()
29+
.getClassLoader()
30+
.getClass()
31+
.getName()
32+
.endsWith("ThrowawayClassLoader")) {
33+
return; // spring-native expects this to be thrown away, not persisted
34+
}
2535
EXTENSIONS.add(extension);
2636
}
2737
}

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static datadog.trace.bootstrap.AgentClassLoading.INJECTING_HELPERS;
44

5+
import datadog.trace.bootstrap.instrumentation.api.EagerHelper;
56
import java.io.IOException;
67
import java.lang.ref.WeakReference;
78
import java.security.CodeSource;
@@ -124,6 +125,18 @@ public DynamicType.Builder<?> transform(
124125
final JavaModule javaModule = JavaModule.ofType(classes.values().iterator().next());
125126
helperModules.add(new WeakReference<>(javaModule.unwrap()));
126127
}
128+
129+
// forcibly initialize any eager helpers
130+
for (Class<?> clazz : classes.values()) {
131+
if (EagerHelper.class.isAssignableFrom(clazz)) {
132+
try {
133+
clazz.getMethod("init").invoke(null);
134+
} catch (Throwable e) {
135+
log.debug("Problem initializing {}", clazz, e);
136+
}
137+
}
138+
}
139+
127140
} catch (final Exception e) {
128141
if (log.isErrorEnabled()) {
129142
log.error(

dd-java-agent/instrumentation/graal/native-image/src/main/java/datadog/trace/instrumentation/graal/nativeimage/NativeImageGeneratorRunnerInstrumentation.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ public static void onEnter(@Advice.Argument(value = 0, readOnly = false) String[
9696
+ "datadog.trace.bootstrap.benchmark.StaticEventLogger:build_time,"
9797
+ "datadog.trace.bootstrap.blocking.BlockingExceptionHandler:build_time,"
9898
+ "datadog.trace.bootstrap.InstrumentationErrors:build_time,"
99-
+ "datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtensions:rerun,"
99+
+ "datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtensions:build_time,"
100100
+ "datadog.trace.bootstrap.instrumentation.java.concurrent.ConcurrentState:build_time,"
101101
+ "datadog.trace.bootstrap.instrumentation.java.concurrent.ExcludeFilter:build_time,"
102102
+ "datadog.trace.bootstrap.instrumentation.java.concurrent.QueueTimeHelper:build_time,"
@@ -105,6 +105,10 @@ public static void onEnter(@Advice.Argument(value = 0, readOnly = false) String[
105105
+ "datadog.trace.bootstrap.instrumentation.jfr.exceptions.ExceptionSampleEvent:build_time,"
106106
+ "datadog.trace.bootstrap.instrumentation.jfr.backpressure.BackpressureSampleEvent:build_time,"
107107
+ "datadog.trace.bootstrap.instrumentation.jfr.directallocation.DirectAllocationTotalEvent:build_time,"
108+
+ "datadog.trace.instrumentation.guava10.GuavaAsyncResultExtension:build_time,"
109+
+ "datadog.trace.instrumentation.reactivestreams.ReactiveStreamsAsyncResultExtension:build_time,"
110+
+ "datadog.trace.instrumentation.reactor.core.ReactorAsyncResultExtension:build_time,"
111+
+ "datadog.trace.instrumentation.rxjava2.RxJavaAsyncResultExtension:build_time,"
108112
+ "datadog.trace.logging.LoggingSettingsDescription:build_time,"
109113
+ "datadog.trace.logging.simplelogger.SLCompatFactory:build_time,"
110114
+ "datadog.trace.logging.LogReporter:build_time,"

dd-java-agent/instrumentation/guava-10/src/main/java/datadog/trace/instrumentation/guava10/GuavaAsyncResultExtension.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
import com.google.common.util.concurrent.ListenableFuture;
44
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
5+
import datadog.trace.bootstrap.instrumentation.api.EagerHelper;
56
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtension;
67
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtensions;
78
import java.util.concurrent.CancellationException;
89
import java.util.concurrent.ExecutionException;
910

10-
public class GuavaAsyncResultExtension implements AsyncResultExtension {
11+
public class GuavaAsyncResultExtension implements AsyncResultExtension, EagerHelper {
1112
static {
1213
AsyncResultExtensions.register(new GuavaAsyncResultExtension());
1314
}
@@ -19,7 +20,7 @@ public class GuavaAsyncResultExtension implements AsyncResultExtension {
1920
* class initialization. This will ensure this extension will only be registered once under {@link
2021
* AsyncResultExtensions}.
2122
*/
22-
public static void initialize() {}
23+
public static void init() {}
2324

2425
@Override
2526
public boolean supports(Class<?> result) {

dd-java-agent/instrumentation/guava-10/src/main/java/datadog/trace/instrumentation/guava10/ListenableFutureInstrumentation.java

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
44
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeScope;
55
import static java.util.Collections.singletonMap;
6-
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
76
import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
87

98
import com.google.auto.service.AutoService;
@@ -47,20 +46,11 @@ public Map<String, String> contextStore() {
4746

4847
@Override
4948
public void methodAdvice(MethodTransformer transformer) {
50-
transformer.applyAdvice(
51-
isConstructor(), ListenableFutureInstrumentation.class.getName() + "$AbstractFutureAdvice");
5249
transformer.applyAdvice(
5350
named("addListener").and(takesArguments(Runnable.class, Executor.class)),
5451
ListenableFutureInstrumentation.class.getName() + "$AddListenerAdvice");
5552
}
5653

57-
public static class AbstractFutureAdvice {
58-
@Advice.OnMethodExit(suppress = Throwable.class)
59-
public static void init() {
60-
GuavaAsyncResultExtension.initialize();
61-
}
62-
}
63-
6454
public static class AddListenerAdvice {
6555
@Advice.OnMethodEnter(suppress = Throwable.class)
6656
public static State addListenerEnter(

dd-java-agent/instrumentation/reactive-streams/src/main/java/datadog/trace/instrumentation/reactivestreams/PublisherInstrumentation.java

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
66
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
77
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activeSpan;
8-
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
98
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
109
import static net.bytebuddy.matcher.ElementMatchers.isStatic;
1110
import static net.bytebuddy.matcher.ElementMatchers.not;
@@ -69,7 +68,6 @@ public String[] helperClassNames() {
6968

7069
@Override
7170
public void methodAdvice(MethodTransformer transformer) {
72-
transformer.applyAdvice(isConstructor(), this.getClass().getName() + "$PublisherAdvice");
7371
transformer.applyAdvice(
7472
isMethod()
7573
.and(not(isStatic()))
@@ -79,13 +77,6 @@ public void methodAdvice(MethodTransformer transformer) {
7977
getClass().getName() + "$PublisherSubscribeAdvice");
8078
}
8179

82-
public static class PublisherAdvice {
83-
@Advice.OnMethodExit(suppress = Throwable.class)
84-
public static void init() {
85-
ReactiveStreamsAsyncResultExtension.initialize();
86-
}
87-
}
88-
8980
public static class PublisherSubscribeAdvice {
9081
@Advice.OnMethodEnter(suppress = Throwable.class)
9182
public static AgentScope onSubscribe(

dd-java-agent/instrumentation/reactive-streams/src/main/java/datadog/trace/instrumentation/reactivestreams/ReactiveStreamsAsyncResultExtension.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
package datadog.trace.instrumentation.reactivestreams;
22

33
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
4+
import datadog.trace.bootstrap.instrumentation.api.EagerHelper;
45
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtension;
56
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtensions;
67
import org.reactivestreams.Publisher;
78
import org.reactivestreams.Subscriber;
89
import org.reactivestreams.Subscription;
910

10-
public class ReactiveStreamsAsyncResultExtension implements AsyncResultExtension {
11+
public class ReactiveStreamsAsyncResultExtension implements AsyncResultExtension, EagerHelper {
1112
static {
1213
AsyncResultExtensions.register(new ReactiveStreamsAsyncResultExtension());
1314
}
@@ -19,7 +20,7 @@ public class ReactiveStreamsAsyncResultExtension implements AsyncResultExtension
1920
* class initialization. This will ensure this extension will only be registered once under {@link
2021
* AsyncResultExtensions}.
2122
*/
22-
public static void initialize() {}
23+
public static void init() {}
2324

2425
@Override
2526
public boolean supports(Class<?> result) {

dd-java-agent/instrumentation/reactor-core-3.1/src/main/java/datadog/trace/instrumentation/reactor/core/BlockingPublisherInstrumentation.java

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.nameStartsWith;
55
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.namedOneOf;
66
import static datadog.trace.bootstrap.instrumentation.api.AgentTracer.activateSpan;
7-
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
87
import static net.bytebuddy.matcher.ElementMatchers.isMethod;
98

109
import com.google.auto.service.AutoService;
@@ -40,13 +39,6 @@ public String[] helperClassNames() {
4039
};
4140
}
4241

43-
@Override
44-
public void methodAdvice(MethodTransformer transformer) {
45-
transformer.applyAdvice(isConstructor(), getClass().getName() + "$AsyncExtensionInstallAdvice");
46-
transformer.applyAdvice(
47-
isMethod().and(nameStartsWith("block")), getClass().getName() + "$BlockingAdvice");
48-
}
49-
5042
@Override
5143
public Map<String, String> contextStore() {
5244
return Collections.singletonMap("org.reactivestreams.Publisher", AgentSpan.class.getName());
@@ -62,6 +54,12 @@ public ElementMatcher<TypeDescription> hierarchyMatcher() {
6254
return hasSuperType(namedOneOf("reactor.core.publisher.Mono", "reactor.core.publisher.Flux"));
6355
}
6456

57+
@Override
58+
public void methodAdvice(MethodTransformer transformer) {
59+
transformer.applyAdvice(
60+
isMethod().and(nameStartsWith("block")), getClass().getName() + "$BlockingAdvice");
61+
}
62+
6563
public static class BlockingAdvice {
6664
@Advice.OnMethodEnter(suppress = Throwable.class)
6765
public static AgentScope before(@Advice.This final Publisher self) {
@@ -79,11 +77,4 @@ public static void after(@Advice.Enter final AgentScope scope) {
7977
}
8078
}
8179
}
82-
83-
public static class AsyncExtensionInstallAdvice {
84-
@Advice.OnMethodExit(suppress = Throwable.class)
85-
public static void init() {
86-
ReactorAsyncResultExtension.initialize();
87-
}
88-
}
8980
}

dd-java-agent/instrumentation/reactor-core-3.1/src/main/java/datadog/trace/instrumentation/reactor/core/ReactorAsyncResultExtension.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
package datadog.trace.instrumentation.reactor.core;
22

33
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
4+
import datadog.trace.bootstrap.instrumentation.api.EagerHelper;
45
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtension;
56
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtensions;
67
import reactor.core.publisher.Flux;
78
import reactor.core.publisher.Mono;
89

9-
public class ReactorAsyncResultExtension implements AsyncResultExtension {
10+
public class ReactorAsyncResultExtension implements AsyncResultExtension, EagerHelper {
1011
static {
1112
AsyncResultExtensions.register(new ReactorAsyncResultExtension());
1213
}
@@ -18,7 +19,7 @@ public class ReactorAsyncResultExtension implements AsyncResultExtension {
1819
* class initialization. This will ensure this extension will only be registered once under {@link
1920
* AsyncResultExtensions}.
2021
*/
21-
public static void initialize() {}
22+
public static void init() {}
2223

2324
@Override
2425
public boolean supports(Class<?> result) {

dd-java-agent/instrumentation/rxjava-2/src/main/java/datadog/trace/instrumentation/rxjava2/RxJavaAsyncResultExtension.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package datadog.trace.instrumentation.rxjava2;
22

33
import datadog.trace.bootstrap.instrumentation.api.AgentSpan;
4+
import datadog.trace.bootstrap.instrumentation.api.EagerHelper;
45
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtension;
56
import datadog.trace.bootstrap.instrumentation.java.concurrent.AsyncResultExtensions;
67
import io.reactivex.Completable;
@@ -9,7 +10,7 @@
910
import io.reactivex.Observable;
1011
import io.reactivex.Single;
1112

12-
public class RxJavaAsyncResultExtension implements AsyncResultExtension {
13+
public class RxJavaAsyncResultExtension implements AsyncResultExtension, EagerHelper {
1314
static {
1415
AsyncResultExtensions.register(new RxJavaAsyncResultExtension());
1516
}
@@ -21,7 +22,7 @@ public class RxJavaAsyncResultExtension implements AsyncResultExtension {
2122
* class initialization. This will ensure this extension will only be registered once under {@link
2223
* AsyncResultExtensions}.
2324
*/
24-
public static void initialize() {}
25+
public static void init() {}
2526

2627
@Override
2728
public boolean supports(Class<?> result) {

0 commit comments

Comments
 (0)