If I create a basic Spring Boot project using https://start.spring.io/#!type=maven-project&language=java&platformVersion=3.2.2&packaging=jar&jvmVersion=17&groupId=com.example&artifactId=demo&name=demo&description=Demo%20project%20for%20Spring%20Boot&packageName=com.example.demo&dependencies=native and I add the spring-orm
dependency
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
</dependency>
then when I run ./mvnw spring-boot:process-aot
I am going to get:
Exception in thread "main" java.lang.IllegalArgumentException: Unable to instantiate factory class [org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypesBeanRegistrationAotProcessor] for factory type [org.springframework.beans.factory.aot.BeanRegistrationAotProcessor]
at org.springframework.core.io.support.SpringFactoriesLoader$FailureHandler.lambda$throwing$0(SpringFactoriesLoader.java:647)
at org.springframework.core.io.support.SpringFactoriesLoader$FailureHandler.lambda$handleMessage$3(SpringFactoriesLoader.java:671)
at org.springframework.core.io.support.SpringFactoriesLoader.instantiateFactory(SpringFactoriesLoader.java:231)
at org.springframework.core.io.support.SpringFactoriesLoader.load(SpringFactoriesLoader.java:206)
at org.springframework.core.io.support.SpringFactoriesLoader.load(SpringFactoriesLoader.java:142)
at org.springframework.beans.factory.aot.AotServices$Loader.load(AotServices.java:211)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.<init>(BeanDefinitionMethodGeneratorFactory.java:68)
at org.springframework.beans.factory.aot.BeanDefinitionMethodGeneratorFactory.<init>(BeanDefinitionMethodGeneratorFactory.java:59)
at org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor.processAheadOfTime(BeanRegistrationsAotProcessor.java:42)
at org.springframework.beans.factory.aot.BeanRegistrationsAotProcessor.processAheadOfTime(BeanRegistrationsAotProcessor.java:37)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.getContributions(BeanFactoryInitializationAotContributions.java:67)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:49)
at org.springframework.context.aot.BeanFactoryInitializationAotContributions.<init>(BeanFactoryInitializationAotContributions.java:44)
at org.springframework.context.aot.ApplicationContextAotGenerator.lambda$processAheadOfTime$0(ApplicationContextAotGenerator.java:58)
at org.springframework.context.aot.ApplicationContextAotGenerator.withCglibClassHandler(ApplicationContextAotGenerator.java:67)
at org.springframework.context.aot.ApplicationContextAotGenerator.processAheadOfTime(ApplicationContextAotGenerator.java:53)
at org.springframework.context.aot.ContextAotProcessor.performAotProcessing(ContextAotProcessor.java:106)
at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:84)
at org.springframework.context.aot.ContextAotProcessor.doProcess(ContextAotProcessor.java:49)
at org.springframework.context.aot.AbstractAotProcessor.process(AbstractAotProcessor.java:82)
at org.springframework.boot.SpringApplicationAotProcessor.main(SpringApplicationAotProcessor.java:80)
Caused by: java.lang.NoClassDefFoundError: jakarta/persistence/PreUpdate
at org.springframework.orm.jpa.persistenceunit.PersistenceManagedTypesBeanRegistrationAotProcessor.<clinit>(PersistenceManagedTypesBeanRegistrationAotProcessor.java:70)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at java.base/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1160)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.ensureClassInitialized(MethodHandleAccessorFactory.java:300)
at java.base/jdk.internal.reflect.MethodHandleAccessorFactory.newConstructorAccessor(MethodHandleAccessorFactory.java:103)
at java.base/jdk.internal.reflect.ReflectionFactory.newConstructorAccessor(ReflectionFactory.java:200)
at java.base/java.lang.reflect.Constructor.acquireConstructorAccessor(Constructor.java:549)
at java.base/java.lang.reflect.Constructor.newInstanceWithCaller(Constructor.java:499)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:486)
at org.springframework.core.io.support.SpringFactoriesLoader$FactoryInstantiator.instantiate(SpringFactoriesLoader.java:382)
at org.springframework.core.io.support.SpringFactoriesLoader.instantiateFactory(SpringFactoriesLoader.java:228)
... 18 more
Caused by: java.lang.ClassNotFoundException: jakarta.persistence.PreUpdate
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:526)
... 29 more
Is it possible to move the PersistenceManagedTypesBeanRegistrationAotProcessor#CALLBACK_TYPES
in the PersistenceManagedTypesBeanRegistrationAotProcessor.JpaManagedTypesBeanRegistrationCodeFragments
. Those are anyways only used in the JpaManagedTypesBeanRegistrationCodeFragments
and I believe if they are moved the exception will be gone.
Comment From: snicoll
@filiphr we're going to obviously fix that but can you share why you are running AOT (on an application) with only spring-orm
on the classpath?
Comment From: filiphr
Thanks @snicoll. Sorry, I should have explained a bit more in the original issue. The example I shared is the minimal example where this is happening.
I noticed this while I was working on integrating the PR from @joshlong and @jbarrez for integrating Native Support in Flowable (https://github.com/flowable/flowable-engine/pull/3815). I am using https://github.com/spring-tips/flowable-processes as a test and moving that into the Flowable project. I wanted to remove the dependency to spring-boot-starter-data-jpa
and I saw the stacktrace. It looks like our spring module is using spring-orm
, I need to investigate whether we can remove that. Hope this clarifies how I found this issue.
Comment From: snicoll
I wasn't really asking how you found the issue but I was more curious why you'd be using AOT with such an environment. Running your tests in a native image is answering that question. Thanks!