2011-09-09 13:46:36 +02:00
|
|
|
/**
|
2012-01-19 18:21:06 +01:00
|
|
|
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
2011-09-09 13:46:36 +02:00
|
|
|
*/
|
|
|
|
|
|
2011-09-20 21:44:50 +02:00
|
|
|
package akka.remote
|
2011-09-09 13:46:36 +02:00
|
|
|
|
2011-09-20 21:44:50 +02:00
|
|
|
import akka.remote.RemoteProtocol._
|
2011-09-09 13:46:36 +02:00
|
|
|
import com.google.protobuf.ByteString
|
Bye-bye ReflectiveAccess, introducing PropertyMaster, see #1750
- PropertyMaster is the only place in Akka which calls
ClassLoader.getClass (apart from kernel, which might be special)
- all PropertyMaster methods (there are only three) take a ClassManifest
of what is to be constructed, and they verify that the obtained object
is actually compatible with the required type
Other stuff:
- noticed that I had forgotten to change to ExtendedActorSystem when
constructing Extensions by ExtensionKey (damn you, reflection!)
- moved Serializer.currentSystem into JavaSerializer, because that’s the
only one needing it (it’s only used in readResolve() methods)
- Serializers are constructed now with one-arg constructor taking
ExtendedActorSystem (if that exists, otherwise no-arg as before), to
allow JavaSerializer to do its magic; possibly necessary for others as
well
- Removed all Option[ClassLoader] signatures
- made it so that the ActorSystem will try context class loader, then
the class loader which loaded the class actually calling into
ActorSystem.apply, then the loader which loaded ActorSystemImpl
- for the second of the above I added a (reflectively accessed hopefully
safe) facility for getting caller Class[_] objects by using
sun.reflect.Reflection; this is optional an defaults to None, e.g. on
Android, which means that getting the caller’s classloader is done on
a best effort basis (there’s nothing we can do because a StackTrace
does not contain actual Class[_] objects).
- refactored DurableMailbox to contain the owner val and use that
instead of declaring that in all subclasses
2012-02-09 11:56:43 +01:00
|
|
|
import akka.actor.ExtendedActorSystem
|
2011-11-22 13:04:10 +01:00
|
|
|
import akka.serialization.SerializationExtension
|
2011-09-09 13:46:36 +02:00
|
|
|
|
|
|
|
|
object MessageSerializer {
|
|
|
|
|
|
Bye-bye ReflectiveAccess, introducing PropertyMaster, see #1750
- PropertyMaster is the only place in Akka which calls
ClassLoader.getClass (apart from kernel, which might be special)
- all PropertyMaster methods (there are only three) take a ClassManifest
of what is to be constructed, and they verify that the obtained object
is actually compatible with the required type
Other stuff:
- noticed that I had forgotten to change to ExtendedActorSystem when
constructing Extensions by ExtensionKey (damn you, reflection!)
- moved Serializer.currentSystem into JavaSerializer, because that’s the
only one needing it (it’s only used in readResolve() methods)
- Serializers are constructed now with one-arg constructor taking
ExtendedActorSystem (if that exists, otherwise no-arg as before), to
allow JavaSerializer to do its magic; possibly necessary for others as
well
- Removed all Option[ClassLoader] signatures
- made it so that the ActorSystem will try context class loader, then
the class loader which loaded the class actually calling into
ActorSystem.apply, then the loader which loaded ActorSystemImpl
- for the second of the above I added a (reflectively accessed hopefully
safe) facility for getting caller Class[_] objects by using
sun.reflect.Reflection; this is optional an defaults to None, e.g. on
Android, which means that getting the caller’s classloader is done on
a best effort basis (there’s nothing we can do because a StackTrace
does not contain actual Class[_] objects).
- refactored DurableMailbox to contain the owner val and use that
instead of declaring that in all subclasses
2012-02-09 11:56:43 +01:00
|
|
|
def deserialize(system: ExtendedActorSystem, messageProtocol: MessageProtocol): AnyRef = {
|
|
|
|
|
val clazz =
|
|
|
|
|
if (messageProtocol.hasMessageManifest) {
|
2012-02-10 11:36:23 +01:00
|
|
|
system.dynamicAccess.createClassFor[AnyRef](messageProtocol.getMessageManifest.toStringUtf8)
|
Bye-bye ReflectiveAccess, introducing PropertyMaster, see #1750
- PropertyMaster is the only place in Akka which calls
ClassLoader.getClass (apart from kernel, which might be special)
- all PropertyMaster methods (there are only three) take a ClassManifest
of what is to be constructed, and they verify that the obtained object
is actually compatible with the required type
Other stuff:
- noticed that I had forgotten to change to ExtendedActorSystem when
constructing Extensions by ExtensionKey (damn you, reflection!)
- moved Serializer.currentSystem into JavaSerializer, because that’s the
only one needing it (it’s only used in readResolve() methods)
- Serializers are constructed now with one-arg constructor taking
ExtendedActorSystem (if that exists, otherwise no-arg as before), to
allow JavaSerializer to do its magic; possibly necessary for others as
well
- Removed all Option[ClassLoader] signatures
- made it so that the ActorSystem will try context class loader, then
the class loader which loaded the class actually calling into
ActorSystem.apply, then the loader which loaded ActorSystemImpl
- for the second of the above I added a (reflectively accessed hopefully
safe) facility for getting caller Class[_] objects by using
sun.reflect.Reflection; this is optional an defaults to None, e.g. on
Android, which means that getting the caller’s classloader is done on
a best effort basis (there’s nothing we can do because a StackTrace
does not contain actual Class[_] objects).
- refactored DurableMailbox to contain the owner val and use that
instead of declaring that in all subclasses
2012-02-09 11:56:43 +01:00
|
|
|
.fold(throw _, Some(_))
|
|
|
|
|
} else None
|
|
|
|
|
SerializationExtension(system)
|
|
|
|
|
.deserialize(messageProtocol.getMessage.toByteArray, messageProtocol.getSerializerId, clazz) match {
|
2011-12-29 16:11:56 +01:00
|
|
|
case Left(e) ⇒ throw e
|
|
|
|
|
case Right(r) ⇒ r
|
|
|
|
|
}
|
2011-09-09 13:46:36 +02:00
|
|
|
}
|
|
|
|
|
|
Bye-bye ReflectiveAccess, introducing PropertyMaster, see #1750
- PropertyMaster is the only place in Akka which calls
ClassLoader.getClass (apart from kernel, which might be special)
- all PropertyMaster methods (there are only three) take a ClassManifest
of what is to be constructed, and they verify that the obtained object
is actually compatible with the required type
Other stuff:
- noticed that I had forgotten to change to ExtendedActorSystem when
constructing Extensions by ExtensionKey (damn you, reflection!)
- moved Serializer.currentSystem into JavaSerializer, because that’s the
only one needing it (it’s only used in readResolve() methods)
- Serializers are constructed now with one-arg constructor taking
ExtendedActorSystem (if that exists, otherwise no-arg as before), to
allow JavaSerializer to do its magic; possibly necessary for others as
well
- Removed all Option[ClassLoader] signatures
- made it so that the ActorSystem will try context class loader, then
the class loader which loaded the class actually calling into
ActorSystem.apply, then the loader which loaded ActorSystemImpl
- for the second of the above I added a (reflectively accessed hopefully
safe) facility for getting caller Class[_] objects by using
sun.reflect.Reflection; this is optional an defaults to None, e.g. on
Android, which means that getting the caller’s classloader is done on
a best effort basis (there’s nothing we can do because a StackTrace
does not contain actual Class[_] objects).
- refactored DurableMailbox to contain the owner val and use that
instead of declaring that in all subclasses
2012-02-09 11:56:43 +01:00
|
|
|
def serialize(system: ExtendedActorSystem, message: AnyRef): MessageProtocol = {
|
2011-12-29 16:11:56 +01:00
|
|
|
val s = SerializationExtension(system)
|
|
|
|
|
val serializer = s.findSerializerFor(message)
|
2011-09-09 13:46:36 +02:00
|
|
|
val builder = MessageProtocol.newBuilder
|
2011-12-29 16:11:56 +01:00
|
|
|
builder.setMessage(ByteString.copyFrom(serializer.toBinary(message)))
|
|
|
|
|
builder.setSerializerId(serializer.identifier)
|
|
|
|
|
if (serializer.includeManifest)
|
|
|
|
|
builder.setMessageManifest(ByteString.copyFromUtf8(message.getClass.getName))
|
2011-09-09 13:46:36 +02:00
|
|
|
builder.build
|
|
|
|
|
}
|
|
|
|
|
}
|