Micronaut构建Native Image成功但启动报错:缺失Undertow构造方法
java.lang.NoSuchMethodError 使用GraalVM 22.2.0 CE、Java 17、Maven 3.8.6构建Micronaut项目Native Image,执行命令mvn package -Dpackaging=native-image成功生成镜像文件,但启动时执行./target/native-image-file报错,无法实例化io.undertow.Undertow Bean,根源错误为:
java.lang.NoSuchMethodError: io.undertow.util.FastConcurrentDirectDeque.<init>()
项目仅使用Undertow服务器,Maven依赖配置如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>micronaut-demo</artifactId> <version>0.1</version> <packaging>${packaging}</packaging> <parent> <groupId>io.micronaut</groupId> <artifactId>micronaut-parent</artifactId> <version>3.6.3</version> </parent> <properties> <packaging>jar</packaging> <jdk.version>17</jdk.version> <release.version>17</release.version> <micronaut.version>3.6.3</micronaut.version> <micronaut.runtime>undertow</micronaut.runtime> <exec.mainClass>com.example.Application</exec.mainClass> </properties> <repositories> <repository> <id>central</id> <url>https://repo.maven.apache.org/maven2</url> </repository> </repositories> <dependencies> <dependency> <groupId>io.micronaut</groupId> <artifactId>micronaut-inject</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>io.micronaut</groupId> <artifactId>micronaut-validation</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-api</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter-engine</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.micronaut.test</groupId> <artifactId>micronaut-test-junit5</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>io.micronaut</groupId> <artifactId>micronaut-http-client</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>io.micronaut</groupId> <artifactId>micronaut-jackson-databind</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>io.micronaut.servlet</groupId> <artifactId>micronaut-http-server-undertow</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>jakarta.annotation</groupId> <artifactId>jakarta.annotation-api</artifactId> <scope>compile</scope> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <scope>runtime</scope> </dependency> <!-- https://mvnrepository.com/artifact/org.graalvm.truffle/truffle-api --> <dependency> <groupId>org.graalvm.truffle</groupId> <artifactId>truffle-api</artifactId> <version>22.2.0</version> </dependency> <dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.6</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>io.micronaut.build</groupId> <artifactId>micronaut-maven-plugin</artifactId> </plugin> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <!-- Uncomment to enable incremental compilation --> <!-- <useIncrementalCompilation>false</useIncrementalCompilation> --> <annotationProcessorPaths combine.children="append"> <path> <groupId>io.micronaut</groupId> <artifactId>micronaut-http-validation</artifactId> <version>${micronaut.version}</version> </path> </annotationProcessorPaths> <compilerArgs> <arg>-Amicronaut.processing.group=com.example</arg> <arg>-Amicronaut.processing.module=micronaut-demo</arg> </compilerArgs> </configuration> </plugin> </plugins> </build> </project>
这个错误源于Undertow版本与GraalVM Native Image的兼容性问题,或是FastConcurrentDirectDeque的无参构造函数未被Native Image正确识别并包含。可通过以下方式解决:
显式指定兼容的Undertow版本:在POM的
<properties>中添加与Micronaut 3.6.3适配的Undertow版本,比如2.2.20.Final,确保版本兼容性:<properties> <!-- 保留原有属性 --> <undertow.version>2.2.20.Final</undertow.version> </properties>添加Native Image反射配置:创建
src/main/resources/META-INF/native-image/io.undertow/undertow/reflection-config.json文件,显式声明FastConcurrentDirectDeque的构造函数,让Native Image编译时包含该类:[ { "name": "io.undertow.util.FastConcurrentDirectDeque", "allDeclaredConstructors": true } ]移除不必要的依赖:如果项目未使用Truffle相关功能,可移除
truffle-api依赖,避免潜在的版本冲突干扰Native Image构建。升级Micronaut版本:考虑将Micronaut升级至3.9.x及以上版本,新版本通常修复了更多Native Image与Undertow的兼容性问题,且默认使用更适配的Undertow版本。
内容的提问来源于stack exchange,提问作者rainbowecho

