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 bde6d6d95 docs: add scala and kotlin docs (#3040)
bde6d6d95 is described below
commit bde6d6d950337d3b622cd00be348dc37099f666e
Author: Shawn Yang <[email protected]>
AuthorDate: Thu Dec 11 10:28:30 2025 +0800
docs: add scala and kotlin docs (#3040)
## Why?
## What does this PR do?
## Related issues
## Does this PR introduce any user-facing change?
- [ ] Does this PR introduce any public API change?
- [ ] Does this PR introduce any binary protocol compatibility change?
## Benchmark
---
cpp/README.md | 2 +-
docs/guide/cpp/index.md | 2 +-
docs/guide/java/index.md | 28 ++
docs/guide/kotlin/default-values.md | 137 +++++++++
docs/guide/kotlin/fory-creation.md | 116 ++++++++
docs/guide/kotlin/index.md | 108 +++++++
docs/guide/kotlin/type-serialization.md | 184 ++++++++++++
docs/guide/rust/index.md | 2 +-
docs/guide/scala/default-values.md | 186 ++++++++++++
docs/guide/scala/fory-creation.md | 139 +++++++++
docs/guide/scala/index.md | 100 +++++++
docs/guide/scala/type-serialization.md | 171 +++++++++++
docs/guide/scala_guide.md | 313 ---------------------
.../{row_format_guide.md => xlang/row_format.md} | 0
.../serialization.md} | 0
kotlin/README.md | 192 ++++++++-----
rust/README.md | 2 +-
rust/fory/src/lib.rs | 2 +-
scala/README.md | 214 +++++++++++++-
19 files changed, 1510 insertions(+), 388 deletions(-)
diff --git a/cpp/README.md b/cpp/README.md
index 5eab2ebd9..7b8663e0b 100644
--- a/cpp/README.md
+++ b/cpp/README.md
@@ -13,7 +13,7 @@ The C++ implementation provides high-performance
serialization with compile-time
- **Type-Safe**: Compile-time type checking with template specialization
- **Shared References**: Automatic tracking of shared and circular references
- **Schema Evolution**: Compatible mode for independent schema changes
-- **Two Modes**: Object graph serialization and zero-copy row-based format
+- **Two Formats**: Object graph serialization and zero-copy row-based format
- **Modern C++17**: Clean API using modern C++ features
## Quick Start
diff --git a/docs/guide/cpp/index.md b/docs/guide/cpp/index.md
index 19c40d992..e31b99244 100644
--- a/docs/guide/cpp/index.md
+++ b/docs/guide/cpp/index.md
@@ -30,7 +30,7 @@ The C++ implementation provides high-performance
serialization with compile-time
- **🎯 Type-Safe**: Compile-time type checking with macro-based struct
registration
- **🔄 Reference Tracking**: Automatic tracking of shared and circular
references
- **📦 Schema Evolution**: Compatible mode for independent schema changes
-- **âš¡ Two Modes**: Object graph serialization and zero-copy row-based format
+- **âš¡ Two Formats**: Object graph serialization and zero-copy row-based format
- **🧵 Thread Safety**: Both single-threaded (fastest) and thread-safe variants
## Installation
diff --git a/docs/guide/java/index.md b/docs/guide/java/index.md
index e7c05a69d..eeecad2fc 100644
--- a/docs/guide/java/index.md
+++ b/docs/guide/java/index.md
@@ -21,6 +21,34 @@ license: |
Apache Foryâ„¢ provides blazingly fast Java object serialization with JIT
compilation and zero-copy techniques. When only Java object serialization is
needed, this mode delivers better performance compared to cross-language object
graph serialization.
+## 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
+
## Quick Start
Note that Fory creation is not cheap, the **Fory instances should be reused
between serializations** instead of creating it every time. You should keep
Fory as a static global variable, or instance variable of some singleton object
or limited objects.
diff --git a/docs/guide/kotlin/default-values.md
b/docs/guide/kotlin/default-values.md
new file mode 100644
index 000000000..76c1882a6
--- /dev/null
+++ b/docs/guide/kotlin/default-values.md
@@ -0,0 +1,137 @@
+---
+title: Default Values
+sidebar_position: 3
+id: kotlin_default_values
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+Fory supports Kotlin data class default values during deserialization when
using compatible mode. This feature enables forward/backward compatibility when
data class schemas evolve.
+
+## Overview
+
+When a Kotlin data class has parameters with default values, Fory can:
+
+1. **Detect default values** using Kotlin reflection
+2. **Apply default values** during deserialization when fields are missing
from serialized data
+3. **Support schema evolution** by allowing new fields with defaults to be
added without breaking existing serialized data
+
+## Usage
+
+This feature is automatically enabled when:
+
+- Compatible mode is enabled (`withCompatibleMode(CompatibleMode.COMPATIBLE)`)
+- Kotlin serializers are registered
(`KotlinSerializers.registerSerializers(fory)`)
+- A field is missing from the serialized data but exists in the target class
with a default value
+
+## Example
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.config.CompatibleMode
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+// Original data class
+data class User(val name: String, val age: Int)
+
+// Evolved data class with new field and default value
+data class UserV2(val name: String, val age: Int, val email: String =
"[email protected]")
+
+fun main() {
+ val fory = Fory.builder()
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .build()
+ KotlinSerializers.registerSerializers(fory)
+ fory.register(User::class.java)
+ fory.register(UserV2::class.java)
+
+ // Serialize with old schema
+ val oldUser = User("John", 30)
+ val serialized = fory.serialize(oldUser)
+
+ // Deserialize with new schema - missing field gets default value
+ val newUser = fory.deserialize(serialized) as UserV2
+ println(newUser) // UserV2(name=John, age=30, [email protected])
+}
+```
+
+## Supported Default Value Types
+
+The following types are supported for default values:
+
+- **Primitive types**: `Int`, `Long`, `Double`, `Float`, `Boolean`, `Byte`,
`Short`, `Char`
+- **Unsigned types**: `UInt`, `ULong`, `UByte`, `UShort`
+- **String**: `String`
+- **Collections**: `List`, `Set`, `Map` (with default instances)
+- **Custom objects**: Any object that can be instantiated via reflection
+
+## Complex Default Values
+
+Default values can be complex expressions:
+
+```kotlin
+data class ConfigV1(val name: String)
+
+data class ConfigV2(
+ val name: String,
+ val settings: Map<String, String> = mapOf("default" to "value"),
+ val tags: List<String> = listOf("default"),
+ val enabled: Boolean = true,
+ val retryCount: Int = 3
+)
+
+val fory = Fory.builder()
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .build()
+KotlinSerializers.registerSerializers(fory)
+
+val original = ConfigV1("myConfig")
+val serialized = fory.serialize(original)
+
+val deserialized = fory.deserialize(serialized) as ConfigV2
+// deserialized.name == "myConfig"
+// deserialized.settings == mapOf("default" to "value")
+// deserialized.tags == listOf("default")
+// deserialized.enabled == true
+// deserialized.retryCount == 3
+```
+
+## Nullable Fields with Defaults
+
+Nullable fields with default values are also supported:
+
+```kotlin
+data class PersonV1(val name: String)
+
+data class PersonV2(
+ val name: String,
+ val nickname: String? = null,
+ val age: Int? = null
+)
+
+val original = PersonV1("John")
+val serialized = fory.serialize(original)
+
+val deserialized = fory.deserialize(serialized) as PersonV2
+// deserialized.name == "John"
+// deserialized.nickname == null (default)
+// deserialized.age == null (default)
+```
+
+## Related Topics
+
+- [Schema Evolution](../java/schema-evolution.md) - Forward/backward
compatibility in Java
+- [Fory Creation](fory-creation.md) - Setting up Fory with compatible mode
diff --git a/docs/guide/kotlin/fory-creation.md
b/docs/guide/kotlin/fory-creation.md
new file mode 100644
index 000000000..1ccf6ff2c
--- /dev/null
+++ b/docs/guide/kotlin/fory-creation.md
@@ -0,0 +1,116 @@
+---
+title: Fory Creation
+sidebar_position: 1
+id: kotlin_fory_creation
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+This page covers Kotlin-specific requirements for creating Fory instances.
+
+## Basic Setup
+
+When using Fory for Kotlin serialization, register Kotlin serializers via
`KotlinSerializers.registerSerializers(fory)`:
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+val fory = Fory.builder()
+ .requireClassRegistration(true)
+ .build()
+
+// Register Kotlin serializers
+KotlinSerializers.registerSerializers(fory)
+```
+
+## Thread Safety
+
+Fory instance creation is not cheap. Instances should be shared between
multiple serializations.
+
+### Single-Thread Usage
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+object ForyHolder {
+ val fory: Fory = Fory.builder()
+ .requireClassRegistration(true)
+ .build().also {
+ KotlinSerializers.registerSerializers(it)
+ }
+}
+```
+
+### Multi-Thread Usage
+
+For multi-threaded applications, use `ThreadSafeFory`:
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.ThreadSafeFory
+import org.apache.fory.ThreadLocalFory
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+object ForyHolder {
+ val fory: ThreadSafeFory = ThreadLocalFory { classLoader ->
+ Fory.builder()
+ .withClassLoader(classLoader)
+ .requireClassRegistration(true)
+ .build().also {
+ KotlinSerializers.registerSerializers(it)
+ }
+ }
+}
+```
+
+### Using Builder Methods
+
+```kotlin
+// Thread-safe Fory
+val fory: ThreadSafeFory = Fory.builder()
+ .requireClassRegistration(true)
+ .buildThreadSafeFory()
+
+KotlinSerializers.registerSerializers(fory)
+```
+
+## Configuration Options
+
+All configuration options from Fory Java are available. See [Java
Configuration Options](../java/configuration.md) for the complete list.
+
+Common options for Kotlin:
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.config.CompatibleMode
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+val fory = Fory.builder()
+ // Enable reference tracking for circular references
+ .withRefTracking(true)
+ // Enable schema evolution support
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ // Enable async compilation for better startup performance
+ .withAsyncCompilation(true)
+ // Compression options
+ .withIntCompressed(true)
+ .withLongCompressed(true)
+ .build()
+
+KotlinSerializers.registerSerializers(fory)
+```
diff --git a/docs/guide/kotlin/index.md b/docs/guide/kotlin/index.md
new file mode 100644
index 000000000..6975c8958
--- /dev/null
+++ b/docs/guide/kotlin/index.md
@@ -0,0 +1,108 @@
+---
+title: Kotlin Serialization Guide
+sidebar_position: 0
+id: kotlin_serialization_index
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+Apache Foryâ„¢ Kotlin provides optimized serializers for Kotlin types, built on
top of Fory Java. Most standard Kotlin types work out of the box with the
default Fory Java implementation, while Fory Kotlin adds additional support for
Kotlin-specific types.
+
+Supported types include:
+
+- `data class` serialization
+- Unsigned primitives: `UByte`, `UShort`, `UInt`, `ULong`
+- Unsigned arrays: `UByteArray`, `UShortArray`, `UIntArray`, `ULongArray`
+- Stdlib types: `Pair`, `Triple`, `Result`
+- Ranges: `IntRange`, `LongRange`, `CharRange`, and progressions
+- Collections: `ArrayDeque`, empty collections (`emptyList`, `emptyMap`,
`emptySet`)
+- `kotlin.time.Duration`, `kotlin.text.Regex`, `kotlin.uuid.Uuid`
+
+## Features
+
+Fory Kotlin inherits all features from Fory Java, plus Kotlin-specific
optimizations:
+
+- **High Performance**: JIT code generation, zero-copy, 20-170x faster than
traditional serialization
+- **Kotlin Type Support**: Optimized serializers for data classes, unsigned
types, ranges, and stdlib types
+- **Default Value Support**: Automatic handling of Kotlin data class default
parameters during schema evolution
+- **Schema Evolution**: Forward/backward compatibility for class schema changes
+
+See [Java Features](../java/index.md#features) for complete feature list.
+
+## Installation
+
+### Maven
+
+```xml
+<dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-kotlin</artifactId>
+ <version>0.13.2</version>
+</dependency>
+```
+
+### Gradle
+
+```kotlin
+implementation("org.apache.fory:fory-kotlin:0.13.2")
+```
+
+## Quick Start
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.ThreadSafeFory
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+data class Person(val name: String, val id: Long, val github: String)
+data class Point(val x: Int, val y: Int, val z: Int)
+
+fun main() {
+ // Create Fory instance (should be reused)
+ val fory: ThreadSafeFory = Fory.builder()
+ .requireClassRegistration(true)
+ .buildThreadSafeFory()
+
+ // Register Kotlin serializers
+ KotlinSerializers.registerSerializers(fory)
+
+ // Register your classes
+ fory.register(Person::class.java)
+ fory.register(Point::class.java)
+
+ val p = Person("Shawn Yang", 1, "https://github.com/chaokunyang")
+ println(fory.deserialize(fory.serialize(p)))
+ println(fory.deserialize(fory.serialize(Point(1, 2, 3))))
+}
+```
+
+## Built on Fory Java
+
+Fory Kotlin is built on top of Fory Java. Most configuration options,
features, and concepts from Fory Java apply directly to Kotlin. Refer to the
Java documentation for:
+
+- [Configuration Options](../java/configuration.md) - All ForyBuilder options
+- [Basic Serialization](../java/basic-serialization.md) - Serialization
patterns and APIs
+- [Type Registration](../java/type-registration.md) - Class registration and
security
+- [Schema Evolution](../java/schema-evolution.md) - Forward/backward
compatibility
+- [Custom Serializers](../java/custom-serializers.md) - Implement custom
serializers
+- [Compression](../java/compression.md) - Int, long, and string compression
+- [Troubleshooting](../java/troubleshooting.md) - Common issues and solutions
+
+## Kotlin-Specific Documentation
+
+- [Fory Creation](fory-creation.md) - Kotlin-specific Fory setup requirements
+- [Type Serialization](type-serialization.md) - Serializing Kotlin types
+- [Default Values](default-values.md) - Kotlin data class default values
support
diff --git a/docs/guide/kotlin/type-serialization.md
b/docs/guide/kotlin/type-serialization.md
new file mode 100644
index 000000000..c555245e8
--- /dev/null
+++ b/docs/guide/kotlin/type-serialization.md
@@ -0,0 +1,184 @@
+---
+title: Type Serialization
+sidebar_position: 2
+id: kotlin_type_serialization
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+This page covers serialization of Kotlin-specific types.
+
+## Setup
+
+All examples assume the following setup:
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.serializer.kotlin.KotlinSerializers
+
+val fory = Fory.builder()
+ .requireClassRegistration(false)
+ .build()
+
+KotlinSerializers.registerSerializers(fory)
+```
+
+## Data Class
+
+```kotlin
+data class Person(val name: String, val age: Int, val id: Long)
+
+fory.register(Person::class.java)
+
+val p = Person("John", 30, 1L)
+println(fory.deserialize(fory.serialize(p)))
+```
+
+## Unsigned Primitives
+
+Kotlin unsigned types are fully supported:
+
+```kotlin
+val uByte: UByte = 255u
+val uShort: UShort = 65535u
+val uInt: UInt = 4294967295u
+val uLong: ULong = 18446744073709551615u
+
+println(fory.deserialize(fory.serialize(uByte)))
+println(fory.deserialize(fory.serialize(uShort)))
+println(fory.deserialize(fory.serialize(uInt)))
+println(fory.deserialize(fory.serialize(uLong)))
+```
+
+## Unsigned Arrays
+
+```kotlin
+val uByteArray = ubyteArrayOf(1u, 2u, 255u)
+val uShortArray = ushortArrayOf(1u, 2u, 65535u)
+val uIntArray = uintArrayOf(1u, 2u, 4294967295u)
+val uLongArray = ulongArrayOf(1u, 2u, 18446744073709551615u)
+
+println(fory.deserialize(fory.serialize(uByteArray)).contentToString())
+println(fory.deserialize(fory.serialize(uShortArray)).contentToString())
+println(fory.deserialize(fory.serialize(uIntArray)).contentToString())
+println(fory.deserialize(fory.serialize(uLongArray)).contentToString())
+```
+
+## Stdlib Types
+
+### Pair and Triple
+
+```kotlin
+val pair = Pair("key", 42)
+val triple = Triple("a", "b", "c")
+
+println(fory.deserialize(fory.serialize(pair)))
+println(fory.deserialize(fory.serialize(triple)))
+```
+
+### Result
+
+```kotlin
+val success: Result<Int> = Result.success(42)
+val failure: Result<Int> = Result.failure(Exception("error"))
+
+println(fory.deserialize(fory.serialize(success)))
+println(fory.deserialize(fory.serialize(failure)))
+```
+
+## Ranges and Progressions
+
+```kotlin
+val intRange = 1..10
+val longRange = 1L..100L
+val charRange = 'a'..'z'
+
+println(fory.deserialize(fory.serialize(intRange)))
+println(fory.deserialize(fory.serialize(longRange)))
+println(fory.deserialize(fory.serialize(charRange)))
+
+// Progressions
+val intProgression = 1..10 step 2
+val longProgression = 1L..100L step 10
+
+println(fory.deserialize(fory.serialize(intProgression)))
+println(fory.deserialize(fory.serialize(longProgression)))
+```
+
+## Collections
+
+### ArrayDeque
+
+```kotlin
+val deque = ArrayDeque<String>()
+deque.addFirst("first")
+deque.addLast("last")
+
+println(fory.deserialize(fory.serialize(deque)))
+```
+
+### Empty Collections
+
+```kotlin
+val emptyList = emptyList<String>()
+val emptySet = emptySet<Int>()
+val emptyMap = emptyMap<String, Int>()
+
+println(fory.deserialize(fory.serialize(emptyList)))
+println(fory.deserialize(fory.serialize(emptySet)))
+println(fory.deserialize(fory.serialize(emptyMap)))
+```
+
+## Duration
+
+```kotlin
+import kotlin.time.Duration
+import kotlin.time.Duration.Companion.hours
+import kotlin.time.Duration.Companion.minutes
+
+val duration: Duration = 2.hours + 30.minutes
+
+println(fory.deserialize(fory.serialize(duration)))
+```
+
+## Regex
+
+```kotlin
+val regex = Regex("[a-zA-Z]+")
+
+println(fory.deserialize(fory.serialize(regex)))
+```
+
+## UUID (Kotlin 2.0+)
+
+```kotlin
+import kotlin.uuid.Uuid
+
+val uuid = Uuid.random()
+
+println(fory.deserialize(fory.serialize(uuid)))
+```
+
+## Types Working Out of the Box
+
+The following types work with the default Fory Java implementation without
needing `KotlinSerializers`:
+
+- **Primitives**: `Byte`, `Boolean`, `Int`, `Short`, `Long`, `Char`, `Float`,
`Double`
+- **String**: `String`
+- **Collections**: `ArrayList`, `HashMap`, `HashSet`, `LinkedHashSet`,
`LinkedHashMap`
+- **Arrays**: `Array`, `BooleanArray`, `ByteArray`, `CharArray`,
`DoubleArray`, `FloatArray`, `IntArray`, `LongArray`, `ShortArray`
+
+However, it's recommended to always call
`KotlinSerializers.registerSerializers(fory)` to ensure all Kotlin types are
properly supported.
diff --git a/docs/guide/rust/index.md b/docs/guide/rust/index.md
index d4b7eebbf..522fbf3c0 100644
--- a/docs/guide/rust/index.md
+++ b/docs/guide/rust/index.md
@@ -31,7 +31,7 @@ The Rust implementation provides versatile and
high-performance serialization wi
- **🔄 Circular References**: Automatic tracking of shared and circular
references with `Rc`/`Arc` and weak pointers
- **🧬 Polymorphic**: Serialize trait objects with `Box<dyn Trait>`, `Rc<dyn
Trait>`, and `Arc<dyn Trait>`
- **📦 Schema Evolution**: Compatible mode for independent schema changes
-- **âš¡ Two Modes**: Object graph serialization and zero-copy row-based format
+- **âš¡ Two Formats**: Object graph serialization and zero-copy row-based format
## Crates
diff --git a/docs/guide/scala/default-values.md
b/docs/guide/scala/default-values.md
new file mode 100644
index 000000000..6c13178f0
--- /dev/null
+++ b/docs/guide/scala/default-values.md
@@ -0,0 +1,186 @@
+---
+title: Default Values
+sidebar_position: 3
+id: scala_default_values
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+Fory supports Scala class default values during deserialization when using
compatible mode. This feature enables forward/backward compatibility when case
classes or regular Scala classes have default parameters.
+
+## Overview
+
+When a Scala class has default parameters, the Scala compiler generates
methods in the companion object (for case classes) or in the class itself (for
regular Scala classes) like `apply$default$1`, `apply$default$2`, etc. that
return the default values. Fory can detect these methods and use them when
deserializing objects where certain fields are missing from the serialized data.
+
+## Supported Class Types
+
+Fory supports default values for:
+
+- **Case classes** with default parameters
+- **Regular Scala classes** with default parameters in their primary
constructor
+- **Nested case classes** with default parameters
+
+## How It Works
+
+1. **Detection**: Fory detects if a class is a Scala class by checking for the
presence of default value methods (`apply$default$N` or `$default$N`).
+
+2. **Default Value Discovery**:
+ - For case classes: Fory scans the companion object for methods named
`apply$default$1`, `apply$default$2`, etc.
+ - For regular Scala classes: Fory scans the class itself for methods named
`$default$1`, `$default$2`, etc.
+
+3. **Field Mapping**: During deserialization, Fory identifies fields that
exist in the target class but are missing from the serialized data.
+
+4. **Value Application**: After reading all available fields from the
serialized data, Fory applies default values to any missing fields.
+
+## Usage
+
+This feature is automatically enabled when:
+
+- Compatible mode is enabled (`withCompatibleMode(CompatibleMode.COMPATIBLE)`)
+- The target class is detected as a Scala class with default values
+- A field is missing from the serialized data but exists in the target class
+
+No additional configuration is required.
+
+## Examples
+
+### Case Class with Default Values
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.config.CompatibleMode
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+// Class WITHOUT default values (for serialization)
+case class PersonV1(name: String)
+
+// Class WITH default values (for deserialization)
+case class PersonV2(name: String, age: Int = 25, city: String = "Unknown")
+
+val fory = Fory.builder()
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+ScalaSerializers.registerSerializers(fory)
+
+// Serialize using class without default values
+val original = PersonV1("John")
+val serialized = fory.serialize(original)
+
+// Deserialize into class with default values
+// Missing fields will use defaults
+val deserialized = fory.deserialize(serialized).asInstanceOf[PersonV2]
+// deserialized.name == "John"
+// deserialized.age == 25 (default)
+// deserialized.city == "Unknown" (default)
+```
+
+### Regular Scala Class with Default Values
+
+```scala
+// Class WITHOUT default values (for serialization)
+class EmployeeV1(val name: String)
+
+// Class WITH default values (for deserialization)
+class EmployeeV2(
+ val name: String,
+ val age: Int = 30,
+ val department: String = "Engineering"
+)
+
+val fory = Fory.builder()
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+ScalaSerializers.registerSerializers(fory)
+
+// Serialize using class without default values
+val original = new EmployeeV1("Jane")
+val serialized = fory.serialize(original)
+
+// Deserialize into class with default values
+val deserialized = fory.deserialize(serialized).asInstanceOf[EmployeeV2]
+// deserialized.name == "Jane"
+// deserialized.age == 30 (default)
+// deserialized.department == "Engineering" (default)
+```
+
+### Complex Default Values
+
+Default values can be complex expressions:
+
+```scala
+// Class WITHOUT default values (for serialization)
+case class ConfigV1(name: String)
+
+// Class WITH default values (for deserialization)
+case class ConfigV2(
+ name: String,
+ settings: Map[String, String] = Map("default" -> "value"),
+ tags: List[String] = List("default"),
+ enabled: Boolean = true
+)
+
+val fory = Fory.builder()
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+ScalaSerializers.registerSerializers(fory)
+
+val original = ConfigV1("myConfig")
+val serialized = fory.serialize(original)
+
+val deserialized = fory.deserialize(serialized).asInstanceOf[ConfigV2]
+// deserialized.name == "myConfig"
+// deserialized.settings == Map("default" -> "value")
+// deserialized.tags == List("default")
+// deserialized.enabled == true
+```
+
+### Nested Case Classes
+
+```scala
+object Models {
+ // Class WITHOUT default values (for serialization)
+ case class PersonV1(name: String)
+
+ // Classes WITH default values (for deserialization)
+ case class Address(street: String, city: String = "DefaultCity")
+ case class PersonV2(name: String, address: Address =
Address("DefaultStreet"))
+}
+
+val fory = Fory.builder()
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+ScalaSerializers.registerSerializers(fory)
+
+val original = Models.PersonV1("Alice")
+val serialized = fory.serialize(original)
+
+val deserialized = fory.deserialize(serialized).asInstanceOf[Models.PersonV2]
+// deserialized.name == "Alice"
+// deserialized.address == Address("DefaultStreet", "DefaultCity")
+```
+
+## Related Topics
+
+- [Schema Evolution](../java/schema-evolution.md) - Forward/backward
compatibility in Java
+- [Fory Creation](fory-creation.md) - Setting up Fory with compatible mode
diff --git a/docs/guide/scala/fory-creation.md
b/docs/guide/scala/fory-creation.md
new file mode 100644
index 000000000..278d72318
--- /dev/null
+++ b/docs/guide/scala/fory-creation.md
@@ -0,0 +1,139 @@
+---
+title: Fory Creation
+sidebar_position: 1
+id: scala_fory_creation
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+This page covers Scala-specific requirements for creating Fory instances.
+
+## Basic Setup
+
+When using Fory for Scala serialization, you must:
+
+1. Enable Scala optimization via `withScalaOptimizationEnabled(true)`
+2. Register Scala serializers via `ScalaSerializers.registerSerializers(fory)`
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+val fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+// Register optimized Fory serializers for Scala
+ScalaSerializers.registerSerializers(fory)
+```
+
+## Registering Scala Internal Types
+
+Depending on the object types you serialize, you may need to register some
Scala internal types:
+
+```scala
+fory.register(Class.forName("scala.Enumeration.Val"))
+```
+
+To avoid such registration, you can disable class registration:
+
+```scala
+val fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .requireClassRegistration(false)
+ .build()
+```
+
+> **Note**: Disabling class registration allows deserialization of unknown
types. This is more flexible but may be insecure if the classes contain
malicious code.
+
+## Reference Tracking
+
+Circular references are common in Scala. Reference tracking should be enabled
with `withRefTracking(true)`:
+
+```scala
+val fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .withRefTracking(true)
+ .build()
+```
+
+> **Note**: If you don't enable reference tracking,
[StackOverflowError](https://github.com/apache/fory/issues/1032) may occur for
some Scala versions when serializing Scala Enumeration.
+
+## Thread Safety
+
+Fory instance creation is not cheap. Instances should be shared between
multiple serializations.
+
+### Single-Thread Usage
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+object ForyHolder {
+ val fory: Fory = {
+ val f = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .build()
+ ScalaSerializers.registerSerializers(f)
+ f
+ }
+}
+```
+
+### Multi-Thread Usage
+
+For multi-threaded applications, use `ThreadSafeFory`:
+
+```scala
+import org.apache.fory.ThreadSafeFory
+import org.apache.fory.ThreadLocalFory
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+object ForyHolder {
+ val fory: ThreadSafeFory = new ThreadLocalFory(classLoader => {
+ val f = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .withClassLoader(classLoader)
+ .build()
+ ScalaSerializers.registerSerializers(f)
+ f
+ })
+}
+```
+
+## Configuration Options
+
+All configuration options from Fory Java are available. See [Java
Configuration Options](../java/configuration.md) for the complete list.
+
+Common options for Scala:
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.config.CompatibleMode
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+val fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ // Enable reference tracking for circular references
+ .withRefTracking(true)
+ // Enable schema evolution support
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ // Enable async compilation for better startup performance
+ .withAsyncCompilation(true)
+ .build()
+
+ScalaSerializers.registerSerializers(fory)
+```
diff --git a/docs/guide/scala/index.md b/docs/guide/scala/index.md
new file mode 100644
index 000000000..7d158bcf1
--- /dev/null
+++ b/docs/guide/scala/index.md
@@ -0,0 +1,100 @@
+---
+title: Scala Serialization Guide
+sidebar_position: 0
+id: scala_serialization_index
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+Apache Foryâ„¢ Scala provides optimized serializers for Scala types, built on
top of Fory Java. It supports all Scala object serialization:
+
+- `case` class serialization
+- `pojo/bean` class serialization
+- `object` singleton serialization
+- `collection` serialization (Seq, List, Map, etc.)
+- `tuple` and `either` types
+- `Option` types
+- Scala 2 and 3 enumerations
+
+Both Scala 2 and Scala 3 are supported.
+
+## Features
+
+Fory Scala inherits all features from Fory Java, plus Scala-specific
optimizations:
+
+- **High Performance**: JIT code generation, zero-copy, 20-170x faster than
traditional serialization
+- **Scala Type Support**: Optimized serializers for case classes, singletons,
collections, tuples, Option, Either
+- **Default Value Support**: Automatic handling of Scala class default
parameters during schema evolution
+- **Singleton Preservation**: `object` singletons maintain referential
equality after deserialization
+- **Schema Evolution**: Forward/backward compatibility for class schema changes
+
+See [Java Features](../java/index.md#features) for complete feature list.
+
+## Installation
+
+Add the dependency with sbt:
+
+```sbt
+libraryDependencies += "org.apache.fory" %% "fory-scala" % "0.13.2"
+```
+
+## Quick Start
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+case class Person(name: String, id: Long, github: String)
+case class Point(x: Int, y: Int, z: Int)
+
+object ScalaExample {
+ // Create Fory with Scala optimization enabled
+ val fory: Fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+ // Register optimized Fory serializers for Scala
+ ScalaSerializers.registerSerializers(fory)
+
+ // Register your classes
+ fory.register(classOf[Person])
+ fory.register(classOf[Point])
+
+ def main(args: Array[String]): Unit = {
+ val p = Person("Shawn Yang", 1, "https://github.com/chaokunyang")
+ println(fory.deserialize(fory.serialize(p)))
+ println(fory.deserialize(fory.serialize(Point(1, 2, 3))))
+ }
+}
+```
+
+## Built on Fory Java
+
+Fory Scala is built on top of Fory Java. Most configuration options, features,
and concepts from Fory Java apply directly to Scala. Refer to the Java
documentation for:
+
+- [Configuration Options](../java/configuration.md) - All ForyBuilder options
+- [Basic Serialization](../java/basic-serialization.md) - Serialization
patterns and APIs
+- [Type Registration](../java/type-registration.md) - Class registration and
security
+- [Schema Evolution](../java/schema-evolution.md) - Forward/backward
compatibility
+- [Custom Serializers](../java/custom-serializers.md) - Implement custom
serializers
+- [Compression](../java/compression.md) - Int, long, and string compression
+- [Troubleshooting](../java/troubleshooting.md) - Common issues and solutions
+
+## Scala-Specific Documentation
+
+- [Fory Creation](fory-creation.md) - Scala-specific Fory setup requirements
+- [Type Serialization](type-serialization.md) - Serializing Scala types
+- [Default Values](default-values.md) - Scala class default values support
diff --git a/docs/guide/scala/type-serialization.md
b/docs/guide/scala/type-serialization.md
new file mode 100644
index 000000000..f8b8107e1
--- /dev/null
+++ b/docs/guide/scala/type-serialization.md
@@ -0,0 +1,171 @@
+---
+title: Type Serialization
+sidebar_position: 2
+id: scala_type_serialization
+license: |
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+---
+
+This page covers serialization of Scala-specific types.
+
+## Setup
+
+All examples assume the following setup:
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+val fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+ScalaSerializers.registerSerializers(fory)
+```
+
+## Case Class
+
+```scala
+case class Person(github: String, age: Int, id: Long)
+
+fory.register(classOf[Person])
+
+val p = Person("https://github.com/chaokunyang", 18, 1)
+println(fory.deserialize(fory.serialize(p)))
+```
+
+## POJO Class
+
+```scala
+class Foo(f1: Int, f2: String) {
+ override def toString: String = s"Foo($f1, $f2)"
+}
+
+fory.register(classOf[Foo])
+
+println(fory.deserialize(fory.serialize(new Foo(1, "chaokunyang"))))
+```
+
+## Object Singleton
+
+Scala `object` singletons are serialized and deserialized to the same instance:
+
+```scala
+object MySingleton {
+ val value = 42
+}
+
+fory.register(MySingleton.getClass)
+
+val o1 = fory.deserialize(fory.serialize(MySingleton))
+val o2 = fory.deserialize(fory.serialize(MySingleton))
+println(o1 == o2) // true
+```
+
+## Collection
+
+Scala collections are fully supported:
+
+```scala
+val seq = Seq(1, 2)
+val list = List("a", "b")
+val map = Map("a" -> 1, "b" -> 2)
+
+println(fory.deserialize(fory.serialize(seq)))
+println(fory.deserialize(fory.serialize(list)))
+println(fory.deserialize(fory.serialize(map)))
+```
+
+## Tuple
+
+All Scala tuple types (Tuple1 through Tuple22) are supported:
+
+```scala
+val tuple2 = (100, 10000L)
+println(fory.deserialize(fory.serialize(tuple2)))
+
+val tuple4 = (100, 10000L, 10000L, "str")
+println(fory.deserialize(fory.serialize(tuple4)))
+```
+
+## Enum
+
+### Scala 3 Enum
+
+```scala
+enum Color { case Red, Green, Blue }
+
+fory.register(classOf[Color])
+
+println(fory.deserialize(fory.serialize(Color.Green)))
+```
+
+### Scala 2 Enumeration
+
+```scala
+object ColorEnum extends Enumeration {
+ type ColorEnum = Value
+ val Red, Green, Blue = Value
+}
+
+fory.register(Class.forName("scala.Enumeration.Val"))
+
+println(fory.deserialize(fory.serialize(ColorEnum.Green)))
+```
+
+> **Note**: For Scala 2 Enumeration, you may need to register
`scala.Enumeration.Val` or enable reference tracking to avoid
`StackOverflowError`.
+
+## Option
+
+```scala
+val some: Option[Long] = Some(100)
+println(fory.deserialize(fory.serialize(some)))
+
+val none: Option[Long] = None
+println(fory.deserialize(fory.serialize(none)))
+```
+
+## Either
+
+```scala
+val right: Either[String, Int] = Right(42)
+println(fory.deserialize(fory.serialize(right)))
+
+val left: Either[String, Int] = Left("error")
+println(fory.deserialize(fory.serialize(left)))
+```
+
+## Nested Types
+
+Complex nested structures are fully supported:
+
+```scala
+case class Address(street: String, city: String)
+case class Company(name: String, address: Address)
+case class Employee(name: String, company: Company, tags: List[String])
+
+fory.register(classOf[Address])
+fory.register(classOf[Company])
+fory.register(classOf[Employee])
+
+val employee = Employee(
+ "John",
+ Company("Acme", Address("123 Main St", "Springfield")),
+ List("developer", "scala")
+)
+
+println(fory.deserialize(fory.serialize(employee)))
+```
diff --git a/docs/guide/scala_guide.md b/docs/guide/scala_guide.md
deleted file mode 100644
index f2d42e0dd..000000000
--- a/docs/guide/scala_guide.md
+++ /dev/null
@@ -1,313 +0,0 @@
----
-title: Scala Serialization Guide
-sidebar_position: 3
-id: scala_serialization
-license: |
- Licensed to the Apache Software Foundation (ASF) under one or more
- contributor license agreements. See the NOTICE file distributed with
- this work for additional information regarding copyright ownership.
- The ASF licenses this file to You under the Apache License, Version 2.0
- (the "License"); you may not use this file except in compliance with
- the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
----
-
-Apache Foryâ„¢ supports all scala object serialization:
-
-- `case` class serialization supported
-- `pojo/bean` class serialization supported
-- `object` singleton serialization supported
-- `collection` serialization supported
-- other types such as `tuple/either` and basic types are all supported too.
-
-Scala 2 and 3 are both supported.
-
-## Install
-
-To add a dependency on Apache Foryâ„¢ scala for with sbt, use the following:
-
-```sbt
-libraryDependencies += "org.apache.fory" %% "fory-scala" % "0.13.2"
-```
-
-## Quick Start
-
-```scala
-case class Person(name: String, id: Long, github: String)
-case class Point(x : Int, y : Int, z : Int)
-
-object ScalaExample {
- val fory: Fory = Fory.builder().withScalaOptimizationEnabled(true).build()
- // Register optimized fory serializers for scala
- ScalaSerializers.registerSerializers(fory)
- fory.register(classOf[Person])
- fory.register(classOf[Point])
-
- def main(args: Array[String]): Unit = {
- val p = Person("Shawn Yang", 1, "https://github.com/chaokunyang")
- println(fory.deserialize(fory.serialize(p)))
- println(fory.deserialize(fory.serialize(Point(1, 2, 3))))
- }
-}
-```
-
-## Fory creation
-
-When using fory for scala serialization, you should create fory at least with
following options:
-
-```scala
-import org.apache.fory.Fory
-import org.apache.fory.serializer.scala.ScalaSerializers
-
-val fory = Fory.builder().withScalaOptimizationEnabled(true).build()
-
-// Register optimized fory serializers for scala
-ScalaSerializers.registerSerializers(fory)
-```
-
-Depending on the object types you serialize, you may need to register some
scala internal types:
-
-```scala
-fory.register(Class.forName("scala.Enumeration.Val"))
-```
-
-If you want to avoid such registration, you can disable class registration by
`ForyBuilder#requireClassRegistration(false)`.
-Note that this option allow to deserialize objects unknown types, more
flexible but may be insecure if the classes contains malicious code.
-
-And circular references are common in scala, `Reference tracking` should be
enabled by `ForyBuilder#withRefTracking(true)`. If you don't enable reference
tracking, [StackOverflowError](https://github.com/apache/fory/issues/1032) may
happen for some scala versions when serializing scala Enumeration.
-
-Note that fory instance should be shared between multiple serialization, the
creation of fory instance is not cheap.
-
-If you use shared fory instance across multiple threads, you should create
`ThreadSafeFory` instead by `ForyBuilder#buildThreadSafeFory()` instead.
-
-## Serialize case class
-
-```scala
-case class Person(github: String, age: Int, id: Long)
-val p = Person("https://github.com/chaokunyang", 18, 1)
-println(fory.deserialize(fory.serialize(p)))
-println(fory.deserializeJavaObject(fory.serializeJavaObject(p)))
-```
-
-## Serialize pojo
-
-```scala
-class Foo(f1: Int, f2: String) {
- override def toString: String = s"Foo($f1, $f2)"
-}
-println(fory.deserialize(fory.serialize(Foo(1, "chaokunyang"))))
-```
-
-## Serialize object singleton
-
-```scala
-object singleton {
-}
-val o1 = fory.deserialize(fory.serialize(singleton))
-val o2 = fory.deserialize(fory.serialize(singleton))
-println(o1 == o2)
-```
-
-## Serialize collection
-
-```scala
-val seq = Seq(1,2)
-val list = List("a", "b")
-val map = Map("a" -> 1, "b" -> 2)
-println(fory.deserialize(fory.serialize(seq)))
-println(fory.deserialize(fory.serialize(list)))
-println(fory.deserialize(fory.serialize(map)))
-```
-
-## Serialize Tuple
-
-```scala
-val tuple = (100, 10000L) //Tuple2
-println(fory.deserialize(fory.serialize(tuple)))
-val tuple = (100, 10000L, 10000L, "str") //Tuple4
-println(fory.deserialize(fory.serialize(tuple)))
-```
-
-## Serialize Enum
-
-### Scala3 Enum
-
-```scala
-enum Color { case Red, Green, Blue }
-println(fory.deserialize(fory.serialize(Color.Green)))
-```
-
-### Scala2 Enum
-
-```scala
-object ColorEnum extends Enumeration {
- type ColorEnum = Value
- val Red, Green, Blue = Value
-}
-println(fory.deserialize(fory.serialize(ColorEnum.Green)))
-```
-
-## Serialize Option
-
-```scala
-val opt: Option[Long] = Some(100)
-println(fory.deserialize(fory.serialize(opt)))
-val opt1: Option[Long] = None
-println(fory.deserialize(fory.serialize(opt1)))
-```
-
-## Scala Class Default Values Support
-
-Fory supports Scala class default values during deserialization when using
compatible mode. This feature enables forward/backward compatibility when case
classes or regular Scala classes have default parameters.
-
-### Overview
-
-When a Scala class has default parameters, the Scala compiler generates
methods in the companion object (for case classes) or in the class itself (for
regular Scala classes) like `apply$default$1`, `apply$default$2`, etc. that
return the default values. Fory can detect these methods and use them when
deserializing objects where certain fields are missing from the serialized data.
-
-### Supported Class Types
-
-Fory supports default values for:
-
-- **Case classes** with default parameters
-- **Regular Scala classes** with default parameters in their primary
constructor
-- **Nested case classes** with default parameters
-- **Deeply nested case classes** with default parameters
-
-### How It Works
-
-1. **Detection**: Fory detects if a class is a Scala class by checking for the
presence of default value methods (`apply$default$N` or `$default$N`).
-
-2. **Default Value Discovery**:
- - For case classes: Fory scans the companion object for methods named
`apply$default$1`, `apply$default$2`, etc.
- - For regular Scala classes: Fory scans the class itself for methods named
`$default$1`, `$default$2`, etc.
-
-3. **Field Mapping**: During deserialization, Fory identifies fields that
exist in the target class but are missing from the serialized data.
-
-4. **Value Application**: After reading all available fields from the
serialized data, Fory applies default values to any missing fields using direct
field access for optimal performance.
-
-### Usage
-
-This feature is automatically enabled when:
-
-- Compatible mode is enabled (`withCompatibleMode(CompatibleMode.COMPATIBLE)`)
-- The target class is detected as a Scala class with default values
-- A field is missing from the serialized data but exists in the target class
-
-No additional configuration is required.
-
-### Examples
-
-#### Case Class with Default Values
-
-```scala
-// Class WITHOUT default values (for serialization)
-case class PersonNoDefaults(name: String)
-
-// Class WITH default values (for deserialization)
-case class PersonWithDefaults(name: String, age: Int = 25, city: String =
"Unknown")
-
-val fory = Fory.builder()
- .withCompatibleMode(CompatibleMode.COMPATIBLE)
- .withScalaOptimizationEnabled(true)
- .build()
-
-// Serialize using class without default values
-val original = PersonNoDefaults("John")
-val serialized = fory.serialize(original)
-
-// Deserialize into class with default values - missing fields will use
defaults
-val deserialized = fory.deserialize(serialized, classOf[PersonWithDefaults])
-// deserialized.name will be "John"
-// deserialized.age will be 25 (default)
-// deserialized.city will be "Unknown" (default)
-```
-
-#### Regular Scala Class with Default Values
-
-```scala
-// Class WITHOUT default values (for serialization)
-class EmployeeNoDefaults(val name: String)
-
-// Class WITH default values (for deserialization)
-class EmployeeWithDefaults(val name: String, val age: Int = 30, val
department: String = "Engineering")
-
-val fory = Fory.builder()
- .withCompatibleMode(CompatibleMode.COMPATIBLE)
- .withScalaOptimizationEnabled(true)
- .build()
-
-// Serialize using class without default values
-val original = new EmployeeNoDefaults("Jane")
-val serialized = fory.serialize(original)
-
-// Deserialize into class with default values - missing fields will use
defaults
-val deserialized = fory.deserialize(serialized, classOf[EmployeeWithDefaults])
-// deserialized.name will be "Jane"
-// deserialized.age will be 30 (default)
-// deserialized.department will be "Engineering" (default)
-```
-
-#### Complex Default Values
-
-```scala
-// Class WITHOUT default values (for serialization)
-case class ConfigurationNoDefaults(name: String)
-
-// Class WITH default values (for deserialization)
-case class ConfigurationWithDefaults(
- name: String,
- settings: Map[String, String] = Map("default" -> "value"),
- tags: List[String] = List("default"),
- enabled: Boolean = true
-)
-
-val fory = Fory.builder()
- .withCompatibleMode(CompatibleMode.COMPATIBLE)
- .withScalaOptimizationEnabled(true)
- .build()
-
-// Serialize using class without default values
-val original = ConfigurationNoDefaults("myConfig")
-val serialized = fory.serialize(original)
-
-// Deserialize into class with default values - missing fields will use
defaults
-val deserialized = fory.deserialize(serialized,
classOf[ConfigurationWithDefaults])
-// deserialized.name will be "myConfig"
-// deserialized.settings will be Map("default" -> "value")
-// deserialized.tags will be List("default")
-// deserialized.enabled will be true
-```
-
-#### Nested Case Classes
-
-```scala
-object NestedClasses {
- // Class WITHOUT default values (for serialization)
- case class SimplePerson(name: String)
-
- // Class WITH default values (for deserialization)
- case class Address(street: String, city: String = "DefaultCity")
- case class PersonWithDefaults(name: String, address: Address =
Address("DefaultStreet"))
-}
-
-val fory = Fory.builder()
- .withCompatibleMode(CompatibleMode.COMPATIBLE)
- .withScalaOptimizationEnabled(true)
- .build()
-
-// Serialize using class without default values
-val original = NestedClasses.SimplePerson("Alice")
-val serialized = fory.serialize(original)
-
-// Deserialize into class with default values - missing address field will use
default
-val deserialized = fory.deserialize(serialized,
classOf[NestedClasses.PersonWithDefaults])
-// deserialized.name will be "Alice"
-// deserialized.address will be Address("DefaultStreet", "DefaultCity")
-```
diff --git a/docs/guide/row_format_guide.md b/docs/guide/xlang/row_format.md
similarity index 100%
rename from docs/guide/row_format_guide.md
rename to docs/guide/xlang/row_format.md
diff --git a/docs/guide/xlang_serialization_guide.md
b/docs/guide/xlang/serialization.md
similarity index 100%
rename from docs/guide/xlang_serialization_guide.md
rename to docs/guide/xlang/serialization.md
diff --git a/kotlin/README.md b/kotlin/README.md
index 8c836e62e..185b63107 100644
--- a/kotlin/README.md
+++ b/kotlin/README.md
@@ -1,40 +1,31 @@
# Apache Foryâ„¢ Kotlin
-This provides additional Apache Foryâ„¢ support for Kotlin Serialization on JVM:
+Apache Foryâ„¢ Kotlin provides optimized serializers for Kotlin types, built on
top of Fory Java. It delivers high-performance serialization for the Kotlin
ecosystem with full support for Kotlin-specific types and idioms.
-Most standard kotlin types are already supported out of the box with the
default Apache Foryâ„¢ java implementation.
+Most standard Kotlin types work out of the box with the default Fory Java
implementation, while Fory Kotlin adds additional support for Kotlin-specific
types.
-Apache Foryâ„¢ Kotlin provides additional tests and implementation support for
Kotlin types.
+## Features
+
+### Supported Types
Apache Foryâ„¢ Kotlin is tested and works with the following types:
-- primitives: `Byte`, `Boolean`, `Int`, `Short`, `Long`, `Char`, `Float`,
`Double`, `UByte`, `UShort`, `UInt`, `ULong`.
-- `Byte`, `Boolean`, `Int`, `Short`, `Long`, `Char`, `Float`, `Double` works
out of the box with the default fory java implementation.
-- stdlib `collection`: `ArrayDeque`, `ArrayList`, `HashMap`,`HashSet`,
`LinkedHashSet`, `LinkedHashMap`.
-- `ArrayList`, `HashMap`,`HashSet`, `LinkedHashSet`, `LinkedHashMap` works out
of the box with the default fory java implementation.
-- `String` works out of the box with the default fory java implementation.
-- arrays: `Array`, `BooleanArray`, `ByteArray`, `CharArray`, `DoubleArray`,
`FloatArray`, `IntArray`, `LongArray`, `ShortArray`
-- all standard array types work out of the box with the default fory java
implementation.
-- unsigned arrays: `UByteArray`, `UShortArray`, `UIntArray`, `ULongArray`
-- from stdlib: `Pair`, `Triple`, `Result`
-- kotlin.random: `Random`
-- kotlin.ranges: `CharRange`, `CharProgression`, `IntRange`, `IntProgression`,
`LongRange`, `LongProgression`, `UintRange`, `UintProgression`, `ULongRange`,
`ULongProgression`
-- kotlin.text: `Regex`
-- kotlin.time: `Duration`
-- kotlin.uuid: `Uuid`
-
-Additional support is added for the following classes in kotlin:
-
-- Unsigned primitives: `UByte`, `UShort`, `UInt`, `ULong`
-- Unsigned array types: `UByteArray`, `UShortArray`, `UIntArray`, `ULongArray`
-- Empty collections: `emptyList`, `emptyMap`, `emptySet`
-- Collections: `ArrayDeque`
-- kotlin.time: `Duration`
-- kotlin.uuid: `Uuid`
-
-Additional Notes:
-
-- wrappers classes created from `withDefault` method is currently not
supported.
+- **Data classes**: Full support for data class serialization with all field
types
+- **Primitives**: `Byte`, `Boolean`, `Int`, `Short`, `Long`, `Char`, `Float`,
`Double` (works out of the box)
+- **Unsigned primitives**: `UByte`, `UShort`, `UInt`, `ULong`
+- **Unsigned arrays**: `UByteArray`, `UShortArray`, `UIntArray`, `ULongArray`
+- **Collections**: `ArrayList`, `HashMap`, `HashSet`, `LinkedHashSet`,
`LinkedHashMap` (works out of the box), `ArrayDeque`
+- **Empty collections**: `emptyList`, `emptyMap`, `emptySet`
+- **Arrays**: All standard array types (works out of the box)
+- **Stdlib types**: `Pair`, `Triple`, `Result`
+- **Ranges**: `IntRange`, `LongRange`, `CharRange`, `IntProgression`,
`LongProgression`, `CharProgression`, `UIntRange`, `ULongRange`
+- **Other**: `kotlin.text.Regex`, `kotlin.time.Duration`, `kotlin.uuid.Uuid`,
`kotlin.random.Random`
+
+### Kotlin-Specific Features
+
+- **Default Value Support**: Automatic handling of Kotlin data class default
parameters during schema evolution
+- **Unsigned Type Support**: Full support for Kotlin unsigned primitives and
arrays
+- **Range Serialization**: Optimized serializers for Kotlin ranges and
progressions
## Quick Start
@@ -44,13 +35,18 @@ import org.apache.fory.ThreadSafeFory
import org.apache.fory.serializer.kotlin.KotlinSerializers
data class Person(val name: String, val id: Long, val github: String)
-data class Point(val x : Int, val y : Int, val z : Int)
+data class Point(val x: Int, val y: Int, val z: Int)
+
+fun main() {
+ // Create Fory instance (should be reused)
+ val fory: ThreadSafeFory = Fory.builder()
+ .requireClassRegistration(true)
+ .buildThreadSafeFory()
-fun main(args: Array<String>) {
- // Note: following fory init code should be executed only once in a global
scope instead
- // of initializing it everytime when serialization.
- val fory: ThreadSafeFory =
Fory.builder().requireClassRegistration(true).buildThreadSafeFory()
+ // Register Kotlin serializers
KotlinSerializers.registerSerializers(fory)
+
+ // Register your classes
fory.register(Person::class.java)
fory.register(Point::class.java)
@@ -62,11 +58,11 @@ fun main(args: Array<String>) {
## Default Value Support
-Apache Foryâ„¢ Kotlin provides support for Kotlin data class default values
during serialization and deserialization. This feature allows for backward and
forward compatibility when data class schemas evolve.
+Apache Foryâ„¢ Kotlin provides support for Kotlin data class default values
during deserialization. This feature enables forward/backward compatibility
when data class schemas evolve.
### How It Works
-When a Kotlin data class has parameters with default values, Apache Foryâ„¢ can:
+When a Kotlin data class has parameters with default values, Fory can:
1. **Detect default values** using Kotlin reflection
2. **Apply default values** during deserialization when fields are missing
from serialized data
@@ -98,53 +94,123 @@ fun main() {
val serialized = fory.serialize(oldUser)
// Deserialize with new schema - missing field gets default value
- val newUser = fory.deserialize(serialized, UserV2::class.java)
+ val newUser = fory.deserialize(serialized) as UserV2
println(newUser) // UserV2(name=John, age=30, [email protected])
}
```
-### Supported Default Value Types
+## Thread-Safe Usage
+
+For multi-threaded applications, use `ThreadSafeFory`:
+
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.ThreadSafeFory
+import org.apache.fory.ThreadLocalFory
+import org.apache.fory.serializer.kotlin.KotlinSerializers
-The following types are supported for default values:
+object ForyHolder {
+ val fory: ThreadSafeFory = ThreadLocalFory { classLoader ->
+ Fory.builder()
+ .withClassLoader(classLoader)
+ .requireClassRegistration(true)
+ .build().also {
+ KotlinSerializers.registerSerializers(it)
+ it.register(Person::class.java)
+ }
+ }
+}
-- **Primitive types**: `Int`, `Long`, `Double`, `Float`, `Boolean`, `Byte`,
`Short`, `Char`
-- **String**: `String`
-- **Collections**: `List`, `Set`, `Map` (with default instances)
-- **Custom objects**: Any object that can be instantiated via reflection
+// Use in multiple threads
+val bytes = ForyHolder.fory.serialize(person)
+val result = ForyHolder.fory.deserialize(bytes)
+```
-### Configuration
+## Configuration
-To enable default value support:
+Fory Kotlin is built on Fory Java, so all Java configuration options are
available:
-1. **Enable compatible mode** (recommended for schema evolution):
+```kotlin
+import org.apache.fory.Fory
+import org.apache.fory.config.CompatibleMode
+import org.apache.fory.serializer.kotlin.KotlinSerializers
- ```kotlin
- val fory = Fory.builder()
- .withCompatibleMode(CompatibleMode.COMPATIBLE)
- .build()
- ```
+val fory = Fory.builder()
+ // Enable reference tracking for circular references
+ .withRefTracking(true)
+ // Enable schema evolution support
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ // Enable async compilation for better startup performance
+ .withAsyncCompilation(true)
+ // Compression options
+ .withIntCompressed(true)
+ .withLongCompressed(true)
+ .build()
+
+KotlinSerializers.registerSerializers(fory)
+```
-2. **Register Kotlin serializers**:
+## Documentation
- ```kotlin
- KotlinSerializers.registerSerializers(fory)
- ```
+| Resource | Link |
+| ----------------- | -------------------------------------------------- |
+| **Website** | https://fory.apache.org/docs/guide/kotlin |
+| **Source Docs** | [docs/guide/kotlin](../docs/guide/kotlin/index.md) |
+| **Java Guide** | [docs/guide/java](../docs/guide/java/index.md) |
+| **API Reference** | [Fory Java API](../java/README.md) |
-## Building Apache Foryâ„¢ Kotlin
+## Installation
-```bash
-mvn clean
-mvn -T10 compile
+### Maven
+
+```xml
+<dependency>
+ <groupId>org.apache.fory</groupId>
+ <artifactId>fory-kotlin</artifactId>
+ <version>0.13.2</version>
+</dependency>
```
-## Code Format
+### Gradle
+
+```kotlin
+implementation("org.apache.fory:fory-kotlin:0.13.2")
+```
+
+## Building
+
+Fory Kotlin requires Fory Java to be installed first:
```bash
-mvn -T10 spotless:apply
+# Install Fory Java
+cd ../java && mvn -T16 install -DskipTests
+
+# Build Fory Kotlin
+cd ../kotlin
+mvn clean package
```
## Testing
```bash
-mvn -T10 test
+mvn test
```
+
+## Code Format
+
+```bash
+mvn spotless:apply
+```
+
+## Additional Notes
+
+- **Fory Reuse**: Always reuse Fory instances; creation is expensive
+- **withDefault Collections**: Wrapper classes created from `withDefault`
method are currently not supported
+
+## Contributing
+
+See [CONTRIBUTING.md](../CONTRIBUTING.md) for development guidelines.
+
+## License
+
+Licensed under the [Apache License 2.0](../LICENSE).
diff --git a/rust/README.md b/rust/README.md
index 05315b6bb..f0bef3569 100644
--- a/rust/README.md
+++ b/rust/README.md
@@ -16,7 +16,7 @@ The Rust implementation provides versatile and
high-performance serialization wi
- **🔄 Circular References**: Automatic tracking of shared and circular
references with `Rc`/`Arc` and weak pointers
- **🧬 Polymorphic**: Serialize trait objects with `Box<dyn Trait>`, `Rc<dyn
Trait>`, and `Arc<dyn Trait>`
- **📦 Schema Evolution**: Compatible mode for independent schema changes
-- **âš¡ Two Modes**: Object graph serialization and zero-copy row-based format
+- **âš¡ Two Formats**: Object graph serialization and zero-copy row-based format
## 📦 Crates
diff --git a/rust/fory/src/lib.rs b/rust/fory/src/lib.rs
index a4e85f31d..1997e3bb9 100644
--- a/rust/fory/src/lib.rs
+++ b/rust/fory/src/lib.rs
@@ -41,7 +41,7 @@
//! - **🔄 Circular References**: Automatic tracking of shared and circular
references with `Rc`/`Arc` and weak pointers
//! - **🧬 Polymorphic**: Serialize trait objects with `Box<dyn Trait>`,
`Rc<dyn Trait>`, and `Arc<dyn Trait>`
//! - **📦 Schema Evolution**: Compatible mode for independent schema changes
-//! - **âš¡ Two Modes**: Object graph serialization and zero-copy row-based
format
+//! - **âš¡ Two Formats**: Object graph serialization and zero-copy row-based
format
//!
//! ## Quick Start
//!
diff --git a/scala/README.md b/scala/README.md
index bbf04b584..71cf7add3 100644
--- a/scala/README.md
+++ b/scala/README.md
@@ -1,11 +1,211 @@
# Apache Foryâ„¢ Scala
-Apache Foryâ„¢ supports all scala object serialization:
+Apache Foryâ„¢ Scala provides optimized serializers for Scala types, built on
top of Fory Java. It delivers **high-performance serialization** for the Scala
ecosystem with full support for Scala-specific types and idioms.
-- `case` class serialization supported
-- `pojo/bean` class serialization supported
-- `object` singleton serialization supported
-- `collection` serialization supported
-- other types such as `tuple/either` and basic types are all supported too.
+Both Scala 2 and Scala 3 are supported.
-For user document, see [scala_guide](/docs/guide/scala_guide.md).
+## Features
+
+### Supported Types
+
+Apache Foryâ„¢ Scala is tested and works with the following types:
+
+- **Case classes**: Full support for case class serialization with all field
types
+- **Regular classes**: POJO/bean style classes with constructor parameters
+- **Object singletons**: Scala `object` singletons preserve identity after
deserialization
+- **Collections**: `Seq`, `List`, `Vector`, `Set`, `Map`, `ArrayBuffer`, and
other Scala collections
+- **Tuples**: All tuple types from `Tuple1` to `Tuple22`
+- **Option types**: `Some` and `None`
+- **Either types**: `Left` and `Right`
+- **Enumerations**: Both Scala 2 `Enumeration` and Scala 3 `enum`
+
+### Scala-Specific Features
+
+- **Default Value Support**: Automatic handling of Scala class default
parameters during schema evolution
+- **Singleton Preservation**: `object` singletons maintain referential
equality after deserialization
+- **Scala Collection Optimization**: Optimized serializers for Scala's
immutable and mutable collections
+
+## Quick Start
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+case class Person(name: String, id: Long, github: String)
+case class Point(x: Int, y: Int, z: Int)
+
+object ScalaExample {
+ // Create Fory with Scala optimization enabled
+ val fory: Fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .build()
+
+ // Register optimized Fory serializers for Scala
+ ScalaSerializers.registerSerializers(fory)
+
+ // Register your classes
+ fory.register(classOf[Person])
+ fory.register(classOf[Point])
+
+ def main(args: Array[String]): Unit = {
+ val p = Person("Shawn Yang", 1, "https://github.com/chaokunyang")
+ println(fory.deserialize(fory.serialize(p)))
+ println(fory.deserialize(fory.serialize(Point(1, 2, 3))))
+ }
+}
+```
+
+## Default Value Support
+
+Apache Foryâ„¢ Scala provides support for Scala class default values during
deserialization. This feature enables forward/backward compatibility when case
classes or regular Scala classes have default parameters.
+
+### How It Works
+
+When a Scala class has default parameters, the Scala compiler generates
methods in the companion object (for case classes) or in the class itself that
return default values. Fory detects these methods and uses them when
deserializing objects where certain fields are missing from the serialized data.
+
+### Example Usage
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.config.CompatibleMode
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+// Original case class
+case class User(name: String, age: Int)
+
+// Evolved case class with new fields and default values
+case class UserV2(name: String, age: Int, email: String = "unknown", active:
Boolean = true)
+
+object DefaultValueExample {
+ val fory: Fory = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ .build()
+
+ ScalaSerializers.registerSerializers(fory)
+
+ def main(args: Array[String]): Unit = {
+ // Serialize with old schema
+ val oldUser = User("John", 30)
+ val serialized = fory.serialize(oldUser)
+
+ // Deserialize with new schema - missing fields get default values
+ val newUser = fory.deserialize(serialized).asInstanceOf[UserV2]
+ println(newUser) // UserV2(John, 30, unknown, true)
+ }
+}
+```
+
+### Supported Default Value Types
+
+- **Primitive types**: `Int`, `Long`, `Double`, `Float`, `Boolean`, `Byte`,
`Short`, `Char`
+- **String**: `String`
+- **Collections**: `List`, `Set`, `Map`, `Seq`, etc.
+- **Option types**: `Option[T]`
+- **Custom objects**: Any serializable object
+
+## Thread-Safe Usage
+
+For multi-threaded applications, use `ThreadSafeFory`:
+
+```scala
+import org.apache.fory.{Fory, ThreadSafeFory, ThreadLocalFory}
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+object ForyHolder {
+ val fory: ThreadSafeFory = new ThreadLocalFory(classLoader => {
+ val f = Fory.builder()
+ .withScalaOptimizationEnabled(true)
+ .withClassLoader(classLoader)
+ .build()
+ ScalaSerializers.registerSerializers(f)
+ f.register(classOf[Person])
+ f
+ })
+}
+
+// Use in multiple threads
+val bytes = ForyHolder.fory.serialize(person)
+val result = ForyHolder.fory.deserialize(bytes)
+```
+
+## Configuration
+
+Fory Scala is built on Fory Java, so all Java configuration options are
available:
+
+```scala
+import org.apache.fory.Fory
+import org.apache.fory.config.CompatibleMode
+import org.apache.fory.serializer.scala.ScalaSerializers
+
+val fory = Fory.builder()
+ // Required for Scala
+ .withScalaOptimizationEnabled(true)
+ // Enable reference tracking for circular references
+ .withRefTracking(true)
+ // Enable schema evolution support
+ .withCompatibleMode(CompatibleMode.COMPATIBLE)
+ // Enable async compilation for better startup performance
+ .withAsyncCompilation(true)
+ // Compression options
+ .withIntCompressed(true)
+ .withLongCompressed(true)
+ .build()
+
+ScalaSerializers.registerSerializers(fory)
+```
+
+## Documentation
+
+| Resource | Link |
+| ----------------- | ------------------------------------------------ |
+| **Website** | https://fory.apache.org/docs/guide/scala |
+| **Source Docs** | [docs/guide/scala](../docs/guide/scala/index.md) |
+| **Java Guide** | [docs/guide/java](../docs/guide/java/index.md) |
+| **API Reference** | [Fory Java API](../java/README.md) |
+
+## Installation
+
+Add the dependency with sbt:
+
+```sbt
+libraryDependencies += "org.apache.fory" %% "fory-scala" % "0.13.2"
+```
+
+## Building
+
+Fory Scala requires Fory Java to be installed first:
+
+```bash
+# Install Fory Java
+cd ../java && mvn -T16 install -DskipTests
+
+# Build Fory Scala
+cd ../scala
+sbt compile
+```
+
+## Testing
+
+```bash
+sbt test
+```
+
+## Code Format
+
+```bash
+sbt scalafmt
+```
+
+## Additional Notes
+
+- **Fory Reuse**: Always reuse Fory instances; creation is expensive
+- **Scala Internal Types**: You may need to register some Scala internal types
like `scala.Enumeration.Val`
+
+## 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]