Resource injection in AOT mode

We have use cases where we use advantage of CommandGateway or another Spring Beans (@Service) injected into our command handlers methods in aggregate. In standard compilation mode it works correctly.

But when we compile our maven application in native mode, with axon-spring-aot extension, it shows an error. We use native-maven-plugin and newest Spring Boot, so AOT is configured mostly automatically. Do we need configure it somehow? Or is it bad practice so it is intentionally not supported in AOT mode?

An error shown:
Exception in thread ā€œmainā€ org.axonframework.messaging.annotation.UnsupportedHandlerException: Unable to resolve parameter 1 (CommandGateway) in handler public void ā€¦

Hi Lukas,

AOT should work, but there might be edge cases where things donā€™t quite get detected like they should.
Just wondering, is AOT without native compilation working normally?

I never worked with AOT or native images before, so I hope I do it right. But if I run command mvn clean compile spring-boot:process-aot package, it fails with same error. (we use current spring boot 3.3.x and Axon BOM 4.10.x)

Command I run before is mvn clean spring-boot:build-image with native profile active.

Just to be sure - do you consider this use case (command gateway injected into command handler) as edge case?

The mvn spring-boot:process-aot command should indeed trigger the AOT, without the native compilation. This step prepares the Spring Application Context in such a way that startup is more efficient. It also makes native compilation a lot faster.

No, injecting beans as parameters is not an edge case. I would expect it to work.

Iā€™ll have a quick look, as I donā€™t remember seeing this fail before.

I think I found the issue. Can you confirm the exception occurs during build time, and not (only) during startup of the application?

Yes, it happens during build time.

Iā€™ve filed an issue. Itā€™s a bit busy with the conference happening next week, so I donā€™t expect this to be a very quick fix.

1 Like

Thank you for GitHub issue creation.

As temporary workaround I use jakarta.inject.Inject annotation, now application compiles and starts as native image, so I can continue in prototyping.


But now I found two more problems in running application, which I canĀ“t figure out how to configure manually (adding to reflect-config.json, RegisterReflectionForBinding annotation did not work), but probably it should work out of box too?

Could you recommend some fix / test, or should I write issue on GitHub too?

  1. In Command handler interceptor (without tracing):
The program tried to reflectively invoke method public void {aggregateClass}.intercept({command}) without it being registered for runtime reflection. Add public void {aggregateClass}.intercept({command}) to the reflection metadata to solve this problem. See https://www.graalvm.org/latest/reference-manual/native-image/metadata/#reflection for help.
2024-09-30 13:29:33     at org.graalvm.nativeimage.builder/com.oracle.svm.core.reflect.MissingReflectionRegistrationUtils.forQueriedOnlyExecutable(MissingReflectionRegistrationUtils.java:72)
2024-09-30 13:29:33     at java.base@21.0.4/java.lang.reflect.Method.acquireMethodAccessor(Method.java:77)
2024-09-30 13:29:33     at java.base@21.0.4/java.lang.reflect.Method.invoke(Method.java:577)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.AnnotatedMessageHandlingMember.handle(AnnotatedMessageHandlingMember.java:153)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.WrappedMessageHandlingMember.handle(WrappedMessageHandlingMember.java:64)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.WrappedMessageHandlingMember.handle(WrappedMessageHandlingMember.java:64)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.MessageHandlerInterceptorDefinition$InterceptedMessageHandlingMember.handle(MessageHandlerInterceptorDefinition.java:123)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.WrappedMessageHandlingMember.handle(WrappedMessageHandlingMember.java:64)
2024-09-30 13:29:33     at org.axonframework.tracing.TracingHandlerEnhancerDefinition$1.lambda$handle$1(TracingHandlerEnhancerDefinition.java:84)
2024-09-30 13:29:33     at org.axonframework.tracing.Span.runCallable(Span.java:132)
2024-09-30 13:29:33     at org.axonframework.tracing.TracingHandlerEnhancerDefinition$1.handle(TracingHandlerEnhancerDefinition.java:84)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.lambda$handle$0(AnnotatedCommandHandlerInterceptor.java:59)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.InterceptorChainParameterResolverFactory.callWithInterceptorChain(InterceptorChainParameterResolverFactory.java:75)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.handle(AnnotatedCommandHandlerInterceptor.java:56)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.lambda$handle$0(AnnotatedCommandHandlerInterceptor.java:60)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.InterceptorChainParameterResolverFactory.callWithInterceptorChain(InterceptorChainParameterResolverFactory.java:75)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.handle(AnnotatedCommandHandlerInterceptor.java:56)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.lambda$handle$0(AnnotatedCommandHandlerInterceptor.java:60)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.InterceptorChainParameterResolverFactory.callWithInterceptorChain(InterceptorChainParameterResolverFactory.java:75)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.handle(AnnotatedCommandHandlerInterceptor.java:56)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.lambda$handle$0(AnnotatedCommandHandlerInterceptor.java:60)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.InterceptorChainParameterResolverFactory.callWithInterceptorChain(InterceptorChainParameterResolverFactory.java:75)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.handle(AnnotatedCommandHandlerInterceptor.java:56)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.lambda$handle$0(AnnotatedCommandHandlerInterceptor.java:60)
2024-09-30 13:29:33     at org.axonframework.messaging.annotation.InterceptorChainParameterResolverFactory.callWithInterceptorChain(InterceptorChainParameterResolverFactory.java:75)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedCommandHandlerInterceptor.handle(AnnotatedCommandHandlerInterceptor.java:56)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedAggregate.handle(AnnotatedAggregate.java:433)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedAggregate.lambda$handle$3(AnnotatedAggregate.java:398)
2024-09-30 13:29:33     at org.axonframework.messaging.Scope.executeWithResult(Scope.java:111)
2024-09-30 13:29:33     at org.axonframework.modelling.command.inspection.AnnotatedAggregate.handle(AnnotatedAggregate.java:405)
2024-09-30 13:29:33     at org.axonframework.modelling.command.LockAwareAggregate.handle(LockAwareAggregate.java:97)
2024-09-30 13:29:33     at org.axonframework.modelling.command.AggregateAnnotationCommandHandler$AggregateCommandHandler.handle(AggregateAnnotationCommandHandler.java:568)
2024-09-30 13:29:33     at org.axonframework.modelling.command.AggregateAnnotationCommandHandler$AggregateCommandHandler.handle(AggregateAnnotationCommandHandler.java:557)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:57)
2024-09-30 13:29:33     at cz.aura.lis.axon.logging.MdcInterceptor.handle(MdcInterceptor.java:29)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 13:29:33     at org.axonframework.messaging.interceptors.CorrelationDataInterceptor.handle(CorrelationDataInterceptor.java:67)
2024-09-30 13:29:33     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 13:29:33     at org.axonframework.messaging.unitofwork.DefaultUnitOfWork.executeWithResult(DefaultUnitOfWork.java:77)
2024-09-30 13:29:33     at org.axonframework.commandhandling.SimpleCommandBus.lambda$handle$2(SimpleCommandBus.java:200)
2024-09-30 13:29:33     at org.axonframework.tracing.Span.runSupplier(Span.java:163)
2024-09-30 13:29:33     at org.axonframework.commandhandling.SimpleCommandBus.handle(SimpleCommandBus.java:191)
2024-09-30 13:29:33     at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:165)
2024-09-30 13:29:33     at org.axonframework.commandhandling.SimpleCommandBus.lambda$dispatch$1(SimpleCommandBus.java:131)
2024-09-30 13:29:33     at org.axonframework.tracing.Span.run(Span.java:101)
2024-09-30 13:29:33     at org.axonframework.commandhandling.SimpleCommandBus.dispatch(SimpleCommandBus.java:125)
2024-09-30 13:29:33     at org.axonframework.axonserver.connector.command.AxonServerCommandBus$CommandProcessingTask.lambda$run$1(AxonServerCommandBus.java:310)
2024-09-30 13:29:33     at org.axonframework.tracing.Span.run(Span.java:101)
2024-09-30 13:29:33     at org.axonframework.axonserver.connector.command.AxonServerCommandBus$CommandProcessingTask.run(AxonServerCommandBus.java:308)
2024-09-30 13:29:33     at org.axonframework.axonserver.connector.PriorityRunnable.run(PriorityRunnable.java:58)
2024-09-30 13:29:33     at java.base@21.0.4/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
2024-09-30 13:29:33     at java.base@21.0.4/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
2024-09-30 13:29:33     at java.base@21.0.4/java.lang.Thread.runWith(Thread.java:1596)
2024-09-30 13:29:33     at java.base@21.0.4/java.lang.Thread.run(Thread.java:1583)
2024-09-30 13:29:33     at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:902)
2024-09-30 13:29:33     at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:878)
  1. Aggregate member (ForwardMatchingInstances, Map<id, MemberClass>, MemberClass has all getters and no args constructor, command is record):
2024-09-30 12:30:01 10:30:01.701 WARN  o.a.m.command.AbstractRepository - Exception occurred while trying to load a aggregate with identifier
2024-09-30 12:30:01 java.lang.NullPointerException: null
2024-09-30 12:30:01     at org.axonframework.common.property.BeanPropertyAccessStrategy.getterName(BeanPropertyAccessStrategy.java:34)
2024-09-30 12:30:01     at org.axonframework.common.property.AbstractMethodPropertyAccessStrategy.propertyFor(AbstractMethodPropertyAccessStrategy.java:39)
2024-09-30 12:30:01     at org.axonframework.common.property.PropertyAccessStrategy.getProperty(PropertyAccessStrategy.java:91)
2024-09-30 12:30:01     at org.axonframework.modelling.command.ForwardMatchingInstances.filterCandidates(ForwardMatchingInstances.java:59)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AggregateMemberAnnotatedChildEntityMapDefinition.resolveEventTargets(AggregateMemberAnnotatedChildEntityMapDefinition.java:98)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AbstractChildEntityDefinition.lambda$createChildDefinition$1(AbstractChildEntityDefinition.java:72)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AnnotatedChildEntity.publish(AnnotatedChildEntity.java:78)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AnnotatedAggregateMetaModelFactory$AnnotatedAggregateModel.lambda$doPublish$20(AnnotatedAggregateMetaModelFactory.java:581)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1708)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:762)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:276)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.HashMap$ValueSpliterator.forEachRemaining(HashMap.java:1787)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AnnotatedAggregateMetaModelFactory$AnnotatedAggregateModel.doPublish(AnnotatedAggregateMetaModelFactory.java:581)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AnnotatedAggregateMetaModelFactory$AnnotatedAggregateModel.publish(AnnotatedAggregateMetaModelFactory.java:565)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AnnotatedAggregate.publish(AnnotatedAggregate.java:378)
2024-09-30 12:30:01     at org.axonframework.eventsourcing.EventSourcedAggregate.publish(EventSourcedAggregate.java:253)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.Iterator.forEachRemaining(Iterator.java:133)
2024-09-30 12:30:01     at org.axonframework.eventsourcing.EventSourcedAggregate.lambda$initializeState$0(EventSourcedAggregate.java:296)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AnnotatedAggregate.lambda$execute$2(AnnotatedAggregate.java:349)
2024-09-30 12:30:01     at org.axonframework.modelling.command.AggregateLifecycle.lambda$execute$0(AggregateLifecycle.java:189)
2024-09-30 12:30:01     at org.axonframework.messaging.Scope.executeWithResult(Scope.java:111)
2024-09-30 12:30:01     at org.axonframework.modelling.command.AggregateLifecycle.execute(AggregateLifecycle.java:188)
2024-09-30 12:30:01     at org.axonframework.modelling.command.inspection.AnnotatedAggregate.execute(AnnotatedAggregate.java:349)
2024-09-30 12:30:01     at org.axonframework.eventsourcing.EventSourcedAggregate.initializeState(EventSourcedAggregate.java:293)
2024-09-30 12:30:01     at org.axonframework.eventsourcing.EventSourcingRepository.doLoadAggregate(EventSourcingRepository.java:158)
2024-09-30 12:30:01     at org.axonframework.eventsourcing.EventSourcingRepository.lambda$doLoadWithLock$0(EventSourcingRepository.java:138)
2024-09-30 12:30:01     at org.axonframework.tracing.Span.runSupplier(Span.java:163)
2024-09-30 12:30:01     at org.axonframework.eventsourcing.EventSourcingRepository.doLoadWithLock(EventSourcingRepository.java:138)
2024-09-30 12:30:01     at org.axonframework.eventsourcing.EventSourcingRepository.doLoadWithLock(EventSourcingRepository.java:56)
2024-09-30 12:30:01     at org.axonframework.modelling.command.LockingRepository.doLoad(LockingRepository.java:137)
2024-09-30 12:30:01     at org.axonframework.modelling.command.LockingRepository.doLoad(LockingRepository.java:60)
2024-09-30 12:30:01     at org.axonframework.modelling.command.AbstractRepository.lambda$null$5(AbstractRepository.java:151)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.HashMap.computeIfAbsent(HashMap.java:1228)
2024-09-30 12:30:01     at org.axonframework.modelling.command.AbstractRepository.lambda$load$7(AbstractRepository.java:148)
2024-09-30 12:30:01     at org.axonframework.tracing.Span.runSupplier(Span.java:163)
2024-09-30 12:30:01     at org.axonframework.modelling.command.AbstractRepository.load(AbstractRepository.java:145)
2024-09-30 12:30:01     at org.axonframework.modelling.command.AggregateAnnotationCommandHandler$AggregateCommandHandler.handle(AggregateAnnotationCommandHandler.java:568)
2024-09-30 12:30:01     at org.axonframework.modelling.command.AggregateAnnotationCommandHandler$AggregateCommandHandler.handle(AggregateAnnotationCommandHandler.java:557)
2024-09-30 12:30:01     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:57)
2024-09-30 12:30:01     at cz.aura.lis.axon.logging.MdcInterceptor.handle(MdcInterceptor.java:29)
2024-09-30 12:30:01     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 12:30:01     at org.axonframework.messaging.interceptors.CorrelationDataInterceptor.handle(CorrelationDataInterceptor.java:67)
2024-09-30 12:30:01     at org.axonframework.messaging.DefaultInterceptorChain.proceed(DefaultInterceptorChain.java:55)
2024-09-30 12:30:01     at org.axonframework.messaging.unitofwork.DefaultUnitOfWork.executeWithResult(DefaultUnitOfWork.java:77)
2024-09-30 12:30:01     at org.axonframework.commandhandling.SimpleCommandBus.lambda$handle$2(SimpleCommandBus.java:200)
2024-09-30 12:30:01     at org.axonframework.tracing.Span.runSupplier(Span.java:163)
2024-09-30 12:30:01     at org.axonframework.commandhandling.SimpleCommandBus.handle(SimpleCommandBus.java:191)
2024-09-30 12:30:01     at org.axonframework.commandhandling.SimpleCommandBus.doDispatch(SimpleCommandBus.java:165)
2024-09-30 12:30:01     at org.axonframework.commandhandling.SimpleCommandBus.lambda$dispatch$1(SimpleCommandBus.java:131)
2024-09-30 12:30:01     at org.axonframework.tracing.Span.run(Span.java:101)
2024-09-30 12:30:01     at org.axonframework.commandhandling.SimpleCommandBus.dispatch(SimpleCommandBus.java:125)
2024-09-30 12:30:01     at org.axonframework.axonserver.connector.command.AxonServerCommandBus$CommandProcessingTask.lambda$run$1(AxonServerCommandBus.java:310)
2024-09-30 12:30:01     at org.axonframework.tracing.Span.run(Span.java:101)
2024-09-30 12:30:01     at org.axonframework.axonserver.connector.command.AxonServerCommandBus$CommandProcessingTask.run(AxonServerCommandBus.java:308)
2024-09-30 12:30:01     at org.axonframework.axonserver.connector.PriorityRunnable.run(PriorityRunnable.java:58)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
2024-09-30 12:30:01     at java.base@21.0.4/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
2024-09-30 12:30:01     at java.base@21.0.4/java.lang.Thread.runWith(Thread.java:1596)
2024-09-30 12:30:01     at java.base@21.0.4/java.lang.Thread.run(Thread.java:1583)
2024-09-30 12:30:01     at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:902)
2024-09-30 12:30:01     at org.graalvm.nativeimage.builder/com.oracle.svm.core.thread.PlatformThreads.threadStartRoutine(PlatformThreads.java:878)

I have created two more issues on GitHub for problems I mentioned before. In case it is my error or unfamiliarity with correct setup, the issues can just be closed.

Command handler interceptor: Command handler interceptor causes errors in running Spring Boot AOT application Ā· Issue #192 Ā· AxonFramework/extension-spring-aot Ā· GitHub
Aggregate member: Aggregate member causes errors in running Spring Boot AOT application Ā· Issue #193 Ā· AxonFramework/extension-spring-aot Ā· GitHub

This issue has been addressed in this PR: