GraalVM Native Image 在 Springdoc 依赖上失败

Posted

技术标签:

【中文标题】GraalVM Native Image 在 Springdoc 依赖上失败【英文标题】:GraalVM Native Image failing on Springdoc dependency 【发布时间】:2020-12-07 20:23:43 【问题描述】:

我正在尝试使用 spring boot 和 GraalVM Native Image 创建一个示例应用程序,但是一旦我添加了 Springdoc 的依赖项,生成的可执行文件就不再工作了,原因如下:

 java.lang.IllegalStateException: Error processing condition on org.springdoc.core.SpringDocConfiguration.springdocBeanFactoryPostProcessor2
        at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60) ~[poc-graalvm-native.exe:na]
        at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108) ~[na:na]
        at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:184) ~[na:na]
        at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144) ~[na:na]
        at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120) ~[na:na]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331) ~[poc-graalvm-native.exe:na]
        at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236) ~[poc-graalvm-native.exe:na]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280) ~[na:na]
        at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96) ~[na:na]
        at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707) ~[na:na]
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533) ~[na:na]
        at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143) ~[na:na]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:315) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1237) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226) ~[poc-graalvm-native.exe:na]
        at c.b.t.graal.GraalVMApplicationPoc.main(GraalVMApplicationPoc.java:31) [poc-graalvm-native.exe:na]
Caused by: java.lang.IllegalStateException: java.io.FileNotFoundException: class path resource [org/springdoc/core/CacheOrGroupedOpenApiCondition$OnCacheDisabled.class] cannot be opened because it does not exist
        at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.getMetadata(AbstractNestedCondition.java:149) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.getMemberConditions(AbstractNestedCondition.java:121) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.<init>(AbstractNestedCondition.java:114) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition.getMatchOutcome(AbstractNestedCondition.java:62) ~[poc-graalvm-native.exe:na]
        at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:47) ~[poc-graalvm-native.exe:na]
        ... 18 common frames omitted
Caused by: java.io.FileNotFoundException: class path resource [org/springdoc/core/CacheOrGroupedOpenApiCondition$OnCacheDisabled.class] cannot be opened because it does not exist
        at org.springframework.core.io.ClassPathResource.getInputStream(ClassPathResource.java:180) ~[poc-graalvm-native.exe:na]
        at org.springframework.core.type.clas-s-reading.SimpleMetadataReader.getClassReader(SimpleMetadataReader.java:55) ~[na:na]
        at org.springframework.core.type.clas-s-reading.SimpleMetadataReader.<init>(SimpleMetadataReader.java:49) ~[na:na]
        at org.springframework.core.type.clas-s-reading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:103) ~[na:na]
        at org.springframework.core.type.clas-s-reading.SimpleMetadataReaderFactory.getMetadataReader(SimpleMetadataReaderFactory.java:81) ~[na:na]
        at org.springframework.boot.autoconfigure.condition.AbstractNestedCondition$MemberConditions.getMetadata(AbstractNestedCondition.java:146) ~[poc-graalvm-native.exe:na]
        ... 22 common frames omitted

我目前的依赖是:

dependencies 
    implementation ('org.springframework.boot:spring-boot-starter-web') 
        exclude group : 'org.apache.tomcat.embed', module : 'tomcat-embed-websocket'
    
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    // Lombok
    compileOnly("org.projectlombok:lombok")
    annotationProcessor("org.projectlombok:lombok")

    testCompileOnly("org.projectlombok:lombok")
    testAnnotationProcessor("org.projectlombok:lombok")

    // https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j
    implementation('org.slf4j:jcl-over-slf4j:2.0.0-alpha1')
    implementation('org.springdoc:springdoc-openapi-webmvc-core:1.4.4')

在我添加 SpringDoc 之前一切正常。 已经尝试将一些springdoc包添加到--initialize-at-build-time,但没有成功。

我正在使用 com.github.ayltai.spring-graalvm-native-plugin 来处理 gradle 任务,我的依赖项是:

dependencies 
    implementation ('org.springframework.boot:spring-boot-starter-web') 
        exclude group : 'org.apache.tomcat.embed', module : 'tomcat-embed-websocket'
    
    implementation("org.springframework.boot:spring-boot-starter-actuator")
    // Lombok
    compileOnly("org.projectlombok:lombok")
    annotationProcessor("org.projectlombok:lombok")

    testCompileOnly("org.projectlombok:lombok")
    testAnnotationProcessor("org.projectlombok:lombok")

    // https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j
    implementation('org.slf4j:jcl-over-slf4j:2.0.0-alpha1')
    implementation('org.springdoc:springdoc-openapi-webmvc-core:1.4.4')

任何提示将不胜感激。

【问题讨论】:

【参考方案1】:

由于v1.5.9springdoc-openapi fully supports GraalVM 和 spring-native。

无需额外配置。

【讨论】:

您好,感谢您的意见!我已经在使用 spring-graalvm-native。但是,添加资源配置似乎会破坏本机映像编译:Fatal error:java.util.MissingFormatArgumentException: Format specifier '%5c' 好的,我正在使用的 gradle 插件似乎有问题。我只是将所有内容都切换到 maven,它开始给出一些不同的错误 - 我在编写时向资源配置添加了更多内容,它似乎正在工作(或至少部分修复了一些问题)。您的回复让我更加了解 json 以及何时/如何使用它们。

以上是关于GraalVM Native Image 在 Springdoc 依赖上失败的主要内容,如果未能解决你的问题,请参考以下文章

使用 GraalVM Native Image 代替混淆

Spring Boot 3的AOT(GraalVM Native Image)应用开发

Spring Boot 3的AOT(GraalVM Native Image)应用开发

在spring boot3中使用native image

基于 docker 构建 graalvm native 应用程序

基于 docker 构建 graalvm native 应用程序