Scala extensions for the Kryo serialization library
Scala Java Shell
gdiet and johnynek Add class scala.collection.immutable.Queue$EmptyQueue$ to AllScalaReg…
…istrar (#317)

* Update to latest scala versions

* Fix for deprecation warning

* Fixed typo in spec and removed unused import

* Added test to ensure long term stability of registration IDs

* Renamed spec

* Require registration for empty set

* Registration for empty set

* Require registration for hash sets

* Registration for hash sets

* Require registration for list set

* Registration for list set

* Require registration for list, queue, range

* Registration for list, queue, range

* Require registration for hash maps, list maps, None, and arrays

* Registration for hash maps, list maps, None, and arrays

* Require registration for wrapped arrays

* Registration for wrapped arrays

* Require registration for wrapped strings

* Registration for wrapped strings

* Registration for streams

* Registration for TreeSet and TreeMap

* Added missing registrations to test

* Registration for the empty map

* Added missing registrations to test

* found a problem when serializing streams

* fixed stream serializer

* finished test examples

* bumping up scala versions for travis ci

* revert ScalaKryoInstantiator to redesign changes in backward compatible

* introduced 0.9.2 compatibility registrar

* re-added registrations, this time with the backward compatibility layer

* improved scaladoc for changed and new stuff

* first idea for SerializedExamplesOfStandardDataSpec

(cherry picked from commit 19cfef1)

* getting first examples (boxed primitives) to work in the new spec

(cherry picked from commit a389b8f)

* started making SerializedExamplesOfStandardDataSpec a working spec

(cherry picked from commit 1c0f50c)

* working around the 'can't use equals' problem for the spec

(cherry picked from commit 6bb3fce)

* added more examples to SerializedExamplesOfStandardDataSpec

(cherry picked from commit f4dc040)

* compile compatibility to Scala 2.11 and 2.10

* added explicit example for serialization incompatibility between scala versions

* final touches to have something that can be discussed as pull request

* Added Scala 2.10.x exception to SerializedExamplesOfStandardDataSpec

(cherry picked from commit 2a40471)

* SerializedExamplesOfStandardDataSpec added more examples

(cherry picked from commit c6e5b05)

* SerializedExamplesOfStandardDataSpec examples for tupleN

(cherry picked from commit 2ac764b)

* SerializedExamplesOfStandardDataSpec examples for specialized Tuple1

(cherry picked from commit 2bf66b8)

* SerializedExamplesOfStandardDataSpec examples for specialized Tuple2

(cherry picked from commit 4e5b504)

* updated to Scala 2.12.6

(cherry picked from commit 22bfcda)

* more examples in SerializedExamplesOfStandardDataSpec

(cherry picked from commit 8531137)

* finished implementing examples for SerializedExamplesOfStandardDataSpec

(cherry picked from commit bcf0176)

* one additional case where serialization changed with scala version

(cherry picked from commit 81fdfaf)

* added serialization examples for BigDecimal and VolatileByteRef that have been added by PR 312

* added (failing) test that immutable.Queue.EmptyQueue is pre-registered

* added Queue.empty to the list of pre-registered scala classes

* Queue.empty is a special case that needed additional attention in SerializedExamplesOfStandardDataSpec
Latest commit b5dc7ee Aug 13, 2018
Permalink
Failed to load latest commit information.
chill-akka/src Clean up build before releasing 2.12 (#271) Dec 11, 2016
chill-algebird/src add QTreeSerializer (#305) Mar 31, 2018
chill-avro/src fix Nov 7, 2014
chill-bijection/src Review comments Aug 18, 2015
chill-hadoop Merge branch 'develop' of github.com:twitter/chill into Kryo3Upgrade Feb 11, 2016
chill-java Use relatively safe max size of java array (#296) Sep 1, 2017
chill-protobuf/src override protobuf serializer copy method (#314) Aug 11, 2018
chill-scala/src Add class scala.collection.immutable.Queue$EmptyQueue$ to AllScalaReg… Aug 14, 2018
chill-scrooge/src/main/scala/com/twitter/chill/scrooge Use matching classloader in scrooge hack Dec 26, 2015
chill-storm/src/main/java/com/twitter/chill/storm Upgrade to Storm API 1.0.2 (#269) Nov 10, 2016
chill-thrift/src/main/java/com/twitter/chill/thrift Adds chill-thrift Nov 5, 2013
project update the plugins Aug 11, 2018
scripts Add IKryoRegistrar and use it Jul 8, 2013
.gitignore Add to CHANGES.md Feb 2, 2016
.travis.yml Ensure the binary representation of serialized classes is not changed… Jun 18, 2018
CHANGES.md Add changes Feb 11, 2016
COMMITTERS.md Create COMMITTERS.md Aug 26, 2016
LICENSE initial serializers. Oct 15, 2012
NOTICE add notice and readme. Oct 16, 2012
README.md Chill-Akka sample configuration (#304) Mar 26, 2018
build.sbt fix scm setting Aug 11, 2018
sbt Update CHANGES, readme, version and sbt versions in prep for rls Oct 22, 2015
version.sbt Setting version to 0.9.4-SNAPSHOT Aug 11, 2018

README.md

Chill

Build Status Codecov branch Latest version Chat

Extensions for the Kryo serialization library including serializers and a set of classes to ease configuration of Kryo in systems like Hadoop, Storm, Akka, etc.

Building Chill

./sbt
> compile # to build chill
> publishM2 # to publish chill to your local .m2 repo
> publish-local # publish to local ivy repo.

Chill has a set of subprojects: chill-java, chill-hadoop, chill-storm and chill-scala. Other than chill-scala, all these projects are written in Java so they are easy to use on any JVM platform.

Chill-Java

The chill-java package includes the KryoInstantiator class (factory for Kryo instances) and the IKryoRegistrar interface (adds Serializers to a given Kryo). These two are composable to build instantiators that create instances of Kryo that have the options and serializers you need. The benefit of this over a direct Kryo instance is that a Kryo instance is mutable and not serializable, which limits the safety and reusability of code that works directly with them.

To deserialize or serialize easily, look at KryoPool:

int POOL_SIZE = 10;
KryoPool kryo = KryoPool.withByteArrayOutputStream(POOL_SIZE, new KryoInstantiator());
byte[] ser = kryo.toBytesWithClass(myObj);
Object deserObj = kryo.fromBytes(myObj);

The KryoPool is a thread-safe way to share Kryo instances and temporary output buffers.

Chill Config

Hadoop, Storm, and Akka all use a configuration that is basically equivalent to a Map[String, String]. The com.twitter.chill.config package makes it easy to build up KryoInstantiator instances given a Config instance, which is an abstract class acting as a thin wrapper over whatever configuration data the system, such as Hadoop, Storm or Akka, might give.

To configure a KryoInstantiator use ConfiguredInstantiator with either reflection, which takes a class name and instantiates that KryoInstantiator, or an instance of KryoInstantiator and serializes that instance to use later:

class TestInst extends KryoInstantiator { override def newKryo = sys.error("blow up") }

// A new Config:
val conf = new JavaMapConfig
// Set-up class-based reflection of our instantiator:
ConfiguredInstantiator.setReflect(conf, classOf[TestInst])
val cci = new ConfiguredInstantiator(conf)
cci.newKryo // uses TestInst
//Or serialize a particular instance into the config to use later (or another node):

ConfiguredInstantiator.setSerialized(conf, new TestInst)
val cci2 = new ConfiguredInstantiator(conf)
cci2.newKryo // uses the particular instance we passed above

Chill in Scala

Scala classes often have a number of properties that distinguish them from usual Java classes. Often scala classes are immutable, and thus have no zero argument constructor. Secondly, object in scala is a singleton that needs to be carefully serialized. Additionally, scala classes often have synthetic (compiler generated) fields that need to be serialized, and by default Kryo does not serialize those.

In addition to a ScalaKryoInstantiator which generates Kryo instances with options suitable for scala, chill provides a number of Kryo serializers for standard scala classes (see below).

The MeatLocker

Many existing systems use Java serialization. MeatLocker is an object that wraps a given instance using Kryo serialization internally, but the MeatLocker itself is Java serializable. The MeatLocker allows you to box Kryo-serializable objects and deserialize them lazily on the first call to get:

import com.twitter.chill.MeatLocker

val boxedItem = MeatLocker(someItem)

// boxedItem is java.io.Serializable no matter what it contains.
val box = roundTripThroughJava(boxedItem)
box.get == boxedItem.get // true!

To retrieve the boxed item without caching the deserialized value, use meatlockerInstance.copy.

Serializers for Scala classes

These are found in the chill-scala directory in the chill jar (originally this project was only scala serializers). Chill provides support for singletons, scala Objects and the following types:

  • Scala primitives
    • scala.Enumeration values
    • scala.Symbol
    • scala.reflect.Manifest
    • scala.reflect.ClassManifest
    • scala.Function[0-22] closure cleaning (removing unused $outer references).
  • Collections and sequences
    • scala.collection.immutable.Map
    • scala.collection.immutable.List
    • scala.collection.immutable.Vector
    • scala.collection.immutable.Set
    • scala.collection.mutable.{Map, Set, Buffer, WrappedArray}
    • all 22 scala tuples

Chill-bijection

Bijections and Injections are useful when considering serialization. If you have an Injection from T to Array[Byte] you have a serialization. Additionally, if you have a Bijection between A and B, and a serialization for B, then you have a serialization for A. See BijectionEnrichedKryo for easy interop between bijection and chill.

KryoInjection: easy serialization to byte Arrays

KryoInjection is an injection from Any to Array[Byte]. To serialize using it:

import com.twitter.chill.KryoInjection

val bytes:  Array[Byte]    = KryoInjection(someItem)
val tryDecode: scala.util.Try[Any] = KryoInjection.invert(bytes)

KryoInjection can be composed with Bijections and Injections from com.twitter.bijection.

Chill-Akka

To use, add a key to your config like:

    akka.actor.serializers {
      kryo = "com.twitter.chill.akka.AkkaSerializer"
    }

Then for the super-classes of all your message types, for instance, java.io.Serializable (all case classes and case objects are serializable), write:

   akka.actor.serialization-bindings {
     "java.io.Serializable" = kryo
   }

With this in place you can now disable Java serialization entirely:

akka.actor {
  # Set this to on to enable serialization-bindings defined in
  # additional-serialization-bindings. Those are by default not included
  # for backwards compatibility reasons. They are enabled by default if
  # akka.remote.artery.enabled=on.
  enable-additional-serialization-bindings = on
  
  allow-java-serialization = off
}

If you want to use the chill.config.ConfiguredInstantiator see ConfiguredAkkaSerializer otherwise, subclass AkkaSerializer and override kryoInstantiator to control how the Kryo object is created.

Documentation

To learn more and find links to tutorials and information around the web, check out the Chill Wiki.

The latest ScalaDocs are hosted on Chill's Github Project Page.

Contact

Discussion occurs primarily on the Chill mailing list. Issues should be reported on the GitHub issue tracker.

Get Involved + Code of Conduct

Pull requests and bug reports are always welcome!

We use a lightweight form of project governance inspired by the one used by Apache projects. Please see Contributing and Committership for our code of conduct and our pull request review process. The TL;DR is send us a pull request, iterate on the feedback + discussion, and get a +1 from a Committer in order to get your PR accepted.

The current list of active committers (who can +1 a pull request) can be found here: Committers

A list of contributors to the project can be found here: Contributors

Maven

Chill modules are available on Maven Central. The current groupid and version for all modules is, respectively, "com.twitter" and 0.9.1 and each scala project is published for 2.10, 2.11 and 2.12. Search search.maven.org when in doubt.

chill-scala is not published separately; to use it, reference chill. To add the dependency to your project using SBT:

"com.twitter" %% "chill" % "0.9.1"

Authors

License

Copyright 2012 Twitter, Inc.

Licensed under the Apache License, Version 2.0.