On this page we describe how to implement Externalizable automatically with the Externalizer4J maven plugins.  By implementing java.io.Externalizable instead of java.io.Serializable you improve java serialization performance:

  • you maximize speed and reduce the serialized data size.

Are you using Maven to automate you builds? Then this page give you all the information you need in integrate the automatic optimization of you classes in your build.Apache Maven

Support for other build systems:

  • Apache Ant support is available as well using the Externalizer4J Ant tasks
  • IntelliJ IDEA users can benefit from the fully integrated IntelliJ plugin

 

maven-term

Implement Externalizable automatically

What do we mean with “implement Externalizable automatically”? Externalizer4J takes your serializable classes and analyses the bytecode. Using this analysis your classes get updated:

  1. Externalizer4J creates the writeExternal() and readExternal() methods
  2. Modifies class so that it implements the Externalizable interface

The result is a class with better serialization performance. The data overhead normally associated with Serializable classes gets removed. And CPU load is reduce by produced optimized serialization logic, no more use of reflection.

Setup externalizer-maven-plugin

Latest version, updated on December 11 2016

<properties>
    <e4j.version>2016.11-SNAPSHOT</e4j.version>
</properties>

Enabling the generation of Externalizable logic  is very simple.  Copy the snippet below into an existing pom.xml. The plugin itself does not require any additional configuration.

To control the optimization or get more information about the optimization process please refer to the configuration reference.

            <plugin>
                <groupId>be.biggerbytes</groupId>
                <artifactId>externalizer-maven-plugin</artifactId>
                <version>${e4j.version}</version>
                <executions>
                    <execution>
                        <id>optimize-classes</id>
                        <goals>
                            <goal>externalize</goal>
                            <goal>externalizeTest</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

Add repository

To use the maven Externalizer4J plugin in an existing build one needs to download the plugin first. All the artifacts needed to execute the plugin are freely available on our company’s maven repository. Simple add the repository to your maven setup. You can do this by either:

  • putting it directly in your pom.xml
  • putting it in your settings.xml

The repository definition below can be copied into you existing pom.xml or settings.xml .

    <pluginRepositories>
        <pluginRepository>
            <id>biggerbytes</id>
            <url>http://www.biggerbytes.be/maven2</url>
            <!-- -->
            <snapshots>
                <enabled>true</enabled>
                <!--<checksumPolicy>fail</checksumPolicy>-->
                <updatePolicy>daily</updatePolicy>
            </snapshots>
            <releases>
                <enabled>true</enabled>
                <!--<checksumPolicy>fail</checksumPolicy>-->
                <updatePolicy>never</updatePolicy>
            </releases>
        </pluginRepository>
    </pluginRepositories>

Configure Externalizer4J

All the Externalizer4J tools, including the Ant tasks, read one and the same configuration: a file called externalizer4j.properties. Whenever the configuration is missing the tools will display a short message and stop without interrupting the build. The optimization will simply not run.

All the Externalizer4J tools are configured using an externalizer4j.properties file

Externalizer4J optimizer expects to find a file externalizer4j.properties file in the root of the classes directory. In the example below the output of the task is ${classes.dir} for instance. The ExternalizerTask will look in this directory for the externalizer4.properties.

Basic externalizer4j.properties

To get started the externalizer4j.properties file should only contain one line: acceptEULA=true

#
# Accept the EULA by setting to true to activate
#
# default: false
#
acceptEULA=true

The Externalizer4J EULA clearly describes all there is the know when you start to use the tools totally for FREE.

The configuration reference details the more advanced optimizations options, how to get more information about the optimization process and much more.

Externalizable creation in action

How does the plugin work inside your maven build. Take a look at the output below. You’ll recognize all the steps of a standard maven build. Let’s take a closer look:

  • line 7 to 16 : resources processing and compilation with the standard maven plugins
  • line 18 to 45 : the Externalizer4J plugin analyses and optimizes the bytecode generated by in the step before
  • line 47 to 54 : test resources processing and test source compilation
  • line 56 to 69 : optimization of the bytecode of the test classes
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building externalizer-demo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ externalizer-demo ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] Copying 1 resource
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ externalizer-demo ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 29 source files to /home/externalizer-demo/target/classes
[WARNING] /home/externalizer-demo/src/main/java/demo/serialization/Benchmark.java: /home/externalizer-demo/src/main/java/demo/serialization/Benchmark.java uses unchecked or unsafe operations.
[WARNING] /home/externalizer-demo/src/main/java/demo/serialization/Benchmark.java: Recompile with -Xlint:unchecked for details.
[INFO]
[INFO] --- externalizer-maven-plugin:2015.2-SNAPSHOT:externalize (optimize-classes) @ externalizer-demo ---
Built on 2015-04-11T11:34:34Z
[INFO] Start collecting information
[INFO] Done collecting
[INFO] Start analyzing
[WARNING] =-&gt; demo/serialization/Basic implements [writeObject]
[INFO] 48 classes will not be optimized
[INFO] Done analyzing in 35.46ms
[INFO] Start optimizing
[INFO] demo/serialization/CollectionData estimated size reduction 68.02%
[INFO] demo/serialization/datadatad/ArraysSerializableUnique estimated size reduction 13.79%
[INFO] demo/serialization/datadatad/CollectionSerializable estimated size reduction 31.13%
[INFO] demo/serialization/datadatad/ChildChildSerializable estimated size reduction 56.22%
[INFO] demo/serialization/datadatad/Field15Serializable estimated size reduction 71.58%
[INFO] demo/serialization/datadatad/ArraysSerializable estimated size reduction 14.81%
[INFO] demo/serialization/datadatad/ChildSerializable estimated size reduction 41.46%
[INFO] demo/serialization/datadatad/ParentDataSerializable estimated size reduction 41.06%
[INFO] demo/serialization/datadatad/SelfReferencing estimated size reduction 54.14%
[INFO] demo/serialization/datadatad/SerFinalField estimated size reduction 31.18%
[INFO] demo/serialization/datadatad/CollectionSerializableUnique estimated size reduction 29.46%
[INFO] demo/serialization/datadatad/SerFieldSmall estimated size reduction 9.88%
[INFO] demo/serialization/Person estimated size reduction 54.62%
[INFO] demo/serialization/AbstractData estimated size reduction 0.00%
[INFO] +----------------------------------------------------------
[INFO] | Average estimated size reduction 49.39%
[INFO] +----------------------------------------------------------
[INFO] Optimized 14 classes
[INFO] Done optimizing in 442.99ms
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ externalizer-demo ---
[WARNING] Using platform encoding (UTF-8 actually) to copy filtered resources, i.e. build is platform dependent!
[INFO] skip non existing resourceDirectory /home/externalizer-demo/src/test/resources
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ externalizer-demo ---
[INFO] Changes detected - recompiling the module!
[WARNING] File encoding has not been set, using platform encoding UTF-8, i.e. build is platform dependent!
[INFO] Compiling 6 source files to /home/externalizer-demo/target/test-classes
[INFO]
[INFO] --- externalizer-maven-plugin:2015.2-SNAPSHOT:externalizeTest (optimize-classes) @ externalizer-demo ---
[INFO] Start collecting information
[INFO] Done collecting
[INFO] Start analyzing
[INFO] 14 classes will not be optimized
[INFO] Done analyzing in 21.12ms
[INFO] Start optimizing
[INFO] demo/TimeData estimated size reduction 0.00%
[INFO] demo/Employee estimated size reduction 46.15%
[INFO] +----------------------------------------------------------
[INFO] | Average estimated size reduction 32.26%
[INFO] +----------------------------------------------------------
[INFO] Optimized 2 classes
[INFO] Done optimizing in 5.43ms
[INFO]

 

Goals

The Externalizer4J plugin comes with 2 separate goals to optimize the classes and the test classes respectively. Each goal is bound to a specific phase of the maven build by default.

  • externalize:
    • optimizes the classes
    • default phase is compile
  • externalizeTest:
    • optimizes the test-classes
    • default phase is test-compile

We recommend executing both the externalize and the externalizeTest goal during the build. This for two reasons:

  1. You want to run the tests using the optimized classes
  2. Test classes can be used by other builds for their test and are best optimized too

pom snippet

    &lt;properties&gt;
        &lt;e4j.version&gt;2015.8.2-SNAPSHOT&lt;/e4j.version&gt;
    &lt;/properties&gt;

    &lt;pluginRepositories&gt;
        &lt;pluginRepository&gt;
            &lt;id&gt;biggerbytes&lt;/id&gt;
            &lt;url&gt;http://www.biggerbytes.be/maven2&lt;/url&gt;
            &lt;!--  --&gt;
            &lt;snapshots&gt;
                &lt;enabled&gt;true&lt;/enabled&gt;
                &lt;checksumPolicy&gt;fail&lt;/checksumPolicy&gt;
                &lt;updatePolicy&gt;daily&lt;/updatePolicy&gt;
            &lt;/snapshots&gt;
            &lt;releases&gt;
                &lt;enabled&gt;true&lt;/enabled&gt;
                &lt;checksumPolicy&gt;fail&lt;/checksumPolicy&gt;
                &lt;updatePolicy&gt;never&lt;/updatePolicy&gt;
            &lt;/releases&gt;
        &lt;/pluginRepository&gt;
    &lt;/pluginRepositories&gt;

    &lt;build&gt;
        &lt;plugins&gt;
            &lt;plugin&gt;
                &lt;groupId&gt;be.biggerbytes&lt;/groupId&gt;
                &lt;artifactId&gt;externalizer-maven-plugin&lt;/artifactId&gt;
                &lt;version&gt;${e4j.version}&lt;/version&gt;
                &lt;executions&gt;
                    &lt;execution&gt;
                        &lt;id&gt;optimize-classes&lt;/id&gt;
                        &lt;goals&gt;
                            &lt;goal&gt;externalize&lt;/goal&gt;
                            &lt;goal&gt;externalizeTest&lt;/goal&gt;
                        &lt;/goals&gt;
                    &lt;/execution&gt;
                &lt;/executions&gt;
            &lt;/plugin&gt;
    &lt;/build&gt;

Summary

Externalizer4J offers a maven plugin to integrate the optimization of the serialization in any build. Using the plugin in a build requires 3 steps

  1. Define the maven repository
  2. Define the maven plugin in the <build/> section of the pom.xml
  3. Optional: tweak
    1. modify the optimization by defining an externalizer4j.properties file

 

maven-term