diff --git a/akka-actor-tests/src/test/scala/akka/serialization/NoVerification.scala b/akka-actor-tests/src/test/scala/akka/serialization/NoVerification.scala new file mode 100644 index 0000000000..3f174c54a9 --- /dev/null +++ b/akka-actor-tests/src/test/scala/akka/serialization/NoVerification.scala @@ -0,0 +1,14 @@ +/** + * Copyright (C) 2009-2016 Lightbend Inc. + */ + +package test.akka.serialization + +import akka.actor.NoSerializationVerificationNeeded + +/** + * This is currently used in NoSerializationVerificationNeeded test cases in SerializeSpec, + * as they needed a serializable class whose top package is not akka. + */ +class NoVerification extends NoSerializationVerificationNeeded with java.io.Serializable { +} 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 701d72c16a..0625e9ce73 100644 --- a/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala +++ b/akka-actor-tests/src/test/scala/akka/serialization/SerializeSpec.scala @@ -17,6 +17,8 @@ import scala.beans.BeanInfo import com.typesafe.config._ import akka.pattern.ask import org.apache.commons.codec.binary.Hex.encodeHex +import akka.actor.NoSerializationVerificationNeeded +import test.akka.serialization.NoVerification object SerializationTests { @@ -424,18 +426,18 @@ class DefaultSerializationWarningSpec extends AkkaSpec( ConfigFactory.parseString("akka.actor.warn-about-java-serializer-usage = on")) { val ser = SerializationExtension(system) - val messagePrefix = "Using the default Java serializer for class.*" + val messagePrefix = "Using the default Java serializer for class" "Using the default Java serializer" must { "log a warning when serializing classes outside of java.lang package" in { - EventFilter.warning(message = messagePrefix) intercept { + EventFilter.warning(start = messagePrefix, occurrences = 1) intercept { ser.serializerFor(classOf[java.math.BigDecimal]) } } "not log warning when serializing classes from java.lang package" in { - EventFilter.warning(message = messagePrefix, occurrences = 0) intercept { + EventFilter.warning(start = messagePrefix, occurrences = 0) intercept { ser.serializerFor(classOf[java.lang.String]) } } @@ -444,6 +446,54 @@ class DefaultSerializationWarningSpec extends AkkaSpec( } +class NoVerificationWarningSpec extends AkkaSpec( + ConfigFactory.parseString( + "akka.actor.warn-about-java-serializer-usage = on\n" + + "akka.actor.warn-on-no-serialization-verification = on")) { + + val ser = SerializationExtension(system) + val messagePrefix = "Using the default Java serializer for class" + + "When warn-on-no-serialization-verification = on, using the default Java serializer" must { + + "log a warning on classes without extending NoSerializationVerificationNeeded" in { + EventFilter.warning(start = messagePrefix, occurrences = 1) intercept { + ser.serializerFor(classOf[java.math.BigDecimal]) + } + } + + "still log warning on classes extending NoSerializationVerificationNeeded" in { + EventFilter.warning(start = messagePrefix, occurrences = 1) intercept { + ser.serializerFor(classOf[NoVerification]) + } + } + } +} + +class NoVerificationWarningOffSpec extends AkkaSpec( + ConfigFactory.parseString( + "akka.actor.warn-about-java-serializer-usage = on\n" + + "akka.actor.warn-on-no-serialization-verification = off")) { + + val ser = SerializationExtension(system) + val messagePrefix = "Using the default Java serializer for class" + + "When warn-on-no-serialization-verification = off, using the default Java serializer" must { + + "log a warning on classes without extending NoSerializationVerificationNeeded" in { + EventFilter.warning(start = messagePrefix, occurrences = 1) intercept { + ser.serializerFor(classOf[java.math.BigDecimal]) + } + } + + "not log warning on classes extending NoSerializationVerificationNeeded" in { + EventFilter.warning(start = messagePrefix, occurrences = 0) intercept { + ser.serializerFor(classOf[NoVerification]) + } + } + } +} + 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 b3aaf7eafd..131f9a83ea 100644 --- a/akka-actor/src/main/resources/reference.conf +++ b/akka-actor/src/main/resources/reference.conf @@ -590,6 +590,12 @@ akka { # you can turn this off. warn-about-java-serializer-usage = on + # To be used with the above warn-about-java-serializer-usage + # When warn-about-java-serializer-usage = on, and this warn-on-no-serialization-verification = off, + # warnings are suppressed for classes extending NoSerializationVerificationNeeded + # to reduce noize. + warn-on-no-serialization-verification = 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 4ece346ed1..bd1fb22fd0 100644 --- a/akka-actor/src/main/scala/akka/serialization/Serialization.scala +++ b/akka-actor/src/main/scala/akka/serialization/Serialization.scala @@ -247,13 +247,20 @@ class Serialization(val system: ExtendedActorSystem) extends Extension { Map(NullSerializer.identifier → NullSerializer) ++ serializers map { case (_, v) ⇒ (v.identifier, v) } private val isJavaSerializationWarningEnabled = settings.config.getBoolean("akka.actor.warn-about-java-serializer-usage") + private val isWarningOnNoVerificationEnabled = settings.config.getBoolean("akka.actor.warn-on-no-serialization-verification") private def shouldWarnAboutJavaSerializer(serializedClass: Class[_], serializer: Serializer) = { + + def suppressWarningOnNonSerializationVerification(serializedClass: Class[_]) = { + //suppressed, only when warn-on-no-serialization-verification = off, and extending NoSerializationVerificationNeeded + !isWarningOnNoVerificationEnabled && classOf[NoSerializationVerificationNeeded].isAssignableFrom(serializedClass) + } + isJavaSerializationWarningEnabled && serializer.isInstanceOf[JavaSerializer] && !serializedClass.getName.startsWith("akka.") && - !serializedClass.getName.startsWith("java.lang.") + !serializedClass.getName.startsWith("java.lang.") && + !suppressWarningOnNonSerializationVerification(serializedClass) } - }