2011-12-15 21:16:19 +01:00
|
|
|
|
|
|
|
|
|
|
.. _serialization-java:
|
|
|
|
|
|
|
|
|
|
|
|
#####################
|
|
|
|
|
|
Serialization (Java)
|
|
|
|
|
|
#####################
|
|
|
|
|
|
|
2011-12-30 22:00:49 +01:00
|
|
|
|
Akka has a built-in Extension for serialization,
|
|
|
|
|
|
and it is both possible to use the built-in serializers and to write your own.
|
|
|
|
|
|
|
|
|
|
|
|
The serialization mechanism is both used by Akka internally to serialize messages,
|
|
|
|
|
|
and available for ad-hoc serialization of whatever you might need it for.
|
|
|
|
|
|
|
|
|
|
|
|
Usage
|
|
|
|
|
|
=====
|
|
|
|
|
|
|
|
|
|
|
|
Configuration
|
|
|
|
|
|
-------------
|
|
|
|
|
|
|
2012-01-05 09:31:21 +01:00
|
|
|
|
For Akka to know which ``Serializer`` to use for what, you need edit your :ref:`configuration`,
|
2011-12-30 22:00:49 +01:00
|
|
|
|
in the "akka.actor.serializers"-section you bind names to implementations of the ``akka.serialization.Serializer``
|
|
|
|
|
|
you wish to use, like this:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialize-serializers-config
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
|
|
|
|
|
After you've bound names to different implementations of ``Serializer`` you need to wire which classes
|
|
|
|
|
|
should be serialized using which ``Serializer``, this is done in the "akka.actor.serialization-bindings"-section:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialization-bindings-config
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
2012-02-07 15:11:16 +01:00
|
|
|
|
You only need to specify the name of an interface or abstract base class of the
|
|
|
|
|
|
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
|
2012-02-07 15:51:41 +01:00
|
|
|
|
and neither is a subtype of the other, a warning will be issued.
|
2012-02-03 17:32:32 +01:00
|
|
|
|
|
2012-02-07 15:11:16 +01:00
|
|
|
|
Akka provides serializers for :class:`java.io.Serializable` and `protobuf
|
|
|
|
|
|
<http://code.google.com/p/protobuf/>`_
|
|
|
|
|
|
:class:`com.google.protobuf.GeneratedMessage` by default (the latter only if
|
|
|
|
|
|
depending on the akka-remote module), so normally you don't need to add
|
|
|
|
|
|
configuration for that; since :class:`com.google.protobuf.GeneratedMessage`
|
|
|
|
|
|
implements :class:`java.io.Serializable`, protobuf messages will always by
|
|
|
|
|
|
serialized using the protobuf protocol unless specifically overridden. In order
|
|
|
|
|
|
to disable a default serializer, map its marker type to “none”::
|
2012-02-03 17:32:32 +01:00
|
|
|
|
|
2012-02-07 15:11:16 +01:00
|
|
|
|
akka.actor.serialization-bindings {
|
|
|
|
|
|
"java.io.Serializable" = none
|
|
|
|
|
|
}
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
|
|
|
|
|
Verification
|
|
|
|
|
|
------------
|
|
|
|
|
|
|
|
|
|
|
|
If you want to verify that your messages are serializable you can enable the following config option:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialize-messages-config
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
|
|
|
|
|
.. warning::
|
|
|
|
|
|
|
|
|
|
|
|
We only recommend using the config option turned on when you're running tests.
|
|
|
|
|
|
It is completely pointless to have it turned on in other scenarios.
|
|
|
|
|
|
|
|
|
|
|
|
If you want to verify that your ``Props`` are serializable you can enable the following config option:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: ../scala/code/docs/serialization/SerializationDocSpec.scala#serialize-creators-config
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
|
|
|
|
|
.. warning::
|
|
|
|
|
|
|
|
|
|
|
|
We only recommend using the config option turned on when you're running tests.
|
|
|
|
|
|
It is completely pointless to have it turned on in other scenarios.
|
|
|
|
|
|
|
|
|
|
|
|
Programmatic
|
|
|
|
|
|
------------
|
|
|
|
|
|
|
|
|
|
|
|
If you want to programmatically serialize/deserialize using Akka Serialization,
|
|
|
|
|
|
here's some examples:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
2012-09-26 10:56:25 +02:00
|
|
|
|
:include: imports
|
|
|
|
|
|
|
|
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
|
|
|
|
|
:include: programmatic
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
|
|
|
|
|
For more information, have a look at the ``ScalaDoc`` for ``akka.serialization._``
|
|
|
|
|
|
|
2012-02-03 17:32:32 +01:00
|
|
|
|
|
2011-12-30 22:00:49 +01:00
|
|
|
|
Customization
|
|
|
|
|
|
=============
|
|
|
|
|
|
|
|
|
|
|
|
So, lets say that you want to create your own ``Serializer``,
|
2012-05-22 11:37:09 +02:00
|
|
|
|
you saw the ``docs.serialization.MyOwnSerializer`` in the config example above?
|
2011-12-30 22:00:49 +01:00
|
|
|
|
|
|
|
|
|
|
Creating new Serializers
|
|
|
|
|
|
------------------------
|
|
|
|
|
|
|
|
|
|
|
|
First you need to create a class definition of your ``Serializer``,
|
|
|
|
|
|
which is done by extending ``akka.serialization.JSerializer``, like this:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
2012-09-26 10:56:25 +02:00
|
|
|
|
:include: imports
|
|
|
|
|
|
|
|
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
|
|
|
|
|
:include: my-own-serializer
|
2011-12-30 22:00:49 +01:00
|
|
|
|
:exclude: ...
|
|
|
|
|
|
|
2012-01-05 09:31:21 +01:00
|
|
|
|
Then you only need to fill in the blanks, bind it to a name in your :ref:`configuration` and then
|
2012-02-09 19:26:02 +01:00
|
|
|
|
list which classes that should be serialized using it.
|
|
|
|
|
|
|
2012-03-05 11:30:21 +01:00
|
|
|
|
Serializing ActorRefs
|
|
|
|
|
|
---------------------
|
|
|
|
|
|
|
|
|
|
|
|
All ActorRefs are serializable using JavaSerializer, but in case you are writing your own serializer,
|
|
|
|
|
|
you might want to know how to serialize and deserialize them properly, here's the magic incantation:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
2012-09-26 10:56:25 +02:00
|
|
|
|
:include: imports
|
|
|
|
|
|
|
|
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
|
|
|
|
|
:include: actorref-serializer
|
2012-03-05 11:30:21 +01:00
|
|
|
|
|
2012-05-15 20:57:39 +02:00
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
|
|
|
|
``ActorPath.toStringWithAddress`` only differs from ``toString`` if the
|
|
|
|
|
|
address does not already have ``host`` and ``port`` components, i.e. it only
|
|
|
|
|
|
inserts address information for local addresses.
|
|
|
|
|
|
|
|
|
|
|
|
This assumes that serialization happens in the context of sending a message
|
|
|
|
|
|
through the remote transport. There are other uses of serialization, though,
|
|
|
|
|
|
e.g. storing actor references outside of an actor application (database,
|
|
|
|
|
|
durable mailbox, etc.). In this case, it is important to keep in mind that the
|
|
|
|
|
|
address part of an actor’s path determines how that actor is communicated with.
|
|
|
|
|
|
Storing a local actor path might be the right choice if the retrieval happens
|
|
|
|
|
|
in the same logical context, but it is not enough when deserializing it on a
|
|
|
|
|
|
different network host: for that it would need to include the system’s remote
|
|
|
|
|
|
transport address. An actor system is not limited to having just one remote
|
|
|
|
|
|
transport per se, which makes this question a bit more interesting.
|
|
|
|
|
|
|
|
|
|
|
|
In the general case, the local address to be used depends on the type of remote
|
|
|
|
|
|
address which shall be the recipient of the serialized information. Use
|
|
|
|
|
|
:meth:`ActorRefProvider.getExternalAddressFor(remoteAddr)` to query the system
|
|
|
|
|
|
for the appropriate address to use when sending to ``remoteAddr``:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
2012-05-15 20:57:39 +02:00
|
|
|
|
:include: external-address
|
|
|
|
|
|
|
|
|
|
|
|
This requires that you know at least which type of address will be supported by
|
|
|
|
|
|
the system which will deserialize the resulting actor reference; if you have no
|
|
|
|
|
|
concrete address handy you can create a dummy one for the right protocol using
|
|
|
|
|
|
``new Address(protocol, "", "", 0)`` (assuming that the actual transport used is as
|
|
|
|
|
|
lenient as Akka’s RemoteActorRefProvider).
|
|
|
|
|
|
|
|
|
|
|
|
There is a possible simplification available if you are just using the default
|
|
|
|
|
|
:class:`NettyRemoteTransport` with the :meth:`RemoteActorRefProvider`, which is
|
|
|
|
|
|
enabled by the fact that this combination has just a single remote address:
|
|
|
|
|
|
|
2012-05-24 22:23:36 +02:00
|
|
|
|
.. includecode:: code/docs/serialization/SerializationDocTestBase.java
|
2012-05-15 20:57:39 +02:00
|
|
|
|
:include: external-address-default
|
|
|
|
|
|
|
|
|
|
|
|
This solution has to be adapted once other providers are used (like the planned
|
|
|
|
|
|
extensions for clustering).
|
|
|
|
|
|
|
2012-03-16 15:57:27 +01:00
|
|
|
|
Deep serialization of Actors
|
|
|
|
|
|
----------------------------
|
|
|
|
|
|
|
|
|
|
|
|
The current recommended approach to do deep serialization of internal actor state is to use Event Sourcing,
|
|
|
|
|
|
for more reading on the topic, see these examples:
|
|
|
|
|
|
|
|
|
|
|
|
`Martin Krasser on EventSourcing Part1 <http://krasserm.blogspot.com/2011/11/building-event-sourced-web-application.html>`_
|
|
|
|
|
|
|
|
|
|
|
|
`Martin Krasser on EventSourcing Part2 <http://krasserm.blogspot.com/2012/01/building-event-sourced-web-application.html>`_
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.. note::
|
|
|
|
|
|
|
|
|
|
|
|
Built-in API support for persisting Actors will come in a later release, see the roadmap for more info:
|
|
|
|
|
|
|
|
|
|
|
|
`Akka 2.0 roadmap <https://docs.google.com/a/typesafe.com/document/d/18W9-fKs55wiFNjXL9q50PYOnR7-nnsImzJqHOPPbM4E>`_
|
|
|
|
|
|
|
2012-02-09 19:26:02 +01:00
|
|
|
|
A Word About Java Serialization
|
|
|
|
|
|
===============================
|
|
|
|
|
|
|
|
|
|
|
|
When using Java serialization without employing the :class:`JavaSerializer` for
|
|
|
|
|
|
the task, you must make sure to supply a valid :class:`ExtendedActorSystem` in
|
|
|
|
|
|
the dynamic variable ``JavaSerializer.currentSystem``. This is used when
|
|
|
|
|
|
reading in the representation of an :class:`ActorRef` for turning the string
|
|
|
|
|
|
representation into a real reference. :class:`DynamicVariable` is a
|
|
|
|
|
|
thread-local variable, so be sure to have it set while deserializing anything
|
|
|
|
|
|
which might contain actor references.
|
2012-02-10 11:41:47 +01:00
|
|
|
|
|
2012-05-22 14:57:27 +02:00
|
|
|
|
External Akka Serializers
|
|
|
|
|
|
=========================
|
|
|
|
|
|
|
2012-05-25 14:33:28 +02:00
|
|
|
|
`Akka-protostuff by Roman Levenstein <https://github.com/romix/akka-protostuff-serialization>`_
|
2012-05-22 14:57:27 +02:00
|
|
|
|
|
|
|
|
|
|
|
2012-05-25 14:33:28 +02:00
|
|
|
|
`Akka-quickser by Roman Levenstein <https://github.com/romix/akka-quickser-serialization>`_
|
2012-05-31 21:58:24 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`Akka-kryo by Roman Levenstein <https://github.com/romix/akka-kryo-serialization>`_
|