Axon Configuration problem (without spring)

Hello, I’m trying to implement Axon Configuration (because I can’t use Spring in my case). And whenever I trie to run the application I get this error: Unable to resolve parameter 0 (MyEvent) in handler,
it is the MyEvent (or MyCommand) that are not resolved but still don’t know why.
this is my simple configuration :

Configurer conf = DefaultConfigurer.defaultConfiguration()
                .configureAggregate(AggregateConfigurer.defaultConfiguration(MyAggregate.class));
        Configuration configuration = conf.start();

the problem is whith The @EventSourcingHandler or @CommandHandler methods.
I wander if there are some other configurations that should be configured before the Aggregate itself,
should I configure a repository before the aggregate’s configuration for exemple?

this MyAggregate class :

@Aggregate
public class MyAggregate {
    @AggregateIdentifier
    private UUID id;
    private String eventType;

    public MyAggregate(){}

    @CommandHandler
    public MyAggregate(com.example.myplugin.command.MyCommand cmd){
        AggregateLifecycle.apply(new MyEvent(cmd.getId(), cmd.getEventType()));

    }
    @EventSourcingHandler
    public void on(com.example.myplugin.event.MyEvent event){
        this.id = event.getId();
        this.eventType = event.getEventType();
    }

As a test, I made a basic sample project myself, using start.axoniq.io and switching the main Spring Boot app to be none-Spring Boot.

To be honest, everything works as expected…
Here’s what I have:

The main class:

package com.example.axon;

import org.axonframework.config.Configuration;
import org.axonframework.config.DefaultConfigurer;
import org.axonframework.eventsourcing.eventstore.inmemory.InMemoryEventStorageEngine;

public class AxonApplication {

	public static void main(String[] args) {
		Configuration config = DefaultConfigurer.defaultConfiguration(false)
											   .configureEmbeddedEventStore(c -> new InMemoryEventStorageEngine())
											   .configureAggregate(MyAggregate.class)
											   .start();

		config.commandGateway()
			  .send(new MyCommand("aggregate", "event"))
			  .join();
	}
}

The aggregate class:

package com.example.axon;

import org.axonframework.commandhandling.CommandHandler;
import org.axonframework.eventsourcing.EventSourcingHandler;
import org.axonframework.modelling.command.AggregateIdentifier;
import org.axonframework.modelling.command.AggregateLifecycle;

public class MyAggregate {

    @AggregateIdentifier
    private String id;
    private String eventType;

    public MyAggregate() {
    }

    @CommandHandler
    public MyAggregate(MyCommand cmd) {
        AggregateLifecycle.apply(new MyEvent(cmd.getId(), cmd.getEventType()));
        System.out.println("Reached commanding");
    }

    @EventSourcingHandler
    public void on(MyEvent event) {
        this.id = event.getId();
        this.eventType = event.getEventType();
        System.out.println("Reached sourcing");
    }
}

The command class:

package com.example.axon;

import org.axonframework.modelling.command.TargetAggregateIdentifier;

public class MyCommand {

    @TargetAggregateIdentifier
    private String id;
    private String eventType;

    public MyCommand(String id, String eventType) {
        this.id = id;
        this.eventType = eventType;
    }

    public String getId() {
        return id;
    }

    public String getEventType() {
        return eventType;
    }
}

The event class:

package com.example.axon;

public class MyEvent {

    private String id;
    private String eventType;

    public MyEvent(String id, String eventType) {
        this.id = id;
        this.eventType = eventType;
    }

    public String getId() {
        return id;
    }

    public String getEventType() {
        return eventType;
    }
}

This configuration runs as expected, using JDK17 and the Axon BOM 4.7.0.
Perhaps you can share a sample project containing your implementation that fails, @AhmedAziz_Elj?

I tried the same implementation as yours, and I still get the same problem, in fact I’m developing a Camunda plugin so it has not a main class …
I modified the configuration into :

this.conf =DefaultConfigurer.defaultConfiguration()
                .registerComponent(MyEvent.class,c-> new MyEvent())
                .registerComponent(MyCommand.class, c-> new MyCommand())
                .configureAggregate(MyAggregate.class)
                .start();

and I added a NoArgsConstructor for both MyEvent and MyCommand classes. Now i succesfully connected to Axon server but I’m getting this error from the axonserver terminal when I tried to send a command :

No Handler for command: com.example.camundaplugin.aggregate.MyCommand

Although I am not familiar with Camunda plugin runtime nor the classpath, I am pretty certain they don’t support the Service Loader mechanism.
Axon Framework internally uses classpath scanning to scan your environment for specific service loader files within the Framework’s project. If a Camunda plugin restricts the classpath, I think we’ve got the culprit.

Note this is a massive hunch! If you could try my code in a non-Camunda plugin environment, you’d get more certainty here, as that’s the outlier compared to other Axon Framework applications.

There are several components of Axon Framework it wires by using this methodology.
Most importantly, the components which allow you to use annotated message handlers and those that enhance the capabilities (e.g., to allow consistent routing or support saga lifecycles).
These are the HandlerDefinition and HandlerEnhancerDefinition.

As stated, I am working on a hunch here since I am by no means versed with Camunda plugins, but perhaps the following addition to your configuration does the trick:

DefaultConfigurer.defaultConfiguration()
                 .registerHandlerDefinition((config, clazz) -> new AnnotatedMessageHandlingMemberDefinition())
                 .registerHandlerEnhancerDefinition(config -> new MultiHandlerEnhancerDefinition(
                         new SagaMethodMessageHandlerDefinition(),
                         new MethodCommandHandlerInterceptorDefinition(),
                         new MethodCommandHandlerDefinition(),
                         new MethodCommandHandlerDefinition(),
                         new MethodQueryMessageHandlerDefinition(),
                         new ReplayAwareMessageHandlerWrapper(),
                         new DeadlineMethodMessageHandlerDefinition(),
                         new MethodCreationPolicyDefinition(),
                         new MethodCreationPolicyDefinition(),
                         new MessageHandlerInterceptorDefinition(),
                         new EndSagaMessageHandlerDefinition()
                 ))/*rest of your configuration*/;

In the meantime, I know some Axon Framework users that are also avid Camunda users. I’ve dropped a question with them too to check whether my assumption is correct.

I know one thing or two about camunda plugins … what are you trying to achieve?

I tried to change my CommandHandler method like this :

    @CommandHandler
    @CreationPolicy(AggregateCreationPolicy.ALWAYS)
    public void handle(CamundaActionEventCmd cmd) throws Exception{
        AggregateLifecycle.apply(new CamundaActionEvent(cmd.getId(), cmd.getEventType(), cmd.getInitializer(), cmd.getVariables()));
    }

and got this error :

org.axonframework.axonserver.connector.command.AxonServerCommandBus.dispatch There was a problem dispatching a command GenericCommandMessage{payload={com.example.camundaplugin.command.CamundaActionEventCmd@6b1827bd}, metadata={}, messageIdentifier='c8bc4e77-df1a-4ca3-b59b-7ac3df3c00e9', commandName='com.example.camundaplugin.command.CamundaActionEventCmd'}.
        org.axonframework.commandhandling.distributed.CommandDispatchException: The command [com.example.camundaplugin.command.CamundaActionEventCmd] does not contain a routing key.

I tried to change @TargetAggregateIdentifire Annotation with @RoutingKey in the Command class but stiil had the same error
now after trying your solution with the CommandHandler method like this :

    @CommandHandler
//    @CreationPolicy(AggregateCreationPolicy.ALWAYS)
    public CamundaActionAggregate(CamundaActionEventCmd cmd) throws Exception{
        AggregateLifecycle.apply(new CamundaActionEvent(cmd.getId(), cmd.getEventType(), cmd.getInitializer(), cmd.getVariables()));
    }

I got the same error.
Bytheway I got this error every time I run the plugin :

org.axonframework.serialization.xml.XStreamSerializer$Builder.build An unsecured XStream instance allowing all types is used. It is strongly recommended to set the security context yourself instead!
        org.axonframework.common.AxonConfigurationException: An unsecured XStream instance allowing all types is used. It is strongly recommended to set the security context yourself instead!

I don’t know if this is what causing the problem even though I emplemented this solution :
I create this class :

public class SecureXStreamSerializer {
    private static XStreamSerializer _instance;

    public static XStreamSerializer get() {
        if (_instance == null) {
            _instance = secureXStreamSerializer();
        }
        return _instance;
    }

    private static XStreamSerializer secureXStreamSerializer() {
        XStream xStream = new XStream();
        xStream.setClassLoader(SecureXStreamSerializer.class.getClassLoader());
        xStream.allowTypesByWildcard(new String[]{
                "org.axonframework.**",
                "com.example.camundaplugin.**"
		});
        return XStreamSerializer.builder().xStream(xStream).build();
    }
}

and I tried to add it to my configuration but it didn’t make any change , this is how I aaded it to the config :

DefaultConfigurer.defaultConfiguration()
      .configureSerializer(configuration -> SecureXStreamSerializer.get())
      .configureMessageSerializer(configuration -> SecureXStreamSerializer.get())
      .configureEventSerializer(configuration -> SecureXStreamSerializer.get())

any idea @Steven_van_Beelen !

Hi @Jan_Galinski , I am trying to intercept actions on camunda and send them to Axon server

We are doing the exact same thing with polyflow, aka camunda-bpm-taskpool. Depending on your concrete use case (processInstance/Variable/task/…) we might already have a solution. Check out: GitHub - holunda-io/camunda-bpm-taskpool: Library for pooling user tasks and process related business objects.

What’s not clear to me @AhmedAziz_Elj is whether my previous suggestion of the HandlerDefinition and HandlerEnhancerDefinition changed anything. Would you mind sharing whether it did?

Routing Key issue

Concerning the routing key exception: once more we got something interesting here.
Let me explain where the message originates, perhaps we can deduce based on that why it’s happening.
Axon Framework uses by default an AnnotationRoutingStrategy to find a field/getter on your command used to consistently route your message.

By default, it assumes the presence of the @RoutingKey annotation, which can be configured to use different annotations too (hence why the strategy is called a AnnotationRoutingStrategy).
Furthermore, the @TargetAggregateIdentifier is meta-annotated with @RoutingKey.
Through that, we very easily ensure commands for a specific aggregate are always routed to the same Axon Framework instance.

Now, as this works based on annotations, there’s a layer of annotation scanning involved.
If you’re curious to the implementation, you can find it here.

In all honesty, to figure out why this default behavior, which mind you works for virtually all applications out of the box, doesn’t for yours. I would need to be able to debug the application to better understand what you’re missing here. Or, what misses when using a Camunda Plugin.

So, if the shared sample from @Jan_Galinski doesn’t help directly, perhaps you can make a reproducible public GitHub repository for us to look at?

Serialization Issue

Do you perhaps have more of a stack trace to share concerning this pointer?
I am pretty confident we cover all spots where a serializer is defined through the Configurer, but we can’t be to sure.

Fact it still may pop us, is that this warning (not error) you’re seeing is required to b kept in Axon Framework, since we used to default the XStreamSerializer for users within the Axon Framework 4 lifecycle.
Removing this behavior would incur a breaking changes for users.
However, it is strongly recommended to switch it. Hence the exception.

So, again, if you could share a full stack trace instead of the last line, that would be helpful.

Hello @Steven_van_Beelen, this is the full stack trace of the Serialization Issue :

AVERTISSEMENT [main] org.axonframework.serialization.xml.XStreamSerializer$Builder.build An unsecured XStream instance allowing all types is used. It is strongly recommended to set the security context yourself instead!
        org.axonframework.common.AxonConfigurationException: An unsecured XStream instance allowing all types is used. It is strongly recommended to set the security context yourself instead!
                at org.axonframework.serialization.xml.XStreamSerializer$Builder.build(XStreamSerializer.java:231)
                at org.axonframework.axonserver.connector.event.axon.AxonServerEventStore$Builder.<init>(AxonServerEventStore.java:154)
                at org.axonframework.axonserver.connector.event.axon.AxonServerEventStore.builder(AxonServerEventStore.java:120)
                at org.axonframework.axonserver.connector.ServerConnectorConfigurerModule.buildEventStore(ServerConnectorConfigurerModule.java:77)
                at org.axonframework.config.Component.get(Component.java:85)
                at org.axonframework.config.DefaultConfigurer$ConfigurationImpl.getComponent(DefaultConfigurer.java:958)
                at org.axonframework.config.Configuration.getComponent(Configuration.java:278)
                at org.axonframework.config.Configuration.eventBus(Configuration.java:70)
                at org.axonframework.config.AggregateConfigurer.lambda$new$28(AggregateConfigurer.java:221)
                at org.axonframework.config.Component.get(Component.java:85)
                at org.axonframework.config.AggregateConfigurer.lambda$new$32(AggregateConfigurer.java:260)
                at org.axonframework.config.Component.get(Component.java:85)
                at org.axonframework.config.AggregateConfigurer.lambda$initialize$34(AggregateConfigurer.java:453)
                at org.axonframework.config.LifecycleOperations.lambda$onStart$0(LifecycleOperations.java:62)
                at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
                at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
                at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
                at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
                at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
                at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
                at java.base/java.util.stream.ReferencePipeline.reduce(ReferencePipeline.java:558)
                at org.axonframework.config.DefaultConfigurer.invokeLifecycleHandlers(DefaultConfigurer.java:883)
                at org.axonframework.config.DefaultConfigurer.invokeStartHandlers(DefaultConfigurer.java:829)
                at org.axonframework.config.DefaultConfigurer$ConfigurationImpl.start(DefaultConfigurer.java:980)
                at org.axonframework.config.Configurer.start(Configurer.java:619)

NO_HANDLER_FOR_COMMAND

After trying your previous suggestion of the HandlerDefinition and HandlerEnhancerDefinition I still have this error.

Routing Key Issue

It seems that the routing key problem was caused by a null value of the command id … I set a value for the id but the handler problem remains

So this is a git repository maybe you could take a look at it, thank you.

Thanks for taking the time to share a project.
I was just on the point of asking this again, as none of your issues make particular sense any more :sweat_smile:

Now, with seeing the code, I do think you’ve missed including the Serializer configuration you’ve shared earler. So, be sure to include that again. Furthermore, it seems you are dealing with a Spring Boot application. If that’s intended, you can simplify the Serializer configuration like so:

@Bean
public Serializer serializer() {
    return /*return you safe XStreamSerializer or JacksonSerializer*/
}

Secondly, your pom.xml shows something odd: you first exclude the axon-server-connector and then add it as a separate dependency.
Note that when adding axon-server-connector, Axon Framework assume you will use Axon Server.

If you aim to use Axon Server, please remove the dedicated dependency and drop the exclusion on the axon-spring-boot-starter dependency.
If you do not want to use Axon Server, it is a lot easier to set axon.axonserver.enabled=false in your properties file.

First of all, thank you for taking the time to look at the code. Secondly, as I mentioned before, I am not dealing with a Spring Boot application because I am unable to use the @Autowired annotation to create an instance of the CommandGateway interface. Whenever I try to do this, I always get a NullPointerException, therefore, I thought this would explain why I’m not using the spring-autoconfig…

Regarding the Serializer, I have already found a solution. Thank you.

Regarding the AxonServer Connector exclusion, I have mentioned in the pom.xml file in a comment that I excluded version 4.7.1 because I had a problem connecting to the Axon server that’s why I added the 4.0.2 version instead.

Finally, I found a solution to make Axon detect my command, but I’m not sure if it’s a good one. I subscribed the command bus to a message handler by creating a class that implements the MessageHandler<CommandMessage<?>> interface and overrides its handle() method.

Alright, here come a ton of replies coming in, as I have a lot of comments on what you just shared:

If you’re not using Spring Boot, why does your sample use the axon-spring-boot-starter? That’s not the right dependency to ingest if you aim to not use Spring at all.
Furthermore, the repo you’ve shared does not contain any mention of the Configurer from Axon Framework.

Again, if you are not using Spring Boot, you need to use the Configurer.

You should not use the @Autowired annotated to create a CommandGateway implementation but rather to wire it. If you want to create a bean, you need to use the @Bean annotation on a method returning the CommandGateway, or you use @Component (or an annotation meta-annotated with @Component) on a custom CommandGateway implementation.

Regardless of the above, 9 out of 10 cases you do not have to construct a CommandGateway yourself since Axon Framework exposes one on the Configuration#commandGateway method.

If wiring causes a NullPointerException, I’d honestly dive into why Spring fails to wire a bean that for all our users simply works. Perhaps you can share the stack trace on that instead.

Would you mind sharing the solution? The forum is intended to be a back-and-forth where other users can check if they have the same issue. Hence, if you give your solution, others can benefit from that as well.

I strongly recommend against using 4.0.2 of the axonserver-connector module. The recent version of the connector contains many bug fixes, enhanced flexibility, features, and performance enhancements.
If you have a problem connecting with the recent version, you’d have a task of sharing what that problem is, so that we can help with that.

In my honest opinion, moving back to a 4-year-old release is the wrong direction to take in any such scenario.

You can do everything manually like this, sure, but you shouldn’t have to.
If you are not using Spring, it is your task to register classes containing message handlers (so, the annotated methods).

Directly using the CommandBus is one way, but you can let the Framework inspect your class and register any message handlers in there, by using Configurer#registerMessageHandler instead.

If you would go for Spring regardless (since as far as I currently now, that should simply work, also for Camunda plugins), you only need to make the class a part of Spring’s Application Context.

When I said “I’m not using spring boot” I didn’t mean I’m not using it at all, but because I got the NullPointerException when spring fails to wire the CommandGateway, so I tried to find a solution where I can do the configuration manually.

Regarding the Serializer I used a solution that I found in your forum, I can’t find the link, but it is the same as yours

Concerning the axon-server-connector this the stack trace :

io.axoniq.axonserver.connector.impl.AxonServerManagedChannel - Connecting to AxonServer node [localhost:8124] failed.
io.grpc.StatusRuntimeException: UNKNOWN
        at io.grpc.stub.ClientCalls.toStatusRuntimeException(ClientCalls.java:271)
        at io.grpc.stub.ClientCalls.getUnchecked(ClientCalls.java:252)
        at io.grpc.stub.ClientCalls.blockingUnaryCall(ClientCalls.java:165)
        at io.axoniq.axonserver.grpc.control.PlatformServiceGrpc$PlatformServiceBlockingStub.getPlatformServer(PlatformServiceGrpc.java:250)
        at io.axoniq.axonserver.connector.impl.AxonServerManagedChannel.connectChannel(AxonServerManagedChannel.java:115)
        at io.axoniq.axonserver.connector.impl.AxonServerManagedChannel.createConnection(AxonServerManagedChannel.java:335)
        at io.axoniq.axonserver.connector.impl.AxonServerManagedChannel.ensureConnected(AxonServerManagedChannel.java:300)
        at io.axoniq.axonserver.connector.impl.AxonServerManagedChannel.getState(AxonServerManagedChannel.java:227)
        at io.axoniq.axonserver.connector.impl.ContextConnection.ensureConnected(ContextConnection.java:221)
        at io.axoniq.axonserver.connector.impl.ContextConnection.connect(ContextConnection.java:158)
        at io.axoniq.axonserver.connector.AxonServerConnectionFactory.connect(AxonServerConnectionFactory.java:166)
        at org.axonframework.axonserver.connector.AxonServerConnectionManager.createConnection(AxonServerConnectionManager.java:130)
        at java.base/java.util.concurrent.ConcurrentHashMap.computeIfAbsent(ConcurrentHashMap.java:1708)
        at org.axonframework.axonserver.connector.AxonServerConnectionManager.getConnection(AxonServerConnectionManager.java:126)
        at org.axonframework.axonserver.connector.command.AxonServerCommandBus.subscribe(AxonServerCommandBus.java:213)
        at com.example.axoncamunda.CustomEventType.<init>(CustomEventType.java:35)
        at com.example.axoncamunda.CustomEventType.<clinit>(CustomEventType.java:30)
        at com.example.axoncamunda.AxonCamundaPlugin.preInit(AxonCamundaPlugin.java:18)
        at org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl.invokePreInit(ProcessEngineConfigurationImpl.java:1401)
        at org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl.init(ProcessEngineConfigurationImpl.java:1109)
        at org.camunda.bpm.engine.impl.cfg.ProcessEngineConfigurationImpl.buildProcessEngine(ProcessEngineConfigurationImpl.java:1100)
        at org.camunda.bpm.container.impl.jmx.services.JmxManagedProcessEngineController.start(JmxManagedProcessEngineController.java:38)
        at org.camunda.bpm.container.impl.jmx.MBeanServiceContainer.startService(MBeanServiceContainer.java:77)
        at org.camunda.bpm.container.impl.jmx.MBeanServiceContainer.startService(MBeanServiceContainer.java:63)
        at org.camunda.bpm.container.impl.deployment.StartProcessEngineStep.performOperationStep(StartProcessEngineStep.java:119)
        at org.camunda.bpm.container.impl.spi.DeploymentOperation.execute(DeploymentOperation.java:120)
        at org.camunda.bpm.container.impl.jmx.MBeanServiceContainer.executeDeploymentOperation(MBeanServiceContainer.java:160)
        at org.camunda.bpm.container.impl.spi.DeploymentOperation$DeploymentOperationBuilder.execute(DeploymentOperation.java:216)
        at org.camunda.bpm.container.impl.tomcat.TomcatBpmPlatformBootstrap.deployBpmPlatform(TomcatBpmPlatformBootstrap.java:83)
        at org.camunda.bpm.container.impl.tomcat.TomcatBpmPlatformBootstrap.lifecycleEvent(TomcatBpmPlatformBootstrap.java:61)
        at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:123)
        at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:423)
        at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:366)
        at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:920)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
        at org.apache.catalina.startup.Catalina.start(Catalina.java:772)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:568)
        at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345)
        at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:476)
Caused by: java.nio.channels.UnsupportedAddressTypeException: null
        at java.base/sun.nio.ch.Net.checkAddress(Net.java:146)
        at java.base/sun.nio.ch.Net.checkAddress(Net.java:157)
        at java.base/sun.nio.ch.SocketChannelImpl.checkRemote(SocketChannelImpl.java:816)
        at java.base/sun.nio.ch.SocketChannelImpl.connect(SocketChannelImpl.java:839)
        at io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:91)
        at io.netty.util.internal.SocketUtils$3.run(SocketUtils.java:88)
        at java.base/java.security.AccessController.doPrivileged(AccessController.java:569)
        at io.netty.util.internal.SocketUtils.connect(SocketUtils.java:88)
        at io.netty.channel.socket.nio.NioSocketChannel.doConnect(NioSocketChannel.java:322)
        at io.netty.channel.nio.AbstractNioChannel$AbstractNioUnsafe.connect(AbstractNioChannel.java:248)
        at io.netty.channel.DefaultChannelPipeline$HeadContext.connect(DefaultChannelPipeline.java:1342)
        at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:653)
        at io.netty.channel.AbstractChannelHandlerContext.connect(AbstractChannelHandlerContext.java:632)
        at io.netty.channel.ChannelDuplexHandler.connect(ChannelDuplexHandler.java:54)
        at io.grpc.netty.WriteBufferingAndExceptionHandler.connect(WriteBufferingAndExceptionHandler.java:157)
        at io.netty.channel.AbstractChannelHandlerContext.invokeConnect(AbstractChannelHandlerContext.java:655)
        at io.netty.channel.AbstractChannelHandlerContext.access$1000(AbstractChannelHandlerContext.java:61)
        at io.netty.channel.AbstractChannelHandlerContext$9.run(AbstractChannelHandlerContext.java:637)
        at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java:174)
        at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:167)
        at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
        at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
        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)

Itried many different versions of grpc and netty bytheway and I got the same stack trace everytime.