diff --git a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/server/RemoteServerInstrumentation.java b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/server/RemoteServerInstrumentation.java index ec90604981..586b657d75 100644 --- a/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/server/RemoteServerInstrumentation.java +++ b/instrumentation/rmi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/rmi/server/RemoteServerInstrumentation.java @@ -11,6 +11,7 @@ import static io.opentelemetry.javaagent.instrumentation.rmi.server.RmiServerSin 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.nameStartsWith; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.not; @@ -28,7 +29,8 @@ import net.bytebuddy.matcher.ElementMatcher; public class RemoteServerInstrumentation implements TypeInstrumentation { @Override public ElementMatcher typeMatcher() { - return implementsInterface(named("java.rmi.Remote")); + return implementsInterface(named("java.rmi.Remote")) + .and(not(nameStartsWith("org.springframework.remoting"))); } @Override diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/build.gradle.kts b/instrumentation/spring/spring-rmi-4.0/javaagent/build.gradle.kts new file mode 100644 index 0000000000..df99e51873 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/build.gradle.kts @@ -0,0 +1,23 @@ +plugins { + id("otel.javaagent-instrumentation") +} + +muzzle { + pass { + group.set("org.springframework") + module.set("spring-context") + versions.set("[4.0.0.RELEASE,)") + } +} + +dependencies { + compileOnly("com.google.auto.value:auto-value-annotations") + annotationProcessor("com.google.auto.value:auto-value") + + bootstrap(project(":instrumentation:rmi:bootstrap")) + testInstrumentation(project(":instrumentation:rmi:javaagent")) + + library("org.springframework:spring-context:4.0.0.RELEASE") + library("org.springframework:spring-aop:4.0.0.RELEASE") + testLibrary("org.springframework.boot:spring-boot:1.1.0.RELEASE") +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/SpringRmiInstrumentationModule.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/SpringRmiInstrumentationModule.java new file mode 100644 index 0000000000..51afede115 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/SpringRmiInstrumentationModule.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.springrmi; + +import static java.util.Arrays.asList; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.instrumentation.springrmi.client.ClientInstrumentation; +import io.opentelemetry.javaagent.instrumentation.springrmi.server.ServerInstrumentation; +import java.util.List; + +@AutoService(InstrumentationModule.class) +public class SpringRmiInstrumentationModule extends InstrumentationModule { + + public SpringRmiInstrumentationModule() { + super("spring-rmi", "spring-rmi-4.0"); + } + + @Override + public List typeInstrumentations() { + return asList(new ClientInstrumentation(), new ServerInstrumentation()); + } +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/SpringRmiSingletons.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/SpringRmiSingletons.java new file mode 100644 index 0000000000..b41e30f0f2 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/SpringRmiSingletons.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.springrmi; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; +import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; +import io.opentelemetry.instrumentation.api.instrumenter.rpc.RpcSpanNameExtractor; +import io.opentelemetry.instrumentation.api.util.ClassAndMethod; +import io.opentelemetry.javaagent.instrumentation.springrmi.client.ClientAttributesExtractor; +import io.opentelemetry.javaagent.instrumentation.springrmi.server.ServerAttributesExtractor; +import java.lang.reflect.Method; + +public final class SpringRmiSingletons { + private static final String INSTRUMENTATION_NAME = "io.opentelemetry.spring-rmi-4.0"; + + private static final Instrumenter CLIENT_INSTRUMENTER = buildClientInstrumenter(); + private static final Instrumenter SERVER_INSTRUMENTER = + buildServerInstrumenter(); + + private static Instrumenter buildClientInstrumenter() { + ClientAttributesExtractor attributesExtractor = new ClientAttributesExtractor(); + + return Instrumenter.builder( + GlobalOpenTelemetry.get(), + INSTRUMENTATION_NAME, + RpcSpanNameExtractor.create(attributesExtractor)) + .addAttributesExtractor(attributesExtractor) + .newInstrumenter(SpanKindExtractor.alwaysClient()); + } + + private static Instrumenter buildServerInstrumenter() { + ServerAttributesExtractor attributesExtractor = new ServerAttributesExtractor(); + + return Instrumenter.builder( + GlobalOpenTelemetry.get(), + INSTRUMENTATION_NAME, + RpcSpanNameExtractor.create(attributesExtractor)) + .addAttributesExtractor(attributesExtractor) + .newInstrumenter(SpanKindExtractor.alwaysServer()); + } + + public static Instrumenter clientInstrumenter() { + return CLIENT_INSTRUMENTER; + } + + public static Instrumenter serverInstrumenter() { + return SERVER_INSTRUMENTER; + } + + private SpringRmiSingletons() {} +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/client/ClientAttributesExtractor.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/client/ClientAttributesExtractor.java new file mode 100644 index 0000000000..1e97daeb34 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/client/ClientAttributesExtractor.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.springrmi.client; + +import io.opentelemetry.instrumentation.api.instrumenter.rpc.RpcAttributesExtractor; +import java.lang.reflect.Method; + +public final class ClientAttributesExtractor extends RpcAttributesExtractor { + + @Override + protected String system(Method method) { + return "spring_rmi"; + } + + @Override + protected String service(Method method) { + return method.getDeclaringClass().getName(); + } + + @Override + protected String method(Method method) { + return method.getName(); + } +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/client/ClientInstrumentation.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/client/ClientInstrumentation.java new file mode 100644 index 0000000000..ffa8c15823 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/client/ClientInstrumentation.java @@ -0,0 +1,80 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.springrmi.client; + +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.extendsClass; +import static io.opentelemetry.javaagent.extension.matcher.AgentElementMatchers.hasClassesNamed; +import static io.opentelemetry.javaagent.instrumentation.springrmi.SpringRmiSingletons.clientInstrumenter; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.api.Java8BytecodeBridge; +import java.lang.reflect.Method; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.aopalliance.intercept.MethodInvocation; + +public class ClientInstrumentation implements TypeInstrumentation { + @Override + public ElementMatcher classLoaderOptimization() { + return hasClassesNamed("org.springframework.remoting.rmi.RmiClientInterceptor"); + } + + @Override + public ElementMatcher typeMatcher() { + return extendsClass(named("org.springframework.remoting.rmi.RmiClientInterceptor")); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + isMethod() + .and(named("invoke")) + .and(takesArgument(0, named("org.aopalliance.intercept.MethodInvocation"))), + this.getClass().getName() + "$InvokeMethodAdvice"); + } + + @SuppressWarnings("unused") + public static class InvokeMethodAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.Argument(0) MethodInvocation methodInv, + @Advice.Local("method") Method method, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + method = methodInv.getMethod(); + Context parentContext = Java8BytecodeBridge.currentContext(); + if (!clientInstrumenter().shouldStart(parentContext, method)) { + return; + } + + context = clientInstrumenter().start(parentContext, method); + scope = context.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Local("method") Method method, + @Advice.Thrown Throwable throwable, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (scope == null) { + return; + } + scope.close(); + clientInstrumenter().end(context, method, null, throwable); + } + } +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/server/ServerAttributesExtractor.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/server/ServerAttributesExtractor.java new file mode 100644 index 0000000000..0c3c104769 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/server/ServerAttributesExtractor.java @@ -0,0 +1,27 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.springrmi.server; + +import io.opentelemetry.instrumentation.api.instrumenter.rpc.RpcAttributesExtractor; +import io.opentelemetry.instrumentation.api.util.ClassAndMethod; + +public final class ServerAttributesExtractor extends RpcAttributesExtractor { + + @Override + protected String system(ClassAndMethod classAndMethod) { + return "spring_rmi"; + } + + @Override + protected String service(ClassAndMethod classAndMethod) { + return classAndMethod.declaringClass().getName(); + } + + @Override + protected String method(ClassAndMethod classAndMethod) { + return classAndMethod.methodName(); + } +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/server/ServerInstrumentation.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/server/ServerInstrumentation.java new file mode 100644 index 0000000000..d553bdc70b --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/springrmi/server/ServerInstrumentation.java @@ -0,0 +1,89 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.springrmi.server; + +import static io.opentelemetry.javaagent.bootstrap.rmi.ThreadLocalContext.THREAD_LOCAL_CONTEXT; +import static io.opentelemetry.javaagent.instrumentation.springrmi.SpringRmiSingletons.serverInstrumenter; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; + +import io.opentelemetry.context.Context; +import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.util.ClassAndMethod; +import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer; +import io.opentelemetry.javaagent.instrumentation.api.CallDepth; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.springframework.remoting.rmi.RmiBasedExporter; +import org.springframework.remoting.support.RemoteInvocation; + +public class ServerInstrumentation implements TypeInstrumentation { + @Override + public ElementMatcher typeMatcher() { + return named("org.springframework.remoting.rmi.RmiBasedExporter"); + } + + @Override + public void transform(TypeTransformer transformer) { + transformer.applyAdviceToMethod( + isMethod() + .and(named("invoke")) + .and(takesArgument(0, named("org.springframework.remoting.support.RemoteInvocation"))), + this.getClass().getName() + "$InvokeMethodAdvice"); + } + + @SuppressWarnings("unused") + public static class InvokeMethodAdvice { + + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void onEnter( + @Advice.This RmiBasedExporter thisObject, + @Advice.Argument(0) RemoteInvocation remoteInv, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelRequest") ClassAndMethod request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + callDepth = CallDepth.forClass(RmiBasedExporter.class); + if (callDepth.getAndIncrement() > 0) { + return; + } + + Context parentContext = THREAD_LOCAL_CONTEXT.getAndResetContext(); + Class serverClass = thisObject.getService().getClass(); + String methodName = remoteInv.getMethodName(); + request = ClassAndMethod.create(serverClass, methodName); + + if (!serverInstrumenter().shouldStart(parentContext, request)) { + return; + } + + context = serverInstrumenter().start(parentContext, request); + scope = context.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelCallDepth") CallDepth callDepth, + @Advice.Local("otelRequest") ClassAndMethod request, + @Advice.Local("otelContext") Context context, + @Advice.Local("otelScope") Scope scope) { + + if (callDepth.decrementAndGet() > 0) { + return; + } + if (scope == null) { + return; + } + scope.close(); + serverInstrumenter().end(context, request, null, throwable); + } + } +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/groovy/SpringRmiTest.groovy b/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/groovy/SpringRmiTest.groovy new file mode 100644 index 0000000000..3ac62c5aed --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/groovy/SpringRmiTest.groovy @@ -0,0 +1,171 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +import static io.opentelemetry.api.trace.StatusCode.ERROR + +import io.opentelemetry.api.trace.SpanKind +import io.opentelemetry.instrumentation.test.AgentInstrumentationSpecification +import io.opentelemetry.instrumentation.test.utils.PortUtils +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes +import org.springframework.boot.SpringApplication +import org.springframework.context.ConfigurableApplicationContext +import org.springframework.context.annotation.Bean +import org.springframework.remoting.rmi.RmiProxyFactoryBean +import org.springframework.remoting.rmi.RmiServiceExporter +import org.springframework.remoting.support.RemoteExporter +import spock.lang.Shared +import springrmi.app.SpringRmiGreeter +import springrmi.app.SpringRmiGreeterImpl + +class SpringRmiTest extends AgentInstrumentationSpecification { + + @Shared + ConfigurableApplicationContext serverAppContext + + @Shared + ConfigurableApplicationContext clientAppContext + + @Shared + static int registryPort + + static class ServerConfig { + @Bean + static RemoteExporter registerRMIExporter() { + RmiServiceExporter exporter = new RmiServiceExporter() + exporter.setServiceName("springRmiGreeter") + exporter.setServiceInterface(SpringRmiGreeter) + exporter.setService(new SpringRmiGreeterImpl()) + exporter.setRegistryPort(registryPort) + return exporter + } + } + + static class ClientConfig { + @Bean + static RmiProxyFactoryBean rmiProxy() { + RmiProxyFactoryBean bean = new RmiProxyFactoryBean() + bean.setServiceInterface(SpringRmiGreeter) + bean.setServiceUrl("rmi://localhost:" + registryPort + "/springRmiGreeter") + return bean + } + } + + def setupSpec() { + registryPort = PortUtils.findOpenPort() + def serverApp = new SpringApplication(ServerConfig) + serverAppContext = serverApp.run() + def clientApp = new SpringApplication(ClientConfig) + clientAppContext = clientApp.run() + } + + def cleanupSpec() { + serverAppContext.close() + clientAppContext.close() + } + + def "Client call creates spans"() { + given: + SpringRmiGreeter client = clientAppContext.getBean(SpringRmiGreeter) + when: + def response = runWithSpan("parent") { client.hello("Test Name") } + then: + response == "Hello Test Name" + assertTraces(1) { + trace(0, 3) { + span(0) { + name "parent" + kind SpanKind.INTERNAL + hasNoParent() + } + span(1) { + name "springrmi.app.SpringRmiGreeter/hello" + kind SpanKind.CLIENT + childOf span(0) + attributes { + "$SemanticAttributes.RPC_SYSTEM" "spring_rmi" + "$SemanticAttributes.RPC_SERVICE" "springrmi.app.SpringRmiGreeter" + "$SemanticAttributes.RPC_METHOD" "hello" + } + } + span(2) { + name "springrmi.app.SpringRmiGreeterImpl/hello" + kind SpanKind.SERVER + childOf span(1) + attributes { + "$SemanticAttributes.RPC_SYSTEM" "spring_rmi" + "$SemanticAttributes.RPC_SERVICE" "springrmi.app.SpringRmiGreeterImpl" + "$SemanticAttributes.RPC_METHOD" "hello" + } + } + } + } + } + + def "Throws exception"() { + given: + SpringRmiGreeter client = clientAppContext.getBean(SpringRmiGreeter) + when: + runWithSpan("parent") { client.exceptional() } + then: + def error = thrown(IllegalStateException) + assertTraces(1) { + trace(0, 3) { + span(0) { + name "parent" + kind SpanKind.INTERNAL + status ERROR + hasNoParent() + event(0) { + eventName("$SemanticAttributes.EXCEPTION_EVENT_NAME") + attributes { + "$SemanticAttributes.EXCEPTION_TYPE" error.getClass().getCanonicalName() + "$SemanticAttributes.EXCEPTION_MESSAGE" error.getMessage() + "$SemanticAttributes.EXCEPTION_STACKTRACE" String + } + } + } + span(1) { + name "springrmi.app.SpringRmiGreeter/exceptional" + kind SpanKind.CLIENT + status ERROR + childOf span(0) + event(0) { + eventName("$SemanticAttributes.EXCEPTION_EVENT_NAME") + attributes { + "$SemanticAttributes.EXCEPTION_TYPE" error.getClass().getCanonicalName() + "$SemanticAttributes.EXCEPTION_MESSAGE" error.getMessage() + "$SemanticAttributes.EXCEPTION_STACKTRACE" String + } + } + attributes { + "$SemanticAttributes.RPC_SYSTEM" "spring_rmi" + "$SemanticAttributes.RPC_SERVICE" "springrmi.app.SpringRmiGreeter" + "$SemanticAttributes.RPC_METHOD" "exceptional" + } + } + span(2) { + name "springrmi.app.SpringRmiGreeterImpl/exceptional" + kind SpanKind.SERVER + childOf span(1) + status ERROR + event(0) { + eventName("$SemanticAttributes.EXCEPTION_EVENT_NAME") + attributes { + "$SemanticAttributes.EXCEPTION_TYPE" error.getClass().getCanonicalName() + "$SemanticAttributes.EXCEPTION_MESSAGE" error.getMessage() + "$SemanticAttributes.EXCEPTION_STACKTRACE" String + } + } + attributes { + "$SemanticAttributes.RPC_SYSTEM" "spring_rmi" + "$SemanticAttributes.RPC_SERVICE" "springrmi.app.SpringRmiGreeterImpl" + "$SemanticAttributes.RPC_METHOD" "exceptional" + } + } + } + } + } + +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/java/springrmi/app/SpringRmiGreeter.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/java/springrmi/app/SpringRmiGreeter.java new file mode 100644 index 0000000000..76e909d804 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/java/springrmi/app/SpringRmiGreeter.java @@ -0,0 +1,14 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package springrmi.app; + +import java.rmi.RemoteException; + +public interface SpringRmiGreeter { + String hello(String name) throws RemoteException; + + void exceptional() throws RemoteException; +} diff --git a/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/java/springrmi/app/SpringRmiGreeterImpl.java b/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/java/springrmi/app/SpringRmiGreeterImpl.java new file mode 100644 index 0000000000..e2022ff5a2 --- /dev/null +++ b/instrumentation/spring/spring-rmi-4.0/javaagent/src/test/java/springrmi/app/SpringRmiGreeterImpl.java @@ -0,0 +1,23 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package springrmi.app; + +public class SpringRmiGreeterImpl implements SpringRmiGreeter { + + @Override + public String hello(String name) { + return someMethod(name); + } + + public String someMethod(String name) { + return "Hello " + name; + } + + @Override + public void exceptional() { + throw new IllegalStateException("expected"); + } +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java index a7b01e5ea7..3a64a32fdf 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java @@ -66,13 +66,18 @@ public class AdditionalLibraryIgnoredTypesConfigurer implements IgnoredTypesConf .ignoreClass("org.springframework.messaging.") .ignoreClass("org.springframework.objenesis.") .ignoreClass("org.springframework.orm.") - .ignoreClass("org.springframework.remoting.") .ignoreClass("org.springframework.scripting.") .ignoreClass("org.springframework.stereotype.") .ignoreClass("org.springframework.transaction.") .ignoreClass("org.springframework.ui.") .ignoreClass("org.springframework.validation."); + builder + .ignoreClass("org.springframework.remoting.") + .allowClass("org.springframework.remoting.rmi.RmiBasedExporter") + .allowClass("org.springframework.remoting.rmi.RmiClientInterceptor") + .allowClass("org.springframework.remoting.rmi.RmiProxyFactoryBean"); + builder .ignoreClass("org.springframework.data.") .allowClass("org.springframework.data.repository.core.support.RepositoryFactorySupport") diff --git a/settings.gradle.kts b/settings.gradle.kts index 937608dc23..d80316ad62 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -369,6 +369,7 @@ include(":instrumentation:spring:spring-integration-4.1:library") include(":instrumentation:spring:spring-integration-4.1:testing") include(":instrumentation:spring:spring-kafka-2.7:javaagent") include(":instrumentation:spring:spring-rabbit-1.0:javaagent") +include(":instrumentation:spring:spring-rmi-4.0:javaagent") include(":instrumentation:spring:spring-scheduling-3.1:javaagent") include(":instrumentation:spring:spring-web-3.1:javaagent") include(":instrumentation:spring:spring-web-3.1:library")