Skip to content

Commit 5586d54

Browse files
fix: avoid final field modification in Weaver instrumentation
1 parent 11646d3 commit 5586d54

1 file changed

Lines changed: 27 additions & 27 deletions

File tree

dd-java-agent/instrumentation/weaver-0.9/src/main/java/datadog/trace/instrumentation/weaver/WeaverInstrumentation.java

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package datadog.trace.instrumentation.weaver;
22

3+
import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named;
34
import static net.bytebuddy.matcher.ElementMatchers.isConstructor;
5+
import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
46

57
import com.google.auto.service.AutoService;
68
import datadog.trace.agent.tooling.Instrumenter;
79
import datadog.trace.agent.tooling.InstrumenterModule;
8-
import de.thetaphi.forbiddenapis.SuppressForbidden;
9-
import java.lang.reflect.Field;
1010
import java.util.concurrent.ConcurrentLinkedQueue;
1111
import java.util.concurrent.LinkedBlockingQueue;
1212
import net.bytebuddy.asm.Advice;
@@ -38,34 +38,34 @@ public String[] helperClassNames() {
3838

3939
@Override
4040
public void methodAdvice(MethodTransformer transformer) {
41+
// disney's implementation (0.8.4+) uses a ConcurrentLinkedQueue
4142
transformer.applyAdvice(
42-
isConstructor(), WeaverInstrumentation.class.getName() + "$SbtTaskCreationAdvice");
43+
isConstructor().and(takesArgument(5, named("java.util.concurrent.ConcurrentLinkedQueue"))),
44+
WeaverInstrumentation.class.getName() + "$ConcurrentLinkedQueueAdvice");
45+
// typelevel's implementation (0.9+) uses a LinkedBlockingQueue
46+
transformer.applyAdvice(
47+
isConstructor().and(takesArgument(5, named("java.util.concurrent.LinkedBlockingQueue"))),
48+
WeaverInstrumentation.class.getName() + "$LinkedBlockingQueueAdvice");
49+
}
50+
51+
public static class ConcurrentLinkedQueueAdvice {
52+
@Advice.OnMethodEnter(suppress = Throwable.class)
53+
public static void wrapQueue(
54+
@Advice.Argument(0) TaskDef taskDef,
55+
@Advice.Argument(value = 5, readOnly = false) ConcurrentLinkedQueue<SuiteEvent> queue) {
56+
if (!(queue instanceof TaskDefAwareConcurrentLinkedQueueProxy)) {
57+
queue = new TaskDefAwareConcurrentLinkedQueueProxy<>(taskDef, queue);
58+
}
59+
}
4360
}
4461

45-
public static class SbtTaskCreationAdvice {
46-
// TODO: JEP 500 - avoid mutating final fields
47-
@SuppressForbidden
48-
@Advice.OnMethodExit(suppress = Throwable.class)
49-
public static void onTaskCreation(
50-
@Advice.This Object sbtTask, @Advice.FieldValue("taskDef") TaskDef taskDef) {
51-
try {
52-
Field queueField = sbtTask.getClass().getDeclaredField("queue");
53-
queueField.setAccessible(true);
54-
Object queue = queueField.get(sbtTask);
55-
if (queue instanceof ConcurrentLinkedQueue) {
56-
// disney's implementation (0.8.4+) uses a ConcurrentLinkedQueue for the field
57-
queueField.set(
58-
sbtTask,
59-
new TaskDefAwareConcurrentLinkedQueueProxy<SuiteEvent>(
60-
taskDef, (ConcurrentLinkedQueue<SuiteEvent>) queue));
61-
} else if (queue instanceof LinkedBlockingQueue) {
62-
// typelevel's implementation (0.9+) uses a LinkedBlockingQueue for the field
63-
queueField.set(
64-
sbtTask,
65-
new TaskDefAwareLinkedBlockingQueueProxy<SuiteEvent>(
66-
taskDef, (LinkedBlockingQueue<SuiteEvent>) queue));
67-
}
68-
} catch (Exception ignored) {
62+
public static class LinkedBlockingQueueAdvice {
63+
@Advice.OnMethodEnter(suppress = Throwable.class)
64+
public static void wrapQueue(
65+
@Advice.Argument(0) TaskDef taskDef,
66+
@Advice.Argument(value = 5, readOnly = false) LinkedBlockingQueue<SuiteEvent> queue) {
67+
if (!(queue instanceof TaskDefAwareLinkedBlockingQueueProxy)) {
68+
queue = new TaskDefAwareLinkedBlockingQueueProxy<>(taskDef, queue);
6969
}
7070
}
7171
}

0 commit comments

Comments
 (0)