From f047cce7c390c4a42e21a00ebd5587aaec41cffb Mon Sep 17 00:00:00 2001 From: Thomas Darimont Date: Tue, 18 Feb 2014 14:55:50 +0100 Subject: [PATCH] DATACMNS-441 - Fixed potential NullPointerException in query method detection on Java 8 compiled code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit We now skip bridge methods for query method processing in order to circumvent the changed behavior of Class#getMethods() in Java 8 (when the code was compiled with target byte code level 1.8). On Java 8 this results in bridge methods being found and inspected for query method annotations. Since we currently cannot analyze generic return types of bridge methods this results in NullPointerExceptions being thrown at a later stage in AbstractRepositoryMetadata#getReturnedDomainClass(…). Original pull request: #64. Related issue: DATAJPA-465. --- .../support/DefaultRepositoryInformation.java | 5 ++-- ...DefaultRepositoryInformationUnitTests.java | 23 ++++++++++++++++++- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java index 103e73246..899a20e61 100644 --- a/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java +++ b/src/main/java/org/springframework/data/repository/core/support/DefaultRepositoryInformation.java @@ -1,5 +1,5 @@ /* - * Copyright 2011-2013 the original author or authors. + * Copyright 2011-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -172,7 +172,8 @@ class DefaultRepositoryInformation implements RepositoryInformation { * @return */ private boolean isQueryMethodCandidate(Method method) { - return isQueryAnnotationPresentOn(method) || !isCustomMethod(method) && !isBaseClassMethod(method); + return !method.isBridge() // + && (isQueryAnnotationPresentOn(method) || !isCustomMethod(method) && !isBaseClassMethod(method)); } /** diff --git a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java index e6af6b44d..78ab79074 100644 --- a/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java +++ b/src/test/java/org/springframework/data/repository/core/support/DefaultRepositoryInformationUnitTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 the original author or authors. + * Copyright 2013-2014 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -49,6 +49,7 @@ import org.springframework.data.repository.core.support.DefaultRepositoryMetadat * Unit tests for {@link DefaultRepositoryInformation}. * * @author Oliver Gierke + * @author Thomas Darimont */ @RunWith(MockitoJUnitRunner.class) public class DefaultRepositoryInformationUnitTests { @@ -208,6 +209,20 @@ public class DefaultRepositoryInformationUnitTests { assertThat(information.getTargetClassMethod(method), is(reference)); } + /** + * @see DATACMNS-441 + */ + @Test + public void getQueryShouldNotReturnAnyBridgeMethods() { + + RepositoryMetadata metadata = new DefaultRepositoryMetadata(CustomDefaultRepositoryMethodsRepository.class); + RepositoryInformation information = new DefaultRepositoryInformation(metadata, CrudRepository.class, null); + + for (Method method : information.getQueryMethods()) { + assertFalse(method.isBridge()); + } + } + private Method getMethodFrom(Class type, String name) { for (Method method : type.getMethods()) { if (method.getName().equals(name)) { @@ -299,4 +314,10 @@ public class DefaultRepositoryInformationUnitTests { } interface BossRepository extends CrudRepository {} + + interface CustomDefaultRepositoryMethodsRepository extends CrudRepository { + + @MyQuery + List findAll(); + } }