diff --git a/instrumentation/jaxws/jaxws-2.0/javaagent/jaxws-2.0-javaagent.gradle b/instrumentation/jaxws/jaxws-2.0/javaagent/jaxws-2.0-javaagent.gradle new file mode 100644 index 0000000000..4b14b298c7 --- /dev/null +++ b/instrumentation/jaxws/jaxws-2.0/javaagent/jaxws-2.0-javaagent.gradle @@ -0,0 +1,15 @@ +apply from: "$rootDir/gradle/instrumentation.gradle" + +muzzle { + pass { + group = "javax.xml.ws" + module = "jaxws-api" + versions = "[2.0,]" + skipVersions += '2.1-1' // contains broken dependency + } +} + +dependencies { + library group: 'javax.xml.ws', name: 'jaxws-api', version: '2.0' + implementation project(":instrumentation:jaxws:jaxws-common:javaagent") +} \ No newline at end of file diff --git a/instrumentation/jaxws/jaxws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/JaxWsInstrumentationModule.java b/instrumentation/jaxws/jaxws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/JaxWsInstrumentationModule.java new file mode 100644 index 0000000000..69bed7d49d --- /dev/null +++ b/instrumentation/jaxws/jaxws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/JaxWsInstrumentationModule.java @@ -0,0 +1,25 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.v2_0; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.tooling.InstrumentationModule; +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.util.Collections; +import java.util.List; + +@AutoService(InstrumentationModule.class) +public class JaxWsInstrumentationModule extends InstrumentationModule { + + public JaxWsInstrumentationModule() { + super("jaxws", "jaxws-2.0"); + } + + @Override + public List typeInstrumentations() { + return Collections.singletonList(new WebServiceProviderInstrumentation()); + } +} diff --git a/instrumentation/jaxws/jaxws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/WebServiceProviderInstrumentation.java b/instrumentation/jaxws/jaxws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/WebServiceProviderInstrumentation.java new file mode 100644 index 0000000000..36fec3716d --- /dev/null +++ b/instrumentation/jaxws/jaxws-2.0/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/WebServiceProviderInstrumentation.java @@ -0,0 +1,81 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.v2_0; + +import static io.opentelemetry.javaagent.instrumentation.jaxws.common.JaxWsTracer.tracer; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.hasInterface; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.isPublic; +import static net.bytebuddy.matcher.ElementMatchers.nameMatches; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArguments; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.lang.reflect.Method; +import java.util.Collections; +import java.util.Map; +import javax.xml.ws.Provider; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class WebServiceProviderInstrumentation implements TypeInstrumentation { + + @Override + public ElementMatcher classLoaderOptimization() { + return hasClassesNamed("javax.xml.ws.Provider"); + } + + @Override + public ElementMatcher typeMatcher() { + return hasInterface(named("javax.xml.ws.Provider")); + } + + @Override + public Map, String> transformers() { + return Collections.singletonMap( + isMethod().and(isPublic()).and(nameMatches("invoke")).and(takesArguments(1)), + WebServiceProviderInstrumentation.class.getName() + "$InvokeAdvice"); + } + + public static class InvokeAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void startSpan( + @Advice.This Object target, + @Advice.Origin Method method, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (CallDepthThreadLocalMap.incrementCallDepth(Provider.class) > 0) { + return; + } + span = tracer().startSpan(target.getClass(), method); + scope = span.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (scope == null) { + return; + } + CallDepthThreadLocalMap.reset(Provider.class); + + scope.close(); + if (throwable == null) { + tracer().end(span); + } else { + tracer().endExceptionally(span, throwable); + } + } + } +} diff --git a/instrumentation/jaxws/jaxws-2.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/JaxWsAnnotationsTest.groovy b/instrumentation/jaxws/jaxws-2.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/JaxWsAnnotationsTest.groovy new file mode 100644 index 0000000000..462a5dd8b6 --- /dev/null +++ b/instrumentation/jaxws/jaxws-2.0/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/JaxWsAnnotationsTest.groovy @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.v2_0 + +import io.opentelemetry.instrumentation.test.AgentTestRunner + +class JaxWsAnnotationsTest extends AgentTestRunner { + + def "Web service providers generate spans"() { + when: + new SoapProvider().invoke(null) + + then: + assertTraces(1, { + trace(0, 1) { + span(0) { + name 'SoapProvider.invoke' + attributes { + attribute('code.namespace', 'io.opentelemetry.javaagent.instrumentation.jaxws.v2_0.SoapProvider') + attribute('code.function', 'invoke') + } + } + } + }) + } +} diff --git a/instrumentation/jaxws/jaxws-2.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/SoapProvider.java b/instrumentation/jaxws/jaxws-2.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/SoapProvider.java new file mode 100644 index 0000000000..92301977d4 --- /dev/null +++ b/instrumentation/jaxws/jaxws-2.0/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/v2_0/SoapProvider.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.v2_0; + +import javax.xml.ws.Provider; + +public class SoapProvider implements Provider { + + @Override + public Message invoke(Message message) { + return message; + } + + public static class Message {} +} diff --git a/instrumentation/jaxws/jaxws-common/javaagent/jaxws-common-javaagent.gradle b/instrumentation/jaxws/jaxws-common/javaagent/jaxws-common-javaagent.gradle new file mode 100644 index 0000000000..7d204735e6 --- /dev/null +++ b/instrumentation/jaxws/jaxws-common/javaagent/jaxws-common-javaagent.gradle @@ -0,0 +1,2 @@ +apply from: "$rootDir/gradle/instrumentation.gradle" + diff --git a/instrumentation/jaxws/jaxws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/common/JaxWsTracer.java b/instrumentation/jaxws/jaxws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/common/JaxWsTracer.java new file mode 100644 index 0000000000..d672940002 --- /dev/null +++ b/instrumentation/jaxws/jaxws-common/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/common/JaxWsTracer.java @@ -0,0 +1,42 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.common; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Context; +import io.opentelemetry.instrumentation.api.tracer.BaseTracer; +import io.opentelemetry.semconv.trace.attributes.SemanticAttributes; +import java.lang.reflect.Method; + +public class JaxWsTracer extends BaseTracer { + + private static final JaxWsTracer TRACER = new JaxWsTracer(); + + public static JaxWsTracer tracer() { + return TRACER; + } + + @Override + protected String getInstrumentationName() { + return "io.opentelemetry.javaagent.jaxws"; + } + + public Span startSpan(Class target, Method method) { + String spanName = spanNameForMethod(target, method); + + Context context = Context.current(); + Span serverSpan = BaseTracer.getCurrentServerSpan(context); + if (serverSpan != null) { + serverSpan.updateName(spanName); + } + + return tracer + .spanBuilder(spanName) + .setAttribute(SemanticAttributes.CODE_NAMESPACE, method.getDeclaringClass().getName()) + .setAttribute(SemanticAttributes.CODE_FUNCTION, method.getName()) + .startSpan(); + } +} diff --git a/instrumentation/jaxws/jws-1.1/javaagent/jws-1.1-javaagent.gradle b/instrumentation/jaxws/jws-1.1/javaagent/jws-1.1-javaagent.gradle new file mode 100644 index 0000000000..4407fde3f0 --- /dev/null +++ b/instrumentation/jaxws/jws-1.1/javaagent/jws-1.1-javaagent.gradle @@ -0,0 +1,14 @@ +apply from: "$rootDir/gradle/instrumentation.gradle" + +muzzle { + pass { + group = "javax.jws" + module = "javax.jws-api" + versions = "[1.1,]" + } +} + +dependencies { + library group: 'javax.jws', name: 'javax.jws-api', version: '1.1' + implementation project(":instrumentation:jaxws:jaxws-common:javaagent") +} \ No newline at end of file diff --git a/instrumentation/jaxws/jws-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsAnnotationsInstrumentation.java b/instrumentation/jaxws/jws-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsAnnotationsInstrumentation.java new file mode 100644 index 0000000000..e5574a7054 --- /dev/null +++ b/instrumentation/jaxws/jws-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsAnnotationsInstrumentation.java @@ -0,0 +1,92 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1; + +import static io.opentelemetry.javaagent.instrumentation.jaxws.common.JaxWsTracer.tracer; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.hasInterface; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.hasSuperMethod; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.AgentElementMatchers.methodIsDeclaredByType; +import static io.opentelemetry.javaagent.tooling.bytebuddy.matcher.ClassLoaderMatcher.hasClassesNamed; +import static java.util.Collections.singletonMap; +import static net.bytebuddy.matcher.ElementMatchers.inheritsAnnotation; +import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; +import static net.bytebuddy.matcher.ElementMatchers.isMethod; +import static net.bytebuddy.matcher.ElementMatchers.isPublic; +import static net.bytebuddy.matcher.ElementMatchers.named; + +import io.opentelemetry.api.trace.Span; +import io.opentelemetry.context.Scope; +import io.opentelemetry.javaagent.instrumentation.api.CallDepthThreadLocalMap; +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.lang.reflect.Method; +import java.util.Map; +import javax.jws.WebService; +import net.bytebuddy.asm.Advice; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +public class JwsAnnotationsInstrumentation implements TypeInstrumentation { + + public static final String JWS_WEB_SERVICE_ANNOTATION = "javax.jws.WebService"; + + @Override + public ElementMatcher classLoaderOptimization() { + return hasClassesNamed(JWS_WEB_SERVICE_ANNOTATION); + } + + @Override + public ElementMatcher typeMatcher() { + return hasInterface(isAnnotatedWith(named(JWS_WEB_SERVICE_ANNOTATION))) + .or(isAnnotatedWith(named(JWS_WEB_SERVICE_ANNOTATION))); + } + + @Override + public Map, String> transformers() { + // JaxWS WebService methods are defined either by implementing an interface annotated + // with @WebService or by any public method from a class annotated with @WebService. + return singletonMap( + isMethod() + .and(isPublic()) + .and( + hasSuperMethod( + methodIsDeclaredByType(inheritsAnnotation(named(JWS_WEB_SERVICE_ANNOTATION))))), + JwsAnnotationsInstrumentation.class.getName() + "$JwsAnnotationsAdvice"); + } + + public static class JwsAnnotationsAdvice { + @Advice.OnMethodEnter(suppress = Throwable.class) + public static void startSpan( + @Advice.This Object target, + @Advice.Origin Method method, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (CallDepthThreadLocalMap.incrementCallDepth(WebService.class) > 0) { + return; + } + span = tracer().startSpan(target.getClass(), method); + scope = span.makeCurrent(); + } + + @Advice.OnMethodExit(onThrowable = Throwable.class, suppress = Throwable.class) + public static void stopSpan( + @Advice.Thrown Throwable throwable, + @Advice.Local("otelSpan") Span span, + @Advice.Local("otelScope") Scope scope) { + if (scope == null) { + return; + } + CallDepthThreadLocalMap.reset(WebService.class); + + scope.close(); + if (throwable == null) { + tracer().end(span); + } else { + tracer().endExceptionally(span, throwable); + } + } + } +} diff --git a/instrumentation/jaxws/jws-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsInstrumentationModule.java b/instrumentation/jaxws/jws-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsInstrumentationModule.java new file mode 100644 index 0000000000..3bb8fa8751 --- /dev/null +++ b/instrumentation/jaxws/jws-1.1/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsInstrumentationModule.java @@ -0,0 +1,25 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.tooling.InstrumentationModule; +import io.opentelemetry.javaagent.tooling.TypeInstrumentation; +import java.util.Collections; +import java.util.List; + +@AutoService(InstrumentationModule.class) +public class JwsInstrumentationModule extends InstrumentationModule { + + public JwsInstrumentationModule() { + super("jaxws", "jws-1.1"); + } + + @Override + public List typeInstrumentations() { + return Collections.singletonList(new JwsAnnotationsInstrumentation()); + } +} diff --git a/instrumentation/jaxws/jws-1.1/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsAnnotationsTest.groovy b/instrumentation/jaxws/jws-1.1/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsAnnotationsTest.groovy new file mode 100644 index 0000000000..ad43f3c3ef --- /dev/null +++ b/instrumentation/jaxws/jws-1.1/javaagent/src/test/groovy/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/JwsAnnotationsTest.groovy @@ -0,0 +1,52 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1 + +import io.opentelemetry.instrumentation.test.AgentTestRunner + +class JwsAnnotationsTest extends AgentTestRunner { + + def "WebService on a class generates spans only for public methods"() { + when: + new WebServiceClass().doSomethingPublic() + new WebServiceClass().doSomethingPackagePrivate() + new WebServiceClass().doSomethingProtected() + + then: + assertTraces(1, { + trace(0, 1) { + span(0) { + name "WebServiceClass.doSomethingPublic" + attributes { + attribute('code.function', 'doSomethingPublic') + attribute('code.namespace', 'io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1.WebServiceClass') + } + } + } + }) + } + + def "WebService via interface generates spans only for methods of the interface"() { + when: + new WebServiceFromInterface().partOfPublicInterface() + new WebServiceFromInterface().notPartOfPublicInterface() + new WebServiceFromInterface().notPartOfAnything() + + then: + assertTraces(1, { + trace(0, 1) { + span(0) { + name "WebServiceFromInterface.partOfPublicInterface" + attributes { + attribute('code.function', 'partOfPublicInterface') + attribute('code.namespace', 'io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1.WebServiceFromInterface') + } + } + } + }) + } + +} diff --git a/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceClass.java b/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceClass.java new file mode 100644 index 0000000000..60d0cb046b --- /dev/null +++ b/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceClass.java @@ -0,0 +1,18 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1; + +import javax.jws.WebService; + +// This is pure java to not have any groovy generated public method surprises +@WebService +public class WebServiceClass { + public void doSomethingPublic() {} + + protected void doSomethingProtected() {} + + void doSomethingPackagePrivate() {} +} diff --git a/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceDefinitionInterface.java b/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceDefinitionInterface.java new file mode 100644 index 0000000000..ecf63fe031 --- /dev/null +++ b/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceDefinitionInterface.java @@ -0,0 +1,13 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1; + +import javax.jws.WebService; + +@WebService +public interface WebServiceDefinitionInterface { + void partOfPublicInterface(); +} diff --git a/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceFromInterface.java b/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceFromInterface.java new file mode 100644 index 0000000000..b84ae59acd --- /dev/null +++ b/instrumentation/jaxws/jws-1.1/javaagent/src/test/java/io/opentelemetry/javaagent/instrumentation/jaxws/jws/v1_1/WebServiceFromInterface.java @@ -0,0 +1,15 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.instrumentation.jaxws.jws.v1_1; + +public class WebServiceFromInterface implements WebServiceDefinitionInterface { + @Override + public void partOfPublicInterface() {} + + public void notPartOfPublicInterface() {} + + void notPartOfAnything() {} +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/AgentElementMatchers.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/AgentElementMatchers.java index ace3de3313..3b1113911e 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/AgentElementMatchers.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/AgentElementMatchers.java @@ -40,7 +40,27 @@ public class AgentElementMatchers { .and(new SafeHasSuperTypeMatcher<>(new SafeErasureMatcher<>(matcher), false)); } - // TODO: add javadoc + /** + * Matches method's declaring class against a given type matcher. + * + * @param matcher type matcher to match method's declaring type against. + * @param Type of the matched object + * @return a matcher that matches method's declaring class against a given type matcher. + */ + public static ElementMatcher.Junction methodIsDeclaredByType( + ElementMatcher matcher) { + return new MethodDeclaringTypeMatcher<>(matcher); + } + + /** + * Matches a method and all its declarations up the class hierarchy including interfaces using + * provided matcher. + * + * @param matcher method matcher to apply to method declarations up the hierarchy. + * @param Type of the matched object + * @return A matcher that matches a method and all its declarations up the class hierarchy + * including interfaces. + */ public static ElementMatcher.Junction hasSuperMethod( ElementMatcher matcher) { return new HasSuperMethodMatcher<>(matcher); diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/HasSuperMethodMatcher.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/HasSuperMethodMatcher.java index 1b66bca696..484775eb4e 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/HasSuperMethodMatcher.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/HasSuperMethodMatcher.java @@ -15,7 +15,12 @@ import net.bytebuddy.description.type.TypeDefinition; import net.bytebuddy.description.type.TypeList; import net.bytebuddy.matcher.ElementMatcher; -// TODO: add javadoc +/** + * Matches a method and all its declarations up the class hierarchy including interfaces using + * provided matcher. + * + * @param Type of the matched method. + */ class HasSuperMethodMatcher extends ElementMatcher.Junction.AbstractBase { diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/MethodDeclaringTypeMatcher.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/MethodDeclaringTypeMatcher.java new file mode 100644 index 0000000000..457ba98451 --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/bytebuddy/matcher/MethodDeclaringTypeMatcher.java @@ -0,0 +1,53 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.bytebuddy.matcher; + +import java.util.Objects; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +/** + * Matches method's declaring class against a given type matcher. + * + * @param Type of the matched object + */ +public class MethodDeclaringTypeMatcher + extends ElementMatcher.Junction.AbstractBase { + + private final ElementMatcher matcher; + + public MethodDeclaringTypeMatcher(ElementMatcher matcher) { + this.matcher = matcher; + } + + @Override + public boolean matches(T target) { + return matcher.matches(target.getDeclaringType().asErasure()); + } + + @Override + public String toString() { + return "methodDeclaringTypeMatcher(matcher=" + matcher + ')'; + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof MethodDeclaringTypeMatcher)) { + return false; + } + MethodDeclaringTypeMatcher that = (MethodDeclaringTypeMatcher) o; + return Objects.equals(matcher, that.matcher); + } + + @Override + public int hashCode() { + return Objects.hash(matcher); + } +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/matcher/AdditionalLibraryIgnoresMatcher.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/matcher/AdditionalLibraryIgnoresMatcher.java index 9ed96127fe..5ded2afe5d 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/matcher/AdditionalLibraryIgnoresMatcher.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/matcher/AdditionalLibraryIgnoresMatcher.java @@ -189,8 +189,8 @@ public class AdditionalLibraryIgnoresMatcher return false; } - // xml-apis, xerces, xalan - if (name.startsWith("javax.xml.") + // xml-apis, xerces, xalan, but not xml web-services + if ((name.startsWith("javax.xml.") && !name.startsWith("javax.xml.ws.")) || name.startsWith("org.apache.bcel.") || name.startsWith("org.apache.html.") || name.startsWith("org.apache.regexp.") diff --git a/settings.gradle b/settings.gradle index ac19adef13..c9237b049d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -118,6 +118,9 @@ include ':instrumentation:jaxrs-client:jaxrs-client-1.1:javaagent' include ':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-common:javaagent' include ':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-jersey-2.0:javaagent' include ':instrumentation:jaxrs-client:jaxrs-client-2.0:jaxrs-client-2.0-resteasy-2.0:javaagent' +include ':instrumentation:jaxws:jaxws-2.0:javaagent' +include ':instrumentation:jaxws:jaxws-common:javaagent' +include ':instrumentation:jaxws:jws-1.1:javaagent' include ':instrumentation:jdbc:javaagent' include ':instrumentation:jdbc:javaagent-unittests' include ':instrumentation:jedis:jedis-1.4:javaagent'