My encounter with maven was all backwards – I started with maven2, and then was compelled to learn the earlier version due to the next project where there was a bit of reluctance to upgrade due to time pressure, and finally I came to know more about Ant as well! 🙂 But let me put this post in the right order here. This is meant to be a crash course just to give the big picture to anyone not familiar with these concepts. The links provide a lot more information, and feel free to ask for any further information.

What is a build utility? I found this description in wiki…

the user specifies what will be used (typically source code files) and what the result should be (typically an application), but the utility itself decides what to do and the order in which to do it.

The simplest compilarion with Java development starts from the command line – using the javac command to compile a single java source file, and then uses java to execute the resulting class file. Then there are IDEs that provide project structures and menus for this build process, which are very IDE centric, and not much scope of automation (we need to launch the IDE to build the project).

And then with increased complexity, we need to add other dependent jars into the class path to start with. Going further we’d need to zip the resulting class files into a jar file, various other possible steps like copying configuration files or adding manifest files. With the increase in tapping into advantages of test driven development, one would like to automatically run regression tests after a build to ensure integrity of the latest development changes.

True, such additional tasks can be managed with command line .bat (or .sh in Unix) shell scripts to a certain extent. But then as one moves on from from project to project, the way source files are organised and the batch files are written keep changing, and this is a big burden to the maintainability of the project.

So going beyond shell commands like make, Apache’s Ant went one step further to improve the build process:

Instead of a model where it is extended with shell-based commands, Ant is extended using Java classes. Instead of writing shell commands, the configuration files are XML-based, calling out a target tree where various tasks get executed. Each task is run by an object that implements a particular Task interface.

An ant task is a single command with parameters, for example – for an ant task to copy a file the parameters would be source file, destination file, and overwrite true or false.

But another Apache project, Maven, was a major milestone in the build process, as it standardised this whole approach to build management. It introduced conventions on how a project and its various artifacts are to be structured.

We wanted a standard way to build the projects, a clear definition of what the project consisted of, an easy way to publish project information and a way to share JARs across several projects.

So a maven project typically has the following structure:

There’s a src\main folder that contains the java and resources sub folder.

+---src
¦   +---main
¦       +---java
¦       ¦     +---com
¦       ¦           +---sm
¦       ¦                 +---data
¦       ¦                 +---util
¦       +---resources
¦           +---conf
+---target
    +---classes

The output goes under the target\classes folder.

There are three files that are associated with a maven 1.x project.

– project.xml
– maven.xml
– project.properties

(Note that they are replaced with just one file pom.xml in maven 2.0)

The first one is the main project file, the second two are optional. The project.xml contains the details of the project, the dependencies of the project, the source and resources directory location.

Before maven, dependent jar files were placed in a lib directory or tree structure (which might be maintained under source control). Now maven introduces the concept of a repository, where the libraries are stored. All references to any dependency in the project.xml file is from this repository.

There are centrally maintained searchable repositories, or one may maintain a repository privately, say within an organisation, to host proprietary jar files. One can use repository server like artifactory. In either case, each development machine will have a local repository that will typically be under the user profile folder – on my Windows machine its C:\Users\sanjay\.maven This contains a cache (internal to maven) and repository folder where all the jar files go, which looks like this…

+---repository
    +---com.thoughtworks.xs
    ¦   +---jars
    +---commons-collections
    ¦   +---jars
    +---commons-dbutils
    ¦   +---jars
    +---jboss
    ¦   +---jars
    +---junit
    ¦   +---jars
    +---log4j
    ¦   +---jars
    +---maven
    ¦   +---jars
    +---org.apache.derby
    ¦   +---jars
    +---org.apache.velocity
    ¦   +---jars
    +---xpp3
        +---jars
        +---java-sources
        +---javadoc.jars

java-sources and javadoc.jars may also be present as shown in the last directory, but the main thing is the jars directory which contains the jar files.

This structure was for maven 1.x. Maven 2.x revamped a lot of things including the repository directory structure. However the main point is just to know that that’s where the jar files go.

Now maven builds the project such that the referenced projects are added to the class path.

There is no need to mess around with CLASSPATH environment variable any more.

A build process has a goal, a typical goal being the resulting binary file i.e. JAR file after compilation. maven has several pre-defined goals, including compile, jar and clean.

To just create a jar file, project.xml alone is enough, but one can do more refined build or post-build steps by specifying them in maven.xml file using Ant tasks. project.properties is a typical properties file (nave value pair) that contains some properties that are used during the build process.

maven needs to be installed, and once installed and the bin directory is added to the system path, one can run the maven command at the project root to build the project.

maven2 is a more sophisticated upgrade. There’s just a single pom.xml file – one can upgrade the existing project.xml file to the new structure by using a convert:one plugin. Since maven 1.x is no longer supported its a pretty good reason to upgrade!

Some further reading…

Integration with eclipse – “maven eclipse” command generates a neat eclipse project file, where all the maven dependencies are added to the project class path.

However with m2eclipse, a plugin for eclipse, this is even further simplified! But somehow I preferred the command line approach even inspite of the plugin.

Another thing is the set up of a maven repository. After going through this comparison of different possible aproaches, I was able to set up artifactory quite easily.

Its strongly recommended that any organisation sets up a maven repository instead of maintaining jar files in some kind of a directory structure!

Here are some of the benefits

  • Consistency in artifact naming
  • quick project setup, no complicated build.xml files, just a POM and go
  • all developers in a project use the same jar dependencies due to centralized POM.
  • Shared build meme. I know how to build any maven project
  • reduce the size of source distributions, because jars can be pulled from a central location
  • 99% of my needs are available out of the box,

These people have worked in this domain over the decades, and have distilled their experience and best practices together, and come up with something that works really well for everybody. At the same time its not a rigid set of rules, and there’s enough flexibility for customization, that’s the real beauty of maven.


In the Microsoft world, we use msbuild and nant.