You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Call the controller: curl -i http://localhost:8080/lowLevelClient
Expected Behaviour
The rxHttpClient bean should be injected and the call should not fail.
Actual Behaviour
The rxHttpClient bean could not be injected and the call fails with this stacktrace:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'test.micronaut.http.LowLevelClientController': Unsatisfied dependency expressed through field 'rxHttpClient'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'io.micronaut.http.client.RxHttpClient' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@javax.inject.Inject(), @io.micronaut.http.client.annotation.Client(path=, id=, configuration=class io.micronaut.http.client.HttpClientConfiguration, value=http://www.google.com, errorType=class io.micronaut.http.hateoas.JsonError)}
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:596)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:90)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:374)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1411)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:592)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105)
at org.grails.web.mapping.mvc.UrlMappingsInfoHandlerAdapter.handle(UrlMappingsInfoHandlerAdapter.groovy:73)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1039)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
at org.grails.web.servlet.mvc.GrailsWebRequestFilter.doFilterInternal(GrailsWebRequestFilter.java:77)
at org.grails.web.filters.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:67)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
I had a talk with James Kleeh on slack, who explained that @client is a custom scope and that annotation is not visible to Micronaut because its not being injected into a Micronaut bean. He did not think that the issue can be solved. So I have made this ticket just to document the following workaround and I hope that someone will include it in the Grails documentation.
Workaround to inject low-level HTTP-client from Micronaut in Grails 4:
Add a new Micronaut bean (that contains the RxHttpClient) in /src/main/groovy/...:
Workaround to manually instantiate low-level HTTP-client from Micronaut in Grails 4, but still get configuration from application.yml (but possible missing other features):
It is also possible to manually instantiate the low-level HTTP-client from Micronaut in Grails 4, but then it does not load micronaut.http.client.* configuration from application.yml. This can be added by injecting the DefaultHttpClientConfiguration bean and then adding it to the DefaultHttpClient constructor. However, this workaround is missing all other injections than DefaultHttpClientConfiguration in the rxHttpClient, so other rxHttpClient features might not work with this workaround. Hence the workaround above is preferred.
Example:
Thanks for posting this, been battling this same problem.
Like you suggested, I believe the issue is that Micronaut will not look inside grails artifacts (Controller in this case) to perform its own annotation processing. However it will process annotations on top level classes. So another solution, similar to what you provided, is to create Micronaut Clients inside their own classes/interfaces by extending the core Micronaut interfaces.
Task List
Steps to Reproduce
./gradlew bootRun
curl -i http://localhost:8080/lowLevelClient
Expected Behaviour
The rxHttpClient bean should be injected and the call should not fail.
Actual Behaviour
The rxHttpClient bean could not be injected and the call fails with this stacktrace:
Environment Information
Example Application
https://github.com/andersaaberg/test-micronaut-http/tree/master
Analysis
I had a talk with James Kleeh on slack, who explained that @client is a custom scope and that annotation is not visible to Micronaut because its not being injected into a Micronaut bean. He did not think that the issue can be solved. So I have made this ticket just to document the following workaround and I hope that someone will include it in the Grails documentation.
Workaround to inject low-level HTTP-client from Micronaut in Grails 4:
The workaround is in the example project branch called "workaround": https://github.com/andersaaberg/test-micronaut-http/tree/workaround
Workaround to manually instantiate low-level HTTP-client from Micronaut in Grails 4, but still get configuration from application.yml (but possible missing other features):
It is also possible to manually instantiate the low-level HTTP-client from Micronaut in Grails 4, but then it does not load
micronaut.http.client.*
configuration from application.yml. This can be added by injecting the DefaultHttpClientConfiguration bean and then adding it to the DefaultHttpClient constructor. However, this workaround is missing all other injections than DefaultHttpClientConfiguration in the rxHttpClient, so other rxHttpClient features might not work with this workaround. Hence the workaround above is preferred.Example:
The workaround is in the example project branch called "workaround2": https://github.com/andersaaberg/test-micronaut-http/tree/workaround2
The text was updated successfully, but these errors were encountered: