[[marshalling]]
= Marshalling
Marshalling is the process of converting Java objects into a binary format that can be transferred over the wire or stored to disk.
Unmarshalling is the reverse process whereby data read from a binary format is transformed back into Java objects.
{brandname} uses marshalling/unmarshalling to:

* Transform data so that it can be sent to other {brandname} nodes in a cluster.
* Transform data so that it can be stored in underlying cache stores.
* Store data in {brandname} in a binary format to provide lazy deserialization capabilities.

{brandname} handles marshalling for all internal types. Users only need to be concerned with the marshalling
of the Java objects that they will store in the cache.

== Marshaller Implementations

[[protostream_cm_config]]
=== ProtoStream (Default)
The default marshaller for {brandname} is link:#protostream[ProtoStream], which marshalls data as link:https://developers.google.com/protocol-buffers[Protocol Buffers].
This is a platform independent format that utilises schemas to provide a structured representation of your Java objects
that can evolve over time but also maintain backwards compatibility".

{brandname} directly integrates with the ProtoStream library by allowing users to configure implementations of the ProtoStream
SerializationContextInitializer interface. These implementations are then used to initialise the various SerializationContexts used by
{brandname} for marshalling, allowing custom user objects to be marshalled for storage and cluster communication.
More details on how to generate/implement your own SerializationContextInitailizers can be found link:#protostream_usage[here].

SerializationContextInitailizers can be configured as follows:

.Programmatic procedure

[source,java]
----
include::code_examples/ProtoStreamMarshaller.java[]
----

.Declarative procedure

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/protostream_marshaller.xml[]
----

[[java_serialization_marshaller]]
=== Java Serialization Marshaller
Java serialization can also be used to marshall your objects. The only requirements are that your Java objects implement
the link:https://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html[Serializable] interface, the
link:{javadocroot}/org/infinispan/commons/marshall/JavaSerializationMarshaller.html[JavaSerializationMarshaller] is specified
and that your objects are added to the serialization white list as part of the global configuration. For example,
to utilise Java serialization with all classes in package "org.infinispan.example.*" and the class "org.infinispan.concrete.SomeClass"
in the white list configure the CacheManager as follows:

.Programmatic procedure

[source,java]
----
include::code_examples/SerializationMarshaller.java[]
----

.Declarative procedure

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/serialization_marshaller.xml[]
----

.Reference

link:#deserialization_whitelist[Adding Java Classes to Deserialization White Lists]

=== JBoss Marshalling
JBoss Marshalling is a Serialization-based marshalling library and was the
default marshaller in older {brandname} versions.

[IMPORTANT]
====
* JBoss Marshalling is deprecated and planned for removal in a future version of {brandname}.
* {brandname} ignores implementations of the `AdvancedExternalizer` interface when persisting data unless you use JBoss Marshalling. However, `AdvancedExternalizer` is deprecated alongside JBoss Marshalling.
====

You should not plan to use serialization-based marshalling with {brandname}
because it is deprecated functionality; however, the steps to do so are as
follows:

. Add the `infinipsan-jboss-marshalling` dependency to your classpath.
. Configure `JBossUserMarshaller` as follows:

.Programmatic procedure

[source,java]
----
include::code_examples/JBossUserMarshaller.java[]
----

.Declarative procedure

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/jboss_user_marshaller.xml[]
----

[IMPORTANT]
====

====

.Reference

* link:#deserialization_whitelist[Adding Java Classes to Deserialization White Lists]
* link:{javadocroot}/org/infinispan/commons/marshall/AdvancedExternalizer.html[AdvancedExternalizer]

=== Kryo Marshalling
{brandname} provides a marshalling implementation that uses Kryo libraries.

Register custom Kryo schemas for object marshalling as follows:

. Implement a service provider for the `SerializerRegistryService.java` interface.
. Place all serializer registrations in the `register(Kryo)` method; where serializers are registered with the supplied `Kryo` object using the Kryo API, for example:
+
----
kryo.register(ExampleObject.class, new ExampleObjectSerializer())
----
+
. Specify the full path of implementing classes in your deployment JAR file within:
+
----
META-INF/services/org/infinispan/marshaller/kryo/SerializerRegistryService
----

//Community only
ifndef::productized[]
{brandname} provides a link:http://central.maven.org/maven2/org/infinispan/infinispan-marshaller-kryo-bundle/{infinispanversion}/infinispan-marshaller-kryo-bundle-{infinispanversion}.jar[Kryo Bundle] that includes all runtime class files for the Kryo marshalling implementation. Download the JAR and add it to the `server/lib` directory of your {brandname} servers.
endif::productized[]

.Reference

link:https://github.com/EsotericSoftware/kryo[Kryo on GitHub]

=== Protostuff Marshalling
{brandname} provides a marshalling implementation that uses Protostuff libraries.

Do one of the following to register custom Protostuff schemas for object
marshalling:


* Call the `register()` method.
+
[source,java]
----
include::code_examples/RegisterCustomProtostuffSchema.java[]
----

* Implement a service provider for the `SerializerRegistryService.java` interface that places all schema registrations in the `register()` method.
+
You should then specify the full path of implementing classes in your deployment JAR file within:
+
----
META-INF/services/org/infinispan/marshaller/protostuff/SchemaRegistryService
----

//Community only
ifndef::productized[]
{brandname} provides a link:http://central.maven.org/maven2/org/infinispan/infinispan-marshaller-protostuff-bundle/{infinispanversion}/infinispan-marshaller-protostuff-bundle-{infinispanversion}.jar[Protostuff Bundle JAR] that includes all runtime class files for the Protostuff marshalling implementation. Download the JAR and add it to the `server/lib` directory of your {brandname} servers.
endif::productized[]

.Reference

link:https://github.com/protostuff/protostuff[Protostuff on GitHub]

=== Custom Implementation
You can provide custom marshaller classes with the link:{javadocroot}/org/infinispan/commons/marshall/Marshaller.html[Marshaller interface].
For example:

.Programmatic procedure

[source,java]
----
include::code_examples/CustomMarshaller.java[]
----

.Declarative procedure

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/custom_marshaller.xml[]
----

[TIP]
====
Custom marshaller implementations can access a configured white list via the
link:{javadocroot}/org/infinispan/commons/marshall/Marshaller.html#initialize[initialize()] method, which is called during startup.
====

[id='deserialization_whitelist']
== Adding Java Classes to Deserialization White Lists
{brandname} does not allow deserialization of arbritrary Java classes for
security reasons, which applies to JSON, XML, and marshalled `byte[]` content.

You must add Java classes to a deserialization white list, either using system
properties or specifying them in the {brandname} configuration.

.System properties

[source,options="nowrap",subs=attributes+]
----
// Specify a comma-separated list of fully qualified class names
-Dinfinispan.deserialization.whitelist.classes=java.time.Instant,com.myclass.Entity

// Specify a regular expression to match classes
-Dinfinispan.deserialization.whitelist.regexps=.*
----

.Declarative

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/deserialization_whitelist.xml[]
----

[NOTE]
====
Java classes that you add to the deserialization whitelist apply to the
{brandname} `CacheContainer` and can be deserialized by all caches that the
`CacheContainer` controls.
====

== Storing Deserialized Objects in {brandname} Servers
If you configure {brandname} caches to use the `application/x-java-object`
MediaType as the storage format (storing POJOs instead of binary content), you
must put class files for all custom objects on the classpath for {brandname}
servers.

* Add JAR files that contain custom classes and/or service provider implementations for marshaller implementations in the `server/lib` directory of your {brandname} servers.

[[store_as_binary]]
== Store As Binary
Store as binary enables data to be stored in its serialized form. This can be useful to achieve lazy deserialization, which is the mechanism by which {brandname} by which serialization and deserialization of objects is deferred till the point in time in which they are used and needed. This typically means that any deserialization happens using the thread context class loader of the invocation that requires deserialization, and is an effective mechanism to provide classloader isolation. By default lazy deserialization is disabled but if you want to enable it, you can do it like this:

.Programmatic procedure

[source,java]
----
include::code_examples/StorageTypeBinary.java[]
----

.Declarative procedure
* Via XML at the Cache level, either under `<*-cache />` element:

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/memory_binary.xml[]
----

=== Equality Considerations

When using lazy deserialization/storing as binary, keys and values are wrapped as link:{javadocroot}/org/infinispan/commons/marshall/[WrappedBytes].
It is this wrapper class that transparently takes care of serialization and deserialization on demand, and internally may have a reference to the object itself being wrapped, or the serialized, byte array representation of this object.

This has a particular effect on the behavior of equality.
The equals() method of this class will either compare binary representations (byte arrays) or delegate to the wrapped object instance's equals() method, depending on whether both instances being compared are in serialized or deserialized form at the time of comparison.
If one of the instances being compared is in one form and the other in another form, then one instance is either serialized or deserialized.

This will affect the way keys stored in the cache will work, when `storeAsBinary` is used, since comparisons happen on the key which will be wrapped by a MarshalledValue. Implementers of equals() methods on their keys need to be aware of the behavior of equality comparison, when a key is wrapped as a MarshalledValue, as detailed above.

=== Store-by-value via defensive copying
The configuration `storeAsBinary` offers the possibility to enable defensive copying, which allows for store-by-value like behaviour.

{brandname} marshalls objects the moment they're stored, hence changes made to object references are not stored in the cache, not even for local caches. This provides store-by-value like behaviour. Enabling `storeAsBinary` can be achieved:

.Programmatic procedure

[source,java]
----
include::code_examples/StoreAsBinary.java[]
----

.Declarative procedure
*  Via XML at the Cache level, either under `<*-cache />` or `<default />` elements:

[source,xml,options="nowrap",subs=attributes+]
----
include::config_examples/store_as_binary.xml[]
----
