Chapter 6. Marshalling

6.1. Marshalling

Marshalling is the process of converting Java objects into a format that is transferable over the wire. Unmarshalling is the reversal of this process where data read from a wire format is converted into Java objects.

Red Hat JBoss Data Grid uses marshalling and unmarshalling to:

  • transform data for relay to other JBoss Data Grid nodes within the cluster.
  • transform data to be stored in underlying cache stores.

6.2. About the JBoss Marshalling Framework

Red Hat JBoss Data Grid uses the JBoss Marshalling Framework to marshall and unmarshall Java POJOs. Using the JBoss Marshalling Framework offers a significant performance benefit, and is therefore used instead of Java Serialization. Additionally, the JBoss Marshalling Framework can efficiently marshall Java POJOs, including Java classes.

The Java Marshalling Framework uses high performance java.io.ObjectOutput and java.io.ObjectInput implementations compared to the standard java.io.ObjectOutputStream and java.io.ObjectInputStream.

6.3. Customizing Marshalling

Instead of using the default Marshaller, which may be slow with payloads that are unnecessarily large, objects may implement java.io.Externalizable so that a custom method of marshalling/unmarshalling classes is performed. With this approach the target class may be created in a variety of ways (direct instantiation, factory methods, reflection, etc.) and the developer has complete control over using the provided stream.

Implementing a Custom Externalizer

To configure a class for custom marshalling an implementation of org.infinispan.marshall.AdvancedExternalizer must be provided. Typically this is performed in a static inner class, as seen in the below externalizer for a Book class:

import org.infinispan.marshall.AdvancedExternalizer;

public class Book {

   final String name;
   final String author;

   public Book(String name, String author) {
      this.name = name;
      this.author = author;
   }

   public static class BookExternalizer implements AdvancedExternalizer<Book> {
      @Override
      public void writeObject(ObjectOutput output, Book book)
            throws IOException {
         output.writeObject(book.name);
         output.writeObject(book.author);
      }

      @Override
      public Person readObject(ObjectInput input)
            throws IOException, ClassNotFoundException {
         return new Person((String) input.readObject(), (String) input.readObject());
      }

      @Override
      public Set<Class<? extends Book>> getTypeClasses() {
         return Util.<Class<? extends Book>>asSet(Book.class);
      }

      @Override
      public Integer getId() {
         return 2345;
      }
   }
}

Once the writeObject() and readObject() methods have been implemented the Externalizer may be linked up with the classes they externalize; this is accomplished with the getTypeClasses() method seen in the above example.

In addition, a positive identifier must be defined as seen in the getId() method above. This value is used to identify the Externalizer at runtime. A list of values used by JBoss Data Grid, which should be avoided in custom Externalizer implementations, may be found at JBoss Data Grid Externalizer IDs.

Registering Custom Marshallers

Custom Marshallers may be registered with JBoss Data Grid programmatically or declaratively, as seen in the following examples:

Declaratively Register a Custom Marshaller

<cache-container>
  <serialization>
    <advanced-externalizer class="Book$BookExternalizer"/>
  </serialization>
</cache-container>

Programmatically Register a Custom Marshaller

GlobalConfigurationBuilder builder = ...
builder.serialization()
   .addAdvancedExternalizer(new Book.BookExternalizer());

6.4. JBoss Data Grid Externalizer IDs

The following values are used as Externalizer IDs inside the Infinispan based modules or frameworks, and should be avoided while implementing custom marshallers.

Table 6.1. JBoss Data Grid Externalizer IDs

Module NameID Range

Infinispan Tree Module

1000-1099

Infinispan Server Modules

1100-1199

Hibernate Infinispan Second Level Cache

1200-1299

Infinispan Lucene Directory

1300-1399

Hibernate OGM

1400-1499

Hibernate Search

1500-1599

Infinispan Query Module

1600-1699

Infinispan Remote Query Module

1700-1799

Infinispan Scripting Module

1800-1849

Infinispan Server Event Logger Module

1850-1899

Infinispan Remote Store

1900-1999