blob: 1969ebf5ddc838d00378d8dc031aba1418273833 [file] [view]
---
title: Scala Serialization Guide
sidebar_position: 4
id: scala_guide
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 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 Fory scala for scala 2 with sbt, use the following:
```sbt
libraryDependencies += "org.apache.fory" % "fory-scala_2.13" % "0.11.1"
```
To add a dependency on Fory scala for scala 3 with sbt, use the following:
```sbt
libraryDependencies += "org.apache.fory" % "fory-scala_3" % "0.11.1"
```
## Quict 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 object
```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 = Tuple2(100, 10000L)
println(fory.deserialize(fory.serialize(tuple)))
val tuple = Tuple4(100, 10000L, 10000L, "str")
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)))
```