Axon 4.7.3 Support for Spring Boot 3 AOT

Hi there,

My team is currently upgrading our axon-based spring boot applications to take advantage of the GraalVM native image generation that comes with the latest major release of spring boot.

This is the command I’m running…

We are experiencing issues with the native compilation as shown below…

Any help would be appreciated.

Hi Kahiga,

we’ve bumped into this issue ourselves as well. I am not sure if this is a bug in Spring Framework, or a configuration error on our side. We’re still figuring that out.

That said, if you were to get Spring AOT working, making it work in Native code is a whole other step. We’ve built Spring-Native support through an extension, but Spring 6 (and Spring Boot 3) redesigned that quite a bit. We haven’t come to testing those changes yet. Your milage may vary.

If you’re interested in the Spring AOT workaround, there are 2 issues that need to be worked around, actually. One is a confirmed issue in Spring Boot that hasn’t been solved yet, the other is the issue I described above.

You can work around these issues by putting the following in a META-INF/spring/aot.factories file:

org.springframework.beans.factory.aot.BeanRegistrationExcludeFilter=\
com.example.EntityScanExcludeFilter

org.springframework.beans.factory.aot.BeanRegistrationAotProcessor=\
 com.example.SpringRepositoryFactoryBeanFixer

And these are the two classes you need to have:
com.example.EntityScanExcludeFilter

public class EntityScanExcludeFilter implements BeanRegistrationExcludeFilter {
	@Override
	public boolean isExcludedFromAotProcessing(RegisteredBean registeredBean) {
		return registeredBean.getBeanClass().equals(EntityScanPackages.class);
	}
}

com.example.SpringRepositoryFactoryBeanFixer

public class SpringRepositoryFactoryBeanFixer implements BeanRegistrationAotProcessor {

    @Override
    public BeanRegistrationAotContribution processAheadOfTime(RegisteredBean registeredBean) {
        if (SpringRepositoryFactoryBean.class.getName().equals(registeredBean.getMergedBeanDefinition().getBeanClassName())) {
            RootBeanDefinition beanDef = registeredBean.getMergedBeanDefinition();
            var indexedArgumentValue = beanDef.getConstructorArgumentValues().getIndexedArgumentValue(0, Class.class);
            if (indexedArgumentValue != null) {
                beanDef.setTargetType(ResolvableType.forClassWithGenerics(SpringRepositoryFactoryBean.class, (Class<?>) indexedArgumentValue.getValue()));
            }
        }
        return null;
    }
}

In the meantime, we’re trying to figure out why this second hack is necessary to make things work…

Hope this helps.
Cheers,

Allard

1 Like

Hi @allardbz,

Working on major refactors required for the Spring 6/Spring Boot 3 migration has been a hectic fortnight.

We have deployed our host of axon applications with Spring AOT successfully so far.
The hack you suggested works for us, but it remains as such. I’m curious about what insights you have uncovered so far.
We also see deprecation errors on application startup…

How do we proceed on the same?

Best,
Kahiga wa Kiguru.

The deprecation warnings are false positives. So you don’t need to do something about them.

Thank you! Much Appreciated @Gerard

Hi Team,

I am currently upgrading spring boot applications from 2.5 to 3.0 , complied the code successfully ,but while running the application, getting issues as below.’

class not found exception : org.springframework.beans.factory.aot.beanregistrationexcludefilter.

A fix related to AOT was recently merged. We didn’t release since than. So you could wait till we do release, use the released snapshot version, or build from master yourself. That probably fixes the problem.

FYI: 4.7.4 with a fix was just released.