micronaut-core icon indicating copy to clipboard operation
micronaut-core copied to clipboard

@Refreshable annotation on a @Factory class with @EachBean breaks

Open sjrd218 opened this issue 4 years ago • 2 comments

Adding @Refreshable to the Factory class that uses @EachBean to create beans driven from @EachProperty configuration causes the app to break.

Steps to Reproduce

  1. Create a config class to be used with @EachProperty
  2. Create a Factory bean
  3. Create a factory method in the factory bean that uses @EachBean to return a bean for each of the config classes that were created in step 1.
  4. Make a class that uses the factory bean
  5. bootstrap the app and confirm the beans are created and work
  6. Add the @Refreshable annotation to the Factory class
  7. bootstrap and try to create a bean with the factory and see the Stacktrace

Stacktrace

 Error starting Micronaut server: Error instantiating bean of type [each.bean.test.$MyBeanFactoryDefinition$Intercepted]: No bean of type [each.bean.test.MyBeanFactory] exists for the given qualifier: @Named('one'). Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type [each.bean.test.$MyBeanFactoryDefinition$Intercepted]: No bean of type [each.bean.test.MyBeanFactory] exists for the given qualifier: @Named('one'). Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1721)
        at io.micronaut.context.DefaultBeanContext.lambda$getScopedBeanForDefinition$56(DefaultBeanContext.java:2111)
        at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
        at io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2104)
        at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2086)
        at io.micronaut.context.DefaultBeanContext.getBeanInternal(DefaultBeanContext.java:2058)
        at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1080)
        at each.bean.test.$MyBeanFactory$CreateMyBean0Definition.build(Unknown Source)
        at io.micronaut.context.BeanDefinitionDelegate.build(BeanDefinitionDelegate.java:125)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1693)
        at io.micronaut.context.DefaultBeanContext$6.get(DefaultBeanContext.java:2153)
        at io.micronaut.inject.ParametrizedProvider.get(ParametrizedProvider.java:44)
        at io.micronaut.runtime.context.scope.refresh.RefreshScope.lambda$get$0(RefreshScope.java:91)
        at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1660)
        at io.micronaut.runtime.context.scope.refresh.RefreshScope.get(RefreshScope.java:90)
        at io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2146)
        at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2086)
        at io.micronaut.context.DefaultBeanContext.getProxyTargetBean(DefaultBeanContext.java:949)
        at each.bean.test.$MyBeanFactory$CreateMyBean0Definition$Intercepted.$resolveTarget(Unknown Source)
        at each.bean.test.$MyBeanFactory$CreateMyBean0Definition$Intercepted.interceptedTarget(Unknown Source)
        at each.bean.test.$MyBeanFactory$CreateMyBean0Definition$Intercepted.myMessage(Unknown Source)
        at each.bean.test.MyBean$myMessage.call(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:119)
        at each.bean.test.MyBeanPrinter$_onApplicationEvent_closure2.doCall(MyBeanPrinter.groovy:39)
        at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.codehaus.groovy.reflection.CachedMethod.invoke(CachedMethod.java:101)
        at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:323)
        at org.codehaus.groovy.runtime.metaclass.ClosureMetaClass.invokeMethod(ClosureMetaClass.java:263)
        at groovy.lang.MetaClassImpl.invokeMethod(MetaClassImpl.java:1041)
        at groovy.lang.Closure.call(Closure.java:405)
        at groovy.lang.Closure.call(Closure.java:421)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2330)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2315)
        at org.codehaus.groovy.runtime.DefaultGroovyMethods.each(DefaultGroovyMethods.java:2344)
        at org.codehaus.groovy.runtime.dgm$184.invoke(Unknown Source)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite$PojoMetaMethodSiteNoUnwrapNoCoerce.invoke(PojoMetaMethodSite.java:244)
        at org.codehaus.groovy.runtime.callsite.PojoMetaMethodSite.call(PojoMetaMethodSite.java:53)
        at org.codehaus.groovy.runtime.callsite.CallSiteArray.defaultCall(CallSiteArray.java:47)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:115)
        at org.codehaus.groovy.runtime.callsite.AbstractCallSite.call(AbstractCallSite.java:127)
        at each.bean.test.MyBeanPrinter.onApplicationEvent(MyBeanPrinter.groovy:38)
        at each.bean.test.MyBeanPrinter.onApplicationEvent(MyBeanPrinter.groovy)
        at io.micronaut.context.DefaultBeanContext.publishEvent(DefaultBeanContext.java:1145)
        at io.micronaut.http.server.netty.NettyHttpServer.fireStartupEvents(NettyHttpServer.java:507)
        at io.micronaut.http.server.netty.NettyHttpServer.start(NettyHttpServer.java:378)
        at io.micronaut.http.server.netty.NettyHttpServer.start(NettyHttpServer.java:96)
        at io.micronaut.runtime.Micronaut.lambda$start$2(Micronaut.java:70)
        at java.util.Optional.ifPresent(Optional.java:159)
        at io.micronaut.runtime.Micronaut.start(Micronaut.java:68)
        at io.micronaut.runtime.Micronaut.run(Micronaut.java:294)
        at io.micronaut.runtime.Micronaut.run(Micronaut.java:280)
        at each.bean.test.Application.main(Application.groovy:10)
Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [each.bean.test.MyBeanFactory] exists for the given qualifier: @Named('one'). Make sure the bean is not disabled by bean requirements (enable trace logging for 'io.micronaut.context.condition' to check) and if the bean is enabled then ensure the class is declared a bean and annotation processing is enabled (for Java and Kotlin the 'micronaut-inject-java' dependency should be configured as an annotation processor).
        at io.micronaut.context.BeanDefinitionRegistry.lambda$getProxyTargetBeanDefinition$1(BeanDefinitionRegistry.java:275)
        at java.util.Optional.orElseThrow(Optional.java:290)
        at io.micronaut.context.BeanDefinitionRegistry.getProxyTargetBeanDefinition(BeanDefinitionRegistry.java:275)
        at io.micronaut.context.DefaultBeanContext.findProxyTargetMethod(DefaultBeanContext.java:972)
        at io.micronaut.context.ExecutionHandleLocator.getProxyTargetMethod(ExecutionHandleLocator.java:184)
        at each.bean.test.$MyBeanFactoryDefinition$Intercepted.<init>(Unknown Source)
        at each.bean.test.$$MyBeanFactoryDefinition$InterceptedDefinition.build(Unknown Source)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1693)
        ... 56 common frames omitted

Expected Behaviour

Factory method should return the configured bean. Factory should participate in RefreshEvents triggered in the application.

Actual Behaviour

Stacktrace is thrown saying the bean cannot be found.

Environment Information

  • Operating System: MacOs
  • Micronaut Version: 1.3.4
  • JDK Version: 1.8.0_222

Example Application

https://github.com/sjrd218/MicronautEachBeanDemo

sjrd218 avatar Apr 29 '20 18:04 sjrd218