+act #17576 Support serializer with string manifest

* useful when evolution is needed, e.g. Akka Persistence

* docs, comments, cluster-metrics and cluster-tools serializers
This commit is contained in:
Patrik Nordwall 2015-05-28 18:42:22 +02:00
parent aeb2302c2f
commit 740f006a38
21 changed files with 605 additions and 93 deletions

View file

@ -13,6 +13,7 @@ import java.io.NotSerializableException
import scala.util.{ Try, DynamicVariable, Failure }
import scala.collection.immutable
import scala.util.control.NonFatal
import scala.util.Success
object Serialization {
@ -91,7 +92,7 @@ class Serialization(val system: ExtendedActorSystem) extends Extension {
/**
* Deserializes the given array of bytes using the specified serializer id,
* using the optional type hint to the Serializer and the optional ClassLoader ot load it into.
* using the optional type hint to the Serializer.
* Returns either the resulting object or an Exception if one was thrown.
*/
def deserialize[T](bytes: Array[Byte], serializerId: Int, clazz: Option[Class[_ <: T]]): Try[T] =
@ -104,9 +105,37 @@ class Serialization(val system: ExtendedActorSystem) extends Extension {
serializer.fromBinary(bytes, clazz).asInstanceOf[T]
}
/**
* Deserializes the given array of bytes using the specified serializer id,
* using the optional type hint to the Serializer.
* Returns either the resulting object or an Exception if one was thrown.
*/
def deserialize(bytes: Array[Byte], serializerId: Int, manifest: String): Try[AnyRef] =
Try {
val serializer = try serializerByIdentity(serializerId) catch {
case _: NoSuchElementException throw new NotSerializableException(
s"Cannot find serializer with id [$serializerId]. The most probable reason is that the configuration entry " +
"akka.actor.serializers is not in synch between the two systems.")
}
serializer match {
case s2: SerializerWithStringManifest s2.fromBinary(bytes, manifest)
case s1
if (manifest == "")
s1.fromBinary(bytes, None)
else {
system.dynamicAccess.getClassFor[AnyRef](manifest) match {
case Success(classManifest)
s1.fromBinary(bytes, Some(classManifest))
case Failure(e)
throw new NotSerializableException(
s"Cannot find manifest class [$manifest] for serializer with id [$serializerId].")
}
}
}
}
/**
* Deserializes the given array of bytes using the specified type to look up what Serializer should be used.
* You can specify an optional ClassLoader to load the object into.
* Returns either the resulting object or an Exception if one was thrown.
*/
def deserialize[T](bytes: Array[Byte], clazz: Class[T]): Try[T] =
@ -118,10 +147,8 @@ class Serialization(val system: ExtendedActorSystem) extends Extension {
* Throws akka.ConfigurationException if no `serialization-bindings` is configured for the
* class of the object.
*/
def findSerializerFor(o: AnyRef): Serializer = o match {
case null NullSerializer
case other serializerFor(other.getClass)
}
def findSerializerFor(o: AnyRef): Serializer =
if (o eq null) NullSerializer else serializerFor(o.getClass)
/**
* Returns the configured Serializer for the given Class. The configured Serializer
@ -205,5 +232,6 @@ class Serialization(val system: ExtendedActorSystem) extends Extension {
*/
val serializerByIdentity: Map[Int, Serializer] =
Map(NullSerializer.identifier -> NullSerializer) ++ serializers map { case (_, v) (v.identifier, v) }
}