diff --git a/akka-actor-tests/src/test/resources/reference.conf b/akka-actor-tests/src/test/resources/reference.conf index fb73c9c8d3..2553b0e032 100644 --- a/akka-actor-tests/src/test/resources/reference.conf +++ b/akka-actor-tests/src/test/resources/reference.conf @@ -1,6 +1,7 @@ akka { actor { - serialize-messages = on + serialize-messages = on + warn-about-java-serializer-usage = off } } diff --git a/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala b/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala index 330f2a4b5b..d288e0e60d 100644 --- a/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala @@ -416,6 +416,24 @@ class OverriddenSystemMessageSerializationSpec extends AkkaSpec(SerializationTes } } +@org.junit.runner.RunWith(classOf[org.scalatest.junit.JUnitRunner]) +class DefaultSerializationWarningSpec extends AkkaSpec( + ConfigFactory.parseString("akka.actor.warn-about-java-serializer-usage = on")) { + + val ser = SerializationExtension(system) + + "Using the default Java serializer" must { + + "log a warning" in { + EventFilter.warning(message = "Using the default Java serializer for class.*") intercept { + ser.serializerFor(classOf[java.lang.Integer]) + } + } + + } + +} + protected[akka] trait TestSerializable protected[akka] class TestSerializer extends Serializer { diff --git a/akka-actor/src/main/resources/reference.conf b/akka-actor/src/main/resources/reference.conf index acf6fc71af..1c81b0ca1e 100644 --- a/akka-actor/src/main/resources/reference.conf +++ b/akka-actor/src/main/resources/reference.conf @@ -501,7 +501,13 @@ akka { "[B" = bytes "java.io.Serializable" = java } - + + # Log warnings when the default Java serialization is used to serialize messages. + # The default serializer uses Java serialization which is not very performant and should not + # be used in production environments unless you don't care about performance. In that case + # you can turn this off. + warn-about-java-serializer-usage = on + # Configuration namespace of serialization identifiers. # Each serializer implementation must have an entry in the following format: # `akka.actor.serialization-identifiers."FQCN" = ID` diff --git a/akka-actor/src/main/scala/akka/serialization/Serialization.scala b/akka-actor/src/main/scala/akka/serialization/Serialization.scala index d9b7bd3079..07d553dc3d 100644 --- a/akka-actor/src/main/scala/akka/serialization/Serialization.scala +++ b/akka-actor/src/main/scala/akka/serialization/Serialization.scala @@ -177,6 +177,11 @@ class Serialization(val system: ExtendedActorSystem) extends Extension { } serializerMap.putIfAbsent(clazz, ser) match { case null ⇒ + if (shouldWarnAboutJavaSerializer(clazz, ser)) { + log.warning("Using the default Java serializer for class [{}] which is not recommended because of " + + "performance implications. Use another serializer or disable this warning using the setting " + + "'akka.actor.warn-about-java-serializer-usage'", clazz.getName) + } log.debug("Using serializer[{}] for message [{}]", ser.getClass.getName, clazz.getName) ser case some ⇒ some @@ -241,5 +246,10 @@ class Serialization(val system: ExtendedActorSystem) extends Extension { val serializerByIdentity: Map[Int, Serializer] = Map(NullSerializer.identifier -> NullSerializer) ++ serializers map { case (_, v) ⇒ (v.identifier, v) } + private def shouldWarnAboutJavaSerializer(serializedClass: Class[_], serializer: Serializer) = + settings.config.getBoolean("akka.actor.warn-about-java-serializer-usage") && + serializer.isInstanceOf[JavaSerializer] && + !serializedClass.getName.startsWith("akka.") + } diff --git a/akka-cluster/src/test/resources/reference.conf b/akka-cluster/src/test/resources/reference.conf index 4948247054..1eca761d06 100644 --- a/akka-cluster/src/test/resources/reference.conf +++ b/akka-cluster/src/test/resources/reference.conf @@ -1,6 +1,7 @@ akka { actor { serialize-creators = on - serialize-messages = on + serialize-messages = on + warn-about-java-serializer-usage = off } } diff --git a/akka-persistence/src/test/scala/akka/persistence/OptionalSnapshotStoreSpec.scala b/akka-persistence/src/test/scala/akka/persistence/OptionalSnapshotStoreSpec.scala index cfa9bce7df..776525d00e 100644 --- a/akka-persistence/src/test/scala/akka/persistence/OptionalSnapshotStoreSpec.scala +++ b/akka-persistence/src/test/scala/akka/persistence/OptionalSnapshotStoreSpec.scala @@ -38,6 +38,8 @@ class OptionalSnapshotStoreSpec extends PersistenceSpec(ConfigFactory.parseStrin akka.persistence.journal.plugin = "akka.persistence.journal.inmem" akka.persistence.journal.leveldb.dir = "target/journal-${classOf[OptionalSnapshotStoreSpec].getName}" + akka.actor.warn-about-java-serializer-usage = off + # snapshot store plugin is NOT defined, things should still work akka.persistence.snapshot-store.local.dir = "target/snapshots-${classOf[OptionalSnapshotStoreSpec].getName}/" """)) with ImplicitSender { diff --git a/akka-persistence/src/test/scala/akka/persistence/PersistenceSpec.scala b/akka-persistence/src/test/scala/akka/persistence/PersistenceSpec.scala index 57afa899a6..fe6641daa8 100644 --- a/akka-persistence/src/test/scala/akka/persistence/PersistenceSpec.scala +++ b/akka-persistence/src/test/scala/akka/persistence/PersistenceSpec.scala @@ -56,6 +56,7 @@ object PersistenceSpec { s""" akka.actor.serialize-creators = ${serialization} akka.actor.serialize-messages = ${serialization} + akka.actor.warn-about-java-serializer-usage = off akka.persistence.publish-plugin-commands = on akka.persistence.journal.plugin = "akka.persistence.journal.${plugin}" akka.persistence.journal.leveldb.dir = "target/journal-${test}" diff --git a/akka-remote-tests/src/test/resources/reference.conf b/akka-remote-tests/src/test/resources/reference.conf index 471b1efcfd..1eca761d06 100644 --- a/akka-remote-tests/src/test/resources/reference.conf +++ b/akka-remote-tests/src/test/resources/reference.conf @@ -2,5 +2,6 @@ akka { actor { serialize-creators = on serialize-messages = on + warn-about-java-serializer-usage = off } }