This is an automated email from the ASF dual-hosted git repository.
chaokunyang pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/fory.git
The following commit(s) were added to refs/heads/main by this push:
new 229ce8c7f docs: refactor readme (#2843)
229ce8c7f is described below
commit 229ce8c7f3545e0ac6a6cb5f745a989105b1497e
Author: Shawn Yang <[email protected]>
AuthorDate: Wed Oct 29 00:36:44 2025 +0800
docs: refactor readme (#2843)
<!--
**Thanks for contributing to Apache Fory™.**
**If this is your first time opening a PR on fory, you can refer to
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).**
Contribution Checklist
- The **Apache Fory™** community has requirements on the naming of pr
titles. You can also find instructions in
[CONTRIBUTING.md](https://github.com/apache/fory/blob/main/CONTRIBUTING.md).
- Apache Fory™ has a strong focus on performance. If the PR you submit
will have an impact on performance, please benchmark it first and
provide the benchmark result here.
-->
## Why?
<!-- Describe the purpose of this PR. -->
## What does this PR do?
<!-- Describe the details of this PR. -->
## Related issues
<!--
Is there any related issue? If this PR closes them you say say
fix/closes:
- #xxxx0
- #xxxx1
- Fixes #xxxx2
-->
## Does this PR introduce any user-facing change?
<!--
If any user-facing interface changes, please [open an
issue](https://github.com/apache/fory/issues/new/choose) describing the
need to do so and update the document if necessary.
Delete section if not applicable.
-->
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
<!--
When the PR has an impact on performance (if you don't know whether the
PR will have an impact on performance, you can submit the PR first, and
if it will have impact on performance, the code reviewer will explain
it), be sure to attach a benchmark data here.
Delete section if not applicable.
-->
---
README.md | 652 ++++++++++++++++++++------------
docs/guide/graalvm_guide.md | 2 +-
docs/guide/java_serialization_guide.md | 212 ++++++++++-
docs/guide/row_format_guide.md | 2 +-
docs/guide/scala_guide.md | 2 +-
docs/guide/xlang_serialization_guide.md | 2 +-
java/README.md | 410 +++++++++++++++++++-
7 files changed, 1027 insertions(+), 255 deletions(-)
diff --git a/README.md b/README.md
index 02d7f0b6a..330b31eab 100644
--- a/README.md
+++ b/README.md
@@ -1,168 +1,182 @@
<div align="center">
- <img width="65%" alt="" src="docs/images/logo/fory-horizontal.png"><br>
+ <img width="65%" alt="Apache Fory logo"
src="docs/images/logo/fory-horizontal.png"><br>
</div>
[](https://github.com/apache/fory/actions/workflows/ci.yml)
[](https://join.slack.com/t/fory-project/shared_invite/zt-36g0qouzm-kcQSvV_dtfbtBKHRwT5gsw)
[](https://x.com/ApacheFory)
[](https://search.maven.org/#search|gav|1|g:"org.apache.fory"%20AND%20a:"fory-core")
+[](https://crates.io/crates/fory)
+[](https://pypi.org/project/pyfory/)
-**Apache Fory™** is a blazingly-fast multi-language serialization framework
powered by **JIT** (just-in-time compilation) and **zero-copy**, providing up
to 170x performance and ultimate ease of use.
+**Apache Fory™** is a blazingly-fast multi-language serialization framework
powered by **JIT compilation**, **zero-copy** techniques, and **advanced code
generation**, achieving up to **170x performance improvement** while
maintaining simplicity and ease of use.
<https://fory.apache.org>
> [!IMPORTANT]
> **Apache Fory™ was previously named as Apache Fury. For versions before
> 0.11, please use "fury" instead of "fory" in package names, imports, and
> dependencies, see [Fury
> Docs](https://fory.apache.org/docs/0.10/docs/introduction/) for how to use
> Fury in older versions**.
-## Features
-
-- **Multiple languages**:
Java/Python/C++/Golang/JavaScript/Rust/Scala/Kotlin/TypeScript.
-- **Zero-copy**: Cross-language out-of-band serialization inspired
- by [pickle5](https://peps.python.org/pep-0574/) and off-heap read/write.
-- **High performance**: A highly-extensible JIT framework to generate
serializer code at runtime in an async multi-thread way to speed serialization,
providing 20-170x speed up by:
- - reduce memory access by inlining variables in generated code.
- - reduce virtual method invocation by inline call in generated code.
- - reduce conditional branching.
- - reduce hash lookup.
-- **Multiple binary protocols**: Object graph, row format, and so on.
-
-In addition to cross-language serialization, Apache Fory™ also features at:
-
-- Drop-in replace Java serialization frameworks such as JDK/Kryo/Hessian, but
100x faster at most, which can greatly improve
- the efficiency of high-performance RPC calls, data transfer, and object
persistence.
-- **100% compatible** with JDK serialization API with much faster
implementation: supporting JDK
`writeObject`/`readObject`/`writeReplace`/`readResolve`/`readObjectNoData`/`Externalizable`
API.
-- Supports **Java 8~24**, Java 17+ `record` is supported too.
-- Supports [AOT compilation serialization](docs/guide/graalvm_guide.md) for
**GraalVM native image**, and no reflection/serialization json config are
needed.
-- Supports shared and circular reference object serialization for golang.
-- Supports [scala serialization](docs/guide/scala_guide.md)
-- Supports [Kotlin serialization](kotlin/README.md)
-- Supports automatic object serialization for golang.
+## Why Choose Apache Fory™?
+
+**Compared to Static Serialization Frameworks**:
+
+- No IDL definitions or schema management required
+- Automatic handling of complex object graphs with references
+- Native support for polymorphic types
+- Significantly faster for most workloads
+
+**Compared to Dynamic Serialization Frameworks**:
+
+- Up to 170x better performance through JIT compilation
+- Smaller serialized data size with compact binary encoding
+- Cross-language support
+- Better security with class registration and deserialization policy controls
+
+## Key Features
+
+### 🚀 High-Performance Serialization
+
+Apache Fory™ delivers exceptional performance through advanced optimization
techniques:
+
+- **JIT Compilation**: Runtime code generation for Java eliminates virtual
method calls and inlines hot paths
+- **Static Code Generation**: Compile-time code generation for Rust, C++, and
Go delivers peak performance without runtime overhead
+- **Zero-Copy Operations**: Direct memory access without intermediate buffer
copies; row format enables random access and partial serialization
+- **Intelligent Encoding**: Variable-length compression for integers and
strings; SIMD acceleration for arrays (Java 16+)
+- **Meta Sharing**: Class metadata packing reduces redundant type information
across serializations
+
+### 🌍 Cross-Language Serialization
+
+The **[xlang serialization
format](docs/specification/xlang_serialization_spec.md)** enables seamless data
exchange across programming languages:
+
+- **Automatic Type Mapping**: Intelligent conversion between language-specific
types ([type mapping](docs/specification/xlang_type_mapping.md))
+- **Reference Preservation**: Shared and circular references work correctly
across languages
+- **Polymorphism**: Objects serialize/deserialize with their actual runtime
types
+- **Schema Evolution**: Optional forward/backward compatibility for evolving
schemas
+- **Automatic Serialization**: No IDL or schema definitions required;
serialize any object directly without code generation
+
+### 📊 Row Format
+
+A cache-friendly **[row format](docs/specification/row_format_spec.md)**
optimized for analytics workloads:
+
+- **Zero-Copy Random Access**: Read individual fields without deserializing
entire objects
+- **Partial Operations**: Selective field serialization and deserialization
for efficiency
+- **Apache Arrow Integration**: Seamless conversion to columnar format for
analytics pipelines
+- **Multi-Language**: Available in Java, Python, Rust and C++
+
+### 🔒 Security & Production-Readiness
+
+Enterprise-grade security and compatibility:
+
+- **Class Registration**: Whitelist-based deserialization control (enabled by
default)
+- **Depth Limiting**: Protection against recursive object graph attacks
+- **Configurable Policies**: Custom class checkers and deserialization policies
+- **Platform Support**: Java 8-24, GraalVM native image, multiple OS platforms
## Protocols
-Apache Fory™ designed and implemented multiple binary protocols for different
scenarios:
+Apache Fory™ implements multiple binary protocols optimized for different
scenarios:
-- **[xlang serialization
format](docs/specification/xlang_serialization_spec.md)**:
- - Cross-language serialize any object automatically, no need for IDL
definition, schema compilation and object to/from
- protocol conversion.
- - Support optional shared reference and circular reference, no duplicate
data or recursion error.
- - Support object polymorphism.
-- **[Java serialization
format](docs/specification/java_serialization_spec.md)**: Highly-optimized and
drop-in replacement for Java serialization.
-- **[Row format format](docs/specification/row_format_spec.md)**: A
cache-friendly binary random access format, supports skipping serialization and
- partial serialization, and can convert to column-format automatically.
+| Protocol |
Use Case | Key Features
|
+| ------------------------------------------------------------------------- |
------------------------------ |
------------------------------------------------------ |
+| **[Xlang Serialization](docs/specification/xlang_serialization_spec.md)** |
Cross-language object exchange | Automatic serialization, references,
polymorphism |
+| **[Java Serialization](docs/specification/java_serialization_spec.md)** |
High-performance Java-only | Drop-in JDK serialization replacement, 100x
faster |
+| **[Row Format](docs/specification/row_format_spec.md)** |
Analytics and data processing | Zero-copy random access, Arrow compatibility
|
+| **Python Native** |
Python-specific serialization | Pickle/cloudpickle replacement with better
performance |
-New protocols can be easily added based on Apache Fory™ existing buffer,
encoding, meta, codegen and other capabilities. All of those share the same
codebase, and the optimization for one protocol can be reused by another
protocol.
+All protocols share the same optimized codebase, allowing improvements in one
protocol to benefit others.
## Benchmarks
-Different serialization frameworks are suitable for different scenarios, and
benchmark results here are for reference only.
+> **Note**: Different serialization frameworks excel in different scenarios.
Benchmark results are for reference only.
+> For your specific use case, conduct benchmarks with appropriate
configurations and workloads.
-If you need to benchmark for your specific scenario, make sure all
serialization frameworks are appropriately configured for that scenario.
+### Java Serialization Performance
-Dynamic serialization frameworks support polymorphism and references, but they
often come with a higher cost compared to static serialization frameworks,
unless they utilize JIT techniques like Fory does.
-To ensure accurate benchmark statistics, it is advisable to **warm up** the
system before collecting data due to Fory's runtime code generation.
+The following benchmarks compare Fory against popular Java serialization
frameworks. Charts labeled **"compatible"** show schema evolution mode with
forward/backward compatibility enabled, while others show schema consistent
mode where class schemas must match.
-### Java Serialization
+**Test Classes**:
-In these charts below, titles containing "compatible" represent schema
compatible mode: type forward/backward compatibility is enabled; while titles
without "compatible" represent schema consistent mode: class schema must be the
same between serialization and deserialization.
+- `Struct`: Class with [100 primitive fields](docs/benchmarks#Struct)
+- `MediaContent`: Class from
[jvm-serializers](https://github.com/eishay/jvm-serializers/blob/master/tpc/src/data/media/MediaContent.java)
+- `Sample`: Class from [Kryo
benchmark](https://github.com/EsotericSoftware/kryo/blob/master/benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/data/Sample.java)
-Where `Struct` is a class with [100 primitive
fields](https://github.com/apache/fory/tree/main/docs/benchmarks#Struct),
`MediaContent` is a class from
[jvm-serializers](https://github.com/eishay/jvm-serializers/blob/master/tpc/src/data/media/MediaContent.java),
and `Sample` is a class from [kryo
benchmark](https://github.com/EsotericSoftware/kryo/blob/master/benchmarks/src/main/java/com/esotericsoftware/kryo/benchmarks/data/Sample.java).
+**Serialization Throughput**:
<p align="center">
-<img width="24%" alt=""
src="docs/benchmarks/compatible/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png">
-<img width="24%" alt=""
src="docs/benchmarks/compatible/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png">
-<img width="24%" alt=""
src="docs/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png">
-<img width="24%" alt=""
src="docs/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png">
+<img width="24%" alt="Struct Serialization Compatible"
src="docs/benchmarks/compatible/bench_serialize_compatible_STRUCT_to_directBuffer_tps.png">
+<img width="24%" alt="MediaContent Serialization Compatible"
src="docs/benchmarks/compatible/bench_serialize_compatible_MEDIA_CONTENT_to_array_tps.png">
+<img width="24%" alt="MediaContent Serialization"
src="docs/benchmarks/serialization/bench_serialize_MEDIA_CONTENT_to_array_tps.png">
+<img width="24%" alt="Sample Serialization"
src="docs/benchmarks/serialization/bench_serialize_SAMPLE_to_array_tps.png">
</p>
+**Deserialization Throughput**:
+
<p align="center">
-<img width="24%" alt=""
src="docs/benchmarks/compatible/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png">
-<img width="24%" alt=""
src="docs/benchmarks/compatible/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png">
-<img width="24%" alt=""
src="docs/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png">
-<img width="24%" alt=""
src="docs/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png">
+<img width="24%" alt="Struct Deserialization Compatible"
src="docs/benchmarks/compatible/bench_deserialize_compatible_STRUCT_from_directBuffer_tps.png">
+<img width="24%" alt="MediaContent Deserialization Compatible"
src="docs/benchmarks/compatible/bench_deserialize_compatible_MEDIA_CONTENT_from_array_tps.png">
+<img width="24%" alt="MediaContent Deserialization"
src="docs/benchmarks/deserialization/bench_deserialize_MEDIA_CONTENT_from_array_tps.png">
+<img width="24%" alt="Sample Deserialization"
src="docs/benchmarks/deserialization/bench_deserialize_SAMPLE_from_array_tps.png">
</p>
-See [benchmarks](https://github.com/apache/fory/tree/main/docs/benchmarks) for
more benchmarks about type forward/backward compatibility, off-heap support,
zero-copy serialization.
+**Important**: Fory's runtime code generation requires proper warm-up for
performance measurement:
-### Rust Serialization
+For additional benchmarks covering type forward/backward compatibility,
off-heap support, and zero-copy serialization, see [Java
Benchmarks](docs/benchmarks).
-**ecommerce_data**
+### Rust Serialization Performance
+
+Fory Rust demonstrates competitive performance compared to other Rust
serialization frameworks.
<p align="center">
-<img src="docs/benchmarks/rust/ecommerce_data.png" width="90%">
+<img src="docs/benchmarks/rust/ecommerce_data.png" width="70%">
</p>
-**system_data**
-
<p align="center">
-<img src="docs/benchmarks/rust/system_data.png" width="90%">
+<img src="docs/benchmarks/rust/system_data.png" width="70%">
</p>
-See [Rust Benchmarks](https://github.com/apache/fory/tree/main/rust/benches)
for more benchmarks about Apache Fory Rust Serialization.
+For more detailed benchmarks and methodology, see [Rust
Benchmarks](rust/benches).
## Installation
-### Java
-
-Nightly snapshot:
+**Java**:
```xml
-<repositories>
- <repository>
- <id>apache</id>
- <url>https://repository.apache.org/snapshots/</url>
- <releases>
- <enabled>false</enabled>
- </releases>
- <snapshots>
- <enabled>true</enabled>
- </snapshots>
- </repository>
-</repositories>
<dependency>
<groupId>org.apache.fory</groupId>
<artifactId>fory-core</artifactId>
- <version>0.14.0-SNAPSHOT</version>
+ <version>0.13.0</version>
</dependency>
-<!-- row/arrow format support -->
-<!-- <dependency>
- <groupId>org.apache.fory</groupId>x
- <artifactId>fory-format</artifactId>
- <version>0.14.0-SNAPSHOT</version>
-</dependency> -->
-```
-
-Release version:
-
-```xml
+<!-- Optional row format support -->
+<!--
<dependency>
<groupId>org.apache.fory</groupId>
- <artifactId>fory-core</artifactId>
+ <artifactId>fory-format</artifactId>
<version>0.13.0</version>
</dependency>
-<!-- row/arrow format support -->
-<!-- <dependency>
+-->
+<!-- SIMD acceleration for array compression (Java 16+) -->
+<!--
+<dependency>
<groupId>org.apache.fory</groupId>
- <artifactId>fory-format</artifactId>
+ <artifactId>fory-simd</artifactId>
<version>0.13.0</version>
-</dependency> -->
+</dependency>
+-->
```
-### Scala
+Snapshots are available from `https://repository.apache.org/snapshots/`
(version `0.14.0-SNAPSHOT`).
-Scala2:
+**Scala**:
```sbt
+// Scala 2.13
libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "0.13.0"
-```
-
-Scala3:
-```sbt
+// Scala 3
libraryDependencies += "org.apache.fory" % "fory-scala_3" % "0.13.0"
```
-### Kotlin
+**Kotlin**:
```xml
<dependency>
@@ -172,166 +186,242 @@ libraryDependencies += "org.apache.fory" %
"fory-scala_3" % "0.13.0"
</dependency>
```
-### Python
+**Python**:
```bash
pip install pyfory
+
+# With row format support
+pip install pyfory[format]
+```
+
+**Rust**:
+
+```toml
+[dependencies]
+fory = "0.13"
```
-### Golang
+**Golang**:
```bash
go get github.com/apache/fory/go/fory
```
-## Quickstart
+## Quick Start
-Here we give a quick start about how to use Apache Fory™, see [user
guide](docs/README.md) for more details about
[java](docs/guide/java_serialization_guide.md), [cross
language](docs/guide/xlang_serialization_guide.md), and [row
format](docs/guide/row_format_guide.md).
+This section provides quick examples for getting started with Apache Fory™.
For comprehensive guides, see the [Documentation](#documentation).
-### Fory java object graph serialization
+### Native Serialization
-If you don't have cross-language requirements, using this mode will
-result in better performance.
+**Always use native mode when working with a single language.** Native mode
delivers optimal performance by avoiding the type metadata overhead required
for cross-language compatibility. Xlang mode introduces additional metadata
encoding costs and restricts serialization to types that are common across all
supported languages. Language-specific types will be rejected during
serialization in xlang-mode.
+
+#### Java Serialization
+
+When you don't need cross-language support, use Java mode for optimal
performance.
```java
import org.apache.fory.*;
import org.apache.fory.config.*;
-import java.util.*;
public class Example {
+ public static class Person {
+ String name;
+ int age;
+ }
+
public static void main(String[] args) {
- SomeClass object = new SomeClass();
- // Note that Fory instances should be reused between
- // multiple serializations of different objects.
- {
- Fory fory = Fory.builder().withLanguage(Language.JAVA)
- .requireClassRegistration(true)
- .build();
- // Registering types can reduce class name serialization overhead, but
not mandatory.
- // If class registration enabled, all custom types must be registered.
- fory.register(SomeClass.class);
- byte[] bytes = fory.serialize(object);
- System.out.println(fory.deserialize(bytes));
- }
- {
- ThreadSafeFory fory = Fory.builder().withLanguage(Language.JAVA)
- .requireClassRegistration(true)
- .buildThreadSafeFory();
- // Registering types can reduce class name serialization overhead, but
not mandatory.
- // If class registration enabled, all custom types must be registered.
- fory.register(SomeClass.class);
- byte[] bytes = fory.serialize(object);
- System.out.println(fory.deserialize(bytes));
- }
- {
- ThreadSafeFory fory = new ThreadLocalFory(classLoader -> {
- Fory f = Fory.builder().withLanguage(Language.JAVA)
- .withClassLoader(classLoader).build();
- f.register(SomeClass.class);
- return f;
- });
- byte[] bytes = fory.serialize(object);
- System.out.println(fory.deserialize(bytes));
- }
+ // Create Fory instance - should be reused across serializations
+ BaseFory fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ // replace `build` with `buildThreadSafeFory` for Thread-Safe Usage
+ .build();
+ // Register your classes (required when class registration is enabled)
+ fory.register(Person.class);
+ // Serialize
+ Person person = new Person();
+ person.name = "chaokunyang";
+ person.age = 28;
+ byte[] bytes = fory.serialize(person);
+ Person result = (Person) fory.deserialize(bytes);
+ System.out.println(result.name + " " + result.age); // Output:
chaokunyang 28
+ }
+}
+```
+
+For detailed Java usage including compatibility modes, compression, and
advanced features, see [Java Serialization
Guide](docs/guide/java_serialization_guide.md) and
[java/README.md](java/README.md).
+
+#### Python Serialization
+
+Python native mode provides a high-performance drop-in replacement for
pickle/cloudpickle with better speed and compatibility.
+
+```python
+from dataclasses import dataclass
+import pyfory
+
+@dataclass
+class Person:
+ name: str
+ age: pyfory.int32
+
+# Create Fory instance - should be reused across serializations
+fory = pyfory.Fory()
+# Register your classes (required when class registration is enabled)
+fory.register_type(Person)
+person = Person(name="chaokunyang", age=28)
+data = fory.serialize(person)
+result = fory.deserialize(data)
+print(result.name, result.age) # Output: chaokunyang 28
+```
+
+For detailed Python usage including type hints, compatibility modes, and
advanced features, see [Python Guide](docs/guide/python_guide.md).
+
+#### Scala Serialization
+
+Scala native mode provides optimized serialization for Scala-specific types
including case classes, collections, and Option types.
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.config.Language
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+case class Person(name: String, age: Int)
+
+object Example {
+ def main(args: Array[String]): Unit = {
+ // Create Fory instance - should be reused across serializations
+ val fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .build()
+ // Register Scala serializers for Scala-specific types
+ ScalaSerializers.registerSerializers(fory)
+ // Register your case classes
+ fory.register(classOf[Person])
+ val bytes = fory.serialize(Person("chaokunyang", 28))
+ val result = fory.deserialize(bytes).asInstanceOf[Person]
+ println(s"${result.name} ${result.age}") // Output: chaokunyang 28
}
}
```
-### Cross-language object graph serialization
+For detailed Scala usage including collection serialization and integration
patterns, see [Scala Guide](docs/guide/scala_guide.md).
+
+#### Kotlin Serialization
+
+Kotlin native mode provides optimized serialization for Kotlin-specific types
including data classes, nullable types, and Kotlin collections.
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.config.Language
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+data class Person(val name: String, val age: Int)
+
+fun main() {
+ // Create Fory instance - should be reused across serializations
+ val fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .requireClassRegistration(true)
+ .build()
+ // Register Kotlin serializers for Kotlin-specific types
+ KotlinSerializers.registerSerializers(fory)
+ // Register your data classes
+ fory.register(Person::class.java)
+ val bytes = fory.serialize(Person("chaokunyang", 28))
+ val result = fory.deserialize(bytes) as Person
+ println("${result.name} ${result.age}") // Output: chaokunyang 28
+}
+```
+
+For detailed Kotlin usage including null safety and default value support, see
[kotlin/README.md](kotlin/README.md).
+
+### Cross-Language Serialization
+
+**Only use xlang mode when you need cross-language data exchange.** Xlang mode
adds type metadata overhead for cross-language compatibility and only supports
types that can be mapped across all languages. For single-language use cases,
always prefer native mode for better performance.
+
+The following examples demonstrate serializing a `Person` object across Java
and Rust. For other languages (Python, Go, JavaScript, etc.), simply set the
language mode to `XLANG` and follow the same pattern.
**Java**
```java
import org.apache.fory.*;
import org.apache.fory.config.*;
-import java.util.*;
-public class ReferenceExample {
- public static class SomeClass {
- SomeClass f1;
- Map<String, String> f2;
- Map<String, String> f3;
- }
+public class XlangExample {
+ public record Person(String name, int age) {}
- public static Object createObject() {
- SomeClass obj = new SomeClass();
- obj.f1 = obj;
- obj.f2 = ofHashMap("k1", "v1", "k2", "v2");
- obj.f3 = obj.f2;
- return obj;
- }
-
- // mvn exec:java -Dexec.mainClass="org.apache.fory.examples.ReferenceExample"
public static void main(String[] args) {
- Fory fory = Fory.builder().withLanguage(Language.XLANG)
- .withRefTracking(true).build();
- fory.register(SomeClass.class, "example.SomeClass");
- byte[] bytes = fory.serialize(createObject());
- // bytes can be data serialized by other languages.
- System.out.println(fory.deserialize(bytes));
+ // Create Fory instance with XLANG mode
+ Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .build();
+
+ // Register with cross-language type id/name
+ fory.register(Person.class, 1);
+ // fory.register(Person.class, "example.Person");
+ Person person = new Person("chaokunyang", 28);
+ byte[] bytes = fory.serialize(person);
+ // bytes can be deserialized by Rust, Python, Go, or other languages
+ Person result = (Person) fory.deserialize(bytes);
+ System.out.println(result.name + " " + result.age); // Output:
chaokunyang 28
}
}
```
-**Python**
+**Rust**
-```python
-from typing import Dict
-import pyfory
+```rust
+use fory::{Fory, ForyObject};
-class SomeClass:
- f1: "SomeClass"
- f2: Dict[str, str]
- f3: Dict[str, str]
-
-fory = pyfory.Fory(ref_tracking=True)
-fory.register_type(SomeClass, typename="example.SomeClass")
-obj = SomeClass()
-obj.f2 = {"k1": "v1", "k2": "v2"}
-obj.f1, obj.f3 = obj, obj.f2
-data = fory.serialize(obj)
-# bytes can be data serialized by other languages.
-print(fory.deserialize(data))
-```
+#[derive(ForyObject, Debug)]
+struct Person {
+ name: String,
+ age: i32,
+}
-**Golang**
-
-```go
-package main
-
-import forygo "github.com/apache/fory/go/fory"
-import "fmt"
-
-func main() {
- type SomeClass struct {
- F1 *SomeClass
- F2 map[string]string
- F3 map[string]string
- }
- fory := forygo.NewFory(true)
- if err := fory.RegisterNamedType(SomeClass{}, "example.SomeClass"); err !=
nil {
- panic(err)
- }
- value := &SomeClass{F2: map[string]string{"k1": "v1", "k2": "v2"}}
- value.F3 = value.F2
- value.F1 = value
- bytes, err := fory.Marshal(value)
- if err != nil {
- }
- var newValue interface{}
- // bytes can be data serialized by other languages.
- if err := fory.Unmarshal(bytes, &newValue); err != nil {
- panic(err)
- }
- fmt.Println(newValue)
+fn main() -> Result<(), Error> {
+ let mut fory = Fory::default();
+ fory.register::<Person>(1)?;
+ // fory.register_by_name::<Person>("example.Person")?;
+ let person = Person {
+ name: "chaokunyang".to_string(),
+ age: 28,
+ };
+ let bytes = fory.serialize(&person);
+ // bytes can be deserialized by Java, Python, Go, or other languages
+ let result: Person = fory.deserialize(&bytes)?;
+ println!("{} {}", result.name, result.age); // Output: chaokunyang 28
}
```
-### Row format
+**Key Points for Cross-Language Serialization**:
+
+- Use `Language.XLANG` mode in all languages
+- Register types with **consistent IDs or names** across all languages:
+ - **By ID** (`fory.register(Person.class, 1)`): Faster serialization, more
compact encoding, but requires coordination to avoid ID conflicts
+ - **By name** (`fory.register(Person.class, "example.Person")`): More
flexible, less prone to conflicts, easier to manage across teams, but slightly
larger encoding
+- Type IDs/names must match across all languages for successful deserialization
+- Only use types that have cross-language mappings (see [Type
Mapping](docs/specification/xlang_type_mapping.md))
+
+For examples with **circular references**, **shared references**, and
**polymorphism** across languages, see:
+
+- [Cross-Language Serialization Guide](docs/guide/xlang_serialization_guide.md)
+- [Java Serialization Guide - Cross
Language](docs/guide/java_serialization_guide.md#cross-language-serialization)
+- [Python Guide - Cross
Language](docs/guide/python_guide.md#cross-language-serialization)
+
+### Row Format Encoding
+
+Row format provides zero-copy random access to serialized data, making it
ideal for analytics workloads and data processing pipelines.
#### Java
```java
+import org.apache.fory.format.*;
+import java.util.*;
+import java.util.stream.*;
+
public class Bar {
String f1;
List<Long> f2;
@@ -348,30 +438,31 @@ RowEncoder<Foo> encoder = Encoders.bean(Foo.class);
Foo foo = new Foo();
foo.f1 = 10;
foo.f2 = IntStream.range(0, 1000000).boxed().collect(Collectors.toList());
-foo.f3 = IntStream.range(0, 1000000).boxed().collect(Collectors.toMap(i ->
"k"+i, i->i));
+foo.f3 = IntStream.range(0, 1000000).boxed().collect(Collectors.toMap(i ->
"k"+i, i -> i));
+
List<Bar> bars = new ArrayList<>(1000000);
for (int i = 0; i < 1000000; i++) {
Bar bar = new Bar();
- bar.f1 = "s"+i;
+ bar.f1 = "s" + i;
bar.f2 = LongStream.range(0, 10).boxed().collect(Collectors.toList());
bars.add(bar);
}
foo.f4 = bars;
-// Can be zero-copy read by python
+
+// Serialize to row format (can be zero-copy read by Python)
BinaryRow binaryRow = encoder.toRow(foo);
-// can be data from python
+
+// Deserialize entire object
Foo newFoo = encoder.fromRow(binaryRow);
-// zero-copy read List<Integer> f2
-BinaryArray binaryArray2 = binaryRow.getArray(1);
-// zero-copy read List<Bar> f4
-BinaryArray binaryArray4 = binaryRow.getArray(3);
-// zero-copy read 11th element of `readList<Bar> f4`
-BinaryRow barStruct = binaryArray4.getStruct(10);
-
-// zero-copy read 6th of f2 of 11th element of `readList<Bar> f4`
-barStruct.getArray(1).getInt64(5);
+
+// Zero-copy access to nested fields without full deserialization
+BinaryArray binaryArray2 = binaryRow.getArray(1); // Access f2 field
+BinaryArray binaryArray4 = binaryRow.getArray(3); // Access f4 field
+BinaryRow barStruct = binaryArray4.getStruct(10); // Access 11th Bar element
+long value = barStruct.getArray(1).getInt64(5); // Access nested value
+
+// Partial deserialization
RowEncoder<Bar> barEncoder = Encoders.bean(Bar.class);
-// deserialize part of data.
Bar newBar = barEncoder.fromRow(barStruct);
Bar newBar2 = barEncoder.fromRow(binaryArray4.getStruct(20));
```
@@ -379,10 +470,16 @@ Bar newBar2 =
barEncoder.fromRow(binaryArray4.getStruct(20));
#### Python
```python
+from dataclasses import dataclass
+from typing import List, Dict
+import pyarrow as pa
+import pyfory
+
@dataclass
class Bar:
f1: str
f2: List[pa.int64]
+
@dataclass
class Foo:
f1: pa.int32
@@ -391,52 +488,117 @@ class Foo:
f4: List[Bar]
encoder = pyfory.encoder(Foo)
-foo = Foo(f1=10, f2=list(range(1000_000)),
- f3={f"k{i}": i for i in range(1000_000)},
- f4=[Bar(f1=f"s{i}", f2=list(range(10))) for i in range(1000_000)])
+foo = Foo(
+ f1=10,
+ f2=list(range(1000_000)),
+ f3={f"k{i}": i for i in range(1000_000)},
+ f4=[Bar(f1=f"s{i}", f2=list(range(10))) for i in range(1000_000)]
+)
+
+# Serialize to row format
binary: bytes = encoder.to_row(foo).to_bytes()
+
+# Zero-copy random access without full deserialization
foo_row = pyfory.RowData(encoder.schema, binary)
-print(foo_row.f2[100000], foo_row.f4[100000].f1, foo_row.f4[200000].f2[5])
+print(foo_row.f2[100000]) # Access element directly
+print(foo_row.f4[100000].f1) # Access nested field
+print(foo_row.f4[200000].f2[5]) # Access deeply nested field
```
+For more details on row format, see [Row Format
Guide](docs/guide/row_format_guide.md).
+
+## Documentation
+
+### User Guides
+
+| Guide | Description
| Source |
Website
|
+| -------------------------------- |
------------------------------------------ |
----------------------------------------------------------------------- |
-----------------------------------------------------------------------------------
|
+| **Java Serialization** | Comprehensive guide for Java
serialization |
[java_serialization_guide.md](docs/guide/java_serialization_guide.md) | [📖
View](https://fory.apache.org/docs/docs/guide/java_serialization)
|
+| **Cross-Language Serialization** | Multi-language object exchange
| [xlang_serialization_guide.md](docs/guide/xlang_serialization_guide.md) | [📖
View](https://fory.apache.org/docs/specification/fory_xlang_serialization_spec)
|
+| **Row Format** | Zero-copy random access format
| [row_format_guide.md](docs/guide/row_format_guide.md) | [📖
View](https://fory.apache.org/docs/specification/fory_row_format_spec)
|
+| **Python** | Python-specific features and usage
| [python_guide.md](docs/guide/python_guide.md) | [📖
View](https://fory.apache.org/docs/docs/guide/python_serialization)
|
+| **Rust** | Rust implementation and patterns
| [rust_guide.md](docs/guide/rust_guide.md) | [📖
View](https://fory.apache.org/docs/docs/guide/rust_serialization)
|
+| **Scala** | Scala integration and best practices
| [scala_guide.md](docs/guide/scala_guide.md) | [📖
View](https://fory.apache.org/docs/docs/guide/scala_serialization)
|
+| **GraalVM** | Native image support and AOT compilation
| [graalvm_guide.md](docs/guide/graalvm_guide.md) | [📖
View](https://fory.apache.org/docs/docs/guide/graalvm_serialization)
|
+| **Development** | Building and contributing to Fory
| [DEVELOPMENT.md](docs/guide/DEVELOPMENT.md) | [📖
View](https://fory.apache.org/docs/docs/guide/development)
|
+
+### Protocol Specifications
+
+| Specification | Description | Source
| Website
|
+| ----------------------- | ------------------------------ |
----------------------------------------------------------------------------- |
-----------------------------------------------------------------------------------
|
+| **Xlang Serialization** | Cross-language binary protocol |
[xlang_serialization_spec.md](docs/specification/xlang_serialization_spec.md) |
[📖
View](https://fory.apache.org/docs/specification/fory_xlang_serialization_spec)
|
+| **Java Serialization** | Java-optimized protocol |
[java_serialization_spec.md](docs/specification/java_serialization_spec.md) |
[📖
View](https://fory.apache.org/docs/specification/fory_java_serialization_spec)
|
+| **Row Format** | Row-based binary format |
[row_format_spec.md](docs/specification/row_format_spec.md) |
[📖 View](https://fory.apache.org/docs/specification/fory_row_format_spec)
|
+| **Type Mapping** | Cross-language type conversion |
[xlang_type_mapping.md](docs/specification/xlang_type_mapping.md) |
[📖
View](https://fory.apache.org/docs/specification/fory_xlang_serialization_spec)
|
+
## Compatibility
### Schema Compatibility
-Apache Fory™ java object graph serialization supports class schema
forward/backward compatibility. The serialization peer and deserialization peer
can add/delete fields independently.
+Apache Fory™ supports class schema forward/backward compatibility across
**Java, Python, Rust, and Golang**, enabling seamless schema evolution in
production systems without requiring coordinated upgrades across all services.
Fory provides two schema compatibility modes:
+
+1. **Schema Consistent Mode (Default)**: Assumes identical class schemas
between serialization and deserialization peers. This mode offers minimal
serialization overhead, smallest data size, and fastest performance: ideal for
stable schemas or controlled environments.
-We plan to add the schema compatibility support of cross-language
serialization after [meta
compression](https://github.com/apache/fory/issues/203) is finished.
+2. **Compatible Mode**: Supports independent schema evolution with forward and
backward compatibility. This mode enables field addition/deletion, limited type
evolution, and graceful handling of schema mismatches. Enable using
`withCompatibleMode(CompatibleMode.COMPATIBLE)` in Java, `compatible=True` in
Python, `compatible_mode(true)` in Rust, or `NewFory(true)` in Go.
### Binary Compatibility
-We are still improving our protocols, thus binary compatibility is not
guaranteed between Fory major releases for now.
-However, it is guaranteed between minor versions. Please
-`versioning` your data by Fory major version if you will upgrade Fory in the
future, see [how to upgrade
fory](https://github.com/apache/fory/blob/main/docs/guide/java_serialization_guide.md#upgrade-fory)
for further details.
+**Current Status**: Binary compatibility is **not guaranteed** between Fory
major releases as the protocol continues to evolve. However, compatibility **is
guaranteed** between minor versions (e.g., 0.13.x).
-Binary compatibility will be guaranteed when Fory 1.0 is released.
+**Recommendations**:
+
+- Version your serialized data by Fory major version
+- Plan migration strategies when upgrading major versions
+- See [upgrade guide](docs/guide/java_serialization_guide.md#upgrade-fory) for
details
+
+**Future**: Binary compatibility will be guaranteed starting from Fory 1.0
release.
## Security
-Static serialization is relatively secure. But dynamic serialization such as
Fory java/python native serialization supports deserializing unregistered
types, which provides more dynamics and flexibility, but also introduce
security risks.
+### Overview
+
+Serialization security varies by protocol:
-For example, the deserialization may invoke `init` constructor or
`equals`/`hashCode` method, if the method body contains malicious code, the
system will be at risk.
+- **Row Format**: Secure with predefined schemas
+- **Object Graph Serialization** (Java/Python native): More flexible but
requires careful security configuration
-Fory provides a class registration option that is enabled by default for such
protocols, allowing only deserialization of trusted registered types or
built-in types.
+Dynamic serialization can deserialize arbitrary types, which may introduces
risks. For example, the deserialization may invoke `init` constructor or
`equals/hashCode` method, if the method body contains malicious code, the
system will be at risk.
+
+Fory enables class registration **by default** for dynamic protocols, allowing
only trusted registered types.
**Do not disable class registration unless you can ensure your environment is
secure**.
-If this option is disabled, you are responsible for serialization security.
You can configure `org.apache.fory.resolver.ClassChecker` by
-`ClassResolver#setClassChecker` to control which classes are allowed for
serialization.
+If this option is disabled, you are responsible for serialization security.
You should implement and configure a customized `ClassChecker` or
`DeserializationPolicy` for fine-grained security control
+
+To report security vulnerabilities in Apache Fory™, please follow the [ASF
vulnerability reporting
process](https://apache.org/security/#reporting-a-vulnerability).
+
+## Community and Support
+
+### Getting Help
-To report security vulnerabilities found in Fory, please follow the [ASF
vulnerability reporting
process](https://apache.org/security/#reporting-a-vulnerability).
+- **Slack**: Join our [Slack
workspace](https://join.slack.com/t/fory-project/shared_invite/zt-36g0qouzm-kcQSvV_dtfbtBKHRwT5gsw)
for community discussions
+- **Twitter/X**: Follow [@ApacheFory](https://x.com/ApacheFory) for updates
and announcements
+- **GitHub Issues**: Report bugs and request features at
[apache/fory](https://github.com/apache/fory/issues)
+- **Mailing Lists**: Subscribe to Apache Fory mailing lists for development
discussions
-## How to Build
+### Contributing
-Please read the [BUILD](docs/guide/DEVELOPMENT.md) guide for instructions on
how to build.
+We welcome contributions! Please read our [Contributing
Guide](CONTRIBUTING.md) to get started.
-## How to Contribute
+**Ways to Contribute**:
-Please read the [CONTRIBUTING](CONTRIBUTING.md) guide for instructions on how
to contribute.
+- 🐛 Report bugs and issues
+- 💡 Propose new features
+- 📝 Improve documentation
+- 🔧 Submit pull requests
+- 🧪 Add test cases
+- 📊 Share benchmarks
+
+See [Development Guide](docs/guide/DEVELOPMENT.md) for build instructions and
development workflow.
## License
-Licensed under the [Apache License, Version 2.0](LICENSE)
+Apache Fory™ is licensed under the [Apache License 2.0](LICENSE).
+
+## Acknowledgments
+
+Apache Fory™ is an [Apache Software Foundation](https://apache.org/) project,
developed and maintained by contributors worldwide. We thank all contributors
for their valuable contributions to the project.
diff --git a/docs/guide/graalvm_guide.md b/docs/guide/graalvm_guide.md
index 88b005552..3f85c2c70 100644
--- a/docs/guide/graalvm_guide.md
+++ b/docs/guide/graalvm_guide.md
@@ -1,7 +1,7 @@
---
title: GraalVM Guide
sidebar_position: 6
-id: graalvm_guide
+id: graalvm_serialization
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
diff --git a/docs/guide/java_serialization_guide.md
b/docs/guide/java_serialization_guide.md
index ba67ef02a..0a9f68bfa 100644
--- a/docs/guide/java_serialization_guide.md
+++ b/docs/guide/java_serialization_guide.md
@@ -1,7 +1,7 @@
---
title: Java Serialization Guide
sidebar_position: 0
-id: java_object_graph_guide
+id: java_serialization
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
@@ -309,8 +309,217 @@ SomeClass a = xxx;
SomeClass copied = fory.copy(a);
```
+### Cross-Language Serialization
+
+Apache Fory™ supports seamless data exchange between Java and other languages
(Python, Rust, Go, JavaScript, etc.) through the xlang serialization format.
This enables multi-language microservices, polyglot data pipelines, and
cross-platform data sharing.
+
+#### Enable Cross-Language Mode
+
+To serialize data for consumption by other languages, use `Language.XLANG`
mode:
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+
+// Create Fory instance with XLANG mode
+Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .withRefTracking(true) // Enable reference tracking for complex graphs
+ .build();
+```
+
+#### Register Types for Cross-Language Compatibility
+
+Types must be registered with **consistent IDs or names** across all
languages. Fory supports two registration methods:
+
+**1. Register by ID (Recommended for Performance)**
+
+```java
+public record Person(String name, int age) {}
+
+// Register with numeric ID - faster and more compact
+fory.register(Person.class, 1);
+
+Person person = new Person("Alice", 30);
+byte[] bytes = fory.serialize(person);
+// bytes can be deserialized by Python, Rust, Go, etc.
+```
+
+**Benefits**: Faster serialization, smaller binary size
+**Trade-offs**: Requires coordination to avoid ID conflicts across
teams/services
+
+**2. Register by Name (Recommended for Flexibility)**
+
+```java
+public record Person(String name, int age) {}
+
+// Register with string name - more flexible
+fory.register(Person.class, "example.Person");
+
+Person person = new Person("Alice", 30);
+byte[] bytes = fory.serialize(person);
+// bytes can be deserialized by Python, Rust, Go, etc.
+```
+
+**Benefits**: Less prone to conflicts, easier management across teams, no
coordination needed
+**Trade-offs**: Slightly larger binary size due to string encoding
+
+#### Cross-Language Example: Java ↔ Python
+
+**Java (Serializer)**
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+
+public record Person(String name, int age) {}
+
+public class Example {
+ public static void main(String[] args) {
+ Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .withRefTracking(true)
+ .build();
+
+ // Register with consistent name
+ fory.register(Person.class, "example.Person");
+
+ Person person = new Person("Bob", 25);
+ byte[] bytes = fory.serialize(person);
+
+ // Send bytes to Python service via network/file/queue
+ }
+}
+```
+
+**Python (Deserializer)**
+
+```python
+import pyfory
+from dataclasses import dataclass
+
+@dataclass
+class Person:
+ name: str
+ age: pyfory.int32
+
+# Create Fory in xlang mode
+fory = pyfory.Fory(ref_tracking=True)
+
+# Register with the SAME name as Java
+fory.register_type(Person, typename="example.Person")
+
+# Deserialize bytes from Java
+person = fory.deserialize(bytes_from_java)
+print(f"{person.name}, {person.age}") # Output: Bob, 25
+```
+
+#### Handling Circular and Shared References
+
+Cross-language mode supports circular and shared references when reference
tracking is enabled:
+
+```java
+public class Node {
+ public String value;
+ public Node next;
+ public Node parent;
+}
+
+Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .withRefTracking(true) // Required for circular references
+ .build();
+
+fory.register(Node.class, "example.Node");
+
+// Create circular reference
+Node node1 = new Node();
+node1.value = "A";
+Node node2 = new Node();
+node2.value = "B";
+node1.next = node2;
+node2.parent = node1; // Circular reference
+
+byte[] bytes = fory.serialize(node1);
+// Python/Rust/Go can correctly deserialize this with circular references
preserved
+```
+
+#### Type Mapping Considerations
+
+Not all Java types have equivalents in other languages. When using xlang mode:
+
+- Use **primitive types** (`int`, `long`, `double`, `String`) for maximum
compatibility
+- Use **standard collections** (`List`, `Map`, `Set`) instead of
language-specific ones
+- Avoid **Java-specific types** like `Optional`, `BigDecimal` (unless the
target language supports them)
+- See [Type Mapping Guide](../specification/xlang_type_mapping.md) for
complete compatibility matrix
+
+**Compatible Types**:
+
+```java
+public record UserData(
+ String name, // ✅ Compatible
+ int age, // ✅ Compatible
+ List<String> tags, // ✅ Compatible
+ Map<String, Integer> scores // ✅ Compatible
+) {}
+```
+
+**Problematic Types**:
+
+```java
+public record UserData(
+ Optional<String> name, // ❌ Not cross-language compatible
+ BigDecimal balance, // ❌ Limited support
+ EnumSet<Status> statuses // ❌ Java-specific collection
+) {}
+```
+
+#### Performance Considerations
+
+Cross-language mode has additional overhead compared to Java-only mode:
+
+- **Type metadata encoding**: Adds extra bytes per type
+- **Type resolution**: Requires name/ID lookup during deserialization
+
+**For best performance**:
+
+- Use **ID-based registration** when possible (smaller encoding)
+- **Disable reference tracking** if you don't need circular references
(`withRefTracking(false)`)
+- **Use Java mode** (`Language.JAVA`) when only Java serialization is needed
+
+#### Cross-Language Best Practices
+
+1. **Consistent Registration**: Ensure all services register types with
identical IDs/names
+2. **Version Compatibility**: Use compatible mode for schema evolution across
services
+
+#### Troubleshooting Cross-Language Serialization
+
+**"Type not registered" errors**:
+
+- Verify type is registered with same ID/name on both sides
+- Check if type name has typos or case differences
+
+**"Type mismatch" errors**:
+
+- Ensure field types are compatible across languages
+- Review [Type Mapping
Guide](https://fory.apache.org/docs/next/specification/xlang_type_mapping)
+
+**Data corruption or unexpected values**:
+
+- Verify both sides use `Language.XLANG` mode
+- Ensure both sides have compatible Fory versions
+
+**See Also**:
+
+- [Cross-Language Serialization
Specification](https://fory.apache.org/docs/next/specification/fory_xlang_serialization_spec)
+- [Type Mapping
Reference](https://fory.apache.org/docs/next/specification/xlang_type_mapping)
+- [Python Cross-Language Guide](python_guide.md#cross-language-serialization)
+- [Rust Cross-Language Guide](rust_guide.md#-cross-language-serialization)
+
### Implement a customized serializer
+````
+
In some cases, you may want to implement a serializer for your type,
especially some class customize serialization by
JDK `writeObject/writeReplace/readObject/readResolve`, which is very
inefficient. For example, if you don't want
following `Foo#writeObject` got invoked, you can take following
`FooSerializer` as an example:
@@ -1537,3 +1746,4 @@ deserialization instead of
`Fory#deserializeJavaObjectAndClass`/`Fory#deserializ
If you serialize an object by invoking `Fory#serializeJavaObjectAndClass`, you
should
invoke `Fory#deserializeJavaObjectAndClass` for deserialization instead
of `Fory#deserializeJavaObject`/`Fory#deserialize`.
+````
diff --git a/docs/guide/row_format_guide.md b/docs/guide/row_format_guide.md
index a2526c1fe..ec6df6d63 100644
--- a/docs/guide/row_format_guide.md
+++ b/docs/guide/row_format_guide.md
@@ -1,7 +1,7 @@
---
title: Row Format Guide
sidebar_position: 5
-id: row_format_guide
+id: row_format
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
diff --git a/docs/guide/scala_guide.md b/docs/guide/scala_guide.md
index 29da5ee33..1070a5ac5 100644
--- a/docs/guide/scala_guide.md
+++ b/docs/guide/scala_guide.md
@@ -1,7 +1,7 @@
---
title: Scala Serialization Guide
sidebar_position: 3
-id: scala_guide
+id: scala_serialization
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
diff --git a/docs/guide/xlang_serialization_guide.md
b/docs/guide/xlang_serialization_guide.md
index 331440b0f..a5715a60a 100644
--- a/docs/guide/xlang_serialization_guide.md
+++ b/docs/guide/xlang_serialization_guide.md
@@ -1,7 +1,7 @@
---
title: Xlang Serialization Guide
sidebar_position: 4
-id: xlang_object_graph_guide
+id: xlang_serialization
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
diff --git a/java/README.md b/java/README.md
index b5b62fad5..97ac71a97 100644
--- a/java/README.md
+++ b/java/README.md
@@ -1,14 +1,414 @@
# Apache Fory™ Java
-## Code format
+[](https://search.maven.org/#search|gav|1|g:"org.apache.fory"%20AND%20a:"fory-core")
+[](https://www.oracle.com/java/)
+[](https://opensource.org/licenses/Apache-2.0)
+
+Apache Fory™ Java provides blazingly-fast serialization for the Java
ecosystem, delivering up to **170x performance improvement** over traditional
frameworks through JIT compilation and zero-copy techniques.
+
+## Features
+
+### 🚀 High Performance
+
+- **JIT Code Generation**: Highly-extensible JIT framework generates
serializer code at runtime using async multi-threaded compilation, delivering
20-170x speedup through:
+ - Inlining variables to reduce memory access
+ - Inlining method calls to eliminate virtual dispatch overhead
+ - Minimizing conditional branching
+ - Eliminating hash lookups
+- **Zero-Copy**: Direct memory access without intermediate buffer copies; row
format supports random access and partial serialization
+- **Variable-Length Encoding**: Optimized compression for integers, longs
+- **Meta Sharing**: Cached class metadata reduces redundant type information
+- **SIMD Acceleration**: Java Vector API support for array operations (Java
16+)
+
+### 🔧 Drop-in Replacement
+
+- **100% JDK Serialization Compatible**: Supports
`writeObject`/`readObject`/`writeReplace`/`readResolve`/`readObjectNoData`/`Externalizable`
+- **Java 8-24 Support**: Works across all modern Java versions including Java
17+ records
+- **GraalVM Native Image**: AOT compilation support without reflection
configuration
+
+### 🔄 Advanced Features
+
+- **Reference Tracking**: Automatic handling of shared and circular references
+- **Schema Evolution**: Forward/backward compatibility for class schema changes
+- **Polymorphism**: Full support for inheritance hierarchies and interfaces
+- **Deep Copy**: Efficient deep cloning of complex object graphs with
reference preservation
+- **Security**: Class registration and configurable deserialization policies
+
+## Documentation
+
+| Topic | Description | Source Doc Link
| Website Doc Link
|
+| --------------------------- | ------------------------- |
------------------------------------------------------------------------------
|
--------------------------------------------------------------------------------------------------
|
+| **Java Serialization** | Comprehensive usage guide |
[java_serialization_guide.md](../docs/guide/java_serialization_guide.md)
| [Java Serialization
Guide](https://fory.apache.org/docs/docs/guide/java_serialization) |
+| **GraalVM Native Image** | Native image support |
[graalvm_guide.md](../docs/guide/graalvm_guide.md)
| [GraalVM
Guide](https://fory.apache.org/docs/docs/guide/graalvm_serialization)
|
+| **Java Serialization Spec** | Protocol specification |
[java_serialization_spec.md](../docs/specification/java_serialization_spec.md)
| [Java Serialization
Spec](https://fory.apache.org/docs/specification/fory_java_serialization_spec) |
+
+## Modules
+
+| Module | Description | Maven Artifact
|
+| ------------------- | ------------------------------------- |
--------------------------------- |
+| **fory-core** | Core serialization engine |
`org.apache.fory:fory-core` |
+| **fory-format** | Row format and Apache Arrow support |
`org.apache.fory:fory-format` |
+| **fory-simd** | SIMD-accelerated array compression |
`org.apache.fory:fory-simd` |
+| **fory-extensions** | Protobuf support and meta compression |
`org.apache.fory:fory-extensions` |
+| **fory-test-core** | Testing utilities and data generators |
`org.apache.fory:fory-test-core` |
+
+## Installation
+
+### Maven
+
+```xml
+<dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-core</artifactId>
+ <version>0.13.0</version>
+</dependency>
+
+<!-- Optional: Row format support -->
+<dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-format</artifactId>
+ <version>0.13.0</version>
+</dependency>
+
+<!-- Optional: Serializers for Protobuf data -->
+<dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-extensions</artifactId>
+ <version>0.13.0</version>
+</dependency>
+
+<!-- Optional: SIMD acceleration (Java 16+) -->
+<dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-simd</artifactId>
+ <version>0.13.0</version>
+</dependency>
+```
+
+### Gradle
+
+```gradle
+dependencies {
+ implementation 'org.apache.fory:fory-core:0.13.0'
+ // Optional modules
+ implementation 'org.apache.fory:fory-format:0.13.0'
+ implementation 'org.apache.fory:fory-simd:0.13.0'
+ implementation 'org.apache.fory:fory-extensions:0.13.0'
+}
+```
+
+## Quick Start
+
+### Basic Usage
+
+Create a Fory instance, register your classes, and start serializing objects.
Remember to reuse the Fory instance for optimal performance:
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+
+// Create Fory instance (should be reused)
+Fory fory = Fory.builder()
+ .requireClassRegistration(true)
+ .build();
+
+// Register your classes
+fory.register(MyClass.class);
+
+// Serialize
+MyClass object = new MyClass();
+byte[] bytes = fory.serialize(object);
+
+// Deserialize
+MyClass result = (MyClass) fory.deserialize(bytes);
+```
+
+### Thread-Safe Usage
+
+For multi-threaded environments, use `ThreadSafeFory` which maintains a pool
of Fory instances:
+
+```java
+import org.apache.fory.*;
+import org.apache.fory.config.*;
+
+// Create thread-safe Fory instance
+private static final ThreadSafeFory fory =
Fory.builder().buildThreadSafeFory();
+
+static {
+ fory.register(MyClass.class);
+}
+
+// Use in multiple threads
+byte[] bytes = fory.serialize(object);
+Object result = fory.deserialize(bytes);
+```
+
+### Schema Evolution
+
+Enable schema compatibility mode to support forward and backward compatibility
when your class definitions change over time:
+
+```java
+// Enable forward/backward compatibility
+Fory fory = Fory.builder()
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .build();
+
+// Serialization and deserialization can use different class versions
+// New fields will be ignored, missing fields will use default values
+```
+
+### Reference Tracking
+
+Enable reference tracking to properly handle shared references and circular
dependencies in your object graphs:
+
+```java
+// Enable reference tracking for circular/shared references
+Fory fory = Fory.builder()
+ .withRefTracking(true)
+ .build();
+
+// Serialize complex object graphs
+GraphNode node = new GraphNode();
+node.next = node; // Circular reference
+byte[] bytes = fory.serialize(node);
+```
+
+### Cross-Language Serialization
+
+Use XLANG mode to serialize data that can be deserialized by other languages
(Python, Rust, Go, etc.):
+
+```java
+// Use XLANG mode for cross-language compatibility
+Fory fory = Fory.builder()
+ .withLanguage(Language.XLANG)
+ .withRefTracking(true)
+ .build();
+
+// Register with cross-language type id/name
+fory.register(MyClass.class, 1);
+// fory.register(MyClass.class, "com.example.MyClass");
+
+// Bytes can be deserialized by Python, Go, etc.
+byte[] bytes = fory.serialize(object);
+```
+
+## Configuration Options
+
+### ForyBuilder Options
+
+Configure Fory with various options to suit your specific use case:
+
+```java
+Fory fory = Fory.builder()
+ // Language mode: JAVA (fastest) or XLANG (cross-language)
+ .withLanguage(Language.JAVA)
+ // Reference tracking for circular/shared references
+ .withRefTracking(true)
+ // Schema evolution mode
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ // Compression options
+ .withIntCompressed(true)
+ .withLongCompressed(true)
+ .withStringCompressed(false)
+ // Security options
+ .requireClassRegistration(true)
+ .withMaxDepth(50)
+ // Performance options
+ .withCodeGen(true)
+ .withAsyncCompilation(true)
+ // Class loader
+ .withClassLoader(classLoader)
+ .build();
+```
+
+See [Java Serialization Guide](../docs/guide/java_serialization_guide.md) for
detailed configuration options.
+
+## Advanced Features
+
+### JDK Serialization Compatibility
+
+Fory fully supports JDK serialization APIs with 100x better performance. You
can use standard Java serialization methods and Fory will handle them
automatically:
+
+```java
+public class MyClass implements Serializable {
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ // Custom serialization logic
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException {
+ // Custom deserialization logic
+ }
+
+ private Object writeReplace() {
+ // Return replacement object
+ }
+
+ private Object readResolve() {
+ // Return resolved object
+ }
+}
+```
+
+### Deep Copy
+
+Enable reference tracking during deep copy to preserve object identity and
handle circular references correctly:
+
+```java
+Fory fory = Fory.builder()
+ .withLanguage(Language.JAVA)
+ .withRefCopy(true)
+ .build();
+
+MyClass original = new MyClass();
+MyClass copy = fory.copy(original);
+```
+
+### Row Format
+
+Fory provides a cache-friendly binary row format optimized for random access
and analytics:
+
+- **Zero-Copy Random Access**: Read individual fields without deserializing
entire objects
+- **Partial Serialization**: Skip unnecessary fields during serialization
+- **Cross-Language Compatible**: Row format data can be read by Python, C++
+- **Apache Arrow Integration**: Convert row format to/from Arrow RecordBatch
for analytics
+
+```java
+import org.apache.fory.format.encoder.*;
+import org.apache.fory.format.row.*;
+
+public class Bar {
+ String f1;
+ List<Long> f2;
+}
+
+public class Foo {
+ int f1;
+ List<Integer> f2;
+ Map<String, Integer> f3;
+ List<Bar> f4;
+}
+
+// Create row encoder
+RowEncoder<Foo> encoder = Encoders.bean(Foo.class);
+
+// Serialize to row format
+Foo foo = new Foo();
+foo.f1 = 10;
+foo.f2 = IntStream.range(0, 1000).boxed().collect(Collectors.toList());
+BinaryRow binaryRow = encoder.toRow(foo);
+
+// Zero-copy random access to fields
+BinaryArray f2Array = binaryRow.getArray(1); // Access f2 without
deserializing entire object
+BinaryArray f4Array = binaryRow.getArray(3); // Access f4
+
+// Zero-copy access nested fields
+BinaryRow barStruct = f4Array.getStruct(10); // Get 11th element
+long value = barStruct.getArray(1).getInt64(5); // Access nested field
+
+// Partial deserialization
+RowEncoder<Bar> barEncoder = Encoders.bean(Bar.class);
+Bar partialBar = barEncoder.fromRow(barStruct); // Deserialize only one Bar
object
+
+// Full deserialization
+Foo deserializedFoo = encoder.fromRow(binaryRow);
+```
+
+See [Row Format Guide](../docs/guide/row_format_guide.md) for more details.
+
+### Array Compression (Java 16+)
+
+Use SIMD-accelerated compression for integer and long arrays to reduce memory
usage when array elements have small values:
+
+```java
+import org.apache.fory.simd.*;
+
+Fory fory = Fory.builder()
+ .withIntArrayCompressed(true)
+ .withLongArrayCompressed(true)
+ .build();
+
+// Register compressed array serializers
+CompressedArraySerializers.registerSerializers(fory);
+
+// Arrays with small values are automatically compressed
+int[] data = new int[1000000];
+byte[] bytes = fory.serialize(data);
+```
+
+### GraalVM Native Image
+
+Fory supports GraalVM native image through code generation, eliminating the
need for reflection configuration. Build your native image as follows:
+
+```bash
+# Generate serializers at build time
+mvn package -Pnative
+
+# Run native image
+./target/my-app
+```
+
+See [GraalVM Guide](../docs/guide/graalvm_guide.md) for details.
+
+## Development
+
+### Building
+
+All commands must be executed in the `java` directory:
+
+```bash
+# Build
+mvn -T16 clean package
+
+# Run tests
+mvn -T16 test
+
+# Install locally
+mvn -T16 install -DskipTests
+
+# Code formatting
+mvn -T16 spotless:apply
+
+# Code style check
+mvn -T16 checkstyle:check
+```
+
+### Testing
```bash
-mvn -T10 spotless:apply
-mvn -T10 checkstyle:check
+# Run all tests
+mvn -T16 test
+
+# Run specific test
+mvn -T16 test -Dtest=MyTestClass#testMethod
+
+# Run with specific JDK
+JAVA_HOME=/path/to/jdk mvn test
```
-## Testing
+### Code Quality
```bash
-mvn -T10 test -Dcheckstyle.skip -Dmaven.javadoc.skip
+# Format code
+mvn -T16 spotless:apply
+
+# Check code style
+mvn -T16 checkstyle:check
```
+
+## Performance Tips
+
+1. **Reuse Fory Instances**: Creating Fory is expensive; reuse instances
across serializations
+2. **Enable Compression**: For numeric-heavy data, enable int/long compression
+3. **Disable Reference Tracking**: If no circular references exist, disable
tracking for better performance
+4. **Use Java Mode**: Use `Language.JAVA` instead of `Language.XLANG` when
cross-language support isn't needed. Java mode reduces type metadata overhead
and supports more Java-native types not available in xlang mode
+5. **Warm Up**: Allow JIT compilation to complete before benchmarking
+6. **Register Classes**: Class registration reduces metadata overhead
+7. **Use SIMD**: Enable array compression on Java 16+ for numeric arrays
+
+## Contributing
+
+See [CONTRIBUTING.md](../CONTRIBUTING.md) for development guidelines.
+
+## License
+
+Licensed under the [Apache License 2.0](../LICENSE).
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]