Skip to content

Commit b9ef656

Browse files
SylvainJugelaurit
andauthored
make javaagent-tooling and testing-common indy-ready (#15133)
Co-authored-by: Lauri Tulmin <[email protected]>
1 parent 90fd359 commit b9ef656

File tree

11 files changed

+101
-53
lines changed

11 files changed

+101
-53
lines changed

javaagent-tooling/src/testExceptionHandler/java/io/opentelemetry/javaagent/tooling/bytebuddy/BadAdvice.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,16 @@
55

66
package io.opentelemetry.javaagent.tooling.bytebuddy;
77

8+
import java.util.concurrent.atomic.AtomicBoolean;
89
import net.bytebuddy.asm.Advice;
910

1011
@SuppressWarnings("unused")
1112
public class BadAdvice {
1213

1314
@Advice.OnMethodExit(suppress = Throwable.class)
14-
public static void throwAnException(@Advice.Return(readOnly = false) boolean returnVal) {
15-
returnVal = true;
15+
public static void throwAnException(@Advice.Return AtomicBoolean isInstrumented) {
16+
// mark that the advice has been executed
17+
isInstrumented.set(true);
1618
throw new IllegalStateException("Test Exception");
1719
}
1820

javaagent-tooling/src/testExceptionHandler/java/io/opentelemetry/javaagent/tooling/bytebuddy/ExceptionHandlerTest.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@
1515
import io.opentelemetry.javaagent.bootstrap.ExceptionLogger;
1616
import java.net.URL;
1717
import java.net.URLClassLoader;
18+
import java.util.concurrent.atomic.AtomicBoolean;
1819
import java.util.logging.Level;
1920
import java.util.logging.Logger;
2021
import net.bytebuddy.agent.ByteBuddyAgent;
2122
import net.bytebuddy.agent.builder.AgentBuilder;
2223
import net.bytebuddy.agent.builder.ResettableClassFileTransformer;
24+
import net.bytebuddy.asm.Advice;
2325
import net.bytebuddy.dynamic.ClassFileLocator;
2426
import org.junit.jupiter.api.AfterAll;
2527
import org.junit.jupiter.api.BeforeAll;
@@ -34,20 +36,24 @@ class ExceptionHandlerTest {
3436

3537
@BeforeAll
3638
static void setUp() {
39+
Advice.WithCustomMapping customMapping =
40+
Advice.withCustomMapping()
41+
// required for AssignReturned annotation and throwable suppression
42+
.with(new Advice.AssignReturned.Factory().withSuppressed(Throwable.class));
3743
AgentBuilder builder =
3844
new AgentBuilder.Default()
3945
.disableClassFormatChanges()
4046
.with(AgentBuilder.RedefinitionStrategy.RETRANSFORMATION)
4147
.type(named(ExceptionHandlerTest.class.getName() + "$SomeClass"))
4248
.transform(
43-
new AgentBuilder.Transformer.ForAdvice()
49+
new AgentBuilder.Transformer.ForAdvice(customMapping)
4450
.with(
4551
new AgentBuilder.LocationStrategy.Simple(
4652
ClassFileLocator.ForClassLoader.of(BadAdvice.class.getClassLoader())))
4753
.withExceptionHandler(ExceptionHandlers.defaultExceptionHandler())
4854
.advice(isMethod().and(named("isInstrumented")), BadAdvice.class.getName()))
4955
.transform(
50-
new AgentBuilder.Transformer.ForAdvice()
56+
new AgentBuilder.Transformer.ForAdvice(customMapping)
5157
.with(
5258
new AgentBuilder.LocationStrategy.Simple(
5359
ClassFileLocator.ForClassLoader.of(BadAdvice.class.getClassLoader())))
@@ -80,7 +86,10 @@ void exceptionHandlerInvoked() {
8086
int initLogEvents = testHandler.getRecords().size();
8187

8288
// Triggers classload and instrumentation
83-
assertThat(SomeClass.isInstrumented()).isTrue();
89+
assertThat(SomeClass.isInstrumented().get())
90+
.describedAs("method should have been instrumented")
91+
.isTrue();
92+
8493
assertThat(testHandler.getRecords())
8594
.hasSize(initLogEvents + 1)
8695
.last()
@@ -104,8 +113,9 @@ void exceptionOnNondelegatingClassloader() throws Exception {
104113

105114
Class<?> someClazz = loader.loadClass(SomeClass.class.getName());
106115
assertThat(someClazz.getClassLoader()).isSameAs(loader);
107-
someClazz.getMethod("isInstrumented").invoke(null);
116+
AtomicBoolean instrumented = (AtomicBoolean) someClazz.getMethod("isInstrumented").invoke(null);
108117
assertThat(testHandler.getRecords()).hasSize(initLogEvents);
118+
assertThat(instrumented.get()).describedAs("method should have been instrumented").isTrue();
109119
}
110120

111121
@Test
@@ -120,8 +130,8 @@ void exceptionHandlerSetsCorrectStackSize() {
120130

121131
public static class SomeClass {
122132

123-
public static boolean isInstrumented() {
124-
return false;
133+
public static AtomicBoolean isInstrumented() {
134+
return new AtomicBoolean();
125135
}
126136

127137
public static void smallStack() {

javaagent-tooling/src/testMissingType/java/io/opentelemetry/javaagent/tooling/bytebuddy/MissingTypeTest.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import net.bytebuddy.agent.ByteBuddyAgent;
1717
import net.bytebuddy.agent.builder.AgentBuilder;
1818
import net.bytebuddy.agent.builder.ResettableClassFileTransformer;
19+
import net.bytebuddy.asm.Advice;
1920
import net.bytebuddy.dynamic.ClassFileLocator;
2021
import net.bytebuddy.dynamic.scaffold.MethodGraph;
2122
import net.bytebuddy.utility.JavaModule;
@@ -33,6 +34,8 @@ class MissingTypeTest {
3334

3435
@BeforeAll
3536
static void setUp() {
37+
Advice.WithCustomMapping customMapping =
38+
Advice.withCustomMapping().with(new Advice.AssignReturned.Factory());
3639
AgentBuilder builder =
3740
new AgentBuilder.Default(
3841
new ByteBuddy().with(MethodGraph.Compiler.ForDeclaredMethods.INSTANCE))
@@ -54,7 +57,7 @@ public void onError(
5457
})
5558
.type(named(MissingTypeTest.class.getName() + "$SomeClass"))
5659
.transform(
57-
new AgentBuilder.Transformer.ForAdvice()
60+
new AgentBuilder.Transformer.ForAdvice(customMapping)
5861
.with(
5962
new AgentBuilder.LocationStrategy.Simple(
6063
ClassFileLocator.ForClassLoader.of(TestAdvice.class.getClassLoader())))

javaagent-tooling/src/testMissingType/java/io/opentelemetry/javaagent/tooling/bytebuddy/TestAdvice.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,14 @@
66
package io.opentelemetry.javaagent.tooling.bytebuddy;
77

88
import net.bytebuddy.asm.Advice;
9+
import net.bytebuddy.asm.Advice.AssignReturned;
910

1011
@SuppressWarnings("unused")
1112
public class TestAdvice {
1213

14+
@AssignReturned.ToReturned
1315
@Advice.OnMethodExit
14-
public static void returnTrue(@Advice.Return(readOnly = false) boolean returnVal) {
15-
returnVal = true;
16+
public static boolean returnTrue() {
17+
return true;
1618
}
1719
}

testing-common/integration-tests/src/main/java/context/ContextTestInstrumentation.java

Lines changed: 28 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,17 @@
55

66
package context;
77

8+
import static context.ContextTestSingletons.CONTEXT;
9+
import static context.ContextTestSingletons.INTEGER;
10+
import static context.ContextTestSingletons.INTERFACE_INTEGER;
811
import static net.bytebuddy.matcher.ElementMatchers.nameStartsWith;
912
import static net.bytebuddy.matcher.ElementMatchers.named;
1013

11-
import io.opentelemetry.instrumentation.api.util.VirtualField;
1214
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1315
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1416
import library.KeyClass;
15-
import library.KeyInterface;
1617
import net.bytebuddy.asm.Advice;
18+
import net.bytebuddy.asm.Advice.AssignReturned;
1719
import net.bytebuddy.description.type.TypeDescription;
1820
import net.bytebuddy.matcher.ElementMatcher;
1921

@@ -42,78 +44,71 @@ public void transform(TypeTransformer transformer) {
4244

4345
@SuppressWarnings("unused")
4446
public static class MarkInstrumentedAdvice {
47+
@AssignReturned.ToReturned
4548
@Advice.OnMethodExit
46-
public static void methodExit(@Advice.Return(readOnly = false) boolean isInstrumented) {
47-
isInstrumented = true;
49+
public static boolean methodExit() {
50+
return true;
4851
}
4952
}
5053

5154
@SuppressWarnings("unused")
5255
public static class StoreAndIncrementApiUsageAdvice {
56+
@AssignReturned.ToReturned
5357
@Advice.OnMethodExit
54-
public static void methodExit(
55-
@Advice.This KeyClass thiz, @Advice.Return(readOnly = false) int contextCount) {
56-
57-
VirtualField<KeyClass, Context> virtualField =
58-
VirtualField.find(KeyClass.class, Context.class);
59-
60-
Context context = virtualField.get(thiz);
58+
public static int methodExit(@Advice.This KeyClass thiz) {
59+
Context context = CONTEXT.get(thiz);
6160
if (context == null) {
6261
context = new Context();
63-
virtualField.set(thiz, context);
62+
CONTEXT.set(thiz, context);
6463
}
6564

66-
contextCount = ++context.count;
65+
return ++context.count;
6766
}
6867
}
6968

7069
@SuppressWarnings("unused")
7170
public static class GetApiUsageAdvice {
71+
72+
@Advice.OnMethodEnter(skipOn = Advice.OnNonDefaultValue.class)
73+
public static boolean methodEnter() {
74+
// always skip original method body
75+
return true;
76+
}
77+
78+
@AssignReturned.ToReturned
7279
@Advice.OnMethodExit
73-
public static void methodExit(
74-
@Advice.This KeyClass thiz, @Advice.Return(readOnly = false) int contextCount) {
75-
VirtualField<KeyClass, Context> virtualField =
76-
VirtualField.find(KeyClass.class, Context.class);
77-
Context context = virtualField.get(thiz);
78-
contextCount = context == null ? 0 : context.count;
80+
public static int methodExit(@Advice.This KeyClass thiz) {
81+
Context context = CONTEXT.get(thiz);
82+
return context == null ? 0 : context.count;
7983
}
8084
}
8185

8286
@SuppressWarnings("unused")
8387
public static class PutApiUsageAdvice {
8488
@Advice.OnMethodExit
8589
public static void methodExit(@Advice.This KeyClass thiz, @Advice.Argument(0) int value) {
86-
VirtualField<KeyClass, Context> virtualField =
87-
VirtualField.find(KeyClass.class, Context.class);
8890
Context context = new Context();
8991
context.count = value;
90-
virtualField.set(thiz, context);
92+
CONTEXT.set(thiz, context);
9193
}
9294
}
9395

9496
@SuppressWarnings("unused")
9597
public static class RemoveApiUsageAdvice {
9698
@Advice.OnMethodExit
9799
public static void methodExit(@Advice.This KeyClass thiz) {
98-
VirtualField<KeyClass, Context> virtualField =
99-
VirtualField.find(KeyClass.class, Context.class);
100-
virtualField.set(thiz, null);
100+
CONTEXT.set(thiz, null);
101101
}
102102
}
103103

104104
@SuppressWarnings("unused")
105105
public static class UseMultipleFieldsAdvice {
106106
@Advice.OnMethodExit
107107
public static void methodExit(@Advice.This KeyClass thiz) {
108-
VirtualField<KeyClass, Context> field1 = VirtualField.find(KeyClass.class, Context.class);
109-
VirtualField<KeyClass, Integer> field2 = VirtualField.find(KeyClass.class, Integer.class);
110-
VirtualField<KeyInterface, Integer> interfaceField =
111-
VirtualField.find(KeyInterface.class, Integer.class);
112-
113-
Context context = field1.get(thiz);
108+
Context context = CONTEXT.get(thiz);
114109
int count = context == null ? 0 : context.count;
115-
field2.set(thiz, count);
116-
interfaceField.set(thiz, count);
110+
INTEGER.set(thiz, count);
111+
INTERFACE_INTEGER.set(thiz, count);
117112
}
118113
}
119114
}

testing-common/integration-tests/src/main/java/context/ContextTestInstrumentationModule.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,29 @@
1010
import com.google.auto.service.AutoService;
1111
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
1212
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule;
1314
import java.util.List;
1415

1516
@AutoService(InstrumentationModule.class)
16-
public class ContextTestInstrumentationModule extends InstrumentationModule {
17+
public class ContextTestInstrumentationModule extends InstrumentationModule
18+
implements ExperimentalInstrumentationModule {
1719
public ContextTestInstrumentationModule() {
1820
super("context-test-instrumentation");
1921
}
2022

2123
@Override
2224
public boolean isHelperClass(String className) {
23-
return className.equals(getClass().getPackage().getName() + ".Context");
25+
String pkg = getClass().getPackage().getName();
26+
return className.equals(pkg + ".Context") || className.equals(pkg + ".ContextTestSingletons");
2427
}
2528

2629
@Override
2730
public List<TypeInstrumentation> typeInstrumentations() {
2831
return singletonList(new ContextTestInstrumentation());
2932
}
33+
34+
@Override
35+
public boolean isIndyReady() {
36+
return true;
37+
}
3038
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package context;
7+
8+
import io.opentelemetry.instrumentation.api.util.VirtualField;
9+
import library.KeyClass;
10+
import library.KeyInterface;
11+
12+
public class ContextTestSingletons {
13+
14+
public static final VirtualField<KeyClass, Context> CONTEXT =
15+
VirtualField.find(KeyClass.class, Context.class);
16+
public static final VirtualField<KeyClass, Integer> INTEGER =
17+
VirtualField.find(KeyClass.class, Integer.class);
18+
public static final VirtualField<KeyInterface, Integer> INTERFACE_INTEGER =
19+
VirtualField.find(KeyInterface.class, Integer.class);
20+
21+
private ContextTestSingletons() {}
22+
}

testing-common/integration-tests/src/main/java/field/VirtualFieldTestInstrumentationModule.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1515
import java.util.List;
1616
import net.bytebuddy.asm.Advice;
17+
import net.bytebuddy.asm.Advice.AssignReturned;
1718
import net.bytebuddy.description.type.TypeDescription;
1819
import net.bytebuddy.matcher.ElementMatcher;
1920

@@ -50,10 +51,11 @@ public void transform(TypeTransformer transformer) {
5051

5152
@SuppressWarnings("unused")
5253
public static class TestAdvice {
54+
@AssignReturned.ToReturned
5355
@Advice.OnMethodExit
54-
public static void onExit(@Advice.Return(readOnly = false) boolean result) {
56+
public static boolean onExit() {
5557
VirtualFieldTestHelper.test();
56-
result = true;
58+
return true;
5759
}
5860
}
5961
}

testing-common/integration-tests/src/main/java/helper/DuplicateHelperInstrumentation.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
1111
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
1212
import net.bytebuddy.asm.Advice;
13+
import net.bytebuddy.asm.Advice.AssignReturned;
1314
import net.bytebuddy.description.type.TypeDescription;
1415
import net.bytebuddy.matcher.ElementMatcher;
1516

@@ -26,9 +27,10 @@ public void transform(TypeTransformer transformer) {
2627

2728
@SuppressWarnings("unused")
2829
public static class TestAdvice {
30+
@AssignReturned.ToReturned
2931
@Advice.OnMethodExit(suppress = Throwable.class)
30-
public static void addSuffix(@Advice.Return(readOnly = false) String string) {
31-
string = DuplicateHelper.addSuffix(string, " foo");
32+
public static String addSuffix(@Advice.Return String string) {
33+
return DuplicateHelper.addSuffix(string, " foo");
3234
}
3335
}
3436
}

testing-common/integration-tests/src/main/java/io/opentelemetry/javaagent/IndyInstrumentationTestModule.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,12 +176,11 @@ public static void onMethodEnter() {
176176
throw new RuntimeException("This exception should be suppressed");
177177
}
178178

179-
@Advice.AssignReturned.ToReturned
180179
@Advice.OnMethodExit(
181180
suppress = Throwable.class,
182181
onThrowable = Throwable.class,
183182
inline = false)
184-
public static void onMethodExit(@Advice.Thrown Throwable throwable) {
183+
public static void onMethodExit() {
185184
throw new RuntimeException("This exception should be suppressed");
186185
}
187186
}

0 commit comments

Comments
 (0)