Allan Cunliffe


This How To assumes you have some experience with Java programming and have installed the following:

  • JDK 1.6 or higher <http://java.sun.com/j2se/1.5.0/download.jsp>
  • Apache Ant <http://ant.apache.org>
  • Xena <http://xena.sourceforge.net>.

New file format

For the purpose of working through this tutorial, let's assume that we have a requirement to create a normaliser for a brand new file format. This file format, the 'foo' file format, is the mainstay of organisation X, and is specified as follows: All 'foo' files are UTF-8 text or ASCII, and should have the extension 'foo', and begin with the sequence of characters:


After that, a foo file is partitioned into parts separated by the '~' character. The '\' character is used as an escape sequence, if it is followed by a '~' or '\' character these characters are taken as literal, otherwise the '\' is ignored. At this stage, this is all we are going to be concerned with. When we preserve 'foo' files, we will be preserving each part of the file as a separate piece of XML.

It is possible that some foo files will not have the correct filename extension, it is also possible that some files which are not 'foo' files will have the foo extension. Organisation X proposes that the XML schema for the preserved 'foo' file format will be as such:

&lt;part&gt;SOME DATA&lt;/part&gt;
&lt;part&gt;MORE DATA, AN EMPTY PART FOLLOWS&lt;/part&gt;
&lt;part&gt;FINAL PART OF FOO FILE&lt;/part&gt;

Create an outline of the plugin that will be loaded by Xena.

Xena expects plugins to be loaded as JAR files, laid out in a specific way. To aid in this, the Apache Ant build tool will be used. To set up our plugin development directory, we will create a new folder, called foo_plugin, at an arbitrary place in the filesystem. This folder will be called the home folder, and designated by '~/' so our plugin will be contained in '~/foo_plugin'. For Windows users, switch the '/' to '\', and the '~' to something like C:\Documents and Settings\UserName\My Documents.

To start off with, we get all the components we need to make a plugin. The first is the name.properties file. This file should be loaded in the base directory of the JAR file, and should contain the fully qualified name of the plugin loader class, which is the class that will load all the components of the plugin. In this example, we will be putting all our classes in the package:


The plugin class loader will be called FooPlugin. So here is the content of our name.properties file:


Create the source folder for the package, and put the name.properties file inside it.

In this example, the source will be created in the folder named 'src', and the output of any compiling will go to 'bin', and a dist folder will contain the built JAR file. Any configuration files will be put into a folder named 'etc', and finally, any required external libraries (probably in JAR form) will be stored in the 'ext' folder. Create those folders and the name.properties file now. At the end of setting up the folder structure, we should have the following entries in the ~/foo_plugin folder:

- /bin
- /dist
- /etc
- /src
- name.properties

Create an Ant build file to do it all automatically.

The foo_plugin directory contains a sample build file. The following instructions can be used to recreate this build file:

1. Create the top-level project element. Everything else in the build.xml file listed below goes between these opening and closing project tags.

&lt;project name="foo" basedir="." default="makejar"&gt;

2. Set the name of the plugin, and match the folder structure used in our project.

&lt;property name="pluginname" value="foo"/&gt;
&lt;property name="srcdir" value="src"/&gt;
&lt;property name="etcdir" value="etc"/&gt;
&lt;property name="builddir" value="bin"/&gt;
&lt;property name="distdir" value="dist"/&gt;

3. Set the location of the xena.jar file in a property named, appropriately, xenajarlocation. This is the most likely property to need changing, unless you happen to have the xena file in the same relative location.

This guide assumes that you have already built the xena.jar file. If this is not the case, please follow the build guide on the Xena website in order to do so.

The default location for the xena.jar file is the xena directory of the root plugin-howto directory.

&lt;property name="xenajarlocation" value="../../xena/xena.jar" /&gt;

4. Create the compile path, to be used when compiling our plugins:

&lt;path id="compile.path"&gt;
        &lt;pathelement location="${xenajarlocation}"/&gt;

5. Add the init and clean targets:

&lt;target name="init" description="Create output directories"&gt;
        &lt;mkdir dir="${builddir}"/&gt;
        &lt;mkdir dir="${distdir}"/&gt;

&lt;target name="clean" depends="init" description="--&gt; Clear all output files"&gt;
        &lt;delete dir="${builddir}"/&gt;
        &lt;delete dir="${distdir}"/&gt;

Then the actual compile job itself, broken into a couple of lines.

&lt;target name="compile" depends="init" description="--&gt;Compile the .java sources"&gt;
                &lt;javac srcdir="${srcdir}" destdir="${builddir}" debug="on"
                        verbose="on" classpathref="compile.path"/&gt;

6. Add the makejar job:

&lt;target name="makejar" description="--&gt;Make the jar file" depends="compile"&gt;
        &lt;delete &gt;
                &lt;fileset file="${distdir}/${pluginname}.jar"/&gt;
        &lt;jar jarfile="${distdir}/${pluginname}.jar" manifest="etc/MANIFEST.MF"&gt;
                &lt;fileset dir="${builddir}"&gt;
                        &lt;include name="**/*.class"/&gt;
                &lt;fileset dir="."&gt;
                        &lt;include name = "name.properties"/&gt;
                &lt;fileset dir="${srcdir}"&gt;
                        &lt;include name = "**/*.properties"/&gt;

The manifest for the JAR file is referenced in the makejar target. Since there will be no main class in our plugin JAR, all we will include in our manifest file will be the line:

Manifest-Version: 1.0

The manifest file should be named MANIFEST.MF, and be placed in the etc folder, as specified in the ant build job. Also, the makejar job looks for the name.properties file in the base directory, and any properties files in the src directory tree.

Create the FooPlugin class

This class will tell Xena what it is we can expect to find in the plugin. It specifies any normalisers, types, guessers, file namers, meta data package wrappers, help sets, basically anything that can be in a normaliser. It will need to extend the XenaPlugin class, found in the au.gov.naa.digipres.xena.kernel.plugin package. For the moment, we will leave it almost entirely blank, we will just override the only two abstract methods in XenaPlugin:

  • getName
  • getVersion.

So, our FooPlugin.java file content will be:

package au.gov.naa.digipres.xena.demo.foo;

import au.gov.naa.digipres.xena.kernel.plugin.XenaPlugin;

public class FooPlugin extends XenaPlugin {

        public static final String FOO_PLUGIN_NAME = "foo";

        public String getName() {
                return FOO_PLUGIN_NAME;

        public String getVersion() {
                return "0.1";


This file is expected to be in the JAR at the location: au/gov/naa/digipres/xena/demo/foo. To make this happen, we will stick it into that location in the source tree.

So, several make directory commands later, we now have the folder:


This folder contains the single file FooPlugin.java.

Build the Foo plugin

It is time to build our (empty) foo plugin for the first time.

1. In a command shell, at the location '~/foo_plugin', type:


If everything works, a JAR file, named foo.jar will now exist in the folder dist.

2. Type:

jar -tvf foo.jar

This reveals the contents of the JAR:

#jar -tvf foo.jar
    0 Wed Nov 21 15:03:48 EST 2007 META-INF/
  106 Wed Nov 21 15:03:46 EST 2007 META-INF/MANIFEST.MF
    0 Wed Nov 21 15:03:46 EST 2007 au/
    0 Wed Nov 21 15:03:46 EST 2007 au/gov/
    0 Wed Nov 21 15:03:46 EST 2007 au/gov/naa/
    0 Wed Nov 21 15:03:46 EST 2007 au/gov/naa/digipres/
    0 Wed Nov 21 15:03:46 EST 2007 au/gov/naa/digipres/xena/
    0 Wed Nov 21 15:03:46 EST 2007 au/gov/naa/digipres/xena/demo/
    0 Wed Nov 21 15:03:46 EST 2007 au/gov/naa/digipres/xena/demo/foo/
  606 Wed Nov 21 15:03:46 EST 2007 au/gov/naa/digipres/xena/demo/foo/FooPlugin.class
   39 Wed Nov 21 09:56:50 EST 2007 name.properties

So the initial set up is complete. The code will start in the next chapter.


Wiki: Main_Page