Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring Boot 2.5.x - "null KeyStore name" occurs for builder().mock(SomeRepository.class) #188

Open
fnl-trackunit opened this issue Aug 2, 2021 · 4 comments

Comments

@fnl-trackunit
Copy link

fnl-trackunit commented Aug 2, 2021

Describe the bug
(using spring-data-mock 2.2.0)

With a JUnit test, I mock a Repository like this (using Java 15/16):

var repository = builder().mock(SomeRepository.class);

This works perfectly under Spring Boot Starter Project 1.4.9, but as soon as I upgrade to Spring Boot 1.5.x, I get an IllegalArgumentException("null KeyStore name")

... and before this exception, I get this error:

com.mmnaseri.utils.spring.data.error.DataOperationDefinitionException: Encountered an error while resolving operation metadata: public abstract void org.springframework.data.repository.CrudRepository.deleteAllById(java.lang.Iterable)

My repository looks like this:

@Repository
public interface CachedSimulatedFaultRepository extends CrudRepository<SimulatedFaultData, String> {

    SimulatedFaultData findFirstByCustomerIdAndMachineIdAndUserId(int customerId, UUID machineId, int userId);

    List<SimulatedFaultData> findByCustomerIdAndMachineId(int customerId, UUID machineId);

    List<SimulatedFaultData> findByCustomerId(int customerId);

    SimulatedFaultData findFirstByMachineId(UUID machineId); // existsByMachineId throws UnsupportedOperationException
}

No other code was changed besides the dependency update.

It is possible to run the test with success from IntelliJ, but it seems to fail only when running mvn test.

To Reproduce
Steps to reproduce the behavior:

  1. Use a regular Spring Boot project using e.g. a Spring Boot JPA repository using Java 15 or newer.
  2. Use spring-boot-starter-parent 1.5.0 or newer as a dependency
  3. Setup a JUnit 5 test that calls builder().mock(SomeRepository.class) in a method with the @beforeeach annotation
  4. Run 'mvn test' to trigger the issue.

Expected behavior
No error occurs, and my repository is being mocked like under Spring Boot 1.4.9.

Screenshots
image

Additional Context
The error occurs in sun.security.util.PolicyUtil

    public static KeyStore getKeyStore
                (URL policyUrl,                 // URL of policy file
                String keyStoreName,            // input: keyStore URL
                String keyStoreType,            // input: keyStore type
                String keyStoreProvider,        // input: keyStore provider
                String storePassURL,            // input: keyStore password
                Debug debug)
        throws KeyStoreException, MalformedURLException, IOException,
                NoSuchProviderException, NoSuchAlgorithmException,
                java.security.cert.CertificateException {

        if (keyStoreName == null) {
            throw new IllegalArgumentException("null KeyStore name");
        }

Stack Trace
getKeyStore:82, PolicyUtil (sun.security.util)
init:523, PolicyFile (sun.security.provider)
run:456, PolicyFile$4 (sun.security.provider)
run:385, PolicyFile$4 (sun.security.provider)
executePrivileged:753, AccessController (java.security)
doPrivileged:312, AccessController (java.security)
initPolicyFile:385, PolicyFile (sun.security.provider)
initPolicyFile:372, PolicyFile (sun.security.provider)
init:329, PolicyFile (sun.security.provider)
:283, PolicyFile (sun.security.provider)
loadPolicyProvider:212, Policy (java.security)
getPolicyNoCheck:183, Policy (java.security)
implies:321, ProtectionDomain (java.security)
impliesWithAltFilePerm:353, ProtectionDomain (java.security)
checkPermission:450, AccessControlContext (java.security)
checkPermission:1036, AccessController (java.security)
run:48, Loader$1 (ch.qos.logback.core.util)
run:45, Loader$1 (ch.qos.logback.core.util)
executePrivileged:753, AccessController (java.security)
doPrivileged:312, AccessController (java.security)
:45, Loader (ch.qos.logback.core.util)
findURLOfDefaultConfigurationFile:119, ContextInitializer (ch.qos.logback.classic.util)
autoConfig:148, ContextInitializer (ch.qos.logback.classic.util)
init:84, StaticLoggerBinder (org.slf4j.impl)
:55, StaticLoggerBinder (org.slf4j.impl)
bind:150, LoggerFactory (org.slf4j)
performInitialization:124, LoggerFactory (org.slf4j)
getILoggerFactory:417, LoggerFactory (org.slf4j)
getLogger:362, LoggerFactory (org.slf4j)
getLogger:388, LoggerFactory (org.slf4j)
:19, MachineFaultMappingService (com.trackunit.can.faults.business)
newInstance:-1, GeneratedSerializationConstructorAccessor1 (jdk.internal.reflect)
newInstanceWithCaller:499, Constructor (java.lang.reflect)
newInstance:480, Constructor (java.lang.reflect)
newInstance:48, SunReflectionFactoryInstantiator (org.objenesis.instantiator.sun)
newInstance:73, ObjenesisBase (org.objenesis)
newInstance:21, ObjenesisInstantiator (org.mockito.internal.creation.instance)
createMock:48, SubclassByteBuddyMockMaker (org.mockito.internal.creation.bytebuddy)
createMock:29, ByteBuddyMockMaker (org.mockito.internal.creation.bytebuddy)
createMock:53, MockUtil (org.mockito.internal.util)
mock:61, MockitoCore (org.mockito.internal)
mock:1949, Mockito (org.mockito)
mock:1860, Mockito (org.mockito)
:29, SimulatedFaultsCacheHouseKeepingTest (com.trackunit.can.faults.business.cache)

@fnl-trackunit
Copy link
Author

Perhaps this is caused by spring-boot-starter-data-jpa 2.5.x?

@fnl-trackunit
Copy link
Author

I found a work-around where I add a default implementation on my CrudRepository for deleteAllById(Iterable):

@Repository
public interface CachedSimulatedFaultRepository extends CrudRepository<SimulatedFaultData, String> {
    ...

    // Work-around to avoid:
    // com.mmnaseri.utils.spring.data.error.DataOperationDefinitionException: Encountered an error while resolving
    // operation metadata: public abstract void org.springframework.data.repository.CrudRepository.deleteAllById(java.lang.Iterable)
    @SuppressWarnings("unused")
    default void deleteAllById(Iterable<? extends String> ids) {
        for (String id : ids) {
            deleteById(id);
        }
    }
}

@ablyeom
Copy link

ablyeom commented Aug 5, 2021

Hi, I found similar issue. In my case, failed on JpaRepository.deleteAllByIdInBatch(Iterable).

I'm using Spring Boot 2.5.2, and Spring Data Mock 2.1.1.

Here's my stacktrace.

Updated
Spring Data Mock 2.2.0 is also same issue.

Caused by:
com.mmnaseri.utils.spring.data.error.DataOperationDefinitionException: Encountered an error while resolving operation metadata: public abstract void org.springframework.data.jpa.repository.JpaRepository.deleteAllByIdInBatch(java.lang.Iterable)
    at com.mmnaseri.utils.spring.data.proxy.impl.resolvers.DefaultDataOperationResolver.resolve(DefaultDataOperationResolver.java:52)
    at com.mmnaseri.utils.spring.data.proxy.impl.DefaultRepositoryFactory.getInvocationMappings(DefaultRepositoryFactory.java:278)
    at com.mmnaseri.utils.spring.data.proxy.impl.DefaultRepositoryFactory.getInstance(DefaultRepositoryFactory.java:119)
    at com.mmnaseri.utils.spring.data.dsl.mock.RepositoryMockBuilder.mock(RepositoryMockBuilder.java:113)
    at com.mmnaseri.utils.spring.data.dsl.mock.RepositoryMockBuilder.mock(RepositoryMockBuilder.java:111)
    at kr.chexcar.data.tests.RequisitionTests.init(RequisitionTests.java:38)

    Caused by:
    com.mmnaseri.utils.spring.data.error.QueryParserException: interface org.springframework.data.jpa.repository.JpaRepository: Could not find property `idInBatch` on `class domain.Entity`
        at com.mmnaseri.utils.spring.data.domain.impl.MethodQueryDescriptionExtractor.getPropertyDescriptor(MethodQueryDescriptionExtractor.java:365)
        at com.mmnaseri.utils.spring.data.domain.impl.MethodQueryDescriptionExtractor.parseExpression(MethodQueryDescriptionExtractor.java:285)
        at com.mmnaseri.utils.spring.data.domain.impl.MethodQueryDescriptionExtractor.extract(MethodQueryDescriptionExtractor.java:177)
        at com.mmnaseri.utils.spring.data.proxy.impl.resolvers.QueryMethodDataOperationResolver.resolve(QueryMethodDataOperationResolver.java:59)
        at com.mmnaseri.utils.spring.data.proxy.impl.resolvers.DefaultDataOperationResolver.resolve(DefaultDataOperationResolver.java:50)
        ... 5 more

        Caused by:
        java.lang.IllegalStateException: Could not find property `inBatch` on `class java.lang.Integer`
            at com.mmnaseri.utils.spring.data.tools.PropertyUtils.getPropertyDescriptor(PropertyUtils.java:230)
            at com.mmnaseri.utils.spring.data.domain.impl.MethodQueryDescriptionExtractor.getPropertyDescriptor(MethodQueryDescriptionExtractor.java:358)
            ... 9 more`

@fnl-trackunit
Copy link
Author

Perhaps it is "just" the repository implementations in spring-data-mock like the DefaultCrudRepository that needs those delete methods to satisfy Spring Boot 2.5.x?
https://github.com/mmnaseri/spring-data-mock/blob/development/spring-data-mock/src/main/java/com/mmnaseri/utils/spring/data/repository/DefaultCrudRepository.java

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants