Quarkus Java 原生编译
bash java -version
输出应包含 `GraalVM` 字样。
4. 安装 `native-image` 组件:
```bash
gu install native-image
验证:
native-image --version
配置 Maven 或 Gradle
Quarkus 提供了扩展插件来简化原生编译流程。对于 Maven,可以在 pom.xml 中引入 quarkus-maven-plugin,并确保配置了 native 构建配置。Quarkus 项目通常使用 quarkus-universe-bom 或 quarkus-bom 来管理依赖。
如果你使用 Gradle,则应用 io.quarkus 插件并配置 quarkusBuild 任务中的 native 参数。
本地开发的可能依赖
- 在 Linux 上,
native-image需要glibc、gcc、zlib等开发包。可运行:
或对应包管理工具安装。dnf install gcc glibc-devel zlib-devel libstdc++-static - 在 macOS 上需要 Xcode 命令行工具。
- Windows 目前需要通过 Windows Subsystem for Linux (WSL 2) 或使用 Docker 来构建原生镜像,因为原生编译在 Windows 上的原生支持有限。
创建 Quarkus 项目
使用 Quarkus CLI 或 Maven 原型快速生成项目。
使用 Maven 命令
mvn io.quarkus.platform:quarkus-maven-plugin:3.8.0:create \
-DprojectGroupId=com.example \
-DprojectArtifactId=hello-native \
-DclassName="com.example.GreetingResource" \
-Dpath="/hello"
cd hello-native
这会生成一个简单的 REST 项目,你可以直接导入 IDE。
检查依赖和配置
生成的 pom.xml 已经包含 Quarkus 依赖。如需添加原生编译支持,确保存在以下插件:
<plugin>
<groupId>${quarkus.platform.group-id}</groupId>
<artifactId>quarkus-maven-plugin</artifactId>
<version>${quarkus.platform.version}</version>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>build</goal>
<goal>generate-code</goal>
<goal>generate-code-tests</goal>
</goals>
</execution>
</executions>
</plugin>
extensions 为 true 时会启用原生镜像配置。
构建原生可执行文件
进入项目目录,用 Maven 命令构建原生镜像。
执行 Maven 构建
./mvnw package -Pnative
此命令会触发 native-image 构建过程。首次构建会下载必要组件并进行分析,过程可能持续几分钟。构建完成后,在 target/ 目录下会生成一个名为 hello-native-1.0.0-SNAPSHOT-runner 的可执行文件(名称取决于 ArtifactId 和版本)。
跳过测试加快构建
添加 -DskipTests 可跳过测试阶段:
./mvnw package -Pnative -DskipTests
运行原生镜像
./target/hello-native-1.0.0-SNAPSHOT-runner
你会看到 Quarkus 应用在几十到几百毫秒内启动,并监听 8080 端口。访问 http://localhost:8080/hello 即可得到响应。
使用 Gradle 构建原生镜像
如果使用 Gradle,执行:
./gradlew build -Dquarkus.package.type=native
或使用 quarkusBuild 任务并指定 --native:
./gradlew build -Dquarkus.native.enabled=true
处理构建时的常见问题
原生编译过程中,由于灰度分析(closed-world analysis)仅限于可达代码,一些反射、资源、动态代理等 JVM 特性需要显式配置,否则会引发 UnsupportedFeatureError 或 ClassNotFoundException。
注册反射类
在 Quarkus 中使用 @RegisterForReflection 注解或通过 application.properties 进行配置。
例:对于 JSON 序列化可能需要的反射类:
@RegisterForReflection(targets = {MyDTO.class, AnotherDTO.class})
public class MyReflectionConfiguration {
}
或者通过配置文件:
quarkus.native.additional-build-args=-H:ReflectionConfigurationFiles=reflection-config.json
然后创建 reflection-config.json 文件,列出需要反射的类和方法。
包含资源文件
如果代码中通过 ClassLoader.getResource() 访问资源,需要在 application.properties 中声明:
quarkus.native.resources.includes=public/**/*.*,templates/**
处理动态代理
Quarkus 会自动检测 REST Client 或其他扩展所需的动态代理。如果使用了自定义接口代理,可配置:
quarkus.native.additional-build-args=--add-exports=<module>/<package>=ALL-UNNAMED
但通常不需要手动配置,多数扩展已经集成。
调试原生镜像
若构建失败,可启用详细日志:
./mvnw package -Pnative -Dnative-image.debug=true
查看 target/native-image-build-output.log 获取详尽信息。
容器化原生镜像
原生可执行文件非常适合制作轻量级 Docker 镜像。你可以使用 scratch 或 distroless 基础镜像,因为它们只包含二进制文件即可运行。
手动编写 Dockerfile
FROM registry.access.redhat.com/ubi8/ubi-minimal:8.9
WORKDIR /work/
COPY target/*-runner /work/application
RUN chmod 775 /work/application
EXPOSE 8080
CMD ["./application", "-Dquarkus.http.host=0.0.0.0"]
构建并运行:
docker build -f src/main/docker/Dockerfile.native -t quarkus/hello-native .
docker run -i --rm -p 8080:8080 quarkus/hello-native