[spring-projects/spring-boot]本机映像无法随 Hibernate 和 Spring Boot 3.1.0 启动

2024-05-08 1 views
2

我的应用程序使用 Spring Boot 3.1.0 和 spring-data-jpa。当我使用生成的图像构建本机图像mvn -Pnative native:compile并运行生成的图像时,出现以下错误:

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

当我将 Hibernate 版本管理到 6.1.7(或使用 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

回答

9

Hibernate 6.2 升级具有挑战性。 Spring 框架问题跟踪器中存在许多问题。我现在要关闭它,请针对 Spring Framework 进行测试6.0.10-SNAPSHOT。如果这仍然不起作用,我们可以考虑重新开放并将其移至包含更多详细信息的框架中。

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

6

@snicoll我让它工作,但只有在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"
                ]
            }
        ]
    }
]

我们可以重新打开它,直到它可以通过 Spring Framework 6.0.10-SNAPSHOT 开箱即用吗?

另外,我如何使用 Hibernate 围绕本机进行某种测试?我确实在公司中推动使用本机映像,但在发布之间经常出现问题。

7

这些提示存在于当前版本的可达性元数据中,但我仍然必须添加它们才能使其正常工作。也许编译器由于某种原因认为它们无法访问(我确实看到了“typeReachable”字段)。

2

@matthenry87 不,我们无法重新打开这个问题,因为它是 Hibernate 特定的问题。检查可达性元数据存储库,这些问题可能已同时修复。如果没有,请在那里报告。

3

@matthenry87 不,我们无法重新打开这个问题,因为它是 Hibernate 特定的问题。检查可达性元数据存储库,这些问题可能已同时修复。如果没有,请在那里报告。

感谢您的回复。将在那里打开一个问题。

0

@matthenry87 您可以在此处链接该问题以供参考吗?

2

另供参考:我在没有发出额外类型提示的情况下就让它工作了。

我使用 Spring Initializr(使用 Native、Data-JPA 和 H2)生成了一个新项目,添加了 Spring Snapshot 存储库并将spring-framework.versionmaven 属性设置为6.0.10-SNAPSHOT.

我还显式配置了本机插件使用的 rechability 元数据版本:

            <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>

我想无论如何这是一个好主意。不过,我发现很奇怪的是,本机 Maven 插件确实会自动提取元数据,但不会告诉它使用哪个版本(即使在verbose模式下运行时也不知道)。

准确地说:

  • 如果我使用 Spring Framework 6.0.10-SNAPSHOT 而不使用最新的元数据版本,则会收到错误java.lang.IllegalArgumentException: Invalid logger interface org.hibernate.dialect.DialectLogging
  • 如果我使用最新的元数据版本,但使用 Spring Boot 3.1.0 附带的 Spring Framework 版本,则会收到com.oracle.svm.core.jdk.UnsupportedFeatureError: No classes have been predefined during the image build to load from bytecodes at runtime.错误消息。

因此,两者都是必需的。

换句话说,对于在 Spring Boot 3.1.0 中使用 Hibernate 的应用程序来说,Spring Native 已被破坏,我们需要等待 3.1.1,它可能会支持 Spring Framework 6.0.10 或更高版本。

2

我觉得很奇怪,原生 Maven 插件会自动提取元数据

我不确定你的意思,但这次谈话不属于这里。

换句话说,对于在 Spring Boot 3.1.0 中使用 Hibernate 的应用程序来说,Spring Native 已被破坏,我们需要等待 3.1.1,它可能会支持 Spring Framework 6.0.10 或更高版本。

Spring Native 之类的东西已经不复存在了,但除此之外,这是对我们最初位置的重写。是的,您现在需要 spring 框架快照,是的,您需要更新的元数据版本,因为我们使用的本机 Maven 插件附带的元数据版本不包含修复程序。

0

我觉得很奇怪,原生 Maven 插件会自动提取元数据

我不确定你的意思,但这次谈话不属于这里。

我的意思是我觉得很奇怪它不输出所使用的元数据的版本。但你是对的,这个讨论不属于这里。我只是发泄一下,抱歉?

0

当你使用JPA和oracle时,如果你将SB更改为3.0.0,它就可以工作。就等官方修复吧。

7

当你使用JPA和oracle时,如果你将SB更改为3.0.0,它就可以工作。就等官方修复吧。

当您只能使用此线程中提到的临时修复程序时,为什么要恢复到 3.0.0?修复了快照的使用(有官方修复),并指向正确的提示。

1

我尝试了 3.1.1-SNAPSHOT,但出现了新的异常。