apache / apache/incubator-seata
[Feature] Provide GraalVM Native Image packaging for Seata Server
- Dominant language
- Java
- Stars
- 26k
- Forks
- 8.8k
- Avg merge
- 1d 8h
- Merged PRs (30d)
- 4
Description
### Check Ahead
- [x] I have searched the [issues](https://github.com/seata/seata/issues) of this repository and believe that this is not a duplicate.
- [x] I am willing to try to implement this feature myself.
### Why you need it?
### Background
The Seata Server has been upgraded to **Spring Boot 4.0.6** (see #8137), which is built on **Spring Framework 7.0.7**. As a result, the server module now requires **JDK 17+** (previously JDK 8). This JDK version jump introduces a deployment friction: users must ensure the target environment has the correct JDK version installed.
### Problem
1. **JDK dependency management burden**: Currently, users who deploy the Seata Server need to manually install and manage JDK 17+ on their servers or container images. This adds complexity to deployment and operation, especially in environments where multiple Java applications with different JDK requirements coexist.
2. **Startup time and resource footprint**: The standard JVM-based Seata Server has non-trivial startup time and memory overhead. For cloud-native and serverless scenarios (e.g., Kubernetes pods scaling up rapidly), faster startup and lower memory consumption are highly desirable.
3. **Spring Boot 4 already supports it**: Spring Boot 4 (via Spring Framework 7) provides first-class **AOT (Ahead-of-Time) compilation** and **GraalVM Native Image** support out of the box. The `spring-boot-maven-plugin` can produce native executables with minimal configuration. However, Seata Server currently does not leverage this capability.
### Benefits of Native Image
| Aspect | JVM Mode | Native Image Mode |
|----------------------|-------------------------|-----------------------------------------|
| JDK requirement | Must install JDK 17+ | Self-contained binary, no JDK needed |
| Startup time | Seconds (JVM warmup) | Milliseconds to sub-second |
| Memory footprint | Higher (JVM overhead) | Lower (no JVM, no class metadata) |
| Container image size | Larger (JDK base image) | Smaller (`distroless` / `scratch` base) |
| Deployment | Requires Java runtime | Single static binary |
### How it could be?
### Proposal: Add GraalVM Native Image packaging support to `seata-server`
Add a Maven profile (e.g., `native`) to the `server/pom.xml` that uses `spring-boot-maven-plugin` with the `native` classifier (or the `native-maven-plugin`) to produce a GraalVM native executable of the Seata Server.
#### High-level Steps
1. **Add AOT/Native build configuration** to `server/pom.xml`:
- Introduce a `native` Maven profile that triggers GraalVM native image compilation via `spring-boot-maven-plugin`'s `process-aot` goal and GraalVM's `native-maven-plugin`.
- Configure native image build args (e.g., `--enable-url-protocols=http`, `--add-opens` for reflection-heavy libraries).
2. **Provide GraalVM reachability metadata** (if needed):
- Some Seata components (e.g., Netty, Kryo serializer, dynamic proxies, reflection-based config loading) may require explicit GraalVM `reflect-config.json`, `resource-config.json`, or `proxy-config.json`.
- Spring Boot 4's AOT engine can auto-generate most of these, but manual hints may be required for non-Spring-managed components.
3. **Container image integration** (optional but recommended):
- Extend the existing `jib-maven-plugin` configuration (or add a `Dockerfile.native`) to build a minimal container image containing only the native binary (e.g., based on `gcr.io/distroless/cc-debian12` or `scratch`).
4. **CI/CD and distribution**:
- Add a CI job to build and publish native binaries as release artifacts (e.g., `seata-server-{version}-linux-amd64`, `seata-server-{version}-linux-arm64`).
- Optionally publish native container images (e.g., `apache/seata-server:{version}-native`).
#### Example Pseudo-configuration
```xml
com.diffplug.spotless
spotless-maven-plugin
${spotless-maven-plugin.version}
src/main/resources/META-INF/native-image/${project.groupId}/${project.artifactId}/*.json
```
```xml
1.1.3
org.graalvm.buildtools
native-maven-plugin
${native-maven-plugin.version}
```
```xml
native-linux-amd64
linux
amd64
linux-amd64
native-linux-aarch64
linux
aarch64
linux-arm64
native-darwin-x86_64
mac os x
x86_64
darwin-amd64
native-darwin-aarch64
mac os x
aarch64
darwin-arm64
native-windows-amd64
windows
amd64
windows-amd64
native
org.apache.maven.plugins
maven-jar-plugin
true
org.springframework.boot
spring-boot-maven-plugin
org.apache.seata.server.ServerApplication
process-aot
process-aot
org.graalvm.buildtools
native-maven-plugin
org.apache.seata.server.ServerApplication
${project.build.outputDirectory}
${project.artifactId}-${project.version}-${native.platform}
true
--enable-url-protocols=http
-H:+ReportExceptionStackTraces
org.springframework.boot
spring-boot-devtools
add-reachability-metadata
add-reachability-metadata
nativeTest
org.junit.platform
junit-platform-launcher
test
org.springframework.boot
spring-boot-maven-plugin
org.apache.seata.server.ServerApplication
process-test-aot
process-test-aot
org.graalvm.buildtools
native-maven-plugin
${project.build.outputDirectory}
org.apache.seata.server.ServerApplication
${project.artifactId}-${project.version}-${native.platform}
true
--enable-url-protocols=http
-H:+ReportExceptionStackTraces
${project.build.outputDirectory}
org.springframework.boot
spring-boot-devtools
native-test
test
```
Users would then build the native image with:
```bash
mvn clean package -Pnative -pl server
```
And run it directly without a JDK:
```bash
./seata-server/target/seata-server
```
### Other related information
### Compatibility Considerations
1. **Reflection-heavy libraries** that Seata depends on may need special handling in native mode:
- **Netty** (used for RPC communication): Netty has existing GraalVM metadata. Spring Boot 4 should handle this via its reachability metadata repository.
- **Kryo / other serializers**: Serialization frameworks often rely on reflection. AOT hints or `@RegisterReflectionForBinding` may be required.
- **Dynamic proxies** (e.g., `java.lang.reflect.Proxy`): Seata's configuration binding and interceptor chains may use proxies.
- **JCommander**: Command-line argument parsing may need reflection config.
2. **Profile-guided optimization (PGO)** can be added later to further improve native image performance.
3. **Not all features need to work in native mode initially** — a phased approach is acceptable:
- Phase 1: Basic server startup, configuration loading, and core transaction coordination in native mode.
- Phase 2: Full feature parity with JVM mode (all serializers, all store modes, all discovery modes).
### Related Links
- [Introducing GraalVM Native Images](https://docs.spring.io/spring-boot/reference/packaging/native-image/introducing-graalvm-native-images.html)
- [GraalVM Native Image Documentation](https://www.graalvm.org/latest/reference-manual/native-image/)
- [GraalVM Reachability Metadata Repository](https://github.com/oracle/graalvm-reachability-metadata)
- PR #8137: Spring Boot 4 upgrade for server
Contributor guide
Research direction
Start with server/pom.xml and build/pom.xml, then inspect the ServerApplication entry point and the existing packaging configuration. Check how the proposed native and nativeTest profiles interact with AOT processing, reachability metadata, container packaging, and CI/CD. Done means the server builds and tests as a native executable for the supported platforms and produces the intended distribution artifacts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, java, spring-boot
- Domain
- backend, build-system, ci-cd, devops
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 25/100