Remove internal-proxy instrumentation
DELETE
instrumentation/internal/internal-proxy/javaagent-unit-tests/build.gradle.kts
-plugins {
- id("otel.java-conventions")
-}
-
-dependencies {
- testImplementation(project(":instrumentation:internal:internal-proxy:javaagent"))
- testImplementation(project(":javaagent-bootstrap"))
-}

DELETE
instrumentation/internal/internal-proxy/javaagent-unit-tests/src/test/groovy/ProxyHelperTest.groovy
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import io.opentelemetry.javaagent.bootstrap.VirtualFieldInstalledMarker
-import io.opentelemetry.javaagent.instrumentation.internal.proxy.ProxyHelper
-import spock.lang.Specification
-
-import java.util.concurrent.Callable
-
-class ProxyHelperTest extends Specification {
-
- def "should filter #interfaces"() {
- expect:
- ProxyHelper.filtered(interfaces.toArray() as Class<?>[]) == filtered.toArray()
-
- where:
- interfaces | filtered
- [] | []
- [Runnable] | [Runnable]
- [Runnable, Callable] | [Runnable, Callable]
- [Runnable, VirtualFieldInstalledMarker] | [Runnable, VirtualFieldInstalledMarker]
- [Runnable, VirtualFieldInstalledMarker, VirtualFieldInstalledMarker] | [Runnable, VirtualFieldInstalledMarker]
- [VirtualFieldInstalledMarker, Runnable] | [VirtualFieldInstalledMarker, Runnable]
- [VirtualFieldInstalledMarker, Runnable, VirtualFieldInstalledMarker] | [VirtualFieldInstalledMarker, Runnable]
- [VirtualFieldInstalledMarker, VirtualFieldInstalledMarker, Runnable] | [VirtualFieldInstalledMarker, Runnable]
- }
-}

DELETE
instrumentation/internal/internal-proxy/javaagent/build.gradle.kts
-plugins {
- id("otel.javaagent-instrumentation")
-}
-
-dependencies {
- compileOnly(project(":javaagent-bootstrap"))
-
- testImplementation(project(":javaagent-bootstrap"))
-}

DELETE
instrumentation/internal/internal-proxy/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/proxy/ProxyHelper.java
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.instrumentation.internal.proxy;
-
-import io.opentelemetry.javaagent.bootstrap.VirtualFieldInstalledMarker;
-import java.util.Arrays;
-import java.util.LinkedHashSet;
-
-public class ProxyHelper {
-
- private static final Class<?>[] EMPTY_CLASS_ARRAY = new Class<?>[0];
-
- public static Class<?>[] filtered(Class<?>[] interfaces) {
- int numMarkers = 0;
- for (Class<?> iface : interfaces) {
- if (iface == VirtualFieldInstalledMarker.class) {
- numMarkers++;
- }
- }
- if (numMarkers <= 1) {
- // no duplicates, safe to use original interfaces
- return interfaces;
- }
-
- // it's probably ok to remove them all(?)
- // but just doing the minimum here and only removing the duplicates to prevent
- // Proxy.newProxyInstance() from throwing IllegalArgumentException: repeated interface
- return new LinkedHashSet<>(Arrays.asList(interfaces)).toArray(EMPTY_CLASS_ARRAY);
- }
-}

DELETE
instrumentation/internal/internal-proxy/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/proxy/ProxyInstrumentation.java
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.instrumentation.internal.proxy;
-
-import static net.bytebuddy.matcher.ElementMatchers.isMethod;
-import static net.bytebuddy.matcher.ElementMatchers.isPublic;
-import static net.bytebuddy.matcher.ElementMatchers.isStatic;
-import static net.bytebuddy.matcher.ElementMatchers.named;
-import static net.bytebuddy.matcher.ElementMatchers.takesArgument;
-import static net.bytebuddy.matcher.ElementMatchers.takesArguments;
-
-import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
-import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
-import java.lang.reflect.InvocationHandler;
-import net.bytebuddy.asm.Advice;
-import net.bytebuddy.description.type.TypeDescription;
-import net.bytebuddy.matcher.ElementMatcher;
-
-public class ProxyInstrumentation implements TypeInstrumentation {
-
- @Override
- public ElementMatcher<TypeDescription> typeMatcher() {
- return named("java.lang.reflect.Proxy");
- }
-
- @Override
- public void transform(TypeTransformer transformer) {
- transformer.applyAdviceToMethod(
- isMethod()
- .and(named("newProxyInstance"))
- .and(takesArguments(3))
- .and(takesArgument(0, ClassLoader.class))
- .and(takesArgument(1, Class[].class))
- .and(takesArgument(2, InvocationHandler.class))
- .and(isPublic())
- .and(isStatic()),
- ProxyInstrumentation.class.getName() + "$FilterDuplicateMarkerInterfaces");
- transformer.applyAdviceToMethod(
- isMethod()
- .and(named("getProxyClass"))
- .and(takesArguments(2))
- .and(takesArgument(0, ClassLoader.class))
- .and(takesArgument(1, Class[].class))
- .and(isPublic())
- .and(isStatic()),
- ProxyInstrumentation.class.getName() + "$FilterDuplicateMarkerInterfaces");
- }
-
- public static class FilterDuplicateMarkerInterfaces {
- @Advice.OnMethodEnter(suppress = Throwable.class)
- public static void onEnter(
- @Advice.Argument(value = 1, readOnly = false) Class<?>[] interfaces) {
- interfaces = ProxyHelper.filtered(interfaces);
- }
- }
-}

DELETE
instrumentation/internal/internal-proxy/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/proxy/ProxyInstrumentationModule.java
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-package io.opentelemetry.javaagent.instrumentation.internal.proxy;
-
-import static java.util.Collections.singletonList;
-
-import com.google.auto.service.AutoService;
-import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
-import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
-import java.util.List;
-
-@AutoService(InstrumentationModule.class)
-public class ProxyInstrumentationModule extends InstrumentationModule {
- public ProxyInstrumentationModule() {
- super("internal-proxy");
- }
-
- @Override
- public boolean defaultEnabled() {
- // internal instrumentations are always enabled by default
- return true;
- }
-
- @Override
- public List<TypeInstrumentation> typeInstrumentations() {
- return singletonList(new ProxyInstrumentation());
- }
-}

DELETE
instrumentation/internal/internal-proxy/javaagent/src/test/groovy/NewProxyInstanceTest.groovy
-/*
- * Copyright The OpenTelemetry Authors
- * SPDX-License-Identifier: Apache-2.0
- */
-
-import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification
-import io.opentelemetry.javaagent.bootstrap.VirtualFieldInstalledMarker
-
-import java.lang.reflect.InvocationHandler
-import java.lang.reflect.Method
-import java.lang.reflect.Proxy
-
-class NewProxyInstanceTest extends AgentInstrumentationSpecification {
- def "should filter out duplicate VirtualFieldInstalledMarker interfaces from newProxyInstance"() {
- setup:
- Class[] interfaces = new Class[3]
- interfaces[0] = Runnable
- interfaces[1] = VirtualFieldInstalledMarker
- interfaces[2] = VirtualFieldInstalledMarker
-
- expect:
- Runnable proxy = Proxy.newProxyInstance(NewProxyInstanceTest.getClassLoader(), interfaces, new MyHandler()) as Runnable
- proxy.run()
-
- // should not throw IllegalArgumentException:
- // repeated interface: io.opentelemetry.javaagent.bootstrap.VirtualFieldInstalledMarker
- }
-
- def "should filter out duplicate VirtualFieldInstalledMarker interfaces from getProxyClass"() {
- setup:
- Class[] interfaces = new Class[3]
- interfaces[0] = Runnable
- interfaces[1] = VirtualFieldInstalledMarker
- interfaces[2] = VirtualFieldInstalledMarker
-
- expect:
- Class<?> proxyClass = Proxy.getProxyClass(NewProxyInstanceTest.getClassLoader(), interfaces)
- def proxy = proxyClass.newInstance(new MyHandler()) as Runnable
- proxy.run()
-
- // should not throw IllegalArgumentException:
- // repeated interface: io.opentelemetry.javaagent.bootstrap.VirtualFieldInstalledMarker
- }
-
- static class MyHandler implements InvocationHandler {
-
- @Override
- Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- return null
- }
- }
-}

MODIFY
instrumentation/internal/internal-reflection/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/reflection/ReflectionHelper.java
instrumentation/internal/internal-reflection/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/internal/reflection/ReflectionHelper.java
@@ -34,15 +34,8 @@ public final class ReflectionHelper {
}
public static Method[] filterMethods(Class<?> containingClass, Method[] methods) {
- if (methods.length == 0) {
- return methods;
- } else if (containingClass.isInterface()
- && containingClass.isSynthetic()
- && VirtualFieldAccessorMarker.class.isAssignableFrom(containingClass)
- && containingClass.getName().contains("VirtualFieldAccessor$")) {
- // hide all methods from virtual field accessor interfaces
- return new Method[0];
- } else if (!VirtualFieldInstalledMarker.class.isAssignableFrom(containingClass)) {
+ if (methods.length == 0
+ || !VirtualFieldInstalledMarker.class.isAssignableFrom(containingClass)) {
// nothing to filter when class does not have any added virtual fields
return methods;
}

MODIFY
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java
javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java
@@ -32,7 +32,6 @@ import io.opentelemetry.javaagent.tooling.ignore.IgnoredTypesMatcher;
import io.opentelemetry.javaagent.tooling.muzzle.AgentTooling;
import io.opentelemetry.javaagent.tooling.util.Trie;
import java.lang.instrument.Instrumentation;
-import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@@ -76,14 +75,6 @@ public class AgentInstaller {
// this needs to be done as early as possible - before the first Config.get() call
ConfigInitializer.initialize();
- // ensure java.lang.reflect.Proxy is loaded, as transformation code uses it internally
- // loading java.lang.reflect.Proxy after the bytebuddy transformer is set up causes
- // the internal-proxy instrumentation module to transform it, and then the bytebuddy
- // transformation code also tries to load it, which leads to a ClassCircularityError
- // loading java.lang.reflect.Proxy early here still allows it to be retransformed by the
- // internal-proxy instrumentation module after the bytebuddy transformer is set up
- Proxy.class.getName();
-
Integer strictContextStressorMillis = Integer.getInteger(STRICT_CONTEXT_STRESSOR_MILLIS);
if (strictContextStressorMillis != null) {
io.opentelemetry.context.ContextStorage.addWrapper(

MODIFY
javaagent/build.gradle.kts
javaagent/build.gradle.kts
@@ -72,7 +72,6 @@ dependencies {
baseJavaagentLibs(project(":instrumentation:internal:internal-class-loader:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-eclipse-osgi-3.6:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-lambda:javaagent"))
- baseJavaagentLibs(project(":instrumentation:internal:internal-proxy:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-reflection:javaagent"))
baseJavaagentLibs(project(":instrumentation:internal:internal-url-class-loader:javaagent"))

MODIFY
settings.gradle.kts
settings.gradle.kts
@@ -139,8 +139,6 @@ include(":instrumentation:internal:internal-class-loader:javaagent-integration-t
include(":instrumentation:internal:internal-eclipse-osgi-3.6:javaagent")
include(":instrumentation:internal:internal-lambda:javaagent")
include(":instrumentation:internal:internal-lambda-java9:javaagent")
-include(":instrumentation:internal:internal-proxy:javaagent")
-include(":instrumentation:internal:internal-proxy:javaagent-unit-tests")
include(":instrumentation:internal:internal-reflection:javaagent")
include(":instrumentation:internal:internal-reflection:javaagent-integration-tests")
include(":instrumentation:internal:internal-url-class-loader:javaagent")

Remove internal-proxy instrumentation (#4749)