# Apache Fory™ Java [![Maven Version](https://img.shields.io/maven-central/v/org.apache.fory/fory-core?style=for-the-badge)](https://search.maven.org/#search|gav|1|g:"org.apache.fory"%20AND%20a:"fory-core") [![Java Version](https://img.shields.io/badge/Java-8%20to%2024-blue?style=for-the-badge)](https://www.oracle.com/java/) [![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg?style=for-the-badge)](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 org.apache.fory fory-core 0.13.2 org.apache.fory fory-format 0.13.2 org.apache.fory fory-extensions 0.13.2 org.apache.fory fory-simd 0.13.2 ``` ### Gradle ```gradle dependencies { implementation 'org.apache.fory:fory-core:0.13.2' // Optional modules implementation 'org.apache.fory:fory-format:0.13.2' implementation 'org.apache.fory:fory-simd:0.13.2' implementation 'org.apache.fory:fory-extensions:0.13.2' } ``` ## 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 f2; } public class Foo { int f1; List f2; Map f3; List f4; } // Create row encoder RowEncoder 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 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 # 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 ``` ### Code Quality ```bash # 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).