feature: add GraalVM native image build support for seata-server#8162
Open
xuxiaowei-com-cn wants to merge 65 commits into
Open
feature: add GraalVM native image build support for seata-server#8162xuxiaowei-com-cn wants to merge 65 commits into
xuxiaowei-com-cn wants to merge 65 commits into
Conversation
- Add native-maven-plugin version management in build/pom.xml - Add native and nativeTest profiles in server/pom.xml for GraalVM AOT compilation - Add Makefile targets: package-server-native, package-server-native-pre, package-server-native-only
…5.5.0 in native workflow 1. actions/setup-java@v3.12.0: No supported distribution was found for input graalvm 2. Node.js 20 is deprecated. The following actions target Node.js 20 but are being forced to run on Node.js 24: actions/checkout@v3, actions/setup-java@v3.12.0. For more information see: https://github.blog/changelog/2025-09-19-deprecation-of-node-20-on-github-actions-runners/
…ing" This reverts commit 08341c1.
- Add ubuntu-latest-arm to native build matrix alongside ubuntu-latest - Update step names to include OS identifier for clarity - Add -am flag to Makefile package-server-native-pre target to also build server module dependencies
…runners Add matrix.os to concurrency group and cancel-in-progress to avoid ubuntu-latest and ubuntu-latest-arm builds cancelling each other.
…rent OS runners" This reverts commit d5fbf67.
Comment out concurrency group and cancel-in-progress to avoid interference between multiple native build workflow runs.
This reverts commit 0e8c990.
Replace ubuntu-latest with ubuntu-24.04 for more reproducible builds.
Add macos-26-intel, macos-26-large, and windows-latest to the native build CI matrix alongside existing Linux runners.
…ve profiles Add --initialize-at-run-time=io.netty.channel.kqueue to both native and nativeTest profiles to fix GraalVM native image issues related to Netty's kqueue transport on non-macOS platforms.
- Add OS/arch-specific Maven profiles (linux-amd64, linux-arm64, darwin-amd64,
darwin-arm64, windows-amd64) to set native.platform property
- Configure native-maven-plugin imageName to
seata-server-{version}-{platform}, e.g. seata-server-2.8.0-SNAPSHOT-linux-amd64
- Add upload-artifact step to native CI workflow
- Exclude .jar files from uploads to only ship the native binary
…server $GRAALVM_HOME/bin/java -agentlib:native-image-agent=config-output-dir=./target/native-image-config -jar ./server/target/seata-server.jar
- reflect-config.json: rename 'type' to 'name' key per GraalVM 25 schema - reflect-config.json: remove deprecated 'jniAccessible' attribute - reflect-config.json: extract proxy entries to separate proxy-config.json - resource-config.json: convert array to object format with 'resources.includes' - resource-config.json: rename 'glob' to 'pattern' key - server/pom.xml: add --initialize-at-build-time=com.alibaba.fastjson2
…er directory for GraalVM 25 compatibility
Add Spotless Jackson JSON formatter in pom.xml and reformat proxy-config.json, reflect-config.json, resource-config.json
Add constructor and method entries for Apollo config classes (ConfigPropertySourceFactory, PlaceholderHelper, SpringValueRegistry), Iterable.iterator(), Iterator.hasNext()/next(), and comprehensive StringBuilder methods to ensure proper reflection access in native image.
…H_DIR logic Remove the if/else branch that switched between resource and file includes based on LOG_BASH_DIR property. Unify to always use resource includes. Also remove conditional appender-refs for logstash, kafka, and metric appenders, replacing them with comments. logback-spring.xml: remove <if> conditionals that require janino runtime compilation (not supported in native image)
…o build/pom.xml Move the fallback native.platform property to the build module POM, keeping it alongside the native-maven-plugin version definition for better co-location of native-image build configuration.
…che#8162) Add PR apache#8162 to the 2.x changelog under the feature section in both English and Chinese versions.
Contributor
Author
|
WIP /cc @funky-eyes |
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 2.x #8162 +/- ##
============================================
+ Coverage 72.79% 72.83% +0.03%
Complexity 1141 1141
============================================
Files 1151 1151
Lines 42272 42272
Branches 5045 5045
============================================
+ Hits 30773 30789 +16
+ Misses 9023 9009 -14
+ Partials 2476 2474 -2
🚀 New features to boost your workflow:
|
…le documentation - Add package-server-native-metadata-file / package-server-native-metadata-file-only targets in Makefile for collecting GraalVM native-image reflection/proxy/resource metadata - Add release-seata-jar Maven profile (simplified repackage without ZIP layout and classifier, suitable for native-image agent metadata collection) - Add detailed comments for Makefile variables, .PHONY declarations, and Maven args - Fix indentation consistency in .PHONY target list
- Add reflection entries for Nacos client (config, naming, remote APIs), gRPC/Netty shaded classes, Spring Boot config classes, and more - Add resource patterns for SPI service files, Nacos API packages, and nacos configuration files - Add missing methods and fields for existing reflect entries
- reflect-config: add java.nio.Bits.UNALIGNED field, Nacos shaded Netty classes (AbstractByteBufAllocator, UnpooledByteBufAllocator, ReferenceCountUtil, ResourceLeakDetector, AbstractChannel, AbstractChannelHandlerContext, DefaultChannelPipeline) - reflect-config: add Nacos naming remote request/response classes (BatchInstanceRequest, PersistentInstanceRequest, BatchInstanceResponse) - reflect-config: add Nacos remote SetupAckRequest/SetupAckResponse - reflect-config: add Seata serializer classes (Serializer, SeataSerializer, SeataSerializerV0, SeataSerializerV1) - resource-config: add Seata SPI services (Serializer, DistributedLocker, DataSourceProvider, RateLimiter) - resource-config: add Nacos SPI services (Payload, ServerListProvider, FailoverDataSource, AbstractAbilityControlManager, LabelsCollector, NacosLoggingAdapter, NacosLoggingAdapterBuilder, AbstractParamChecker, PathEncoder, AbstractClientAuthService, ServerProvider)
…nary - Add test job that downloads and verifies the native binary across all platforms - Verify native binary starts successfully with PID liveness check - Add separate port 8091 listening check step using ss/netstat - Clean up native process after verification - Update upload artifact path pattern from seata-server-* to seata-*-*
- Remove single-value java matrix, hardcode java-version to 25 - Add type matrix to test job for future extensibility - Add conditional if on verify step based on matrix.type
- Move native binary verification and port 8091 check from separate test job into build job - Remove chmod, file, and kill commands - Reorder delete snapshots and save cache steps after verification
- Replace runner.temp with worktree-relative pid file path to avoid Windows backslash escaping issues in shell - Replace ss/netstat/lsof with curl-based HTTP health check for cross-platform port verification on Windows/macOS/Linux - Add retry loop (6x5s) to allow native image sufficient startup time
Root path returns 404, causing curl to fail. Use /health endpoint which returns 200 ok.
Add a new test-suite/test-native module containing: - Spring Boot application with early database initialization - Entity classes (Account, Order, Storage, UndoLog) - DAO layer (AccountDAO, OrderDAO, StorageDAO, UndoLogDAO) - Service layer with AT mode business logic - Integration tests (DataSourceProxyModeAtTests, SeataTestNativeApplicationTests) - SQL schema and test data setup Also update native workflow, Makefile, and POM files to include the new module in the build.
… prevent UnsupportedFeatureError on shutdown
- Add REST controllers (Account, Order, Storage, Seata) and DTOs for test-native module - Replace DataSourceProxyModeAtTests with focused service/controller test classes - Add test-native app startup step in native build CI workflow - Add GraalVM native-image agent config generation to Makefile
- Add Apache License 2.0 headers to all test-native Java source files - Restrict native.yml 'Start test-native app' step to Linux only - Remove unused imports, Logger fields, and unused injected dependencies in service implementations
This reverts commit 122068f.
…tting - Remove unused test data (U002, U003 accounts; C001, C002 storage) - Update all test references from U003 to U001 - Adjust U001 initial balance from 10000 to 100 - Clean up empty lines in BusinessServiceImpl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Ⅰ. Describe what this PR did
This PR adds GraalVM Native Image packaging support to the Seata Server, enabling users to build and deploy the Seata Server as a self-contained native binary with sub-second startup time, lower memory footprint, and no JDK dependency at runtime.
Changes Overview (14 files, +3636 / −105)
1. GraalVM Native Image Build Profiles (
server/pom.xml)nativeMaven profile that configuresspring-boot-maven-plugin(AOT processing) andnative-maven-plugin(GraalVM native image compilation).nativeTestprofile for AOT-based native testing withjunit-platform-launcher.native-linux-amd64,native-linux-aarch64,native-darwin-x86_64,native-darwin-aarch64,native-windows-amd64) that set thenative.platformclassifier were later promoted to the rootpom.xmlso the property is available to all submodules.logback,slf4j,fastjson2and run-time initialization fornetty.channel.kqueue.mainClasstoorg.apache.seata.server.ServerApplication.Spring-Boot-Native-Processed: truemanifest entry.spring-boot-devtoolsfrom native compilation.2. GraalVM Reachability Metadata (3 new config files)
reflect-config.json(~2801 lines) — registers classes, methods, and fields for reflective access at native image build time, covering Seata's core components (serializers, codecs, RPC handlers, store managers, configuration providers, discovery providers, etc.).resource-config.json(~463 lines) — registers resource bundles and configuration files (Spring factories, SPI service descriptors, SQL scripts, configuration templates) for inclusion in the native image.proxy-config.json— registers dynamic proxy interfaces used by Seata (e.g., Spring AOP proxies, configuration binding interfaces).All metadata files are placed under
META-INF/native-image/org.apache.seata/seata-server/for GraalVM 25 compatibility.3. CI/CD: Multi-Platform Native Build Workflow (
.github/workflows/native.yml)Native Build) that builds GraalVM native images for the Seata Server across 5 platforms:ubuntu-24.04(amd64),ubuntu-24.04-arm(arm64),macos-26-intel(x86_64),macos-26(apple silicon),windows-latest(amd64).actions/setup-java@v5.5.0.actions/cache/restore@v4/actions/cache/save@v4) with SNAPSHOT cleanup.actions/upload-artifact@v7.0.1.2.x,develop,masterbranches (ignores markdown-only changes).4. logback-spring.xml Simplification (GraalVM Compatibility)
<if>conditional logic (e.g.,<if condition='property("LOGSTASH_APPENDER_ENABLED").equals("true")'>) because Janino's dynamic bytecode compilation is not supported in GraalVM native images.console-appenderandfile-appenderby default.LOG_BASH_DIRexternal directory path logic.<appender-ref>elements — these are documented with inline comments.5. Spring AOT Compatibility:
@Resource→@AutowiredSetter InjectionAbstractSeataInstanceStrategy: Replaced@Resourcefield injection with@Autowiredsetter-based injection forregistryProperties,serverProperties, andregistryNamingServerProperties. RemovedApplicationContextdependency and@PostConstructinitialization — properties are now injected directly via setters, which is compatible with Spring AOT's closed-world analysis.ServerInstanceStrategyConfig: ChangedseataInstanceStrategy()bean method to accept dependencies via constructor parameters and pass them to the strategy via setters, eliminating the implicitApplicationContext.getBean()lookup.SpringBootConfigurationProvider: Adjusted for AOT compatibility.6. Build Infrastructure (
build/pom.xml, rootpom.xml,Makefile)build/pom.xml:native-maven-pluginversion (1.1.3) topluginManagement.native.platformproperty (promoted fromserver/pom.xml) so it is available to all submodules for GraalVM native-image builds.pom.xml:native-linux-*,native-darwin-*,native-windows-*) — promoted fromserver/pom.xmlso thenative.platformproperty is available to all submodules for GraalVM native-image builds.Makefile:package-server-native-pre,package-server-native,package-server-native-onlytargets for building native images.spotless-checkandspotless-applytargets.-eflag to all Maven commands for consistent error output.7. Dependency Update
zstd-jnifrom1.5.0-4to1.5.7-3(dependencies/pom.xml).8. Test Adjustment
AppenderTest(@Disabled) due to the logback configuration simplification that removed Janino-based conditional appender logic.Usage
Regenerate GraalVM Reachability Metadata (e.g., after adding new components that use reflection):
Run the Seata Server with the Native Image Agent to generate metadata into a temporary directory:
Update the generated metadata into the project resource directory:
server/src/main/resources/META-INF/native-image/org.apache.seata/seata-server/Compile the Native Image
Build the Native Image:
Run the native binary (no JDK required):
./server/target/seata-server-{version}-{platform}Ⅱ. Does this pull request fix one issue?
#8161
This PR implements the feature proposal described in issue #8137 (Spring Boot 4 upgrade) follow-up — adding GraalVM Native Image support to the Seata Server for improved deployment efficiency and cloud-native compatibility.
Ⅲ. Why don't you add test cases (unit test/integration test)?
native.yml) builds native binaries on 5 platforms on every PR/push, and a successful native image compilation validates the GraalVM reachability metadata and AOT compatibility.AppenderTesthas been disabled because it tested Janino<if>conditional logic inlogback-spring.xml, which was removed for GraalVM compatibility. The logback appender behavior (console, file) is implicitly verified by the native image build succeeding and the server starting correctly.nativeTestMaven profile is provided for future AOT-based native testing usingjunit-platform-launcher.Config Mode Tests
filenacosconsulapollozketcd3Registry Mode Tests
filenacoseurekarediszkconsuletcd3sofaseataStore Mode Tests
filedbredisraftTest Plan for Each Mode
Each mode test should verify:
ClassNotFoundException,NoSuchMethodException, or reflection errors at runtime for the mode-specific components.Ⅳ. Describe how to verify it
Option 1: Local verification (requires GraalVM JDK 25)
Expected: The Seata Server starts in milliseconds (vs. seconds in JVM mode) and is ready to accept transactions.
Option 2: CI verification
Check the
Native Buildworkflow results on this PR — it builds native images on ubuntu-24.04 (amd64), ubuntu-24.04-arm (arm64), macos-26-intel, macos-26 (apple silicon), and windows-latest.Ⅴ. Special notes for reviews
GraalVM reachability metadata (
reflect-config.json,resource-config.json,proxy-config.json): These files were generated through iterative native image builds and testing. They register all classes, methods, resources, and proxies that Seata accesses via reflection at runtime. Reviewers should focus on whether any critical Seata components are missing from these configs.Injection style change:
@Resourcefield injection was replaced with@Autowiredsetter/constructor injection inAbstractSeataInstanceStrategyandServerInstanceStrategyConfig. This is required because Spring AOT's closed-world analysis cannot resolve@Resource-injected fields during native compilation. The runtime behavior is identical.logback-spring.xml breaking change: The removal of Janino
<if>conditions means thatLOGSTASH_APPENDER_ENABLED,KAFKA_APPENDER_ENABLED, andMETRIC_APPENDER_ENABLEDproperties no longer dynamically control appender inclusion at runtime. Users who need these appenders must manually uncomment the corresponding<appender-ref>elements inlogback-spring.xml. This is a known limitation of GraalVM native images (no runtime bytecode generation). A follow-up PR could add programmatic appender registration via Spring's@Conditionalbeans.Phased approach: This PR focuses on Phase 1 — basic server startup, configuration loading, and core transaction coordination in native mode. Full feature parity with JVM mode (all serializers, all store modes, all discovery modes) will be addressed in follow-up PRs as testing coverage expands.
PGO (Profile-Guided Optimization): Not included in this PR. Can be added later to further improve native image runtime performance.