We are using Axon Framework 3.4.1 with spring boot 2.0.0.RELEASE. For our service we use the AxonConfiguration file to configure various things like the Event Store. The Event Store is then used in another configuration pieceAnnouncingSagaConfiguration which is used to configure a saga tracking processor.
The problem we are facing is a bit weird. When we build the service (we use maven) sometimes there is no problem, but a next build of the same source code can fail to boot, producing the following logs:
So we have an “Unsatisfied dependency” of the eventStore bean, which should be created in the AxonConfiguration file. For a working build we see that the AxonConfiguration file is ‘executed’ before the execution of the pieceAnnouncingSagaConfiguration file, causing a regular start up without any problems.
The maven build seems to be non-deterministic, which is very odd…
there is probably a dependency that is “almost” circular. Do you rely on the AxonConfiguration bean anywhere?
Do you define your own event store, or do you have it autoconfigured for you?
I had to do some digging, as the way Sagas and Event Handlers are configured has changed (simplified, of course) in Axon 4.
I don’t have full context to find out what is exactly going on, but is does seem that your approach to defining tracking processors is rather “unconventional”.
We recommend defining a bean of type SagaConfiguration (beware the naming convention: simpleSagaClassNameConfiguration) that defines how you want to configure your Saga. On your EventProcessingConfiguration (which is available as a bean, so you can use @Autowired to configure it), you can finetune the TrackingProcessor for the Saga, if needed.
The problem seemed to be solved for a long time after we rewrote the configuration like you told us.
However, now we are trying to implement Axon 4 with Spring Boot, we have the circular dependency again. When deploying we get the message:
> org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'soapControllerConfiguration': Unsatisfied dependency expressed through field 'shipmentSoapController'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'shipmentSoapController': Unsatisfied dependency expressed through field 'commandGateway'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'commandGateway' defined in class path resource [org/axonframework/springboot/autoconfig/AxonAutoConfiguration.class]: Unsatisfied dependency expressed through method 'commandGateway' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'axonConfiguration': Unsatisfied dependency expressed through method 'configure' parameter 0; nested exception is org.springframework.beans.factory.BeanCurrentlyInCreationException: Error creating bean with name 'commandBus': Requested bean is currently in creation: Is there an unresolvable circular reference?
We don't have a clue what's going on here. It seems like the commandBus is depending on something else here? I'll give the relevant parts of the configurations:
SoapControllerConfiguration could not be created, it depends on ShipmentSoapController:

ShipmentController depends on CommandGateway:

Finally, AxonConfiguration depends on CommandBus:

We use Axon version 4.0.3 (axon, axon-server-connector, axon-spring and axon-spring-boot-starter artifacts)
Can you please help us out with this one please?
Kind regards,
once you know where you look, this one’s pretty easy to resolve.
The problem is in your AxonConfiguration class. You have a @Bean and an @Autowired. Since @Autowired methods are considered part of the initialization of the configuration bean, Spring will want to invoke those first. But that depends on a CommandBus. So Spring wants to build the CommandBus first. For it to be able to do that, it needs to initialize the AxonConfiguration class, which has a dependency on… the commandbus again. Circular dependency.
Instead of relying on the commandbus in an @Autowired method, just put the other dependencies as part of the CommandBus definition.
@Bean
public CommandBus(KnownSupplierInterceptor … etc) {
// build command bus instance
// do additional configuration
// return command bus instance
}