Sunday, October 16, 2011

Creating standalone applications with Java and Maven

The challenge

In this installment we're going to take a look at what does it take to create a standalone Java application that's a little bit more sophisticated than the famous Hello, World. Let's start with the simplest example:
package org.example;

public class Main {
    public static void main(String[] args) {
        System.out.println("Hello, world!");
    }
}
To compile and run this one we need to invoke the javac compiler, package it to some jar file (say example.jar), create a manifest file (or not..) and start the application passing on the proper classpath and class name that is the entry point to our application. This might look something like this:
java -cp . org.example.Main

The "proper" way

I know for a fact that Maven can be a pain in the ass if used by some inexperienced fellow that wanted it to do everything but didn't know how to ask for it. For example for tasks that Maven is good at like specifying dependencies using Ivy and Ant for it makes no sense, right? Well, you wish! I've seen those kind of nonsense a lot of time with pom.xml reaching out beyond the magic 100k boundary...

Instead of cranking up the heat I'd like to see people develop simple mojos solving one problem at a time and not resorting to ant or anything like it. But above all, for crying out loud, use what's already there to do the job!

Doing Spring in standalone Java application

If you can imagine how hard would it be to prepare a standalone Java application that uses external configuration, external libraries and resembles what users are already used to (the bin folder, the lib folder, maybe some conf or etc for the configuration files) you'll appreciate the fine job application assembler is going to do for you.

<plugin>
    <groupId>org.codehaus.mojo</groupId>
    <artifactId>appassembler-maven-plugin</artifactId>
    <version>1.1.1</version>
    <configuration>
        <copyConfigurationDirectory>true</copyConfigurationDirectory>
        <configurationDirectory>etc</configurationDirectory>
        <repositoryName>lib</repositoryName>
        <repositoryLayout>flat</repositoryLayout>
        <programs>
            <program>
                <mainClass>org.example.Main</mainClass>
                <name>example</name>
            </program>
        </programs>
    </configuration>
</plugin>
That's pretty much it! All you have to do now is to call maven to do your bidding.
mvn clean package appassembler:assemble
Please note I didn't change anything in the application itself. Well that's because it's not a post about how to instantiate Spring in a console application but rather how to package everything so that it works as expected. You can take a look at a fully working example on GitHub.

Have fun!

No comments: