A Maven plugin for creating DAR files

Summary

Fork me on GitHub

Apache Maven has become the de facto build tool for Java projects. The Push development team uses it to create the Diffusion™ Server and sample applications. We have and are continuing to improve our support for creating Diffusion Applications using Maven, allowing our users to benefit from its declarative approach to full-lifecycle builds, component dependency management, and rich integration with development tools. In this article I introduce mvndar, a Maven plugin for creating Diffusion Archive (DAR) files. Mvndar is the first component we are making available from the new Push Technology Public Maven Repository. The mvndar plugin adds the following features to Maven:

  • A new dar packaging type for creating Diffusion DAR files.
  • Packaging of project build output and dependencies within the DAR.
  • Inclusion of other resources within the DAR such as etc or html configuration files.
  • Automatic addition of a Diffusion-Version header to the DAR manifest.

It’s open source, available from GitHub, and you can use it today.

What’s a DAR?

Publishers are server-side components that run in a Diffusion server and act as central switchboards for your application. A publisher can send messages to topics, and hence to clients, and process messages received from clients. Most Diffusion applications have at least one publisher. Since it’s good practice to package logically separate parts of an application as separate publisher implementations, more complex applications may have several publishers. Publishers can be configured statically in the server’s etc/Publishers.xml file. This is simple, but doesn’t allow a publisher to be changed or reconfigured without restarting the server. The preferred way to deploy publishers is to package them into a Diffusion Archive (DAR) file. DARs are jar format files that contain compiled code, libraries, and  configuration. They have a similar purpose to Java EE EAR or WAR files, and can be dynamically deployed to and undeployed from a running Diffusion server. The server expects the contents of a DAR file to be arranged in a particular structure. Please refer to the Diffusion documentation for details. Previously the best way to automate the process of packing application code and configuration into this structure was to use an Ant script, or perhaps the Maven assembly plugin. The mvndar plugin takes care of the packaging for you, so you no longer need custom scripts. Because mvndar inherits Maven’s “configuration by convention” approach, you need do very little to use it. Simply change the packaging type in your pom file, and Maven will orchestrate the compilation, testing, and packaging of your DAR, and optionally publish it to a Maven repository for distribution to other projects.

Where can I get it?

documentation is available on GitHub. Mvndar is the first component we are making available from the new Push Technology Public Maven Repository at http://download.diffusiondata.com/maven/. Its coordinates are:

<dependency>
  <groupId>com.pushtechnology</groupId>
  <artifactId>dar-maven-plugin</artifactId>
  <version>1.0</version>
  <type>maven-plugin</type>
</dependency>

In version 1.1, the groupId was changed to com.pushtechnology.tools.

Enough talk, show me the code

Let me take you through the steps of packaging the EchoServer sample publisher as a DAR. If you selected the examples when you installed Diffusion, the EchoServer source code can be found in the Diffusion product directory below examples/publishers. The following shows the actions taken from my Linux command line, with the DIFFUSION_HOME environment variable set to the location of a Diffusion 4.5.4 installation. You should be able to translate these to the corresponding actions for other operating systems. First let’s start with a new Maven project.

% mvn archetype:generate -DgroupId=com.pushtechnology -DartifactId=echo
  -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

This command will create an echo subdirectory, and populate it with a simple pom.xml file and some sample Java code. We don’t need the sample code, so next I’ll replace it with the EchoServer code.

% cd echo
% rm -rf src/main/java/com src/test
% rsync -am $DIFFUSION_HOME/examples/publishers/ ./src/main/java/
    --include="echo/*" --exclude="*.java"

We now have the following three files in the echo project.

src/main/java/com/pushtechnology/diffusion/demos/publishers/echo/MessagesTopicDataHandler.java
src/main/java/com/pushtechnology/diffusion/demos/publishers/echo/EchoServer.java
pom.xml

MessagesTopicDataHandler is a message handler implementation used by EchoServer. A publisher needs to be configured a Publishers.xml file, so let’s create one and add it as src/main/diffusion/etc/Publishers.xml.

<publishers>
  <publisher name="EchoServer">
    <class>com.pushtechnology.diffusion.demos.publishers.echo.EchoServer</class>
    <start>true</start>
  </publisher>
</publishers>

The publisher code depends on the DIFFUSION and requires diffusion.jar file to be in the CLASSPATH. Before building the project, we must change the pom.xml file to tell Maven where to find Diffusion. I’ll do so by defining a system scope dependency, and while I’m at it remove some of the sample boilerplate, leaving the following.

<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                      http://maven.apache.org/maven-v4_0_0.xsd">

  <modelVersion>4.0.0</modelVersion>
  <groupId>com.pushtechnology</groupId>
  <artifactId>echo</artifactId>
  <packaging>jar</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>echo</name>

  <dependencies>
    <dependency>
      <groupId>com.pushtechnology</groupId>
      <artifactId>diffusion</artifactId>
      <version>4.5.4</version>
      <scope>system</scope>
      <systemPath>${DIFFUSION_HOME}/lib/diffusion.jar</systemPath>
      <optional>true</optional>
    </dependency>
  </dependencies>
</project>

At this stage, we’ve a conventional Maven project. We can ask Maven to build the project (mvn clean package), but it will create a jar file. Let’s fix that.

Enter mvndar

To configure the project to use mvndar, we need to allow Maven to fetch plugins from the Push Technology repository …

<pluginRepositories>
  <pluginRepository>
    <id>push-repository</id>
    <url>http://download.pushtechnology.com/maven/</url>
  </pluginRepository>
</pluginRepositories>

… add mvndar to the configured plugins …

<build>
  <plugins>
    <plugin>
      <groupId>com.pushtechnology</groupId>
      <artifactId>dar-maven-plugin</artifactId>
      <version>1.0</version>
      <extensions>true</extensions>
    </plugin>
  </plugins>
</build>

… and change the project packaging from jar to dar

<packaging>dar</packaging>

The completed project can be found in our blogs repository on GitHub. Finally, we can build our DAR file (I’ve omitted some lines for clarity):

% mvn clean package
[INFO] Scanning for projects...
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building echo 1.0-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO]
[INFO] --- maven-clean-plugin:2.4.1:clean (default-clean) @ echo ---
[INFO]
[INFO] --- maven-resources-plugin:2.6:resources (default-resources) @ echo ---
[INFO]
[INFO] --- maven-compiler-plugin:3.1:compile (default-compile) @ echo ---
[INFO] Changes detected - recompiling the module!
[INFO] Compiling 2 source files to /home/philipa/push/product/Diffusion4.5.4_01/examples/echo/target/classes
[INFO]
[INFO] --- maven-resources-plugin:2.6:testResources (default-testResources) @ echo ---
[INFO]
[INFO] --- maven-compiler-plugin:3.1:testCompile (default-testCompile) @ echo ---
[INFO] Nothing to compile - all classes are up to date
[INFO]
[INFO] --- maven-surefire-plugin:2.15:test (default-test) @ echo ---
[INFO] No tests to run.
[INFO]
[INFO] --- dar-maven-plugin:1.0:dar (default-dar) @ echo ---
[INFO] Assembling DAR [echo]
[INFO] Building jar: /home/philipa/push/product/Diffusion4.5.4_01/examples/echo/target/echo-1.0-SNAPSHOT.dar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

Success! A dar file has appeared in the target directory that we can happily deploy to a server.

Options

The default behaviour of mvndar should suit most publishers, but let’s take a lightning tour through how the plugin works, and the things you can fiddle with. A manifest file will automatically be created, containing a Diffusion-Version entry, with a default value of 4.5.0. This will prevent the DAR from being deployed on an earlier version of the server. It may be altered using the <minimumDiffusionVersion> configuration element.

...
<plugin>
  <groupId>com.pushtechnology</groupId>
  <artifactId>dar-maven-plugin</artifactId>
  <version>1.0</version>
  <extensions>true</extensions>
  <configuration>
    <minimumDiffusionVersion>4.4.0</minimumDiffusionVersion>
  </configuration>
</plugin>
...

The compiled project code and resources, together with a subset of the project’s dependencies will be added to the ext directory. You may have noticed that we marked the diffusion.jar dependency as optional. This prevents it from being included in the dar. The following rules are used to filter the dependencies.

  • The dependency type must be jar.
  • The dependency scope must be compile, runtime, or system. Any provided and test dependencies will not be included. Optional dependencies will not be included.
  • A subset of the project code and resources can be selected using the configuration elements <outputIncludes/> or <outputExcludes/> to specify list of fileset patterns.

The publisher’s configuration files should be packaged in subdirectories of src/main/diffusion. Any content in data, etc, or html subdirectories of src/main/diffusion will be added to the DAR file. You can filter the content from src/main/diffusion using <diffusionIncludes>/<diffusionInclude> or <diffusionExcludes>/<diffusionExclude>. To handle archiving, the mvndar uses the Maven Archiver. This allows control over the DAR manifest, whether the Maven pom.xml and pom.properties files are added to the DAR, and whether the DAR file is compressed. For example, here’s how to add implementation entries to the manifest.

...
<plugin>
  <groupId>com.pushtechnology</groupId>
  <artifactId>dar-maven-plugin</artifactId>
  <version>1.0</version>
  <extensions>true</extensions>
  <configuration>
    <archiver>
      <manifest>
        <addDefaultImplementationEntries>true</addDefaultImplementationEntries>
      </manifest>
    </archiver>
  </configuration>
</plugin>
...

Future plans

We’re always looking for ways to make it easier to develop applications with Diffusion. Two of the things we would like to do in the future are first to enhance the Diffusion eclipse tools to provide an option to create a Maven-based project using mvndar, and allow the resulting dar to be deployed to a server. Secondly, we are also considering providing a separate API jar that through the Push Public Maven Repository is sufficient to build applications. Do let us know what you think of these ideas.

Conclusion

We hope you find mvndar convenient for building Diffusion applications using Maven.