tone it down: just a Warning in case of ambiguous serializers

This commit is contained in:
Roland 2012-02-07 15:51:41 +01:00
parent 8b9f1caf67
commit 224ce7f773
6 changed files with 29 additions and 24 deletions

View file

@ -4,7 +4,7 @@
package akka.serialization
import akka.testkit.AkkaSpec
import akka.testkit.{ AkkaSpec, EventFilter }
import akka.actor._
import java.io._
import akka.dispatch.Await
@ -179,9 +179,17 @@ class SerializeSpec extends AkkaSpec(SerializeSpec.config) {
ser.serializerFor(classOf[ExtendedPlainMessage]).getClass must be(classOf[TestSerializer])
}
"throw exception for message with several bindings" in {
intercept[java.io.NotSerializableException] {
ser.serializerFor(classOf[Both])
"give warning for message with several bindings" in {
EventFilter.warning(start = "Multiple serializers found", occurrences = 1) intercept {
ser.serializerFor(classOf[Both]).getClass must be(classOf[TestSerializer])
}
}
"resolve serializer in the order of the bindings" in {
ser.serializerFor(classOf[A]).getClass must be(classOf[JavaSerializer])
ser.serializerFor(classOf[B]).getClass must be(classOf[TestSerializer])
EventFilter.warning(start = "Multiple serializers found", occurrences = 1) intercept {
ser.serializerFor(classOf[C]).getClass must be(classOf[JavaSerializer])
}
}

View file

@ -272,8 +272,8 @@ akka {
}
# Class to Serializer binding. You only need to specify the name of an interface
# or abstract base class of the messages. In case of ambiguity it is
# using the most specific configured class, throwing an exception otherwise.
# or abstract base class of the messages. In case of ambiguity it is using the
# most specific configured class, or giving a warning and choosing the “first” one.
#
# To disable one of the default serializers, assign its class to "none", like
# "java.io.Serializable" = none

View file

@ -129,19 +129,20 @@ class Serialization(val system: ExtendedActorSystem) extends Extension {
def unique(cs: Seq[Class[_]], ser: Set[Serializer]): Boolean = (cs forall (_ isAssignableFrom cs(0))) || ser.size == 1
val possible = bindings filter { _._1 isAssignableFrom clazz }
possible.size match {
val ser = possible.size match {
case 0
throw new NotSerializableException("No configured serialization-bindings for class [%s]" format clazz.getName)
case x if x == 1 || unique(possible map (_._1), possible.map(_._2)(scala.collection.breakOut))
val ser = possible(0)._2
serializerMap.putIfAbsent(clazz, ser) match {
case null
log.debug("Using serializer[{}] for message [{}]", ser.getClass.getName, clazz.getName)
ser
case some some
}
possible(0)._2
case _
throw new NotSerializableException("Multiple serializers found for " + clazz + ": " + possible)
log.warning("Multiple serializers found for " + clazz + ", choosing first: " + possible)
possible(0)._2
}
serializerMap.putIfAbsent(clazz, ser) match {
case null
log.debug("Using serializer[{}] for message [{}]", ser.getClass.getName, clazz.getName)
ser
case some some
}
case ser ser
}

View file

@ -37,8 +37,7 @@ messages. In case of ambiguity, i.e. the message implements several of the
configured classes, the most specific configured class will be used, i.e. the
one of which all other candidates are superclasses. If this condition cannot be
met, because e.g. ``java.io.Serializable`` and ``MyOwnSerializable`` both apply
and neither is a subtype of the other, an exception will be thrown during
serialization.
and neither is a subtype of the other, a warning will be issued.
Akka provides serializers for :class:`java.io.Serializable` and `protobuf
<http://code.google.com/p/protobuf/>`_

View file

@ -37,8 +37,7 @@ messages. In case of ambiguity, i.e. the message implements several of the
configured classes, the most specific configured class will be used, i.e. the
one of which all other candidates are superclasses. If this condition cannot be
met, because e.g. ``java.io.Serializable`` and ``MyOwnSerializable`` both apply
and neither is a subtype of the other, an exception will be thrown during
serialization.
and neither is a subtype of the other, a warning will be issued
Akka provides serializers for :class:`java.io.Serializable` and `protobuf
<http://code.google.com/p/protobuf/>`_

View file

@ -5,20 +5,18 @@
# This the reference config file has all the default settings.
# Make your edits/overrides in your application.conf.
# comments above akka.actor settings left out where they are already in akka-
# actor.jar, because otherwise they would be repeated in config rendering.
akka {
actor {
# Entries for pluggable serializers and their bindings.
serializers {
proto = "akka.serialization.ProtobufSerializer"
}
# Class to Serializer binding. You only need to specify the name of an interface
# or abstract base class of the messages. In case of ambiguity it is
# using the most specific configured class, giving an error if two mappings are found
# which cannot be decided by sub-typing relation.
serialization-bindings {
# Since com.google.protobuf.Message does not extend Serializable but GeneratedMessage
# does, need to use the more specific one here in order to avoid ambiguity