|
1 | 1 | package datadog.trace.instrumentation.weaver; |
2 | 2 |
|
| 3 | +import static datadog.trace.agent.tooling.bytebuddy.matcher.NameMatchers.named; |
3 | 4 | import static net.bytebuddy.matcher.ElementMatchers.isConstructor; |
| 5 | +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; |
4 | 6 |
|
5 | 7 | import com.google.auto.service.AutoService; |
6 | 8 | import datadog.trace.agent.tooling.Instrumenter; |
7 | 9 | import datadog.trace.agent.tooling.InstrumenterModule; |
8 | | -import de.thetaphi.forbiddenapis.SuppressForbidden; |
9 | | -import java.lang.reflect.Field; |
10 | 10 | import java.util.concurrent.ConcurrentLinkedQueue; |
11 | 11 | import java.util.concurrent.LinkedBlockingQueue; |
12 | 12 | import net.bytebuddy.asm.Advice; |
@@ -38,34 +38,34 @@ public String[] helperClassNames() { |
38 | 38 |
|
39 | 39 | @Override |
40 | 40 | public void methodAdvice(MethodTransformer transformer) { |
| 41 | + // disney's implementation (0.8.4+) uses a ConcurrentLinkedQueue |
41 | 42 | 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 | + } |
43 | 60 | } |
44 | 61 |
|
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); |
69 | 69 | } |
70 | 70 | } |
71 | 71 | } |
|
0 commit comments