AxonFramework: AxonDbSchedulerAutoConfiguration can not be used multiple times in hierarchical Spring context due to static fields
Hi,
We are using multiple instances of the deadline manager implementation for DbScheduler in a hierarchical Spring context. This leads to various errors, as the configuration relies on static fields and thus changes the state of beans in other contexts.
Basic information
- Axon Framework version: 4.8.2
- JDK version: 17
Steps to reproduce
Use the AxonDbSchedulerAutoConfiguration in a hierarchical Spring context multiple times. If one of the contexts use an aggregate with a deadline which is not known in the other context, deadline messages are executed without effect.
The same holds true for the event scheduler configuration, but we are only considering the deadline manager implementation here.
The issue lies in AxonDbSchedulerAutoConfiguration and the DbSchedulerDeadlineManager. The bean definition for deadlineDetailsTask uses the static method binaryTask of the DbSchedulerDeadlineManager. This method itself relies on the static field deadlineManagerReference. This field is set during construction of the DbSchedulerDeadlineManager. This means that all tasks, created with those static methods, use whatever deadline manager is created last.
So, technically we wouldn’t even need a hierarchical context to get an invalid configuration. We would just have to create another instance of DbSchedulerDeadlineManager after the Spring context has been started and all already created tasks would now point to the newly created manager.
A little bit more simplified we are doing the following:
DbSchedulerDeadlineManager manager1 = DbSchedulerDeadlineManager
.builder( )
...
.build( );
Task<DbSchedulerBinaryDeadlineDetails> binaryTask1 = DbSchedulerDeadlineManager.binaryTask( );
DbSchedulerDeadlineManager manager2 = DbSchedulerDeadlineManager
.builder( )
...
.build( );
Now binaryTask1 points to manager2 thanks to the lambda expression.
I suggest to remove the static field completely. Instead rely on instance methods of the deadline manager to create and register the tasks. The only issue now is the cyclic dependency, I think: Scheduler needs the task, tasks needs now the deadline manager, deadline manager needs the scheduler. In order to break this cycle one probably has to use a Lazy annotation or something similar.
Expected behaviour
All bean definitions created by the configuration classes should be independent from each other.
Actual behaviour
Using the same configurations multiple times leads to modified states in other contexts.
Best regards
Nils
About this issue
- Original URL
- State: closed
- Created 9 months ago
- Comments: 15 (15 by maintainers)
JobRunr itself is already heavily relying on static fields (as can be seen in the method JobRunr.configure which stores the global configuration in a static field), so I would take another approach. I will try and find the time to provide a PR for this issue.