Skip to content

Commit eba7e20

Browse files
committed
add jpms compatible class file transformer
1 parent eb945b8 commit eba7e20

File tree

3 files changed

+54
-34
lines changed

3 files changed

+54
-34
lines changed

instrumentation/internal/internal-lambda/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/lambda/LambdaTransformer.java

Lines changed: 13 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,11 @@
1111

1212
/** Helper class for transforming lambda class bytes. */
1313
public final class LambdaTransformer {
14-
private static final boolean IS_JAVA_9 = isJava9();
1514

1615
private LambdaTransformer() {}
1716

18-
private static boolean isJava9() {
19-
try {
20-
Class.forName("java.lang.Module", false, null);
21-
return true;
22-
} catch (ClassNotFoundException exception) {
23-
return false;
24-
}
25-
}
26-
2717
/**
28-
* Called from {@code java.lang.invoke.InnerClassLambdaMetafactory} to transform lambda class
18+
* Called from {@code java.lang.invoke.InnerClassLambdaMetaFactory} to transform lambda class
2919
* bytes.
3020
*/
3121
@SuppressWarnings("unused")
@@ -34,29 +24,21 @@ public static byte[] transform(byte[] classBytes, String slashClassName, Class<?
3424
if (InjectedClassHelper.isHelperClass(targetClass)) {
3525
return classBytes;
3626
}
37-
3827
ClassFileTransformer transformer = ClassFileTransformerHolder.getClassFileTransformer();
39-
if (transformer != null) {
40-
try {
41-
byte[] result;
42-
if (IS_JAVA_9) {
43-
result =
44-
Java9LambdaTransformer.transform(
45-
transformer, classBytes, slashClassName, targetClass);
46-
} else {
47-
result =
48-
transformer.transform(
49-
targetClass.getClassLoader(), slashClassName, null, null, classBytes);
50-
}
51-
if (result != null) {
52-
return result;
53-
}
54-
} catch (Throwable throwable) {
55-
// sun.instrument.TransformerManager catches Throwable from ClassFileTransformer and ignores
56-
// it, we do the same.
28+
if (transformer == null) {
29+
return classBytes;
30+
}
31+
try {
32+
byte[] result =
33+
transformer.transform(
34+
targetClass.getClassLoader(), slashClassName, targetClass, null, classBytes);
35+
if (result != null) {
36+
classBytes = result;
5737
}
38+
} catch (Throwable throwable) {
39+
// sun.instrument.TransformerManager catches Throwable from ClassFileTransformer and ignores
40+
// it, we do the same.
5841
}
59-
6042
return classBytes;
6143
}
6244
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.tooling;
7+
8+
import java.lang.instrument.ClassFileTransformer;
9+
import java.lang.instrument.IllegalClassFormatException;
10+
import java.security.ProtectionDomain;
11+
12+
/** {@link ClassFileTransformer} implementation that provides java9 jpms module compatibility */
13+
public class JavaModuleClassFileTransformer implements ClassFileTransformer {
14+
15+
private ClassFileTransformer delegate;
16+
17+
public JavaModuleClassFileTransformer(ClassFileTransformer delegate) {
18+
this.delegate = delegate;
19+
}
20+
21+
@Override
22+
public byte[] transform(
23+
ClassLoader loader,
24+
String className,
25+
Class<?> targetClass,
26+
ProtectionDomain protectionDomain,
27+
byte[] classfileBuffer)
28+
throws IllegalClassFormatException {
29+
30+
Module module = targetClass != null ? targetClass.getModule() : null;
31+
return delegate.transform(
32+
module, loader, className, targetClass, protectionDomain, classfileBuffer);
33+
}
34+
}

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
4949
import io.opentelemetry.sdk.autoconfigure.SdkAutoconfigureAccess;
5050
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
51+
import java.lang.instrument.ClassFileTransformer;
5152
import java.lang.instrument.Instrumentation;
5253
import java.util.ArrayList;
5354
import java.util.Collections;
@@ -63,7 +64,6 @@
6364
import net.bytebuddy.ByteBuddy;
6465
import net.bytebuddy.agent.builder.AgentBuilder;
6566
import net.bytebuddy.agent.builder.AgentBuilderUtil;
66-
import net.bytebuddy.agent.builder.ResettableClassFileTransformer;
6767
import net.bytebuddy.description.type.TypeDefinition;
6868
import net.bytebuddy.description.type.TypeDescription;
6969
import net.bytebuddy.dynamic.DynamicType;
@@ -199,9 +199,13 @@ private static void installBytebuddyAgent(
199199
logger.log(FINE, "Installed {0} extension(s)", numberOfLoadedExtensions);
200200

201201
agentBuilder = AgentBuilderUtil.optimize(agentBuilder);
202-
ResettableClassFileTransformer resettableClassFileTransformer = agentBuilder.installOn(inst);
202+
ClassFileTransformer transformer = agentBuilder.installOn(inst);
203203
instrumentationInstalled = true;
204-
ClassFileTransformerHolder.setClassFileTransformer(resettableClassFileTransformer);
204+
if (JavaModule.isSupported()) {
205+
// wrapping in a JPMS compliant implementation
206+
transformer = new JavaModuleClassFileTransformer(transformer);
207+
}
208+
ClassFileTransformerHolder.setClassFileTransformer(transformer);
205209

206210
addHttpServerResponseCustomizers(extensionClassLoader);
207211

0 commit comments

Comments
 (0)