2011-12-30 22:00:49 +01:00
|
|
|
/**
|
2012-01-19 18:21:06 +01:00
|
|
|
* Copyright (C) 2009-2012 Typesafe Inc. <http://www.typesafe.com>
|
2011-12-30 22:00:49 +01:00
|
|
|
*/
|
|
|
|
|
package akka.docs.serialization;
|
|
|
|
|
|
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.japi.Option;
|
2011-12-30 22:00:49 +01:00
|
|
|
import akka.serialization.JSerializer;
|
|
|
|
|
import akka.serialization.Serialization;
|
|
|
|
|
import akka.serialization.SerializationExtension;
|
|
|
|
|
import akka.serialization.Serializer;
|
|
|
|
|
import org.junit.Test;
|
2011-12-30 22:13:25 +01:00
|
|
|
import static org.junit.Assert.*;
|
2011-12-30 22:00:49 +01:00
|
|
|
//#imports
|
|
|
|
|
|
|
|
|
|
import akka.serialization.*;
|
|
|
|
|
import akka.actor.ActorSystem;
|
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.PropertyMaster;
|
2011-12-30 22:00:49 +01:00
|
|
|
import com.typesafe.config.*;
|
|
|
|
|
|
|
|
|
|
//#imports
|
|
|
|
|
|
|
|
|
|
public class SerializationDocTestBase {
|
|
|
|
|
//#my-own-serializer
|
|
|
|
|
public static class MyOwnSerializer extends JSerializer {
|
|
|
|
|
|
|
|
|
|
// This is whether "fromBinary" requires a "clazz" or not
|
|
|
|
|
@Override public boolean includeManifest() {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Pick a unique identifier for your Serializer,
|
|
|
|
|
// you've got a couple of billions to choose from,
|
|
|
|
|
// 0 - 16 is reserved by Akka itself
|
|
|
|
|
@Override public int identifier() {
|
|
|
|
|
return 1234567;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// "toBinary" serializes the given object to an Array of Bytes
|
|
|
|
|
@Override public byte[] toBinary(Object obj) {
|
|
|
|
|
// Put the code that serializes the object here
|
|
|
|
|
//#...
|
|
|
|
|
return new byte[0];
|
|
|
|
|
//#...
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// "fromBinary" deserializes the given array,
|
|
|
|
|
// using the type hint (if any, see "includeManifest" above)
|
|
|
|
|
// into the optionally provided classLoader.
|
|
|
|
|
@Override public Object fromBinary(byte[] bytes,
|
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
|
|
|
Class clazz) {
|
2011-12-30 22:00:49 +01:00
|
|
|
// Put your code that deserializes here
|
|
|
|
|
//#...
|
|
|
|
|
return null;
|
|
|
|
|
//#...
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#my-own-serializer
|
|
|
|
|
@Test public void haveExamples() {
|
|
|
|
|
/*
|
|
|
|
|
//#serialize-messages-config
|
|
|
|
|
akka {
|
|
|
|
|
actor {
|
|
|
|
|
serialize-messages = on
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#serialize-messages-config
|
|
|
|
|
|
|
|
|
|
//#serialize-creators-config
|
|
|
|
|
akka {
|
|
|
|
|
actor {
|
|
|
|
|
serialize-creators = on
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#serialize-creators-config
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//#serialize-serializers-config
|
|
|
|
|
akka {
|
|
|
|
|
actor {
|
|
|
|
|
serializers {
|
|
|
|
|
default = "akka.serialization.JavaSerializer"
|
|
|
|
|
|
|
|
|
|
myown = "akka.docs.serialization.MyOwnSerializer"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#serialize-serializers-config
|
|
|
|
|
|
|
|
|
|
//#serialization-bindings-config
|
|
|
|
|
akka {
|
|
|
|
|
actor {
|
|
|
|
|
serializers {
|
|
|
|
|
default = "akka.serialization.JavaSerializer"
|
|
|
|
|
java = "akka.serialization.JavaSerializer"
|
2012-02-03 17:32:32 +01:00
|
|
|
proto = "akka.serialization.ProtobufSerializer"
|
2011-12-30 22:00:49 +01:00
|
|
|
myown = "akka.docs.serialization.MyOwnSerializer"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
serialization-bindings {
|
|
|
|
|
java = ["java.lang.String",
|
|
|
|
|
"app.my.Customer"]
|
2012-02-03 17:32:32 +01:00
|
|
|
proto = ["com.google.protobuf.Message"]
|
2011-12-30 22:00:49 +01:00
|
|
|
myown = ["my.own.BusinessObject",
|
|
|
|
|
"something.equally.Awesome",
|
2012-02-03 17:32:32 +01:00
|
|
|
"akka.docs.serialization.MyOwnSerializable"
|
2011-12-30 22:00:49 +01:00
|
|
|
"java.lang.Boolean"]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
//#serialization-bindings-config
|
|
|
|
|
*/
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test public void demonstrateTheProgrammaticAPI() {
|
|
|
|
|
//#programmatic
|
|
|
|
|
ActorSystem system = ActorSystem.create("example");
|
|
|
|
|
|
|
|
|
|
// Get the Serialization Extension
|
|
|
|
|
Serialization serialization = SerializationExtension.get(system);
|
|
|
|
|
|
|
|
|
|
// Have something to serialize
|
|
|
|
|
String original = "woohoo";
|
|
|
|
|
|
|
|
|
|
// Find the Serializer for it
|
|
|
|
|
Serializer serializer = serialization.findSerializerFor(original);
|
|
|
|
|
|
|
|
|
|
// Turn it into bytes
|
|
|
|
|
byte[] bytes = serializer.toBinary(original);
|
|
|
|
|
|
|
|
|
|
// Turn it back into an object,
|
|
|
|
|
// the nulls are for the class manifest and for the classloader
|
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
|
|
|
String back = (String)serializer.fromBinary(bytes, Option.<Class<?>>none().asScala());
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
|
|
|
// Voilá!
|
|
|
|
|
assertEquals(original, back);
|
|
|
|
|
|
|
|
|
|
//#programmatic
|
|
|
|
|
system.shutdown();
|
|
|
|
|
}
|
|
|
|
|
}
|