Apache Geode CHANGELOG

Using Automatic Reflection-Based PDX Serialization

You can configure your cache to automatically serialize and deserialize domain objects without having to add any extra code to them.

You can automatically serialize and deserialize domain objects without coding a PdxSerializer class. You do this by registering your domain objects with a custom PdxSerializer called ReflectionBasedAutoSerializer that uses Java reflection to infer which fields to serialize.

You can also extend the ReflectionBasedAutoSerializer to customize its behavior. For example, you could add optimized serialization support for BigInteger and BigDecimal types. See Extending the ReflectionBasedAutoSerializer for details.

Note: Your custom PDX autoserializable classes cannot use the org.apache.geode package. If they do, the classes will be ignored by the PDX auto serializer.

Prerequisites

  • Understand generally how to configure the Geode cache.
  • Understand how PDX serialization works and how to configure your application to use PdxSerializer.

Procedure

In your application where you manage data from the cache, provide the following configuration and code as appropriate:

  1. In the domain classes that you wish to autoserialize, make sure each class has a zero-arg constructor. For example:

    public PortfolioPdx(){}
    
  2. Using one of the following methods, set the PDX serializer to ReflectionBasedAutoSerializer.

    1. In gfsh, execute the following command prior to starting up any members that host data:

      gfsh>configure pdx --auto-serializable-classes=com\.company\.domain\..*
      

      By using gfsh, this configuration can propagated across the cluster through the Cluster Configuration Service.

    2. Alternately, in cache.xml:

      <!-- Cache configuration configuring auto serialization behavior -->
      <cache>
        <pdx>
          <pdx-serializer>
            <class-name>
             org.apache.geode.pdx.ReflectionBasedAutoSerializer
            </class-name>
            <parameter name="classes">
            <string>com.company.domain.DomainObject</string>
           </parameter>
        </pdx-serializer>
       </pdx>
        ...
      </cache>
      

      The parameter, classes, takes a comma-separated list of class patterns to define the domain classes to serialize. If your domain object is an aggregation of other domain classes, you need to register the domain object and each of those domain classes explicitly for the domain object to be serialized completely.

    3. Using the Java API:

      Cache c = new CacheFactory()
        .setPdxSerializer(new ReflectionBasedAutoSerializer("com.company.domain.DomainObject"))
        .create();
      
  3. Customize the behavior of the ReflectionBasedAutoSerializer using one of the following mechanisms:

    • By using a class pattern string to specify the classes to auto-serialize and customize how the classes are serialized. Class pattern strings can be specified in the API by passing strings to the ReflectionBasedAutoSerializer constructor or by specifying them in cache.xml. See Customizing Serialization with Class Pattern Strings for details.
    • By creating a subclass of ReflectionBasedAutoSerializer and overriding specific methods. See Extending the ReflectionBasedAutoSerializer for details.
  4. If desired, configure the ReflectionBasedAutoSerializer to check the portability of the objects it is passed before it tries to autoserialize them. When this flag is set to true, the ReflectionBasedAutoSerializer will throw a NonPortableClassException error when trying to autoserialize a non-portable object. To set this, use the following configuration:

    • In gfsh, use the following command:

      gfsh>configure pdx --portable-auto-serializable-classes=com\.company\.domain\..*
      

      By using gfsh, this configuration can propagated across the cluster through the Cluster Configuration Service.

    • In cache.xml:

      <!-- Cache configuration configuring auto serialization behavior -->
      <cache>
        <pdx>
          <pdx-serializer>
            <class-name>
             org.apache.geode.pdx.ReflectionBasedAutoSerializer
            </class-name>
          <parameter name="classes">
            <string>com.company.domain.DomainObject</string>
          </parameter>
          <parameter name="check-portability">
            <string>true</string>
          </parameter>
        </pdx-serializer>
       </pdx>
        ...
      </cache>
      
    • Using the Java API:

      Cache c = new CacheFactory()
        .setPdxSerializer(new ReflectionBasedAutoSerializer(true,"com.company.domain.DomainObject"))
        .create();
      

For each domain class you provide, all fields are considered for serialization except those defined as static or transient and those you explicitly exclude using the class pattern strings.

Note: The ReflectionBasedAutoSerializer traverses the given domain object’s class hierarchy to retrieve all fields to be considered for serialization. So if DomainObjectB inherits from DomainObjectA, you only need to register DomainObjectB to have all of DomainObjectB serialized.