micronaut-projects / micronaut-core

Micronaut Application Framework
http://micronaut.io
Apache License 2.0
6.08k stars 1.07k forks source link

Rare occurrence of "Recursive update" #5469

Open highmtworks opened 3 years ago

highmtworks commented 3 years ago

Rare occurrence of "Recursive update"

After #5384, it can fail to instantiate beans of RequestScope depending on other RequestScope beans. It does not occur deteministically, but if it occurs, it continues to occur.

I am very sorry not to attach code to reproduce, because this occurred in production and as the product is not open, I cannot share it, and I have little time to write new reproduction code.

Instead, I describe what I investigated. If I get time, I may add reproduction code.

Task List

Steps to Reproduce

  1. Create a web project that does the following:
    • it accepts a HTTP request
    • the handler for the HTTP request instantiates a bean of @RequestScope, instantiated by @Factory
    • the factory method of the @Factory uses another bean of @RequestScope to instatiate the bean above
  2. Run the application.
  3. Send HTTP Request to the application.
  4. If "Recursive update" does not occur, repeat 2 and 3.

Expected Behaviour

Instantiation of beans of RequestScope depending on other RequestScope beans succeeds.

Actual Behaviour

BeanInstantiationException with the inner exception 'java.lang.IllegalStateException: Recursive update' is thrown.

Stack trace from the inner exception (some code masked):

0 = {StackTraceElement@11033} "java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1763)"
1 = {StackTraceElement@11034} "io.micronaut.runtime.http.scope.RequestCustomScope.get(RequestCustomScope.java:84)"
2 = {StackTraceElement@11035} "io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2489)"
3 = {StackTraceElement@11036} "io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2429)"
4 = {StackTraceElement@11037} "io.micronaut.context.DefaultBeanContext.getProxyTargetBean(DefaultBeanContext.java:1089)"
5 = {StackTraceElement@11038} "(our-product-package).$XxxInfoDtoFactory$XxxInfoDto0Definition$Intercepted.$resolveTarget(Unknown Source)"
6 = {StackTraceElement@11039} "(our-product-package).$XxxInfoDtoFactory$XxxInfoDto0Definition$Intercepted.interceptedTarget(Unknown Source)"
7 = {StackTraceElement@11040} "(our-product-package).$XxxInfoDtoFactory$XxxInfoDto0Definition$Intercepted.getXxx(Unknown Source)"
8 = {StackTraceElement@11041} "(our-product-package).DbContextConfiguration.dbContext(DbContextConfiguration.java:39)"
9 = {StackTraceElement@11042} "(our-product-package).$DbContextConfiguration$DbContext0Definition.build(Unknown Source)"
10 = {StackTraceElement@11043} "io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1979)"
11 = {StackTraceElement@11044} "io.micronaut.context.DefaultBeanContext$7.get(DefaultBeanContext.java:2496)"
12 = {StackTraceElement@11045} "io.micronaut.inject.ParametrizedProvider.get(ParametrizedProvider.java:44)"
13 = {StackTraceElement@11046} "io.micronaut.runtime.http.scope.RequestCustomScope.lambda$get$0(RequestCustomScope.java:85)"
14 = {StackTraceElement@11047} "java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)"
15 = {StackTraceElement@11048} "io.micronaut.runtime.http.scope.RequestCustomScope.get(RequestCustomScope.java:84)"
16 = {StackTraceElement@11049} "io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2489)"
17 = {StackTraceElement@11050} "io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2429)"
18 = {StackTraceElement@11051} "io.micronaut.context.DefaultBeanContext.getProxyTargetBean(DefaultBeanContext.java:1089)"
19 = {StackTraceElement@11052} "(our-product-package).$DbContextConfiguration$DbContext0Definition$Intercepted.$resolveTarget(Unknown Source)"
20 = {StackTraceElement@11053} "(our-product-package).$DbContextConfiguration$DbContext0Definition$Intercepted.interceptedTarget(Unknown Source)"
21 = {StackTraceElement@11054} "(our-product-package).$DbContextConfiguration$DbContext0Definition$Intercepted.getDslContext(Unknown Source)"
22 = {StackTraceElement@11055} "(our-product-package).XxxDataAccessImpl.lambda$getXxxAsync$0(XxxDataAccessImpl.java:46)"
23 = {StackTraceElement@11056} "io.reactivex.internal.operators.single.SingleFromCallable.subscribeActual(SingleFromCallable.java:44)"
24 = {StackTraceElement@11057} "io.reactivex.Single.subscribe(Single.java:3603)"
25 = {StackTraceElement@11058} "io.micronaut.reactive.rxjava2.RxInstrumentedSingle.subscribeActual(RxInstrumentedSingle.java:52)"
26 = {StackTraceElement@11059} "io.reactivex.Single.subscribe(Single.java:3603)"
27 = {StackTraceElement@11060} "io.reactivex.internal.operators.single.SingleSubscribeOn$SubscribeOnObserver.run(SingleSubscribeOn.java:89)"
28 = {StackTraceElement@11061} "io.reactivex.Scheduler$DisposeTask.run(Scheduler.java:578)"
29 = {StackTraceElement@11062} "io.reactivex.internal.schedulers.ScheduledRunnable.run(ScheduledRunnable.java:66)"
30 = {StackTraceElement@11063} "io.reactivex.internal.schedulers.ScheduledRunnable.call(ScheduledRunnable.java:57)"
31 = {StackTraceElement@11064} "java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)"
32 = {StackTraceElement@11065} "java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304)"
33 = {StackTraceElement@11066} "java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1130)"
34 = {StackTraceElement@11067} "java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:630)"
35 = {StackTraceElement@11068} "java.base/java.lang.Thread.run(Thread.java:831)"

What I investigated:

Environment Information

Example Application

highmtworks commented 3 years ago

As the nested calls of computeIfAbsent are invoked on the same thread (as the stack trace shows), I suspect that adding synchronized ( without removing computedIfAbsent ) will have no effect for this issue.

I am sorry to be late, but I created a possible reproducer. Could you try this one please ?

  1. mn create-app test5469

  2. add the following Test5469Controller.java file in test5469/src/main/java/test5469

package test5469;

import javax.inject.Inject;

import io.micronaut.context.ApplicationContext;
import io.micronaut.context.annotation.Factory;
import io.micronaut.http.MediaType;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.runtime.http.scope.RequestScope;

@Controller("/test5469")
public class Test5469Controller {
    @Inject
    private ApplicationContext applicationContext;

    @Get(produces = MediaType.TEXT_PLAIN)
    public String index() {
        var c = applicationContext.getBean(Component1.class);
        c.touch();
        return "OK";
    }
}

@Factory class Component1Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component1 getComponent() { var c = applicationContext.getBean(Component2.class); c.touch(); return new Component1(); } }
@Factory class Component2Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component2 getComponent() { var c = applicationContext.getBean(Component3.class); c.touch(); return new Component2(); } }
@Factory class Component3Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component3 getComponent() { var c = applicationContext.getBean(Component4.class); c.touch(); return new Component3(); } }
@Factory class Component4Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component4 getComponent() { var c = applicationContext.getBean(Component5.class); c.touch(); return new Component4(); } }
@Factory class Component5Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component5 getComponent() { var c = applicationContext.getBean(Component6.class); c.touch(); return new Component5(); } }
@Factory class Component6Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component6 getComponent() { var c = applicationContext.getBean(Component7.class); c.touch(); return new Component6(); } }
@Factory class Component7Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component7 getComponent() { var c = applicationContext.getBean(Component8.class); c.touch(); return new Component7(); } }
@Factory class Component8Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component8 getComponent() { var c = applicationContext.getBean(Component9.class); c.touch(); return new Component8(); } }
@Factory class Component9Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component9 getComponent() { var c = applicationContext.getBean(Component10.class); c.touch(); return new Component9(); } }
@Factory class Component10Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component10 getComponent() { var c = applicationContext.getBean(Component11.class); c.touch(); return new Component10(); } }
@Factory class Component11Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component11 getComponent() { var c = applicationContext.getBean(Component12.class); c.touch(); return new Component11(); } }
@Factory class Component12Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component12 getComponent() { var c = applicationContext.getBean(Component13.class); c.touch(); return new Component12(); } }
@Factory class Component13Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component13 getComponent() { var c = applicationContext.getBean(Component14.class); c.touch(); return new Component13(); } }
@Factory class Component14Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component14 getComponent() { var c = applicationContext.getBean(Component15.class); c.touch(); return new Component14(); } }
@Factory class Component15Factory { @Inject private ApplicationContext applicationContext; @RequestScope public Component15 getComponent() { var c = applicationContext.getBean(Component16.class); c.touch(); return new Component15(); } }
@Factory class Component16Factory { @RequestScope public Component16 getComponent() { return new Component16(); } }

class Component1 { public void touch() { } }
class Component2 { public void touch() { } }
class Component3 { public void touch() { } }
class Component4 { public void touch() { } }
class Component5 { public void touch() { } }
class Component6 { public void touch() { } }
class Component7 { public void touch() { } }
class Component8 { public void touch() { } }
class Component9 { public void touch() { } }
class Component10 { public void touch() { } }
class Component11 { public void touch() { } }
class Component12 { public void touch() { } }
class Component13 { public void touch() { } }
class Component14 { public void touch() { } }
class Component15 { public void touch() { } }
class Component16 { public void touch() { } }
  1. gradlew run

  2. then access curl http://localhost:8080/test5469

It will return

{"message":"Internal Server Error: Error instantiating bean of type [test5469.Component1]: Recursive update","_links":{"self":{"href":"/test5469","templated":false}}}

on micronaut 2.5.9.

highmtworks commented 3 years ago

I tried running the above reproducer for #5810. Replacing RequestCustomScope in the reproducer with #5810 https://github.com/micronaut-projects/micronaut-core/blob/5a4c0c30381103e6bf780f3c3930893bfc8fe01a/runtime/src/main/java/io/micronaut/runtime/http/scope/RequestCustomScope.java still causes "Recursive update" in my environment.

Caused by: java.lang.IllegalStateException: Recursive update
        at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1763)
        at io.micronaut.runtime.http.scope.RequestCustomScope.get(RequestCustomScope.java:85)
        at io.micronaut.context.DefaultBeanContext.getScopedBeanForDefinition(DefaultBeanContext.java:2487)
        at io.micronaut.context.DefaultBeanContext.getBeanForDefinition(DefaultBeanContext.java:2427)
        at io.micronaut.context.DefaultBeanContext.getProxyTargetBean(DefaultBeanContext.java:1089)
        at test5469.$Component3Factory$GetComponent0Definition$Intercepted.$resolveTarget(Unknown Source)
        at test5469.$Component3Factory$GetComponent0Definition$Intercepted.interceptedTarget(Unknown Source)
        at test5469.$Component3Factory$GetComponent0Definition$Intercepted.touch(Unknown Source)
        at test5469.Component2Factory.getComponent(Test5469Controller.java:26)
        at test5469.$Component2Factory$GetComponent0Definition.build(Unknown Source)
        at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:1979)
        ... 102 common frames omitted
mancze commented 3 years ago

I found this issue when searching for "recursive update" problem. After reading description it seems that it might match my problem. I have created a github project on which this should be reproducible (non-deterministically). It is this one: https://github.com/mancze/micronaut-recursive-update-issue . I'm not sure if it has common cause as @Factory is not being used in my project.

I'm not sure if it will be useful since @highmtworks already provided reproducer, but since I already prepared it I thought it might be worth mentioning.

glazzari commented 3 years ago

@graemerocher It looks similar to https://github.com/micronaut-projects/micronaut-core/pull/3632.

I've been facing the same issue in 2.5.5. I have another service running 2.0.3 with no issues. I have a declarative client (which is singleton by default, right?) that calls a service annotated with @RequestScope.

I cannot reproduce the issue if I change the service to @Singleton. Can I annotate a declarative client @Client with @RequestScope?

johndevs commented 9 months ago

I am getting the same with the GraphQL library.

It is not reproducable but when it occurs I have to restart the service multiple times until it then just starts working.

Here is my code:


@Slf4j
@Factory
public class GraphQLFactory {

    @Bean
    public GraphQL graphQL(GraphQLSchemaBuilder schemaBuilder,
                           List<Instrumentation> instrumentations) {
        return GraphQL.newGraphQL(schemaBuilder.getSchema()).instrumentation(new ChainedInstrumentation(instrumentations)).build();
    }

    @Bean
    @Replaces(GraphQLInvocation.class)
    @Refreshable
    public GraphQLInvocation graphQLInvocation(GraphQL graphQL,
                                               GraphQLExecutionInputCustomizer graphQLExecutionInputCustomizer,
                                               @Nullable BeanProvider<DataLoaderRegistry> dataLoaderRegistry) {
        return new DefaultGraphQLInvocation(graphQL, graphQLExecutionInputCustomizer, dataLoaderRegistry);
    }
}

And the stacktrace when it occurs:


11:00:39.437 ERROR- Unexpected error occurred: Error instantiating bean of type  [io.micronaut.configuration.graphql.GraphQLInvocation]

Message: Recursive update
Path Taken: new GraphQLController(GraphQLInvocation graphQLInvocation,GraphQLExecutionResultHandler graphQLExecutionResultHandler,GraphQLJsonSerializer graphQLJsonSerializer) --> new GraphQLController([GraphQLInvocation graphQLInvocation],GraphQLExecutionResultHandler graphQLExecutionResultHandler,GraphQLJsonSerializer graphQLJsonSerializer) --> GraphQLFactory.graphQLInvocation([GraphQL graphQL],GraphQLExecutionInputCustomizer graphQLExecutionInputCustomizer,BeanProvider dataLoaderRegistry)
io.micronaut.context.exceptions.BeanInstantiationException: Error instantiating bean of type  [io.micronaut.configuration.graphql.GraphQLInvocation]

Message: Recursive update
Path Taken: new GraphQLController(GraphQLInvocation graphQLInvocation,GraphQLExecutionResultHandler graphQLExecutionResultHandler,GraphQLJsonSerializer graphQLJsonSerializer) --> new GraphQLController([GraphQLInvocation graphQLInvocation],GraphQLExecutionResultHandler graphQLExecutionResultHandler,GraphQLJsonSerializer graphQLJsonSerializer) --> GraphQLFactory.graphQLInvocation([GraphQL graphQL],GraphQLExecutionInputCustomizer graphQLExecutionInputCustomizer,BeanProvider dataLoaderRegistry)
    at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2324)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2279)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2291)
    at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3054)
    at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2944)
    at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2730)
    at io.micronaut.context.DefaultBeanContext.getBean(DefaultBeanContext.java:1729)
    at io.micronaut.context.AbstractBeanResolutionContext.getBean(AbstractBeanResolutionContext.java:89)
    at io.micronaut.context.AbstractInitializableBeanDefinition.resolveBean(AbstractInitializableBeanDefinition.java:2165)
    at io.micronaut.context.AbstractInitializableBeanDefinition.getBeanForConstructorArgument(AbstractInitializableBeanDefinition.java:1328)
    at com.devsoap.valo.core.graphql.$GraphQLFactory$GraphQLInvocation1$Definition.instantiate(Unknown Source)
    at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2309)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2279)
    at io.micronaut.context.DefaultBeanContext.doCreateBean(DefaultBeanContext.java:2291)
    at io.micronaut.context.DefaultBeanContext.createRegistration(DefaultBeanContext.java:3054)
    at io.micronaut.context.DefaultBeanContext$5.create(DefaultBeanContext.java:3032)
    at io.micronaut.runtime.context.scope.refresh.RefreshScope.lambda$getOrCreate$0(RefreshScope.java:88)
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
    at io.micronaut.runtime.context.scope.refresh.RefreshScope.getOrCreate(RefreshScope.java:87)
    at io.micronaut.context.DefaultBeanContext.getOrCreateScopedRegistration(DefaultBeanContext.java:3015)
    at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2941)
    at io.micronaut.context.DefaultBeanContext.getProxyTargetBean(DefaultBeanContext.java:1489)
    at com.devsoap.valo.core.graphql.$GraphQLFactory$GraphQLInvocation1$Definition$Intercepted.interceptedTarget(Unknown Source)
    at com.devsoap.valo.core.graphql.$GraphQLFactory$GraphQLInvocation1$Definition$Intercepted.invoke(Unknown Source)
    at io.micronaut.configuration.graphql.GraphQLController.executeRequest(GraphQLController.java:200)
    at io.micronaut.configuration.graphql.GraphQLController.post(GraphQLController.java:154)
    at io.micronaut.configuration.graphql.$GraphQLController$Definition$Exec.dispatch(Unknown Source)
    at io.micronaut.context.AbstractExecutableMethodsDefinition$DispatchedExecutableMethod.invokeUnsafe(AbstractExecutableMethodsDefinition.java:447)
    at io.micronaut.context.DefaultBeanContext$BeanContextUnsafeExecutionHandle.invokeUnsafe(DefaultBeanContext.java:4214)
    at io.micronaut.web.router.AbstractRouteMatch.execute(AbstractRouteMatch.java:263)
    at io.micronaut.http.context.ServerRequestContext.with(ServerRequestContext.java:74)
    at io.micronaut.http.server.RouteExecutor.executeRouteAndConvertBody(RouteExecutor.java:480)
    at io.micronaut.http.server.RouteExecutor.callRoute(RouteExecutor.java:468)
    at io.micronaut.http.server.RequestLifecycle.lambda$normalFlow$2(RequestLifecycle.java:146)
    at io.micronaut.core.execution.ImperativeExecutionFlowImpl.flatMap(ImperativeExecutionFlowImpl.java:72)
    at io.micronaut.http.server.RequestLifecycle.lambda$normalFlow$4(RequestLifecycle.java:146)
    at io.micronaut.http.server.RequestLifecycle.lambda$runWithFilters$14(RequestLifecycle.java:264)
    at io.micronaut.http.filter.TerminalFilter.processRequestFilter(TerminalFilter.java:58)
    at io.micronaut.http.filter.FilterRunner.filterRequest0(FilterRunner.java:153)
    at io.micronaut.http.filter.FilterRunner.lambda$filterRequest0$2(FilterRunner.java:153)
    at io.micronaut.core.execution.ImperativeExecutionFlowImpl.flatMap(ImperativeExecutionFlowImpl.java:72)
    at io.micronaut.http.filter.MethodFilter.processRequestFilter(MethodFilter.java:263)
    at io.micronaut.http.filter.FilterRunner.filterRequest0(FilterRunner.java:153)
    at io.micronaut.http.filter.FilterRunner.filterRequest0(FilterRunner.java:153)
    at io.micronaut.http.filter.FilterRunner.lambda$filterRequest0$2(FilterRunner.java:153)
    at io.micronaut.core.execution.ImperativeExecutionFlowImpl.flatMap(ImperativeExecutionFlowImpl.java:72)
    at io.micronaut.http.filter.MethodFilter.processRequestFilter(MethodFilter.java:263)
    at io.micronaut.http.filter.FilterRunner.filterRequest0(FilterRunner.java:153)
    at io.micronaut.http.filter.FilterRunner.filterRequest(FilterRunner.java:137)
    at io.micronaut.http.filter.FilterRunner.run(FilterRunner.java:132)
    at io.micronaut.http.server.RequestLifecycle.runWithFilters(RequestLifecycle.java:281)
    at io.micronaut.http.server.RequestLifecycle.normalFlow(RequestLifecycle.java:143)
    at io.micronaut.http.server.netty.NettyRequestLifecycle.handleNormal(NettyRequestLifecycle.java:85)
    at io.micronaut.http.server.netty.RoutingInBoundHandler.accept(RoutingInBoundHandler.java:220)
    at io.micronaut.http.server.netty.websocket.NettyServerWebSocketUpgradeHandler.accept(NettyServerWebSocketUpgradeHandler.java:156)
    at io.micronaut.http.server.netty.handler.PipeliningServerHandler$OptimisticBufferingInboundHandler.read(PipeliningServerHandler.java:422)
    at io.micronaut.http.server.netty.handler.PipeliningServerHandler.channelRead(PipeliningServerHandler.java:206)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
    at io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandler.channelRead(WebSocketServerExtensionHandler.java:88)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.handler.codec.MessageToMessageDecoder.channelRead(MessageToMessageDecoder.java:103)
    at io.netty.handler.codec.MessageToMessageCodec.channelRead(MessageToMessageCodec.java:111)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.channel.ChannelInboundHandlerAdapter.channelRead(ChannelInboundHandlerAdapter.java:93)
    at io.netty.handler.codec.http.HttpServerKeepAliveHandler.channelRead(HttpServerKeepAliveHandler.java:64)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:436)
    at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346)
    at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318)
    at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:251)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.handler.timeout.IdleStateHandler.channelRead(IdleStateHandler.java:286)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:442)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412)
    at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1410)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440)
    at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420)
    at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:919)
    at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166)
    at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724)
    at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562)
    at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
    at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalStateException: Recursive update
    at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1763)
    at io.micronaut.runtime.context.scope.refresh.RefreshScope.getOrCreate(RefreshScope.java:87)
    at io.micronaut.context.DefaultBeanContext.getOrCreateScopedRegistration(DefaultBeanContext.java:3015)
    at io.micronaut.context.DefaultBeanContext.resolveBeanRegistration(DefaultBeanContext.java:2941)
    at io.micronaut.context.DefaultBeanContext.getProxyTargetBean(DefaultBeanContext.java:1489)
    at com.devsoap.valo.core.graphql.$GraphQLSchemaBuilder$Definition$Intercepted.interceptedTarget(Unknown Source)
    at com.devsoap.valo.core.graphql.$GraphQLSchemaBuilder$Definition$Intercepted.getSchema(Unknown Source)
    at com.devsoap.valo.core.graphql.GraphQLFactory.graphQL(GraphQLFactory.java:35)
    at com.devsoap.valo.core.graphql.$GraphQLFactory$GraphQL0$Definition.instantiate(Unknown Source)
    at io.micronaut.context.DefaultBeanContext.resolveByBeanFactory(DefaultBeanContext.java:2309)
    ... 102 common frames omitted
``