Fadelis / grpcmock

A gRPC Java testing tool to easily mock endpoints of gRPC services for IT or Unit testing
http://grpcmock.org
Apache License 2.0
144 stars 13 forks source link

upgrade to Spring Boot 3, upgrade to Java 17 #25

Closed rfscouto closed 4 months ago

rfscouto commented 1 year ago

I've upgraded to Java 17, a pre-requirement for Spring Boot 3. Hope there are no issues with the build and release pipelines.

According to the Spring Boot 3 migration guide (https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide):

Until grpc-java allows a way to not add the javax.annotation.Generated by default, or moves to jakarta.annotation.Generated, we rely on having the javax.annotation-api dependency. https://github.com/grpc/grpc-java/issues/9179

I faced also issues with mocking the new DefaultListableBeanFactory on the GrpcMockConfigurationTest; I believe it might be an issue with Mockito and Java 17? https://github.com/mockito/mockito/issues/2272 https://github.com/mockito/mockito/issues/2589

org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class org.springframework.beans.factory.support.DefaultListableBeanFactory.

If you're not sure why you're getting this error, please open an issue on GitHub.

Java               : 17
JVM vendor name    : Homebrew
JVM vendor version : 17.0.5+0
JVM name           : OpenJDK 64-Bit Server VM
JVM version        : 17.0.5+0
JVM info           : mixed mode, sharing
OS name            : Mac OS X
OS version         : 13.1

You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.

Underlying exception : org.mockito.exceptions.base.MockitoException: Could not modify all classes [interface org.springframework.beans.factory.config.SingletonBeanRegistry, class org.springframework.beans.factory.support.DefaultSingletonBeanRegistry, interface org.springframework.beans.factory.config.ConfigurableBeanFactory, interface org.springframework.beans.factory.support.BeanDefinitionRegistry, interface java.io.Serializable, class org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory, class org.springframework.beans.factory.support.AbstractBeanFactory, class org.springframework.core.SimpleAliasRegistry, class org.springframework.beans.factory.support.FactoryBeanRegistrySupport, interface org.springframework.beans.factory.config.AutowireCapableBeanFactory, class org.springframework.beans.factory.support.DefaultListableBeanFactory, interface org.springframework.core.AliasRegistry, interface org.springframework.beans.factory.config.ConfigurableListableBeanFactory]

    at org.grpcmock.springboot.GrpcMockConfigurationTest.<init>(GrpcMockConfigurationTest.java:30)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
    at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:480)
    at org.junit.platform.commons.util.ReflectionUtils.newInstance(ReflectionUtils.java:552)
    at org.junit.jupiter.engine.execution.ConstructorInvocation.proceed(ConstructorInvocation.java:56)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
    at org.junit.jupiter.api.extension.InvocationInterceptor.interceptTestClassConstructor(InvocationInterceptor.java:73)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.lambda$invoke$0(InterceptingExecutableInvoker.java:93)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.proceed(InvocationInterceptorChain.java:64)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.chainAndInvoke(InvocationInterceptorChain.java:45)
    at org.junit.jupiter.engine.execution.InvocationInterceptorChain.invoke(InvocationInterceptorChain.java:37)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:92)
    at org.junit.jupiter.engine.execution.InterceptingExecutableInvoker.invoke(InterceptingExecutableInvoker.java:62)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeTestClassConstructor(ClassBasedTestDescriptor.java:363)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateTestClass(ClassBasedTestDescriptor.java:310)
    at org.junit.jupiter.engine.descriptor.ClassTestDescriptor.instantiateTestClass(ClassTestDescriptor.java:79)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.instantiateAndPostProcessTestInstance(ClassBasedTestDescriptor.java:286)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$4(ClassBasedTestDescriptor.java:278)
    at java.base/java.util.Optional.orElseGet(Optional.java:364)
    at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$testInstancesProvider$5(ClassBasedTestDescriptor.java:277)
    at org.junit.jupiter.engine.execution.TestInstancesProvider.getTestInstances(TestInstancesProvider.java:31)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$prepare$0(TestMethodTestDescriptor.java:105)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:104)
    at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.prepare(TestMethodTestDescriptor.java:68)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$prepare$2(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.prepare(NodeTestTask.java:123)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:90)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at java.base/java.util.ArrayList.forEach(ArrayList.java:1511)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:41)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$6(NodeTestTask.java:155)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:141)
    at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:137)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$9(NodeTestTask.java:139)
    at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:138)
    at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:95)
    at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:35)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57)
    at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:54)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:147)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:127)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:90)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.lambda$execute$0(EngineExecutionOrchestrator.java:55)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.withInterceptedStreams(EngineExecutionOrchestrator.java:102)
    at org.junit.platform.launcher.core.EngineExecutionOrchestrator.execute(EngineExecutionOrchestrator.java:54)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:114)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:86)
    at org.junit.platform.launcher.core.DefaultLauncherSession$DelegatingLauncher.execute(DefaultLauncherSession.java:86)
    at org.junit.platform.launcher.core.SessionPerRequestLauncher.execute(SessionPerRequestLauncher.java:53)
    at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:57)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
    at com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
Caused by: org.mockito.exceptions.base.MockitoException: Could not modify all classes [interface org.springframework.beans.factory.config.SingletonBeanRegistry, class org.springframework.beans.factory.support.DefaultSingletonBeanRegistry, interface org.springframework.beans.factory.config.ConfigurableBeanFactory, interface org.springframework.beans.factory.support.BeanDefinitionRegistry, interface java.io.Serializable, class org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory, class org.springframework.beans.factory.support.AbstractBeanFactory, class org.springframework.core.SimpleAliasRegistry, class org.springframework.beans.factory.support.FactoryBeanRegistrySupport, interface org.springframework.beans.factory.config.AutowireCapableBeanFactory, class org.springframework.beans.factory.support.DefaultListableBeanFactory, interface org.springframework.core.AliasRegistry, interface org.springframework.beans.factory.config.ConfigurableListableBeanFactory]
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
    at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
    at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
    ... 72 more
Caused by: java.lang.UnsupportedOperationException: class redefinition failed: attempted to change the class NestHost, NestMembers, Record, or PermittedSubclasses attribute
    at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
    at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(InstrumentationImpl.java:169)
    at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:280)
    at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:217)
    at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.lambda$mockClass$0(TypeCachingBytecodeGenerator.java:47)
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:168)
    at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:399)
    at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:190)
    at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:410)
    at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:40)
    at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMockType(InlineDelegateByteBuddyMockMaker.java:396)
    at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.doCreateMock(InlineDelegateByteBuddyMockMaker.java:355)
    at org.mockito.internal.creation.bytebuddy.InlineDelegateByteBuddyMockMaker.createMock(InlineDelegateByteBuddyMockMaker.java:334)
    at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:56)
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:99)
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:88)
    at org.mockito.Mockito.mock(Mockito.java:1998)
    at org.mockito.Mockito.mock(Mockito.java:1913)
    ... 72 more

For the time being, I've resorted to getting the actual implementation of DefaultListableBeanFactory through its default constructor. Open to suggestions here.

The verify step was failing, because spotbugs was reporting: Low: Overridable method logServerStarted is called from constructor new org.grpcmock.junit5.GrpcMockExtension(GrpcMock). [org.grpcmock.junit5.GrpcMockExtension] At GrpcMockExtension.java:[line 44] MC_OVERRIDABLE_METHOD_CALL_IN_CONSTRUCTOR

Which is weird, because there were no changes in this file. spotbugs version was updated after I got the error above.

Fadelis commented 1 year ago

Hi @rfscouto , thanks for the PR. Though I'm not sure that I'd want to raise the required JDK to 17 and default spring-boot to 3, as it's quite new. Doesn't gRPCMock work in spring-boot 3 without these changes, since the spring boot integration doesn't tie to a specific version of the library and should allow to run it if the newer version is API compatible?

rfscouto commented 1 year ago

Hi! I mostly created the PR to have this work scheduled for the future as it will be eventually required. gRPCmock should work in Spring Boot 3 projects as a dependency based on my current tests and the adjustment to the TestSockUtils on my prior PR, I’ve not adapted those changes on my personal projects since gRPC libs themselves were not Spring Boot 3 compatible - breaking the gRPC communication. You can close the PR or put it to draft, as you think is best.

On 9. Dec 2022, at 11:58, Paulius Paplauskas @.***> wrote:

Hi @rfscouto https://github.com/rfscouto , thanks for the PR. Though I'm not sure that I'd want to raise the required JDK to 17 and default spring-boot to 3, as it's quite new. Doesn't gRPCMock work in spring-boot 3 without these changes, since the spring boot integration doesn't tie to a specific version of the library and should allow to run it if the newer version is API compatible?

— Reply to this email directly, view it on GitHub https://github.com/Fadelis/grpcmock/pull/25#issuecomment-1344155788, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAW4CDTFCWDV76JQVJDFYWTWMMGFXANCNFSM6AAAAAASLMUYUQ. You are receiving this because you were mentioned.