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
This commit is contained in:
kfujita 2019-10-25 19:55:13 +09:00 committed by Tyler Benson
parent 733342de5e
commit d8bd12bef8
4 changed files with 74 additions and 1 deletions

View File

@ -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.+'
}

View File

@ -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);

View File

@ -0,0 +1,59 @@
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() {
}
}
}

View File

@ -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)
}