<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.3.4">Jekyll</generator><link href="https://desousa.com.pt/feed.xml" rel="self" type="application/atom+xml" /><link href="https://desousa.com.pt/" rel="alternate" type="text/html" /><updated>2026-09-21T23:06:46+01:00</updated><id>https://desousa.com.pt/feed.xml</id><title type="html">// TODO: title</title><subtitle>Blog and recipes by Filipe</subtitle><entry><title type="html">Restarting</title><link href="https://desousa.com.pt/2026/08/09/restarting/" rel="alternate" type="text/html" title="Restarting" /><published>2026-08-09T20:00:00+01:00</published><updated>2026-08-09T20:00:00+01:00</updated><id>https://desousa.com.pt/2026/08/09/restarting</id><content type="html" xml:base="https://desousa.com.pt/2026/08/09/restarting/"><![CDATA[<p>Some people have the ability to write down their thoughts and feelings, without making them incoherent. I make no such promises.</p>

<p>This is a fresh start (again) on a platform that should work for me (no effort free hosting, without the hassles of sign-ups and non-free articles, like with Medium).</p>

<p>The first post is an old one, that has been grandfathered into my multiple moves of blog hosts over the past 13 years.</p>]]></content><author><name></name></author><category term="news" /><category term="meta" /><summary type="html"><![CDATA[Some people have the ability to write down their thoughts and feelings, without making them incoherent. I make no such promises.]]></summary></entry><entry><title type="html">Portable Object Format Serialisation With Inheritance</title><link href="https://desousa.com.pt/2013/11/14/pof-serialisation-inheritance/" rel="alternate" type="text/html" title="Portable Object Format Serialisation With Inheritance" /><published>2013-11-14T00:00:00+00:00</published><updated>2013-11-14T00:00:00+00:00</updated><id>https://desousa.com.pt/2013/11/14/pof-serialisation-inheritance</id><content type="html" xml:base="https://desousa.com.pt/2013/11/14/pof-serialisation-inheritance/"><![CDATA[<p>An older article of mine, written about Portable Object Format, used in a past role for a project.</p>

<!--excerpt-->

<h2 id="introduction">Introduction</h2>

<p>The basics of POF serialisation are covered enough across the internet, but this article tries to show what you can do about serialising objects while accounting for changeable inheritance structures.</p>

<p>As part of the previous sprint at work we began implementing versioned and evolvable serialised objects for our Oracle Coherence cache in Portable Object Format (POF), which is currently not used in an easily evolvable way.</p>

<p>This post is a bit of a brain dump on how we’ve implemented versioning, which somebody may find useful, since the documentation isn’t always perfectly clear about some points meaning it’s been a trial-and-error implementation.</p>

<p>Implementation of POF serialisation and making objects evolvable is all done in code and requires hard-coding of the index numbers to keep it compatible between versions and languages, which makes for a rather tedious few days of work. When your colleagues haven’t written unit tests for some objects you’re making evolvable, you don’t have cache nodes to test on, and have multiple objects with deep inheritance models to adapt across multiple languages, it becomes an awful lot of fun to work on.</p>

<p>Before setting off I’m going to point out an excellent post by Shan He, which helped more than any other blog post, implementation example, or even the official documentation in understanding how to implement a solution. That post is occasionally quoted and paraphrased below, since it really illuminates some areas well alone.</p>

<h2 id="simple-serialisation">Simple Serialisation</h2>
<p>There are two basic ways to serialise objects into POF, which involve either making the object self-serialisable or using a separate serialiser class. Each have some advantages and disadvantages as is to be expected. With either approach, implementing the Evolvable interface or extending AbstractEvolvable in the serialised object is practically essential, and provides the base for evolvable object serialisation.</p>

<p>If you’re going for the self-serialisation route you implement the PortableObject interface (or the useful EvolvablePortableObject interface that simply combines Evolvable and PortableObject interfaces in one), using the method <code class="language-plaintext highlighter-rouge">readExternal(PofReader)</code> to deserialise an object from the PofReader, and using the method <code class="language-plaintext highlighter-rouge">writeExternal(PofWriter)</code> to serialise the object into the PofWriter.</p>

<p>For the separate serialiser, you write another class that implements PofSerializer, defining the method <code class="language-plaintext highlighter-rouge">serialize(PofWriter, Object)</code> to serialise to the PofWriter, and the method <code class="language-plaintext highlighter-rouge">deserialize(PofReader)</code> to deserialise from the PofReader.</p>

<h3 id="modelling-a-simplistic-bond">Modelling a Simplistic Bond</h3>
<p>Let’s have a look at a really basic example of both approaches, serialising a simple representation of a Bond.</p>

<h4 id="bond-object-definition">Bond object definition</h4>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Fields and their data types:</span>
<span class="kd">class</span> <span class="nc">Bond</span> <span class="o">{</span>
    <span class="cm">/* Define the fields */</span>
    <span class="kt">long</span> <span class="n">contractNumber</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">counterparty</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">instrument</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">issuer</span><span class="o">;</span>
    <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">;</span>
    <span class="kt">double</span> <span class="n">principal</span><span class="o">;</span>
    <span class="kt">double</span> <span class="n">coupon</span><span class="o">;</span>
    <span class="kt">double</span> <span class="n">price</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="simple-evolvable-portable-objectexample">Simple Evolvable Portable Object Example</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Bond</span> <span class="kd">extends</span> <span class="nc">AbstractEvolvable</span> <span class="kd">implements</span> <span class="nc">EvolvablePortableObject</span> <span class="o">{</span>
    <span class="cm">/* Define object implementation version */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">IMPL_VERSION</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
    
    <span class="cm">/* Define the indices of the serialised fields */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">CONTRACT_NUMBER_INDEX</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">CURRENCY_INDEX</span> <span class="o">=</span> <span class="mi">2</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">COUNTERPARTY_INDEX</span> <span class="o">=</span> <span class="mi">3</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">INSTRUMENT_INDEX</span> <span class="o">=</span> <span class="mi">4</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">ISSUER_INDEX</span> <span class="o">=</span> <span class="mi">5</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">MATURITY_DATE_INDEX</span> <span class="o">=</span> <span class="mi">6</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">PRINCIPAL_INDEX</span> <span class="o">=</span> <span class="mi">7</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">COUPON_INDEX</span> <span class="o">=</span> <span class="mi">8</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">PRICE_INDEX</span> <span class="o">=</span> <span class="mi">9</span><span class="o">;</span>
    
    <span class="cm">/* Define the fields */</span>
    <span class="kd">private</span> <span class="kt">long</span> <span class="n">contractNumber</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">instrument</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">issuer</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">principal</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">coupon</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">price</span><span class="o">;</span>

	<span class="cm">/* Define no-args constructor and other constructors */</span>
	<span class="kd">public</span> <span class="nf">Bond</span><span class="o">()</span> <span class="o">{</span>
		<span class="kd">super</span><span class="o">();</span>
	<span class="o">}</span>

	<span class="kd">public</span> <span class="nf">Bond</span><span class="o">(</span><span class="kt">long</span> <span class="n">contractNumber</span><span class="o">,</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">,</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">,</span> <span class="nc">String</span> <span class="n">instrument</span><span class="o">,</span>
                <span class="nc">String</span> <span class="n">issuer</span><span class="o">,</span> <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">,</span> <span class="kt">double</span> <span class="n">principal</span><span class="o">,</span> <span class="kt">double</span> <span class="n">coupon</span><span class="o">,</span> <span class="kt">double</span> <span class="n">price</span><span class="o">)</span> <span class="o">{</span>
    	<span class="kd">super</span><span class="o">();</span>
    
    	<span class="k">this</span><span class="o">.</span><span class="na">contractNumber</span> <span class="o">=</span> <span class="n">contractNumber</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">currency</span> <span class="o">=</span> <span class="n">currency</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">counterparty</span> <span class="o">=</span> <span class="n">counterparty</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">instrument</span> <span class="o">=</span> <span class="n">instrument</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">issuer</span> <span class="o">=</span> <span class="n">issuer</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">maturityDate</span> <span class="o">=</span> <span class="n">maturityDate</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">principal</span> <span class="o">=</span> <span class="n">principal</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">coupon</span> <span class="o">=</span> <span class="n">coupon</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">price</span> <span class="o">=</span> <span class="n">price</span><span class="o">;</span>
	<span class="o">}</span>

	<span class="cm">/* SNIP */</span>

	<span class="cm">/* Serialisation method */</span>
    <span class="nd">@Override</span>    
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">writeExternal</span><span class="o">(</span><span class="nc">PofWriter</span> <span class="n">writer</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
    	<span class="n">writer</span><span class="o">.</span><span class="na">setVersionId</span><span class="o">(</span><span class="nc">Math</span><span class="o">.</span><span class="na">max</span><span class="o">(</span><span class="n">getImplVersion</span><span class="o">(),</span> <span class="n">getDataVersion</span><span class="o">()));</span>
        <span class="cm">/* Serialise ourselves in ascending index order */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeLong</span><span class="o">(</span><span class="no">CONTRACT_NUMBER_INDEX</span><span class="o">,</span> <span class="n">getContractNumber</span><span class="o">());</span>
        <span class="cm">/* Skipping rest of writes */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeRemainder</span><span class="o">(</span><span class="n">getFutureData</span><span class="o">());</span>
    <span class="o">}</span>

    <span class="cm">/* Deserialisation method */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">readExternal</span><span class="o">(</span><span class="nc">PofReader</span> <span class="n">reader</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
        <span class="n">setDataVersion</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">getVersionId</span><span class="o">());</span>
        <span class="cm">/* Deserialise ourselves in ascending index order */</span>
        <span class="n">setContractNumber</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">readLong</span><span class="o">(</span><span class="no">CONTRACT_NUMBER_INDEX</span><span class="o">));</span>
        <span class="cm">/* Skipping rest of reads */</span>
        <span class="n">setFutureData</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">readRemainder</span><span class="o">());</span>
    <span class="o">}</span>
    
    <span class="cm">/* Return the constant implementation version */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">getImplVersion</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="no">IMPL_VERSION</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>If you prefer not to break the single responsibility principle, and consider a class taking care of its own serialisation a breach of that principle, this is not the method for you. The one below will likely make more sense.</p>

<h3 id="simple-evolvable-object-serialiser-example">Simple Evolvable Object Serialiser Example</h3>

<h4 id="object">Object</h4>
<p>For this example, we keep just the object’s fields and methods, implement just Evolvable by extending AbstractEvolvable, and remove the serialisation code.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Bond</span> <span class="kd">extends</span> <span class="nc">AbstractEvolvable</span> <span class="o">{</span>
    <span class="cm">/* Define object implementation version */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">IMPL_VERSION</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>

    <span class="cm">/* Define the fields */</span>
    <span class="kd">private</span> <span class="kt">long</span> <span class="n">contractNumber</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">instrument</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">issuer</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">principal</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">coupon</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">price</span><span class="o">;</span>
    
    <span class="cm">/* Define no-args constructor and other constructors */</span>
    <span class="kd">public</span> <span class="nf">Bond</span><span class="o">()</span> <span class="o">{</span>
    	<span class="kd">super</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nf">Bond</span><span class="o">(</span><span class="kt">long</span> <span class="n">contractNumber</span><span class="o">,</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">,</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">,</span> <span class="nc">String</span> <span class="n">instrument</span><span class="o">,</span>
                <span class="nc">String</span> <span class="n">issuer</span><span class="o">,</span> <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">,</span> <span class="kt">double</span> <span class="n">principal</span><span class="o">,</span> <span class="kt">double</span> <span class="n">coupon</span><span class="o">,</span> <span class="kt">double</span> <span class="n">price</span><span class="o">)</span> <span class="o">{</span>
    	<span class="kd">super</span><span class="o">();</span>

        <span class="k">this</span><span class="o">.</span><span class="na">contractNumber</span> <span class="o">=</span> <span class="n">contractNumber</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">currency</span> <span class="o">=</span> <span class="n">currency</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">counterparty</span> <span class="o">=</span> <span class="n">counterparty</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">instrument</span> <span class="o">=</span> <span class="n">instrument</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">issuer</span> <span class="o">=</span> <span class="n">issuer</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">maturityDate</span> <span class="o">=</span> <span class="n">maturityDate</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">principal</span> <span class="o">=</span> <span class="n">principal</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">coupon</span> <span class="o">=</span> <span class="n">coupon</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">price</span> <span class="o">=</span> <span class="n">price</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="cm">/* SNIP */</span>

    <span class="cm">/* Return the constant implementation version */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">getImplVersion</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="no">IMPL_VERSION</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h4 id="serialiser">Serialiser</h4>
<p>The serialisation code and field indices are now in the serialiser class, which does the heavy lifting on serialising and deserialising the class.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">BondSerializer</span> <span class="kd">implements</span> <span class="nc">PofSerializer</span> <span class="o">{</span>
    <span class="cm">/* Define indices for the serialised fields */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">CONTRACT_NUMBER_INDEX</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">CURRENCY_INDEX</span> <span class="o">=</span> <span class="mi">2</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">COUNTERPARTY_INDEX</span> <span class="o">=</span> <span class="mi">3</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">INSTRUMENT_INDEX</span> <span class="o">=</span> <span class="mi">4</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">ISSUER_INDEX</span> <span class="o">=</span> <span class="mi">5</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">MATURITY_DATE_INDEX</span> <span class="o">=</span> <span class="mi">6</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">PRINCIPAL_INDEX</span> <span class="o">=</span> <span class="mi">7</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">COUPON_INDEX</span> <span class="o">=</span> <span class="mi">8</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">PRICE_INDEX</span> <span class="o">=</span> <span class="mi">9</span><span class="o">;</span>

    <span class="cm">/* Serialise the object into the writer */</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">serialize</span><span class="o">(</span><span class="nc">PofWriter</span> <span class="n">writer</span><span class="o">,</span> <span class="nc">Object</span> <span class="n">o</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
    	<span class="cm">/* Check Object is of correct type to serialize */</span>
    	<span class="k">if</span> <span class="o">(!(</span><span class="n">o</span> <span class="k">instanceof</span> <span class="nc">Bond</span><span class="o">))</span> <span class="o">{</span>
    		<span class="c1">// Handle the case of an invalid/null object</span>
    	<span class="o">}</span>

        <span class="nc">Bond</span> <span class="n">bond</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Bond</span><span class="o">)</span> <span class="n">o</span><span class="o">;</span>        
        <span class="n">writer</span><span class="o">.</span><span class="na">setVersionId</span><span class="o">(</span><span class="nc">Math</span><span class="o">.</span><span class="na">max</span><span class="o">(</span><span class="n">bond</span><span class="o">.</span><span class="na">getImplVersion</span><span class="o">(),</span> <span class="n">bond</span><span class="o">.</span><span class="na">getDataVersion</span><span class="o">()));</span>
        <span class="cm">/* Serialise ourselves in ascending index order */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeLong</span><span class="o">(</span><span class="no">CONTRACT_NUMBER_INDEX</span><span class="o">,</span> <span class="n">bond</span><span class="o">.</span><span class="na">getContractNumber</span><span class="o">());</span>
        <span class="cm">/* Skipping rest of writes */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeRemainder</span><span class="o">(</span><span class="n">bond</span><span class="o">.</span><span class="na">getFutureData</span><span class="o">());</span>
    <span class="o">}</span>

    <span class="cm">/* Deserialise from the reader into a new object */</span>
    <span class="kd">public</span> <span class="nc">Object</span> <span class="nf">deserialize</span><span class="o">(</span><span class="nc">PofReader</span> <span class="n">reader</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
        <span class="cm">/* Instantiate a new Bond to deserialise into */</span>
        <span class="nc">Bond</span> <span class="n">bond</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Bond</span><span class="o">();</span>
        <span class="n">bond</span><span class="o">.</span><span class="na">setDataVersion</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">getVersionId</span><span class="o">());</span>
    
        <span class="cm">/* Deserialise ourselves in ascending index order */</span>
        <span class="n">bond</span><span class="o">.</span><span class="na">setContractNumber</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">readLong</span><span class="o">(</span><span class="no">CONTRACT_NUMBER_INDEX</span><span class="o">));</span>
        
        <span class="cm">/* Skipping rest of reads */</span>
        <span class="n">bond</span><span class="o">.</span><span class="na">setFutureData</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">readRemainder</span><span class="o">());</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>It is just more of the same, a case of defining the serialisation outside of the class instead of part of it, with both forms of serialisation displayed above being suitable for our current object hierarchy of one.</p>

<p>For the above examples a simple Bond contract was implemented, but what if we want to model a Future? Do we really need to re-implement all of the useful fields that apply to both? Of course not, we abstract things!</p>

<h2 id="serialisation-and-inheritance">Serialisation and Inheritance</h2>
<p>In POF serialisation there are three important attributes for evolvable objects, implementation version, data version and future data. Future data is a record of any data we may not be able to process because it’s from a newer implementation, and the version numbers define what version data being serialised or deserialised is, and also what it should contain.</p>

<p>By extending AbstractEvolvable, the storage of data version and future data is taken care of. The object must define its own <code class="language-plaintext highlighter-rouge">getImplVersion()</code> method returning the implementation version. Whether implementing PortableObject, or defining a separate PofSerializer, the base has been established.</p>

<p>What happens when you inherit from an evolvable object?</p>

<p>As stated above, to make objects backwards- and forwards-compatible and allow evolution, POF serialisation uses implementation version, data version and future data, which are stored in the object. When you are serialising a class with super-classes that require serialisation, where do you get the version number from, and what happens when adding new fields? The documentation does not clarify the situation, so below is my interpretation of what should happen.</p>

<p>Implementation version defines the version of the implementation of the object. Every time a serialisable attribute is changed in the object this version number should increase, since this number will also define the version number of data constructed by this implementation. The Evolvable interface defines the function <code class="language-plaintext highlighter-rouge">getImplVersion()</code> which is expected to return the version number of the object’s implementation. Its use is related to the data version, explained below.</p>

<p>Data version defines the version of the data being serialised or deserialised. If the object has just been instantiated the data version will be the same as the implementation version, but if it’s been previously deserialised the data could have come from a future implementation. This is why you see the call to <code class="language-plaintext highlighter-rouge">Math.max(getImplVersion(), getDataVersion())</code> in the examples when calling <code class="language-plaintext highlighter-rouge">PofWriter.setVersionId()</code>, so we always define the latest version suitable for the data.</p>

<p>Future data is held in a Binary object, and is read via <code class="language-plaintext highlighter-rouge">PofReader.readRemainder()</code>, which does what it says on the tin, reading any remaining data we haven’t read. If deserialising from a newer implementation version, we might have some remaining data that should be kept in case we must serialise the same object again. As mentioned above, this is why we keep a copy of the data version around, and call <code class="language-plaintext highlighter-rouge">setVersionId(Math.max(getImplVersion(), getDataVersion()))</code> to set the version to the latest one.</p>

<p>As each layer should have its own implementation version, it should also hold onto its own data version and future data. This means AbstractEvolvable should not be extended, instead (re)implementing Evolvable at each level with private versions and data members. PortableObject also requires (re)implementation at each level, with sub-classes calling their super-class methods with a nested POF reader when deserialising, or writer when serialising. There’s a fair portion of code being copied around, but it’s a necessary evil to have the implementation we want.</p>

<p>Solutions that account for inheritance using the afore-mentioned nested readers and writers have great flexibility. Due to the nesting implementation, each class can have index numbers without clashes. Sub-classes can be added to the inheritance structure without changing the serialisation or implementation of a super-class. Super-classes are none-the-wiser that they’re not the top-level serialised objects. The greatest benefit of all, is that a new serialised attribute of a super-class can be shared to all sub-classes, with no changes to their own serialisation. Most articles and posts don’t detail this implementation, avoiding the subject due to not knowing its intent or use, or because they were written before it was available in the API.</p>

<p>POF serialisation becomes a bit tedious once you’ve a large enough class, as you write much the same code over and over. After declaring a new field, write the getter and setter methods, add a new index for the field to be serialised and deserialised at, increment the implementation version, and add the lines to serialise and deserialise the field. That’s the very basics of it, and if you have to add thirty fields, you must follow those steps thirty times. Imagine the extreme tedium of serialising classes five levels deep.</p>

<h2 id="modelling-bonds-and-futures-contracts">Modelling Bonds and Futures Contracts</h2>
<p>We’re extending the modelled objects further to give us possibility for some new examples, adding Futures contracts to the system, which share a number of base attributes with Bonds contracts. First, defining what goes into each layer.</p>

<h3 id="contract-base">Contract Base</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Fields and their data types:</span>
<span class="kd">class</span> <span class="nc">Contract</span> <span class="o">{</span>
    <span class="cm">/* Define the fields */</span>
    <span class="kt">long</span> <span class="n">contractNumber</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">counterparty</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">broker</span><span class="o">;</span>
    <span class="kt">double</span> <span class="n">price</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The fields defined above would have been found in both a Bond and a Future contract, but note the addition of the Broker field to the contract base so a Bond can have a Broker assigned to it as well as a Future.</p>

<h3 id="bond-contract">Bond Contract</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Fields and their data types:</span>
<span class="kd">class</span> <span class="nc">Bond</span> <span class="o">:</span> <span class="nc">Contract</span> <span class="o">{</span>
    <span class="cm">/* Define the fields */</span>
    <span class="nc">String</span> <span class="n">issuer</span><span class="o">;</span>
    <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">;</span>
    <span class="kt">double</span> <span class="n">principal</span><span class="o">;</span>
    <span class="kt">double</span> <span class="n">price</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>We’re keeping the above fields specifically only for Bonds, since they’re not relevant for all of the products we want to implement. The fields in the base were previously held exclusively in Bond, but they’ve now been abstracted out, as seen in the definition of Contract above.</p>

<h3 id="future-contract">Future Contract</h3>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Fields and their data types:</span>
<span class="kd">class</span> <span class="nc">Future</span> <span class="o">:</span> <span class="nc">Contract</span> <span class="o">{</span>
    <span class="cm">/* Define the fields */</span>
    <span class="nc">String</span> <span class="n">contract</span><span class="o">;</span>
    <span class="nc">String</span> <span class="n">tenorCode</span><span class="o">;</span>
    <span class="kt">long</span> <span class="n">lots</span><span class="o">;</span>
<span class="o">}</span>
</code></pre></div></div>

<p>To make a basic Future contract we only need a few attributes, so this looks rather minimal and with good reason. Everything else we currently absolutely require is held in the base.</p>

<h2 id="evolvable-portable-objects-with-inheritance-example">Evolvable Portable Objects with Inheritance Example</h2>

<h3 id="contract">Contract</h3>

<p>We’re making the Contract evolvable, and self-serialisable so that it may hold its own data version, implementation version and future data without clashes with sub-classes replacing them. As it’s able to be abstract, we’ll take advantage of that to ignore implementations of part of the Evolvable interface. Otherwise, this is very similar to the original Bond serialisation example.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">abstract</span> <span class="kd">class</span> <span class="nc">Contract</span> <span class="kd">implements</span> <span class="nc">EvolvablePortableObject</span> <span class="o">{</span>
    <span class="cm">/* Define object implementation version */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">IMPL_VERSION</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>

    <span class="cm">/* Define the indices of the serialised fields */</span>
    <span class="c1">// Superclass index should be the same in all sub-classes</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">SUPERCLASS_INDEX</span> <span class="o">=</span> <span class="mi">0</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">CONTRACT_NUMBER_INDEX</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">CURRENCY_INDEX</span> <span class="o">=</span> <span class="mi">2</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">COUNTERPARTY_INDEX</span> <span class="o">=</span> <span class="mi">3</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">BROKER_INDEX</span> <span class="o">=</span> <span class="mi">4</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">PRICE_INDEX</span> <span class="o">=</span> <span class="mi">5</span><span class="o">;</span>

    <span class="cm">/* Define serialisation-specific fields */</span>
    <span class="kd">private</span> <span class="kt">int</span> <span class="n">dataVersion</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Binary</span> <span class="n">futureData</span><span class="o">;</span>

    <span class="cm">/* Define the fields */</span>
    <span class="kd">private</span> <span class="kt">long</span> <span class="n">contractNumber</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">broker</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">price</span><span class="o">;</span>

    <span class="cm">/* Define no-args constructor and any others */</span>
    <span class="kd">protected</span> <span class="nf">Contract</span><span class="o">()</span> <span class="o">{</span>
    	<span class="c1">// Nothing to do here, no super(), nothing...</span>
    <span class="o">}</span>

    <span class="kd">protected</span> <span class="nf">Contract</span><span class="o">(</span><span class="kt">long</span> <span class="n">contractNumber</span><span class="o">,</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">,</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">,</span> <span class="nc">String</span> <span class="n">broker</span><span class="o">,</span> <span class="kt">double</span> <span class="n">price</span><span class="o">)</span> <span class="o">{</span>
        <span class="k">this</span><span class="o">.</span><span class="na">contractNumber</span> <span class="o">=</span> <span class="n">contractNumber</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">currency</span> <span class="o">=</span> <span class="n">currency</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">counterparty</span> <span class="o">=</span> <span class="n">counterparty</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">broker</span> <span class="o">=</span> <span class="n">broker</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">price</span> <span class="o">=</span> <span class="n">price</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="cm">/* SNIP */</span>

    <span class="cm">/* Serialisation method */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">writeExternal</span><span class="o">(</span><span class="nc">PofWriter</span> <span class="n">writer</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
    	<span class="n">writer</span><span class="o">.</span><span class="na">setVersionId</span><span class="o">(</span><span class="nc">Math</span><span class="o">.</span><span class="na">max</span><span class="o">(</span><span class="no">IMPL_VERSION</span><span class="o">,</span> <span class="n">dataVersion</span><span class="o">));</span>
    	<span class="cm">/* Serialise ourselves in ascending index order */</span>
    	<span class="n">writer</span><span class="o">.</span><span class="na">writeLong</span><span class="o">(</span><span class="no">CONTRACT_NUMBER_INDEX</span><span class="o">,</span> <span class="n">getContractNumber</span><span class="o">());</span>
    	<span class="cm">/* Skipping rest of writes */</span>
    	<span class="n">writer</span><span class="o">.</span><span class="na">writeRemainder</span><span class="o">(</span><span class="n">futureData</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="cm">/* Deserialisation method */</span>
    <span class="nd">@Override</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">readExternal</span><span class="o">(</span><span class="nc">PofReader</span> <span class="n">reader</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
    	<span class="n">dataVersion</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">getVersionId</span><span class="o">();</span>
    	<span class="cm">/* Deserialise ourselves in ascending index order */</span>
    	<span class="n">setContractNumber</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">readLong</span><span class="o">(</span><span class="no">CONTRACT_NUMBER_INDEX</span><span class="o">));</span>
    	<span class="cm">/* Skipping rest of reads */</span>
    	<span class="n">futureData</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">readRemainder</span><span class="o">();</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="bond">Bond</h3>
<p>The first, and most important, thing to note are the calls to <code class="language-plaintext highlighter-rouge">PofWriter.createNestedPofWriter()</code> and <code class="language-plaintext highlighter-rouge">PofReader.createNestedPofReader()</code>, which will allow serialising and deserialising to and from a numbered field, without the object being handed the reader/writer instance knowing there’s a difference. This is how we handle serialisation of our superclasses, by giving it a nested reader/writer, always using field number zero.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Bond</span> <span class="kd">extends</span> <span class="nc">Contract</span> <span class="o">{</span>
    <span class="cm">/* Define object implementation version
       This can differ from Contract Base */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">IMPL_VERSION</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
    
    <span class="cm">/* Define the indices of the serialised fields
       You can use same indices as super-class */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">INSTRUMENT_INDEX</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">ISSUER_INDEX</span> <span class="o">=</span> <span class="mi">2</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">MATURITY_DATE_INDEX</span> <span class="o">=</span> <span class="mi">3</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">PRINCIPAL_INDEX</span> <span class="o">=</span> <span class="mi">4</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">COUPON_INDEX</span> <span class="o">=</span> <span class="mi">5</span><span class="o">;</span>
    
    <span class="cm">/* Define serialisation-specific fields */</span>
    <span class="kd">private</span> <span class="kt">int</span> <span class="n">dataVersion</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Binary</span> <span class="n">futureData</span><span class="o">;</span>
    
    <span class="cm">/* Define the fields */</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">instrument</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">issuer</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">principal</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">coupon</span><span class="o">;</span>
    
    <span class="cm">/* Define no-args constructor and any others */</span>
    <span class="kd">public</span> <span class="nf">Bond</span><span class="o">()</span> <span class="o">{</span>
    	<span class="kd">super</span><span class="o">();</span>
    <span class="o">}</span>
    
    <span class="kd">public</span> <span class="nf">Bond</span><span class="o">(</span><span class="kt">long</span> <span class="n">contractNumber</span><span class="o">,</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">,</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">,</span> <span class="nc">String</span> <span class="n">broker</span><span class="o">,</span> <span class="kt">double</span> <span class="n">price</span><span class="o">,</span> <span class="nc">String</span> <span class="n">instrument</span><span class="o">,</span> <span class="nc">String</span> <span class="n">issuer</span><span class="o">,</span> <span class="nc">Date</span> <span class="n">maturityDate</span><span class="o">,</span> <span class="kt">double</span> <span class="n">principal</span><span class="o">,</span> <span class="kt">double</span> <span class="n">coupon</span><span class="o">)</span> <span class="o">{</span>
        <span class="kd">super</span><span class="o">(</span><span class="n">contractNumber</span><span class="o">,</span> <span class="n">currency</span><span class="o">,</span> <span class="n">counterparty</span><span class="o">,</span> <span class="n">broker</span><span class="o">,</span> <span class="n">price</span><span class="o">);</span>
        <span class="k">this</span><span class="o">.</span><span class="na">instrument</span> <span class="o">=</span> <span class="n">instrument</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">issuer</span> <span class="o">=</span> <span class="n">issuer</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">maturityDate</span> <span class="o">=</span> <span class="n">maturityDate</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">principal</span> <span class="o">=</span> <span class="n">principal</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">coupon</span> <span class="o">=</span> <span class="n">coupon</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="cm">/* SNIP */</span>
    
    <span class="cm">/* Return the constant implementation version */</span>
    
    <span class="cm">/* Serialisation method */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">writeExternal</span><span class="o">(</span><span class="nc">PofWriter</span> <span class="n">writer</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">setVersionId</span><span class="o">(</span><span class="nc">Math</span><span class="o">.</span><span class="na">max</span><span class="o">(</span><span class="no">IMPL_VERSION</span><span class="o">,</span> <span class="n">dataVersion</span><span class="o">));</span>
        <span class="cm">/* Serialise superclass first using nested writer */</span>
        <span class="nc">PofWriter</span> <span class="n">subWriter</span> <span class="o">=</span> <span class="n">writer</span><span class="o">.</span><span class="na">createNestedPofWriter</span><span class="o">(</span><span class="no">SUPERCLASS_INDEX</span><span class="o">);</span>
        <span class="kd">super</span><span class="o">.</span><span class="na">writeExternal</span><span class="o">(</span><span class="n">subWriter</span><span class="o">);</span>
        <span class="cm">/* Serialise ourselves in ascending index order */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeString</span><span class="o">(</span><span class="no">INSTRUMENT_INDEX</span><span class="o">,</span> <span class="n">getInstrument</span><span class="o">());</span>
        <span class="cm">/* Skipping rest of writes */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeRemainder</span><span class="o">(</span><span class="n">futureData</span><span class="o">);</span>
    <span class="o">}</span>
    
    <span class="cm">/* Deserialisation method */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">readExternal</span><span class="o">(</span><span class="nc">PofReader</span> <span class="n">reader</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
        <span class="n">dataVersion</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">getVersionId</span><span class="o">();</span>
        <span class="cm">/* Deserialise superclass first using nested reader */</span>
        <span class="nc">PofReader</span> <span class="n">subReader</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">createNestedPofReader</span><span class="o">(</span><span class="no">SUPERCLASS_INDEX</span><span class="o">);</span>
        <span class="kd">super</span><span class="o">.</span><span class="na">readExternal</span><span class="o">(</span><span class="n">subReader</span><span class="o">);</span>
        <span class="cm">/* Deserialise ourselves in ascending index order */</span>
        <span class="n">setInstrument</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">readString</span><span class="o">(</span><span class="no">INSTRUMENT_INDEX</span><span class="o">));</span>
        <span class="cm">/* Skipping rest of reads */</span>
        <span class="n">futureData</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">readRemainder</span><span class="o">();</span>
    <span class="o">}</span>
    
    <span class="cm">/* Evolvable implementation */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">getImplVersion</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="no">IMPL_VERSION</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">getDataVersion</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="n">dataVersion</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setDataVersion</span><span class="o">(</span><span class="kt">int</span> <span class="n">dataVersion</span><span class="o">)</span> <span class="o">{</span>
    	<span class="k">this</span><span class="o">.</span><span class="na">dataVersion</span> <span class="o">=</span> <span class="n">dataVersion</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="nc">Binary</span> <span class="nf">getFutureData</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="n">futureData</span><span class="o">;</span>
    <span class="o">}</span>
    
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setFutureData</span><span class="o">(</span><span class="nc">Binary</span> <span class="n">futureData</span><span class="o">)</span> <span class="o">{</span>
    	<span class="k">this</span><span class="o">.</span><span class="na">futureData</span> <span class="o">=</span> <span class="n">futureData</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h3 id="future">Future</h3>
<p>This has the same structure as the Bond class, with differences in the fields used, so it’s nothing exciting.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Future</span> <span class="kd">extends</span> <span class="nc">Contract</span> <span class="o">{</span>
    <span class="cm">/* Define object implementation version
       This can differ from Contract Base */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">IMPL_VERSION</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>

    <span class="cm">/* Define the indices of the serialised fields
       You can use same indices as super-class */</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">CONTRACT_INDEX</span> <span class="o">=</span> <span class="mi">1</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">TENOR_CODE_INDEX</span> <span class="o">=</span> <span class="mi">2</span><span class="o">;</span>
    <span class="kd">public</span> <span class="kd">static</span> <span class="kd">final</span> <span class="kt">int</span> <span class="no">LOTS_INDEX</span> <span class="o">=</span> <span class="mi">3</span><span class="o">;</span>

    <span class="cm">/* Define serialisation-specific fields */</span>
    <span class="kd">private</span> <span class="kt">int</span> <span class="n">dataVersion</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">Binary</span> <span class="n">futureData</span><span class="o">;</span>

    <span class="cm">/* Define the fields */</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">contract</span><span class="o">;</span>
    <span class="kd">private</span> <span class="nc">String</span> <span class="n">tenorCode</span><span class="o">;</span>
    <span class="kd">private</span> <span class="kt">double</span> <span class="n">lots</span><span class="o">;</span>
    
    <span class="cm">/* Define no-args constructor and any others */</span>
    <span class="kd">public</span> <span class="nf">Future</span><span class="o">()</span> <span class="o">{</span>
    	<span class="kd">super</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="kd">public</span> <span class="nf">Future</span><span class="o">(</span><span class="kt">long</span> <span class="n">contractNumber</span><span class="o">,</span> <span class="nc">String</span> <span class="n">currency</span><span class="o">,</span> <span class="nc">String</span> <span class="n">counterparty</span><span class="o">,</span> <span class="nc">String</span> <span class="n">broker</span><span class="o">,</span> <span class="kt">double</span> <span class="n">price</span><span class="o">,</span> <span class="nc">String</span> <span class="n">contract</span><span class="o">,</span> <span class="nc">String</span> <span class="n">tenorCode</span><span class="o">,</span> <span class="kt">double</span> <span class="n">lots</span><span class="o">)</span> <span class="o">{</span>
        <span class="kd">super</span><span class="o">(</span><span class="n">contractNumber</span><span class="o">,</span> <span class="n">currency</span><span class="o">,</span> <span class="n">counterparty</span><span class="o">,</span> <span class="n">broker</span><span class="o">,</span> <span class="n">price</span><span class="o">);</span>
        <span class="k">this</span><span class="o">.</span><span class="na">contract</span> <span class="o">=</span> <span class="n">contract</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">tenorCode</span> <span class="o">=</span> <span class="n">tenorCode</span><span class="o">;</span>
        <span class="k">this</span><span class="o">.</span><span class="na">lots</span> <span class="o">=</span> <span class="n">lots</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="cm">/* SNIP */</span>

    <span class="cm">/* Serialisation method */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">writeExternal</span><span class="o">(</span><span class="nc">PofWriter</span> <span class="n">writer</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">setVersionId</span><span class="o">(</span><span class="nc">Math</span><span class="o">.</span><span class="na">max</span><span class="o">(</span><span class="no">IMPL_VERSION</span><span class="o">,</span> <span class="n">dataVersion</span><span class="o">));</span>

        <span class="cm">/* Serialise superclass first using nested writer */</span>
        <span class="nc">PofWriter</span> <span class="n">subWriter</span> <span class="o">=</span> <span class="n">writer</span><span class="o">.</span><span class="na">createNestedPofWriter</span><span class="o">(</span><span class="no">SUPERCLASS_INDEX</span><span class="o">);</span>
        <span class="kd">super</span><span class="o">.</span><span class="na">writeExternal</span><span class="o">(</span><span class="n">subWriter</span><span class="o">);</span>

        <span class="cm">/* Serialise ourselves in ascending index order */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeString</span><span class="o">(</span><span class="no">CONTRACT_INDEX</span><span class="o">,</span> <span class="n">getContract</span><span class="o">());</span>
        <span class="cm">/* Skipping rest of writes */</span>
        <span class="n">writer</span><span class="o">.</span><span class="na">writeRemainder</span><span class="o">(</span><span class="n">futureData</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="cm">/* Deserialisation method */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">readExternal</span><span class="o">(</span><span class="nc">PofReader</span> <span class="n">reader</span><span class="o">)</span> <span class="kd">throws</span> <span class="nc">IOException</span> <span class="o">{</span>
        <span class="n">dataVersion</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">getVersionId</span><span class="o">();</span>

        <span class="cm">/* Deserialise superclass first using nested reader */</span>
        <span class="nc">PofReader</span> <span class="n">subReader</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">createNestedPofReader</span><span class="o">(</span><span class="no">SUPERCLASS_INDEX</span><span class="o">);</span>
        <span class="kd">super</span><span class="o">.</span><span class="na">readExternal</span><span class="o">(</span><span class="n">subReader</span><span class="o">);</span>

        <span class="cm">/* Deserialise ourselves in ascending index order */</span>
        <span class="n">setContract</span><span class="o">(</span><span class="n">reader</span><span class="o">.</span><span class="na">readString</span><span class="o">(</span><span class="no">CONTRACT_INDEX</span><span class="o">));</span>
        <span class="cm">/* Skipping rest of reads */</span>
        <span class="n">futureData</span> <span class="o">=</span> <span class="n">reader</span><span class="o">.</span><span class="na">readRemainder</span><span class="o">();</span>
    <span class="o">}</span>

    <span class="cm">/* Evolvable implementation */</span>
    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">getImplVersion</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="no">IMPL_VERSION</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">int</span> <span class="nf">getDataVersion</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="n">dataVersion</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setDataVersion</span><span class="o">(</span><span class="kt">int</span> <span class="n">dataVersion</span><span class="o">)</span> <span class="o">{</span>
    	<span class="k">this</span><span class="o">.</span><span class="na">dataVersion</span> <span class="o">=</span> <span class="n">dataVersion</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="nc">Binary</span> <span class="nf">getFutureData</span><span class="o">()</span> <span class="o">{</span>
    	<span class="k">return</span> <span class="n">futureData</span><span class="o">;</span>
    <span class="o">}</span>

    <span class="nd">@Override</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">setFutureData</span><span class="o">(</span><span class="nc">Binary</span> <span class="n">futureData</span><span class="o">)</span> <span class="o">{</span>
    	<span class="k">this</span><span class="o">.</span><span class="na">futureData</span> <span class="o">=</span> <span class="n">futureData</span><span class="o">;</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<h2 id="alternatives">Alternatives</h2>
<p>The above can be inelegant and messy. Here are some alternatives you might want to check out.</p>

<h3 id="dont-break-the-single-responsibility-principle">Don’t break the single-responsibility principle!</h3>
<p>“How about if I’m trying not to break the single-responsibility principle?”</p>

<p>Easy, reflection can help you, and to be more specific <a href="https://code.google.com/p/gridkit/wiki/ReflectionPofSerializer">Alexey Ragozin’s open-source ReflectionPofSerializer</a> can do this for you. <a href="http://blog.griddynamics.com/2009/09/oracle-coherence-using-pof-without.html">Read about the implementation right here on Grid Dynamics’ blog</a>.</p>

<h3 id="interface-inheritance-over-implementation-inheritance">Interface inheritance over implementation inheritance</h3>
<p>Is inheritance really all that important? <a href="http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html">Considering some people consider extends to be evil</a>, even James Gosling, creator of Java, should we really be pushing to use it when it makes the job more difficult? Not only does Oracle seemingly discourage it with their implementation of POF serialization, but <a href="https://code.google.com/p/protobuf/">Google’s Protocol Buffers</a> prefers nesting of messages rather than using an inheritance model.</p>

<p>Having learned ever since sixth form programming lectures that I should use inheritance all the time (they were a little extreme), it’s a big change to my normal thought processes. I can certainly see the advantages of solutions that use nested objects (matching the POF serialization model), over inheritance when using Coherence to store objects.</p>

<p>Overall this might be considered the better approach when you are given free-reign to refactor, or are writing from the ground up. With nested or separately defined objects you’re free to either implement a PofSerializer for each object, or make them PortableObjects as you wish, without as much of the hassle.</p>

<p>For backwards compatibility a newer implementation version should provide suitable defaults for attributes missing from older data, and the wholeness of data should be kept for the benefit of older versions.</p>

<p>For forwards compatibility an older implementation version should keep the wholeness of the serialised data even for parts not recognised by the implementation.</p>

<p>Using <code class="language-plaintext highlighter-rouge">setFutureData(reader.readRemainder())</code> in deserialisers and <code class="language-plaintext highlighter-rouge">writer.writeRemainder(getFutureData())</code> in serialisers achieves the above by simply holding onto any future data, and handing it over where necessary.</p>

<p>For backwards compatibility a newer implementation version should provide suitable defaults for attributes missing from older data, and the wholeness of data should be kept for the benefit of older versions. For forwards compatibility an older implementation version should keep the wholeness of the serialised data even for parts not recognised by the implementation. Using <code class="language-plaintext highlighter-rouge">setFutureData(reader.readRemainder())</code> in deserialisers and <code class="language-plaintext highlighter-rouge">writer.writeRemainder(getFutureData())</code> in serialisers achieves the above by simply holding onto any future data, and handing it over where necessary.</p>

<p>Implementation version should increase with each change to the implementation. Data versions of serialised objects should always be the higher of the current implementation version or the previous data version, whichever is the greater; <code class="language-plaintext highlighter-rouge">writer.setDataVersion(Math.max(getImplVersion(), getDataVersion())</code> is used in serialiser methods for this very purpose.</p>

<p>As POF serialisation expects to write data in increasing index numbers, and read that data back in the same order, we should add fields in increasing index number order.</p>

<p>Since we will only ever add to serialised objects, we should never go back on index numbers or change the usage of an index number. If the type of a serialised field changes, so should its associated index number.</p>

<p>As POF serialisation expects to write data in increasing index numbers, and read that data back in the same order, we should add fields in increasing index number order. Since we will only ever add to serialised objects, we should never go back on index numbers or change the usage of an index number. If the type of a serialised field changes, so should its associated index number.</p>

<p>The majority of serialisation unit tests will revolve around making certain the right calls are made to the right methods, and they’re done the right number of times. This is where a good mocking framework should be employed to mock up PofReaders and PofWriters to your heart’s content. Add a few calls to <code class="language-plaintext highlighter-rouge">Assert.assertEquals(expected, actual)</code> to be absolutely certain nothing odd has occurred, and you’re golden.</p>

<p>When testing that your objects serialise and deserialise correctly under normal circumstances, you need to use an ExternalizableHelper and a PofContext. You register your user types to the PofContext, and use the ExternalizableHelper to serialise and deserialise your object type.</p>

<p>It’s much easier to show an example than to explain how to use ExternalizableHelper and PofContext in conjunction.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@Test</span>
<span class="kd">public</span> <span class="kt">void</span> <span class="nf">testBondSerialisationDeserialisation</span><span class="o">()</span> <span class="o">{</span>
    <span class="cm">/* Register serialisable user types required to
       serialise your object */</span>
    <span class="nc">SimplePofContext</span> <span class="n">pofContext</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">SimplePofContext</span><span class="o">();</span>
    <span class="n">pofContext</span><span class="o">.</span><span class="na">registerUserType</span><span class="o">(</span><span class="mi">1001</span><span class="o">,</span> <span class="nc">Bond</span><span class="o">.</span><span class="na">class</span><span class="o">,</span> <span class="k">new</span> <span class="nc">PortableObjectSerializer</span><span class="o">(</span><span class="mi">1001</span><span class="o">));</span>

    <span class="cm">/* Make sure you have whatever object you want to
       test serialisation on */</span>
    <span class="nc">Bond</span> <span class="n">original</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Bond</span><span class="o">(</span><span class="mi">123</span><span class="o">,</span> <span class="s">"EUR"</span><span class="o">,</span> <span class="s">"ABC"</span><span class="o">,</span> <span class="s">"DEF"</span><span class="o">,</span> <span class="mf">100.0</span><span class="o">,</span> <span class="s">"GHI"</span><span class="o">,</span> <span class="s">"JKL"</span><span class="o">,</span> <span class="k">new</span> <span class="nc">Date</span><span class="o">(</span><span class="mi">456789</span><span class="o">),</span> <span class="mf">800.0</span><span class="o">,</span> <span class="mf">9.0</span><span class="o">);</span>

    <span class="cm">/* Use ExternalizableHelper.toBinary to serialise
       your object to Binary */</span>
    <span class="nc">Binary</span> <span class="n">bin</span> <span class="o">=</span> <span class="nc">ExternalizableHelper</span><span class="o">.</span><span class="na">toBinary</span><span class="o">(</span><span class="n">original</span><span class="o">,</span> <span class="n">pofContext</span><span class="o">);</span>

    <span class="cm">/* Use ExternalizableHelper.fromBinary to deserialise
       object from Binary */</span>
    <span class="nc">Object</span> <span class="n">obj</span> <span class="o">=</span> <span class="nc">ExternalizableHelper</span><span class="o">.</span><span class="na">fromBinary</span><span class="o">(</span><span class="n">bin</span><span class="o">,</span> <span class="n">pofContext</span><span class="o">);</span>

    <span class="c1">// Now do your tests - some simple examples</span>
    <span class="n">assertTrue</span><span class="o">(</span><span class="n">obj</span> <span class="k">instanceof</span> <span class="nc">Bond</span><span class="o">);</span>
    <span class="nc">Bond</span> <span class="n">copy</span> <span class="o">=</span> <span class="o">(</span><span class="nc">Bond</span><span class="o">)</span> <span class="n">obj</span><span class="o">;</span>
    <span class="n">assertEquals</span><span class="o">(</span><span class="n">original</span><span class="o">,</span> <span class="n">copy</span><span class="o">);</span>

    <span class="c1">// Good idea to do your own checks of individual members</span>
<span class="o">}</span>
</code></pre></div></div>

<p>The test is rather simple, and easy to add to. We don’t want to test that the PofSerializer, PofContext or ExternalizableHelper work, or that the Binary format is valid. Rather, we’re only interested in making sure our object is correctly serialised and deserialised, and the resulting object is equivalent to the original.</p>

<p>One thing you should probably not test is the byte array values of serialised objects. You can test using byte arrays via the <code class="language-plaintext highlighter-rouge">ExternalizableHelper.toByteArray()</code> and <code class="language-plaintext highlighter-rouge">ExternalizableHelper.fromByteArray()</code> functions, but you probably shouldn’t. It wastes your time whenever there is a change to a serialised object, having to manually edit the byte arrays to change the expected data. Only if you rely upon the byte array values should you be testing against them.</p>

<p>Testing serialisation code’s use of the PofReader and PofWriter is rather easy using a good mocking framework, since they’re both interfaces. You could even test the nesting, making sure your code uses the correct reader and writer for each serialised object, and the sequence in which fields are serialised or deserialised, as in this example.</p>

<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nd">@RunWith</span><span class="o">(</span><span class="nc">JMock</span><span class="o">.</span><span class="na">class</span><span class="o">)</span>
<span class="kd">public</span> <span class="kd">class</span> <span class="nc">FutureTest</span> <span class="o">{</span>
    <span class="nc">Mockery</span> <span class="n">context</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">JUnit4Mockery</span><span class="o">();</span>

    <span class="c1">// Setup mocks for PofWriter tests</span>
    <span class="nd">@Mock</span> <span class="nc">PofWriter</span> <span class="n">writer</span><span class="o">;</span>
    <span class="nd">@Mock</span> <span class="nc">PofWriter</span> <span class="n">subWriter</span><span class="o">;</span>

    <span class="c1">// Setup mocks for PofReader tests</span>
    <span class="nd">@Mock</span> <span class="nc">PofReader</span> <span class="n">reader</span><span class="o">;</span>
    <span class="nd">@Mock</span> <span class="nc">PofReader</span> <span class="n">subReader</span><span class="o">;</span>

    <span class="c1">// Setup sequence - only one needed</span>
    <span class="nd">@Auto</span> <span class="nc">Sequence</span> <span class="n">sequence</span><span class="o">;</span>

    <span class="c1">// Define some test data e.g.:</span>
    <span class="c1">// Contract</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="kt">long</span> <span class="n">contractNumber</span> <span class="o">=</span> <span class="mi">1234567890</span><span class="o">;</span>
    <span class="c1">// Future</span>
    <span class="kd">private</span> <span class="kd">final</span> <span class="nc">String</span> <span class="n">contract</span> <span class="o">=</span> <span class="s">"ABCD"</span><span class="o">;</span>

    <span class="nd">@Test</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">testFutureSerialisation</span><span class="o">()</span> <span class="o">{</span>
        <span class="n">context</span><span class="o">.</span><span class="na">checking</span><span class="o">(</span><span class="k">new</span> <span class="nc">Expectations</span><span class="o">()</span> <span class="o">{{</span>
        	<span class="c1">// Invocations in Future</span>
        	<span class="n">oneOf</span><span class="o">(</span><span class="n">writer</span><span class="o">).</span><span class="na">setVersionId</span><span class="o">(</span><span class="nc">Future</span><span class="o">.</span><span class="na">IMPL_VERSION</span><span class="o">);</span>
        	<span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
        	<span class="n">oneOf</span><span class="o">(</span><span class="n">writer</span><span class="o">).</span><span class="na">createNestedPofWriter</span><span class="o">(</span><span class="nc">Future</span><span class="o">.</span><span class="na">SUPERCLASS_INDEX</span><span class="o">);</span>
        	<span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
        	<span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="n">subWriter</span><span class="o">));</span>

        	<span class="c1">// Invocations in Contract</span>
        	<span class="n">oneOf</span><span class="o">(</span><span class="n">subWriter</span><span class="o">).</span><span class="na">setVersionId</span><span class="o">(</span><span class="nc">Contract</span><span class="o">.</span><span class="na">IMPL_VERSION</span><span class="o">);</span>
        	<span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
        	<span class="n">oneOf</span><span class="o">(</span><span class="n">subWriter</span><span class="o">).</span><span class="na">writeLong</span><span class="o">(</span><span class="nc">Contract</span><span class="o">.</span><span class="na">CONTRACT_NUMBER_INDEX</span><span class="o">,</span> <span class="n">contractNumber</span><span class="o">);</span>
        	<span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>

        	<span class="c1">// Write rest of serialised fields</span>
        	<span class="n">oneOf</span><span class="o">(</span><span class="n">subWriter</span><span class="o">).</span><span class="na">writeRemainder</span><span class="o">(</span><span class="n">aNull</span><span class="o">(</span><span class="nc">Binary</span><span class="o">.</span><span class="na">class</span><span class="o">));</span>
        	<span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>

        	<span class="c1">// Continue invocations in Future</span>
        	<span class="n">oneOf</span><span class="o">(</span><span class="n">writer</span><span class="o">).</span><span class="na">writeString</span><span class="o">(</span><span class="nc">Future</span><span class="o">.</span><span class="na">CONTRACT_INDEX</span><span class="o">,</span> <span class="n">contract</span><span class="o">);</span>
        	<span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>

        	<span class="c1">// Write rest of serialised fields</span>
        	<span class="n">oneOf</span><span class="o">(</span><span class="n">writer</span><span class="o">).</span><span class="na">writeRemainder</span><span class="o">(</span><span class="n">aNull</span><span class="o">(</span><span class="nc">Binary</span><span class="o">.</span><span class="na">class</span><span class="o">));</span>
        	<span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
        <span class="o">}});</span>

        <span class="c1">// Instantiate object to serialise using test data</span>
        <span class="nc">Future</span> <span class="n">future</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Future</span><span class="o">(</span><span class="n">contractNumber</span><span class="o">,</span> <span class="n">currency</span><span class="o">,</span> <span class="n">counterparty</span><span class="o">,</span> <span class="n">broker</span><span class="o">,</span> <span class="n">price</span><span class="o">,</span> <span class="n">contract</span><span class="o">,</span> <span class="n">tenorCode</span><span class="o">,</span> <span class="n">lots</span><span class="o">);</span>

        <span class="c1">// Serialise to check the expectations are correct</span>
        <span class="n">future</span><span class="o">.</span><span class="na">writeExternal</span><span class="o">(</span><span class="n">writer</span><span class="o">);</span>
    <span class="o">}</span>

    <span class="nd">@Test</span>
    <span class="kd">public</span> <span class="kt">void</span> <span class="nf">testFutureDeserialisation</span><span class="o">()</span> <span class="o">{</span>
        <span class="n">context</span><span class="o">.</span><span class="na">checking</span><span class="o">(</span><span class="k">new</span> <span class="nc">Exceptions</span><span class="o">()</span> <span class="o">{{</span>
            <span class="c1">// Invocations in Future</span>
            <span class="n">oneOf</span><span class="o">(</span><span class="n">reader</span><span class="o">).</span><span class="na">getVersionId</span><span class="o">();</span>
            <span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
            <span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="nc">Future</span><span class="o">.</span><span class="na">IMPL_VERSION</span><span class="o">));</span>
            <span class="n">oneOf</span><span class="o">(</span><span class="n">reader</span><span class="o">).</span><span class="na">createNestedPofReader</span><span class="o">(</span><span class="nc">Future</span><span class="o">.</span><span class="na">SUPERCLASS_INDEX</span><span class="o">);</span>
            <span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
            <span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="n">subReader</span><span class="o">));</span>

            <span class="c1">// Invocations in Contract</span>
            <span class="n">oneOf</span><span class="o">(</span><span class="n">subReader</span><span class="o">).</span><span class="na">getVersionId</span><span class="o">();</span>
            <span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
            <span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="nc">Contract</span><span class="o">.</span><span class="na">IMPL_VERSION</span><span class="o">));</span>
            <span class="n">oneOf</span><span class="o">(</span><span class="n">subReader</span><span class="o">).</span><span class="na">readLong</span><span class="o">(</span><span class="nc">Contract</span><span class="o">.</span><span class="na">CONTRACT_NUMBER_INDEX</span><span class="o">);</span>
            <span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
            <span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="n">contractNumber</span><span class="o">));</span>

            <span class="c1">// Read rest of serialised fields</span>
            <span class="n">oneOf</span><span class="o">(</span><span class="n">subReader</span><span class="o">).</span><span class="na">readRemainder</span><span class="o">();</span>
            <span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
            <span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="kc">null</span><span class="o">));</span>

            <span class="c1">// Continue invocations in Future</span>
            <span class="n">oneOf</span><span class="o">(</span><span class="n">reader</span><span class="o">).</span><span class="na">readString</span><span class="o">(</span><span class="nc">Future</span><span class="o">.</span><span class="na">CONTRACT_INDEX</span><span class="o">);</span>
            <span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
            <span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="n">contract</span><span class="o">));</span>

            <span class="c1">// Write rest of serialised fields</span>
            <span class="n">oneOf</span><span class="o">(</span><span class="n">reader</span><span class="o">).</span><span class="na">readRemainder</span><span class="o">();</span>
            <span class="n">inSequence</span><span class="o">(</span><span class="n">sequence</span><span class="o">);</span>
            <span class="n">will</span><span class="o">(</span><span class="n">returnValue</span><span class="o">(</span><span class="kc">null</span><span class="o">));</span>
        <span class="o">}});</span>

        <span class="c1">// Instantiate Future object with default constructor to deserialise</span>
        <span class="nc">Future</span> <span class="n">future</span> <span class="o">=</span> <span class="k">new</span> <span class="nc">Future</span><span class="o">();</span>

        <span class="c1">// Deserialise to check the expectations are correct</span>
        <span class="n">future</span><span class="o">.</span><span class="na">readExternal</span><span class="o">(</span><span class="n">reader</span><span class="o">);</span>

        <span class="c1">// Check data is the same as expected with asserts</span>
        <span class="n">assertEquals</span><span class="o">(</span><span class="n">contractNumber</span><span class="o">,</span> <span class="n">future</span><span class="o">.</span><span class="na">getContractNumber</span><span class="o">());</span>
        <span class="n">assertEquals</span><span class="o">(</span><span class="n">contract</span><span class="o">,</span> <span class="n">future</span><span class="o">.</span><span class="na">getContract</span><span class="o">());</span>

        <span class="c1">// Skipping rest of asserts</span>
    <span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>

<p>Shan He touches on testing serialisation in his post, and suggests creating two projects to test with. One project would contain the older implementation, the other project containing the newer implementation. The two then transfer serialised objects checking they serialise and deserialise correctly between the versions in test.
When upgrading a Coherence cluster, nodes can be brought down one at a time, upgraded and brought back up.
To test the case of an old version node passing an object to a new version, the old implementation constructs an object, serialises and passes it to the new implementation. The new implementation would deserialise, re-serialise and return the object. The old implementation deserialises and checks its equality.
To test the case of a new version node passing an object to an old version, just swap the roles and have the new implementation construct the object at the start, and check the object at the end.</p>

<p>The process of making a class serialisable in Portable Object Format is not complicated, but can be tedious. There can be a large amount of duplicate code, making potential for errors higher, but if both the super- and sub-classes being serialised can evolve, that duplication can be the only way to implement a solution. Hopefully this post has helped in figuring out what’s needed for a working implementation in other systems.</p>

<h2 id="references">References</h2>

<p>Shan He, 27 June 2011. Understanding the evolvable POF objects in Coherence. Shanhe.me
<a href="http://shanhe.me/2011/06/27/understanding-the-evolvable-pof-objects-in-coherence">http://shanhe.me/2011/06/27/understanding-the-evolvable-pof-objects-in-coherence</a></p>

<p>Alexey Ragozin, 18 September 2009. Oracle Coherence using POF, without a single line of code. Blog.GridDynamics.com
<a href="http://blog.griddynamics.com/2009/09/oracle-coherence-using-pof-without.html">http://blog.griddynamics.com/2009/09/oracle-coherence-using-pof-without.html</a></p>

<p>Allen Holub, 1 August 2003. Why extends is evil. JavaWorld.com
<a href="http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html">http://www.javaworld.com/javaworld/jw-08-2003/jw-0801-toolbox.html</a></p>]]></content><author><name></name></author><category term="java" /><category term="software development" /><category term="oracle coherence" /><summary type="html"><![CDATA[An older article of mine, written about Portable Object Format, used in a past role for a project.]]></summary></entry></feed>