My application uses Spring Boot 3.1.0 and spring-data-jpa. When I build a native image using mvn -Pnative native:compile and run the resulting image, I get the following error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory': No classes have been predefined during the image build to load from bytecodes at runtime.
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1770) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:598) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:520) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:326) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:324) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[postfachservice-persistence:6.0.9]
        at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1156) ~[postfachservice-persistence:6.0.9]
        at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:931) ~[postfachservice-persistence:6.0.9]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:608) ~[postfachservice-persistence:6.0.9]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:733) ~[postfachservice-persistence:3.1.0]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:435) ~[postfachservice-persistence:3.1.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:311) ~[postfachservice-persistence:3.1.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1305) ~[postfachservice-persistence:3.1.0]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1294) ~[postfachservice-persistence:3.1.0]
        at de.gema.opp.postfachservice.persistence.PersistenceApplication.main(PersistenceApplication.java:12) ~[postfachservice-persistence:na]
Caused by: com.oracle.svm.core.jdk.UnsupportedFeatureError: No classes have been predefined during the image build to load from bytecodes at runtime.
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.util.VMError.unsupportedFeature(VMError.java:89) ~[na:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.PredefinedClassesSupport.throwNoBytecodeClasses(PredefinedClassesSupport.java:76) ~[na:na]
        at org.graalvm.nativeimage.builder/com.oracle.svm.core.hub.PredefinedClassesSupport.loadClass(PredefinedClassesSupport.java:130) ~[na:na]
        at java.base@17.0.5/java.lang.ClassLoader.defineClass(ClassLoader.java:294) ~[postfachservice-persistence:na]
        at net.bytebuddy.utility.dispatcher.JavaDispatcher$DynamicClassLoader.invoker(JavaDispatcher.java:1383) ~[na:na]
        at net.bytebuddy.utility.dispatcher.JavaDispatcher$InvokerCreationAction.run(JavaDispatcher.java:459) ~[na:na]
        at net.bytebuddy.utility.dispatcher.JavaDispatcher$InvokerCreationAction.run(JavaDispatcher.java:452) ~[na:na]
        at java.base@17.0.5/java.security.AccessController.executePrivileged(AccessController.java:168) ~[na:na]
        at java.base@17.0.5/java.security.AccessController.doPrivileged(AccessController.java:318) ~[na:na]
        at net.bytebuddy.utility.dispatcher.JavaDispatcher.doPrivileged(JavaDispatcher.java) ~[na:na]
        at net.bytebuddy.utility.dispatcher.JavaDispatcher.<clinit>(JavaDispatcher.java:87) ~[na:na]
        at net.bytebuddy.description.type.TypeDescription$ForLoadedType.<clinit>(TypeDescription.java:8659) ~[na:na]
        at net.bytebuddy.matcher.ElementMatchers.isFinalizer(ElementMatchers.java:1624) ~[na:na]
        at org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState$ProxyDefinitionHelpers.<init>(ByteBuddyState.java:296) ~[na:na]
        at org.hibernate.bytecode.internal.bytebuddy.ByteBuddyState.<clinit>(ByteBuddyState.java:71) ~[na:na]
        at org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl.<init>(BytecodeProviderImpl.java:123) ~[na:na]
        at org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl.<init>(BytecodeProviderImpl.java:115) ~[na:na]
        at org.hibernate.bytecode.internal.BytecodeProviderInitiator.buildBytecodeProvider(BytecodeProviderInitiator.java:59) ~[na:na]
        at org.hibernate.bytecode.internal.BytecodeProviderInitiator.buildDefaultBytecodeProvider(BytecodeProviderInitiator.java:46) ~[na:na]
        at org.hibernate.jpa.internal.enhance.EnhancingClassTransformerImpl.<init>(EnhancingClassTransformerImpl.java:34) ~[na:na]
        at org.hibernate.jpa.boot.internal.PersistenceUnitInfoDescriptor.pushClassTransformer(PersistenceUnitInfoDescriptor.java:113) ~[postfachservice-persistence:6.2.0.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:340) ~[postfachservice-persistence:6.2.0.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.<init>(EntityManagerFactoryBuilderImpl.java:190) ~[postfachservice-persistence:6.2.0.Final]
        at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[na:na]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:376) ~[postfachservice-persistence:6.0.9]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:409) ~[postfachservice-persistence:6.0.9]
        at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:396) ~[postfachservice-persistence:6.0.9]
        at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:352) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1816) ~[postfachservice-persistence:6.0.9]
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1766) ~[postfachservice-persistence:6.0.9]
        ... 15 common frames omitted

The problem disappears when I manage the Hibernate version to 6.1.7 (or use Spring Boot 3.0.7).

$ java -version                          
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.0 (build 17.0.5+8-jvmci-22.3-b08, mixed mode, sharing)

spring-boot-native-example.zip

Comment From: matthenry87

I am also experiencing this same issue/error. Here is an even more minimal reproducer that uses h2 instead of postgres:

https://start.spring.io/starter.zip?type=maven-project&language=java&bootVersion=3.1.0&baseDir=native-three-point-one&packaging=jar&javaVersion=17&dependencies=native,data-jpa,h2

Comment From: snicoll

The Hibernate 6.2 upgrade was challenging. There are numerous issues in the Spring Framework issue tracker. I am going to close this now and please test against Spring Framework 6.0.10-SNAPSHOT. If that still doesn't work, we can consider reopening and moving this one to framework with more details.

Duplicates https://github.com/spring-projects/spring-framework/issues/30492

Comment From: matthenry87

@snicoll I got it to work, but only after adding the following hints in a reflect-config.json:

[
    {
        "name": "org.hibernate.dialect.DialectLogging_$logger",
        "methods":
        [
            {
                "name": "<init>",
                "parameterTypes":
                [
                    "org.jboss.logging.Logger"
                ]
            }
        ]
    },
    {
        "name": "org.hibernate.metamodel.mapping.MappingModelCreationLogging_$logger",
        "methods":
        [
            {
                "name": "<init>",
                "parameterTypes":
                [
                    "org.jboss.logging.Logger"
                ]
            }
        ]
    }
]

Can we re-open this until it works out of the box w/ Spring Framework 6.0.10-SNAPSHOT?

Also, how can I contribute some sort of testing around native with Hibernate? I am really pushing the use of native-image at my company, but things keep breaking between releases pretty often.

Comment From: matthenry87

Those hints are present in the current version of the reachability metadata, but I still had to add them to make it work. Maybe the compiler doesn't think they're reachable for some reason (I do see the 'typeReachable' field).

Comment From: snicoll

@matthenry87 no, we can't reopen this issue as it is something that's Hibernate-specific. Check the reachability metadata repo, those might have been fixed in the meantime. If not, please report that there.

Comment From: matthenry87

@matthenry87 no, we can't reopen this issue as it is something that's Hibernate-specific. Check the reachability metadata repo, those might have been fixed in the meantime. If not, please report that there.

Thanks for the response. Will open an issue over there.

Comment From: davidbilge

@matthenry87 can you please link that issue here, for reference?

Comment From: davidbilge

Also for reference: I got this to work without issuing additional type hints.

I generated a new project using Spring Initializr (with Native, Data-JPA and H2), added the Spring Snapshot repo and set the spring-framework.version maven property to 6.0.10-SNAPSHOT.

I also explicitly configured the rechability metadata version to be used by the native plugin:

            <plugin>
                <groupId>org.graalvm.buildtools</groupId>
                <artifactId>native-maven-plugin</artifactId>
                <configuration>
                    <metadataRepository>
                        <enabled>true</enabled>
                        <version>0.3.1</version>
                    </metadataRepository>

                    <verbose>true</verbose>
                </configuration>
            </plugin>

I guess this is a good idea anyways. Still, I find it quite strange that the native maven plugin does pull metadata automatically but does not tell which version it used (not even when run in verbose mode).

To be precise:

  • If I use Spring Framework 6.0.10-SNAPSHOT without using the latest metadata version, I get the java.lang.IllegalArgumentException: Invalid logger interface org.hibernate.dialect.DialectLogging error.
  • If I use the latest metadata version but use the Spring Framework version coming with Spring Boot 3.1.0, I get the com.oracle.svm.core.jdk.UnsupportedFeatureError: No classes have been predefined during the image build to load from bytecodes at runtime. error.

Thus, both are required.

In other words, Spring Native is broken for applications using Hibernate in Spring Boot 3.1.0 and we need to wait for 3.1.1 that probably picks up Spring Framework 6.0.10 or later.

Comment From: snicoll

I find it quite strange that the native maven plugin does pull metadata automatically

I am not sure what you mean by that, but that conversation doesn't belong here.

In other words, Spring Native is broken for applications using Hibernate in Spring Boot 3.1.0 and we need to wait for 3.1.1 that probably picks up Spring Framework 6.0.10 or later.

There's no such thing as Spring Native anymore but, other than than, this is a rewrite of where we were initially. Yes, you need spring framework snapshot for now and, yes, you need a more recent metadata version as the one that shipped with the native maven plugin we use didn't contain the fix.

Comment From: davidbilge

I find it quite strange that the native maven plugin does pull metadata automatically

I am not sure what you mean by that, but that conversation doesn't belong here.

I meant that I find it strange that it does not output the version of the used metadata. But you are right, this discussion does not belong here. I was just venting, sorry 😊

Comment From: wilkinsona

It's available from https://repo.spring.io/snapshot.

If you have any further questions, please follow up on Stack Overflow or Gitter. As mentioned in the guidelines for contributing, we prefer to use GitHub issues only for bugs and enhancements.

Comment From: dchack

It's works if you change your SB to 3.0.0 when you use JPA and oracle. Just wait for a official fix.

Comment From: matthenry87

It's works if you change you SB to 3.0.0 when you use JPA and oracle. Just wait for a official fix.

Why revert to 3.0.0 when you can just use the temporary fixes mentioned in this thread? Fix being usage of the snapshot (that has official fix), and pointing at the right hints.

Comment From: dchack

I try the 3.1.1-SNAPSHOT,but get a new exception.

Comment From: jrgarcia-gire

New error when running: org.hibernate.bytecode.internal.bytebuddy.BytecodeProviderImpl.() in SB 3.3.5

Comment From: snicoll

@jrgarcia-gire please do not comment on closed issues, especially with that level of details. If you believe you found a bug in Spring Boot, create a new issue with a small sample that we can use to reproduce the error locally, see how to get help for more details.