This file provides comprehensive guidance to AI coding agents when working with the Apache Fory codebase.
While working on Fory, please remember:
fory codegen to generate the serializer when building graalvm native image, do not use graallvm reflect-related configuration unless for JDK proxy.java directory.java must pass the code style check and tests.17+ installed.# Clean the build mvn -T16 clean # Build mvn -T16 package # Install mvn -T16 install -DskipTests # Code format check mvn -T16 spotless:check # Code format mvn -T16 spotless:apply # Code style check mvn -T16 checkstyle:check # Run tests mvn -T16 test # Run specific tests mvn -T16 test -Dtest=org.apache.fory.TestClass#testMethod
cpp directory.clang-format to update the codeResult, always use FORY_TRY unless in a control flow context.FORY_PREDICT_FALSE for branch prediction optimization.# Build C++ library bazel build //cpp/... # Build Cython extensions (replace X.Y with your Python version, e.g., 3.10) bazel build //:cp_fory_so --@rules_python//python/config_settings:python_version=X.Y # Run tests bazel test $(bazel query //cpp/...) # Run serialization tests bazel test $(bazel query //cpp/fory/serialization/...) # Run specific test bazel test //cpp/fory/util:buffer_test # format c++ code clang-format -i $file
Run C++ xlang tests:
cd java mvn -T16 install -DskipTests cd fory-core FORY_CPP_JAVA_CI=1 ENABLE_FORY_DEBUG_OUTPUT=1 mvn -T16 test -Dtest=org.apache.fory.xlang.CPPXlangTest
python directory.python must pass the code style check and tests.ENABLE_FORY_CYTHON_SERIALIZATION environment variable to enable or disable cython serialization.ENABLE_FORY_CYTHON_SERIALIZATION=0 first to verify the behavior.3.8+ installed although some modules such as fory-core use java8.# clean build rm -rf build dist .pytest_cache bazel clean --expunge # Code format ruff format . ruff check --fix . # Install pip install -v -e . # Build native extension when cython code changed (replace X.Y with your Python version) bazel build //:cp_fory_so --@rules_python//python/config_settings:python_version=X.Y --config=x86_64 # For x86_64 bazel build //:cp_fory_so --@rules_python//python/config_settings:python_version=X.Y --copt=-fsigned-char # For arm64 and aarch64 # Run tests without cython ENABLE_FORY_CYTHON_SERIALIZATION=0 pytest -v -s . # Run tests with cython ENABLE_FORY_CYTHON_SERIALIZATION=1 pytest -v -s .
Run Python xlang tests:
cd java mvn -T16 install -DskipTests cd fory-core # disable fory cython for faster debugging FORY_PYTHON_JAVA_CI=1 ENABLE_FORY_CYTHON_SERIALIZATION=0 mvn -T16 test -Dtest=org.apache.fory.xlang.PythonXlangTest # enable fory cython FORY_PYTHON_JAVA_CI=1 ENABLE_FORY_CYTHON_SERIALIZATION=1 ENABLE_FORY_DEBUG_OUTPUT=1 mvn -T16 test -Dtest=org.apache.fory.xlang.PythonXlangTest
go/fory directory.go must pass the format check and tests.# Format code go fmt ./... # Run tests go test -v ./... # Run tests with race detection go test -race -v ./... # Build go build # Generate code (if using go:generate) go generate ./...
Run Go xlang tests:
cd java mvn -T16 install -DskipTests cd fory-core FORY_GO_JAVA_CI=1 ENABLE_FORY_DEBUG_OUTPUT=1 mvn test -Dtest=org.apache.fory.xlang.GoXlangTest
rust directory.rust must pass the clippy check and tests.RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 when debuging rust tests to get backtrace.-- --nocapture to cargo test command when debuging tests.FORY_PANIC_ON_ERROR=1 when runing all rust tests to check whether all tests pass, some tests will check Error content, which will fail if error just panic.# Check code cargo check # Build cargo build # Run linter for all services. cargo clippy --all-targets --all-features -- -D warnings # Run tests (requires test features) cargo test --features tests # run specific test cargo test -p tests --test $test_file $test_method # run specific test under subdirectory cargo test --test mod $dir$::$test_file::$test_method # debug specific test under subdirectory and get backtrace RUST_BACKTRACE=1 FORY_PANIC_ON_ERROR=1 ENABLE_FORY_DEBUG_OUTPUT=1 cargo test --test mod $dir$::$test_file::$test_method -- --nocapture # inspect generated code by fory derive macro cargo expand --test mod $mod$::$file$ > expanded.rs # Format code cargo fmt # Check formatting cargo fmt --check # Build documentation cargo doc --lib --no-deps --all-features # Run benchmarks cd $project_dir/benchmarks/rust_benchmark cargo bench
Run Rust xlang tests:
cd java mvn -T16 install -DskipTests cd fory-core FORY_RUST_JAVA_CI=1 ENABLE_FORY_DEBUG_OUTPUT=1 mvn test -Dtest=org.apache.fory.xlang.RustXlangTest
javascript directory.# Install dependencies npm install # Run tests node ./node_modules/.bin/jest --ci --reporters=default --reporters=jest-junit # Format code git ls-files -- '*.ts' | xargs -P 5 node ./node_modules/.bin/eslint
dart directory.# First, generate necessary code dart run build_runner build # Run all tests dart test # Format code dart analyze dart fix --dry-run dart fix --apply
kotlin directory.cd ../java && mvn -T16 install -DskipTests. If no code changes after installed fory java, you can skip the installation step.# Build mvn clean package # Run tests mvn test
scala directory.cd ../java && mvn -T16 install -DskipTests. If no code changes after installed fory java, you can skip the installation step.# Build with sbt sbt compile # Run tests sbt test # Format code sbt scalafmt
integration_tests directory.cd ../java && mvn -T16 install -DskipTests. If no code changes after installed fory java, you can skip the installation step.it_dir=$(pwd) # Run graalvm tests cd $it_dir/graalvm_tests && mvn -T16 -DskipTests=true -Pnative package && target/main # Run latest_jdk_tests cd $it_dir/latest_jdk_tests && mvn -T16 test # Run JDK compatibility tests cd $it_dir/jdk_compatibility_tests && mvn -T16 test # Run JPMS tests cd $it_dir/jpms_tests && mvn -T16 test # Run Python benchmarks cd $it_dir/cpython_benchmark && pip install -r requirements.txt && python benchmark.py
prettier --write $file to format.docs/.docs/specification/** contains Fory protocol specifications. Read these documents carefully before making protocol changes.docs/guide/** contains user guides for different features and languages.Apache Fory is an open-source project hosted on GitHub. The git repository for Apache Fory is https://github.com/apache/fory . Contributors always fork the repository and create a pull request to propose changes. The origin points to forked repository instead of the official repository.
docs/: Documentation, specifications, and guides
docs/specification/: Protocol specifications (critical for understanding)docs/guide/: User guides and development guidesdocs/benchmarks/: Performance benchmarks documentationLanguage Implementations:
java/: Java implementation (maven-based, multi-module)python/: Python implementation (pip/setuptools + bazel)cpp/: C++ implementation (bazel-based)go/: Go implementation (go modules)rust/: Rust implementation (cargo-based)javascript/: JavaScript/TypeScript implementation (npm-based)dart/: Dart implementation (pub-based)kotlin/: Kotlin implementation (maven-based)scala/: Scala implementation (sbt-based)Testing and CI:
integration_tests/: Cross-language integration tests.github/workflows/: GitHub Actions CI/CD workflowsci/: CI scripts and configurationsBuild Configuration:
BUILD, WORKSPACE: Bazel configuration.bazelrc, .bazelversion: Bazel settingspom.xml, package.json, Cargo.toml, etc.AGENTS.md: This file - AI coding guidanceCLAUDE.md: Claude Code specific instructionsCONTRIBUTING.md: Contribution guidelinesREADME.md: Project overview and quick start.gitignore: Git ignore patterns (includes build dirs)licenserc.toml: License header configurationApache Fory is a blazingly-fast multi-language serialization framework that revolutionizes data exchange between systems and languages. By leveraging JIT compilation, code generation and zero-copy techniques, Fory delivers up to 170x faster performance compared to other serialization frameworks while being extremely easy to use.
Fory uses binary protocols for efficient serialization and deserialization. Fory designed and implemented multiple binary protocols for different scenarios:
**docs/specification/** are the specification for the Fory protocol, please read those documents carefully and think hard and make sure you understand them before making changes to code and documentation.
Fory serialization for every language is implemented independently to minimize the object memory layout interoperability, object allocation, memory access cost, thus maximize the performance. There is no code reuse between languages except for fory python, which reused code from fory c++.
fory-core: Java library implementing the core object graph serialization
java/fory-core/src/main/java/org/apache/fory/Fory.java: main serialization entry pointjava/fory-core/src/main/java/org/apache/fory/resolver/TypeResolver.java: type resolution and serializer dispatchjava/fory-core/src/main/java/org/apache/fory/resolver/RefResolver.java: class for resolving shared/circular references when ref tracking is enabledjava/fory-core/src/main/java/org/apache/fory/serializer: serializers for each supported typejava/fory-core/src/main/java/org/apache/fory/codegen: code generators, provide expression abstraction and compile expression tree to java code and byte codejava/fory-core/src/main/java/org/apache/fory/builder: build expression tree for serialization to generate serialization codejava/fory-core/src/main/java/org/apache/fory/reflect: reflection utilitiesjava/fory-core/src/main/java/org/apache/fory/type: java generics and type inference utilitiesjava/fory-core/src/main/java/org/apache/fory/util: utility classesfory-format: Java library implementing the core row format encoding and decoding
java/fory-format/src/main/java/org/apache/fory/format/row: row format data structuresjava/fory-format/src/main/java/org/apache/fory/format/encoder: generate row format encoder and decoder to encode/decode objects to/from row formatjava/fory-format/src/main/java/org/apache/fory/format/type: type inference for row formatjava/fory-format/src/main/java/org/apache/fory/format/vectorized: interoperation with apache arrow columnar formatfory-extensions: extension libraries for java, including:
fory-simd: SIMD-accelerated serialization and deserialization based on java vector API
java/fory-simd/src/main/java/org/apache/fory/util: SIMD utilitiesjava/fory-simd/src/main/java/org/apache/fory/serializer: SIMD accelerated serializersfory-test-core: Core test utilities and data generators
testsuite: Complex test suite for issues reported by users and hard to reproduce using simple test cases
benchmark: Benchmark suite based on jmh
bazel dir provides build support for fory C++ and Cython:
bazel/cython_library.bzl: pyx_library rule for building Cython extensionsDependencies are managed via MODULE.bazel using bzlmod (Bazel 8+).
cpp/fory/row: Row format data structurescpp/fory/meta: Compile-time reflection utilities for extract struct fields information.cpp/fory/encoder: Row format encoder and decodercpp/fory/util: Common utilitiescpp/fory/util/buffer.h: Buffer for reading and writing datacpp/fory/util/bit_util.h: utilities for bit manipulationcpp/fory/util/string_util.h: String utilitiescpp/fory/util/status.h: Status code for error handlingFory python has two implementations for the protocol:
xlang serialization format, used for debugging and testing only. This mode can be enabled by setting ENABLE_FORY_CYTHON_SERIALIZATION=0 environment variable.xlang serialization format, which is used by default and has better performance than pure python. This mode can be enabled by setting ENABLE_FORY_CYTHON_SERIALIZATION=1 environment variable.Code structure:
python/pyfory/serialization.pyx: Core serialization logic and entry point for cython mode based on xlang serialization formatpython/pyfory/_fory.py: Serialization entry point for pure python mode based on xlang serialization formatpython/pyfory/_registry.py: Type registry, resolution and serializer dispatch for pure python mode, which is also used by cython mode. Cython mode use a cache to reduce invocations to this module.python/pyfory/serializer.py: Serializers for non-internal typespython/pyfory/includes: Cython headers for c++ functions and classes.python/pyfory/resolver.py: resolving shared/circular references when ref tracking is enabled in pure python modepython/pyfory/format: Fory row format encoding and decoding, arrow columnar format interoperationpython/pyfory/_util.pyx: Buffer for reading/writing data, string utilities. Used by serialization.pyx and python/pyfory/format at the same time.Fory go provides reflection-based and codegen-based serialization and deserialization.
go/fory/fory.go: serialization entry pointgo/fory/resolver.go: resolving shared/circular references when ref tracking is enabledgo/fory/type.go: type system and type resolution, serializer dispatchgo/fory/slice.go: serializers for slice typego/fory/map.go: serializers for map typego/fory/set.go: serializers for set typego/fory/struct.go: serializers for struct typego/fory/string.go: serializers for string typego/fory/buffer.go: Buffer for reading/writing datago/fory/codegen: code generators, provide code generator to be invoked by go:generate to generate serialization code to speed up the serialization.go/fory/meta: Meta string compressionFory rust provides macro-based serialization and deserialization. Fory rust consists of:
rust/fory/src/lib.rs: main library entry point to export API to usersrust/fory-core/src/fory.rs: main serialization entry pointrust/fory-core/src/resolver/type_resolver.rs: type resolution and registrationrust/fory-core/src/resolver/metastring_resolver.rs: resolver for meta stringrust/fory-core/src/resolver/context.rs: context for reading/writingrust/fory-core/src/buffer.rs: buffer for reading/writing datarust/fory-core/src/meta: meta string compression, type meta encodingrust/fory-core/src/serializer: serializers for each supported typerust/fory-core/src/row: row format encoding and decodingrust/fory-derive/src/object: macro for serializing/deserializing structsrust/fory-derive/src/fory_row: macro for encoding/decoding row formatintegration_tests contains integration tests with following modules:
reflect-config.json for serialization, this is the core advantage of compared to graalvm JDK serialization.jdk17+ versionsdocs/specification/xlang_type_mapping.md)integration_tests/ for cross-language compatibilitytest_cross_language.py for language and protocol alignmentdocs/docs/specification/docs/specification/ENABLE_FORY_CYTHON_SERIALIZATION=0 for debuggingdocs/specification/bazel clean --expunge for deep cleaningci.yml: Main CI workflow for all languagesbuild-native-*.yml: Mac/Window python wheel build workflowsbuild-containerized-*.yml: Containerized python wheel build workflows for linuxlint.yml: Code formatting and lintingpr-lint.yml: PR-specific checksUse the GitHub CLI (gh) to inspect and fix CI failures:
# List all checks for a PR and their status gh pr checks <PR_NUMBER> --repo apache/fory # View failed job logs (get job ID from pr checks output) gh run view <RUN_ID> --repo apache/fory --job <JOB_ID> --log-failed # View full job logs gh run view <RUN_ID> --repo apache/fory --job <JOB_ID> --log # Example workflow for fixing CI errors: # 1. List checks to find failing jobs gh pr checks 2942 --repo apache/fory # 2. Get the failed job logs (RUN_ID and JOB_ID from step 1) gh run view 19735911308 --repo apache/fory --job 56547673283 --log-failed # 3. Fix the issues based on error messages # 4. Commit and push fixes
Common CI failures and fixes:
clang-format, prettier, spotless:apply, etc.)prettier --write <file> for markdown filesUse conventional commits with language scope:
feat(java): add codegen support for xlang serialization fix(rust): fix collection header when collection is empty docs(python): add docs for xlang serialization refactor(java): unify serialization exceptions hierarchy perf(cpp): optimize buffer allocation in encoder test(integration): add cross-language reference cycle tests ci: update build matrix for latest JDK versions chore(deps): update guava dependency to 32.0.0