Skip to content

Commit b77428c

Browse files
committed
add LambdaTransformer interface + rename things
1 parent a38763f commit b77428c

File tree

9 files changed

+115
-107
lines changed

9 files changed

+115
-107
lines changed

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ public void visitMethodInsn(
128128
Opcodes.GETFIELD, slashClassName, "targetClass", "Ljava/lang/Class;");
129129
mv.visitMethodInsn(
130130
Opcodes.INVOKESTATIC,
131-
Type.getInternalName(LambdaTransformer.class),
131+
Type.getInternalName(LambdaTransformerHelper.class),
132132
"transform",
133133
"([BLjava/lang/String;Ljava/lang/Class;)[B",
134134
false);
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,14 @@
55

66
package io.opentelemetry.javaagent.instrumentation.internal.lambda;
77

8-
import io.opentelemetry.javaagent.bootstrap.ClassFileTransformerHolder;
98
import io.opentelemetry.javaagent.bootstrap.InjectedClassHelper;
10-
import java.lang.instrument.ClassFileTransformer;
9+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformer;
10+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformerHolder;
1111

1212
/** Helper class for transforming lambda class bytes. */
13-
public final class LambdaTransformer {
13+
public final class LambdaTransformerHelper {
1414

15-
private LambdaTransformer() {}
15+
private LambdaTransformerHelper() {}
1616

1717
/**
1818
* Called from {@code java.lang.invoke.InnerClassLambdaMetafactory} to transform lambda class
@@ -24,18 +24,13 @@ public static byte[] transform(byte[] classBytes, String slashClassName, Class<?
2424
if (InjectedClassHelper.isHelperClass(targetClass)) {
2525
return classBytes;
2626
}
27-
ClassFileTransformer transformer = ClassFileTransformerHolder.getLambdaClassFileTransformer();
27+
LambdaTransformer transformer = LambdaTransformerHolder.setLambdaTransformer();
2828
if (transformer == null) {
2929
return classBytes;
3030
}
3131

3232
try {
33-
// The 'targetClass' needs to be non-null as it is used in Java9LambdaClassFileTransformer
34-
// to get a reference to the jpms module. However, a null value must be passed to the
35-
// underlying transformer as this code is called when the lambda is defined.
36-
byte[] result =
37-
transformer.transform(
38-
targetClass.getClassLoader(), slashClassName, targetClass, null, classBytes);
33+
byte[] result = transformer.transform(slashClassName, targetClass, classBytes);
3934
if (result != null) {
4035
classBytes = result;
4136
}

javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/ClassFileTransformerHolder.java

-38
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.bootstrap;
7+
8+
import java.lang.instrument.IllegalClassFormatException;
9+
10+
/** Transformer for lambda bytecode */
11+
public interface LambdaTransformer {
12+
13+
/**
14+
* Transforms lambda bytecode for instrumentation
15+
*
16+
* @param className class name in JVM format with slashes
17+
* @param targetClass target class, must not be {@literal null}
18+
* @param classfileBuffer target class bytecode
19+
* @return instrumented lambda bytecode
20+
* @throws IllegalClassFormatException if bytecode is invalid
21+
*/
22+
byte[] transform(String className, Class<?> targetClass, byte[] classfileBuffer)
23+
throws IllegalClassFormatException;
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.bootstrap;
7+
8+
/**
9+
* Holder for {@link LambdaTransformer} used by the instrumentation. Calling transform on this
10+
* transformer processes given bytes the same way as they would be processed during loading of the
11+
* class.
12+
*/
13+
public final class LambdaTransformerHolder {
14+
15+
private static volatile LambdaTransformer lambdaTransformer;
16+
17+
/**
18+
* get lambda transformer
19+
*
20+
* @return class transformer for defining lambdas
21+
*/
22+
public static LambdaTransformer setLambdaTransformer() {
23+
return lambdaTransformer;
24+
}
25+
26+
/**
27+
* set lambda transformer
28+
*
29+
* @param transformer transformer
30+
*/
31+
public static void setLambdaTransformer(LambdaTransformer transformer) {
32+
lambdaTransformer = transformer;
33+
}
34+
35+
private LambdaTransformerHolder() {}
36+
}

javaagent-tooling/javaagent-tooling-java9/src/main/java/io/opentelemetry/javaagent/tooling/Java9LambdaClassFileTransformer.java

-42
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.javaagent.tooling;
7+
8+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformer;
9+
import java.lang.instrument.ClassFileTransformer;
10+
import java.lang.instrument.IllegalClassFormatException;
11+
12+
/** lambda transformer with java9 jpms module compatibility */
13+
public class Java9LambdaTransformer implements LambdaTransformer {
14+
15+
private final ClassFileTransformer delegate;
16+
17+
public Java9LambdaTransformer(ClassFileTransformer delegate) {
18+
this.delegate = delegate;
19+
}
20+
21+
@Override
22+
public byte[] transform(String className, Class<?> targetClass, byte[] classfileBuffer)
23+
throws IllegalClassFormatException {
24+
25+
// lambda instrumentation happens only when the lambda is defined, thus the classBeingRedefined
26+
// must be null otherwise we get a partial instrumentation, for example virtual fields are not
27+
// properly applied
28+
return delegate.transform(
29+
targetClass.getModule(),
30+
targetClass.getClassLoader(),
31+
className,
32+
null,
33+
null,
34+
classfileBuffer);
35+
}
36+
}

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

+6-4
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@
2121
import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties;
2222
import io.opentelemetry.javaagent.bootstrap.AgentClassLoader;
2323
import io.opentelemetry.javaagent.bootstrap.BootstrapPackagePrefixesHolder;
24-
import io.opentelemetry.javaagent.bootstrap.ClassFileTransformerHolder;
2524
import io.opentelemetry.javaagent.bootstrap.DefineClassHelper;
2625
import io.opentelemetry.javaagent.bootstrap.InstrumentedTaskClasses;
26+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformer;
27+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformerHolder;
2728
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizer;
2829
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseCustomizerHolder;
2930
import io.opentelemetry.javaagent.bootstrap.http.HttpServerResponseMutator;
@@ -200,14 +201,15 @@ private static void installBytebuddyAgent(
200201

201202
agentBuilder = AgentBuilderUtil.optimize(agentBuilder);
202203
ClassFileTransformer transformer = agentBuilder.installOn(inst);
204+
LambdaTransformer lambdaTransformer;
203205
if (JavaModule.isSupported()) {
204206
// wrapping in a JPMS compliant implementation
205-
transformer = new Java9LambdaClassFileTransformer(transformer);
207+
lambdaTransformer = new Java9LambdaTransformer(transformer);
206208
} else {
207209
// wrapping in a java 8 compliant transformer
208-
transformer = new LambdaClassFileTransformer(transformer);
210+
lambdaTransformer = new Java8LambdaTransformer(transformer);
209211
}
210-
ClassFileTransformerHolder.setLambdaClassFileTransformer(transformer);
212+
LambdaTransformerHolder.setLambdaTransformer(lambdaTransformer);
211213

212214
instrumentationInstalled = true;
213215

javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/LambdaClassFileTransformer.java javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/Java8LambdaTransformer.java

+6-11
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,26 @@
55

66
package io.opentelemetry.javaagent.tooling;
77

8+
import io.opentelemetry.javaagent.bootstrap.LambdaTransformer;
89
import java.lang.instrument.ClassFileTransformer;
910
import java.lang.instrument.IllegalClassFormatException;
10-
import java.security.ProtectionDomain;
1111

12-
/** {@link ClassFileTransformer} for lambda instrumentation without jpms modules */
13-
public class LambdaClassFileTransformer implements ClassFileTransformer {
12+
/** lambda transformer for java < 9 without jpms modules support */
13+
public class Java8LambdaTransformer implements LambdaTransformer {
1414

1515
private final ClassFileTransformer delegate;
1616

17-
public LambdaClassFileTransformer(ClassFileTransformer delegate) {
17+
public Java8LambdaTransformer(ClassFileTransformer delegate) {
1818
this.delegate = delegate;
1919
}
2020

2121
@Override
22-
public byte[] transform(
23-
ClassLoader loader,
24-
String className,
25-
Class<?> classBeingRedefined,
26-
ProtectionDomain protectionDomain,
27-
byte[] classfileBuffer)
22+
public byte[] transform(String className, Class<?> targetClass, byte[] classfileBuffer)
2823
throws IllegalClassFormatException {
2924

3025
// lambda instrumentation happens only when the lambda is defined, thus the classBeingRedefined
3126
// must be null otherwise we get a partial instrumentation, for example virtual fields are not
3227
// properly applied.
33-
return delegate.transform(loader, className, null, null, classfileBuffer);
28+
return delegate.transform(targetClass.getClassLoader(), className, null, null, classfileBuffer);
3429
}
3530
}

0 commit comments

Comments
 (0)