micronaut-gcp
micronaut-gcp copied to clipboard
Tests fail for GCP Http Function - Message: Binder registry is not mutable
I wrote a test for the example GCP http function and it failed by throwing exception:
io.micronaut.context.exceptions.BeanInstantiationException at DefaultBeanContext.java:1915 Caused by: java.lang.UnsupportedOperationException at ArgumentBinderRegistry.java:38
If I remove the @MicronautTest
annotation, the test passes.
Task List
- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)
Steps to Reproduce
- Set up this example:
https://github.com/micronaut-projects/micronaut-gcp/tree/master/examples/hello-world-cloud-function
- Write a micronaut test with @MicronautTest annotation.
- Run the test.
- It fails
Expected Behaviour
Test should run
Actual Behaviour
Test fails to run with an an exception
Error instantiating bean of type [io.micronaut.http.server.netty.NettyRequestArgumentSatisfier] Message: Binder registry is not mutable Path Taken: new NettyHttpServer(NettyHttpServerConfiguration serverConfiguration,ApplicationContext applicationContext,Router router,[RequestArgumentSatisfier requestArgumentSatisfier],MediaTypeCodecRegistry mediaTypeCodecRegistry,NettyCustomizableResponseTypeHandlerRegistry customizableResponseTypeHandlerRegistry,StaticResourceResolver resourceResolver,Provider ioExecutor,ThreadFactory threadFactory,ExecutorSelector executorSelector,ServerSslBuilder serverSslBuilder,List outboundHandlers,EventLoopGroupFactory eventLoopGroupFactory,EventLoopGroupRegistry eventLoopGroupRegistry,HttpCompressionStrategy httpCompressionStrategy,HttpContentProcessorResolver httpContentProcessorResolver,ChannelOptionFactory channelOptionFactory) --> new NettyRequestArgumentSatisfier([RequestBinderRegistry requestBinderRegistry]) io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [io.micronaut.http.server.netty.NettyRequestArgumentSatisfier] Message: Binder registry is not mutable Path Taken: new NettyHttpServer(NettyHttpServerConfiguration serverConfiguration,ApplicationContext applicationContext,Router router,[RequestArgumentSatisfier requestArgumentSatisfier],MediaTypeCodecRegistry mediaTypeCodecRegistry,NettyCustomizableResponseTypeHandlerRegistry customizableResponseTypeHandlerRegistry,StaticResourceResolver resourceResolver,Provider ioExecutor,ThreadFactory threadFactory,ExecutorSelector executorSelector,ServerSslBuilder serverSslBuilder,List outboundHandlers,EventLoopGroupFactory eventLoopGroupFactory,EventLoopGroupRegistry eventLoopGroupRegistry,HttpCompressionStrategy httpCompressionStrategy,HttpContentProcessorResolver httpContentProcessorResolver,ChannelOptionFactory channelOptionFactory) --> new NettyRequestArgumentSatisfier([RequestBinderRegistry requestBinderRegistry]) at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1915) at io.micronaut.context.DefaultBeanContext.createAndRegisterSingletonInternal(DefaultBeanContext.java:2630) at io.micronaut.context.DefaultBeanContext.createAndRegisterSingleton(DefaultBeanContext.java:2616) at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2299) at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2273) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1233) at io.micronaut.context.AbstractBeanDefinition.getBeanForConstructorArgument(AbstractBeanDefinition.java:1035) at io.micronaut.http.server.netty.$NettyHttpServerDefinition.build(Unknown Source) at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1888) at io.micronaut.context.DefaultBeanContext.createAndRegisterSingletonInternal(DefaultBeanContext.java:2630) at io.micronaut.context.DefaultBeanContext.createAndRegisterSingleton(DefaultBeanContext.java:2616) at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2299) at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2273) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:727) at io.micronaut.test.extensions.AbstractMicronautExtension.beforeClass(AbstractMicronautExtension.java:206) at io.micronaut.test.extensions.junit5.MicronautJunit5Extension.beforeAll(MicronautJunit5Extension.java:51) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.lambda$invokeBeforeAllCallbacks$7(ClassBasedTestDescriptor.java:359) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor$$Lambda$273/00000000E6A4B420.execute(Unknown Source) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.invokeBeforeAllCallbacks(ClassBasedTestDescriptor.java:359) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:189) at org.junit.jupiter.engine.descriptor.ClassBasedTestDescriptor.before(ClassBasedTestDescriptor.java:78) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:132) at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$224/00000000E99CB220.execute(Unknown Source) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$223/00000000E99CAC20.invoke(Unknown Source) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$222/00000000E99CA620.execute(Unknown Source) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService$$Lambda$228/00000000E67A4B30.accept(Unknown Source) at java.base/java.util.ArrayList.forEach(ArrayList.java:1540) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.invokeAll(SameThreadHierarchicalTestExecutorService.java:38) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$5(NodeTestTask.java:139) at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$224/00000000E99CB220.execute(Unknown Source) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$7(NodeTestTask.java:125) at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$223/00000000E99CAC20.invoke(Unknown Source) at org.junit.platform.engine.support.hierarchical.Node.around(Node.java:135) at org.junit.platform.engine.support.hierarchical.NodeTestTask.lambda$executeRecursively$8(NodeTestTask.java:123) at org.junit.platform.engine.support.hierarchical.NodeTestTask$$Lambda$222/00000000E99CA620.execute(Unknown Source) at org.junit.platform.engine.support.hierarchical.ThrowableCollector.execute(ThrowableCollector.java:73) at org.junit.platform.engine.support.hierarchical.NodeTestTask.executeRecursively(NodeTestTask.java:122) at org.junit.platform.engine.support.hierarchical.NodeTestTask.execute(NodeTestTask.java:80) at org.junit.platform.engine.support.hierarchical.SameThreadHierarchicalTestExecutorService.submit(SameThreadHierarchicalTestExecutorService.java:32) at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:57) at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:51) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:248) at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$5(DefaultLauncher.java:211) at org.junit.platform.launcher.core.DefaultLauncher$$Lambda$190/00000000E6A30A20.accept(Unknown Source) at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:226) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:199) at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:132) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.processAllTestClasses(JUnitPlatformTestClassProcessor.java:99) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor$CollectAllTestClassesExecutor.access$000(JUnitPlatformTestClassProcessor.java:79) at org.gradle.api.internal.tasks.testing.junitplatform.JUnitPlatformTestClassProcessor.stop(JUnitPlatformTestClassProcessor.java:75) at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33) at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94) at com.sun.proxy.$Proxy4.stop(Unknown Source) at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:133) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:566) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36) at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:182) at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:164) at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:414) at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64) at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:48) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:56) at java.base/java.lang.Thread.run(Thread.java:834) Caused by: java.lang.UnsupportedOperationException: Binder registry is not mutable at io.micronaut.core.bind.ArgumentBinderRegistry.addRequestArgumentBinder(ArgumentBinderRegistry.java:38) at io.micronaut.http.server.netty.binders.NettyBinderRegistrar.onCreated(NettyBinderRegistrar.java:71) at io.micronaut.http.server.netty.binders.NettyBinderRegistrar.onCreated(NettyBinderRegistrar.java:40) at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1945) at io.micronaut.context.DefaultBeanContext.createAndRegisterSingletonInternal(DefaultBeanContext.java:2630) at io.micronaut.context.DefaultBeanContext.createAndRegisterSingleton(DefaultBeanContext.java:2616) at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2299) at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2273) at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1233) at io.micronaut.context.AbstractBeanDefinition.getBeanForConstructorArgument(AbstractBeanDefinition.java:1035) at io.micronaut.http.server.netty.$NettyRequestArgumentSatisfierDefinition.build(Unknown Source) at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1888) ... 84 more EventProcessorControllerTest > initializationError FAILED io.micronaut.context.exceptions.BeanInstantiationException at DefaultBeanContext.java:1915 Caused by: java.lang.UnsupportedOperationException at ArgumentBinderRegistry.java:38
Environment Information
- Operating System: Mac OS Catalina 10.15.6
- Micronaut Version: 2.0.0
- JDK Version: 11
- ** Gradle version:** 6.5
Example Application
- https://github.com/micronaut-projects/micronaut-gcp/tree/master/examples/hello-world-cloud-function
- Gradle file is exactly the same.
Hey, I was able to solve this.
In build.gradle if I remove
test.classpath += configurations.developmentOnly
It works.
I did not dig in much however.
Workaround only works when we are not using @Inject or any bean instantiation while writing the tests.
On Digging further, I found out that NettyBinderResgistrar
's onCreated
method is trying to add ArgumentBinders
to the registry. However, the registry is instantiated as GoogleBinderRegistry
, which does not have addRequestArgumentBinder
operation implemented and hence, throws an exception.
@Override
public RequestBinderRegistry onCreated(BeanCreatedEvent<RequestBinderRegistry> event) {
RequestBinderRegistry registry = event.getBean(); //It is of type GoogleBinderRegistry.class
registry.addRequestArgumentBinder(
new BasicAuthArgumentBinder()
);
....
}
Leaving this here for posterity in case this helps someone else in the future. One way to get "Binder registry is not mutable" exception is to have a mix of runtimes in your Micronaut service. In other words if you specified as your runtime something like tomcat or undertow i.e.
micronaut { runtime("undertow")
but somehow you declared dependency on another service which has a runtime of 'netty'. Micronaut will try to start netty with scaffolding from Servlet engine and you will get weirdness like this. I.e. take a look at your classpath and how your microservice was built.