maven (Pete's notes)

Get the Better Builds with Maven book

I got Better-Builds-with-Maven.pdf from http://www.devzsuz.com.

Install maven 2

On 2007-07-07, I installed maven 2 on my Powerbook using MacPorts. Later, when I got my MacBook Pro, I deleted the entire /opt to get rid of old MacPorts PowerPC binaries and reinstalled using fink to get native binaries, like so:

sudo fink install maven

Create a sample project named TranslateCIM

Then I sorta followed the basic instructions in the Maven in 5 Minutes webpage...

First I verified that maven was installed:

okapi$ mvn --version
Maven version: 2.0.10
Java version: 1.6.0_07
OS name: "mac os x" version: "10.5.6" arch: "x86_64" Family: "mac"
okapi$

Then I created a sample maven project named "TranslateCIM". Eventually it will hold translatecim, but initially it'll hold a simple demo program.

$ cd
$ mvn archetype:create -DgroupId=com.kyben.app -DartifactId=TranslateCIM

This created a directory named "TranslateCIM", with a sample application in ~/TranslateCIM/src/main/java/com/kyben/app/App.java. It also downloaded a bunch of stuff into my local maven repository. Then I built it with

$ cd TranslateCIM
$ mvn package

This downloaded more stuff and created finally ~/TranslateCIM/target/TranslateCIM-1.0-SNAPSHOT.jar. To run the sample program, I did

$ java -cp target/TranslateCIM-1.0-SNAPSHOT.jar com.kyben.app.App

It displayed "Hello World!". Cool. This completes the Maven in 5 Minutes webpage. Onward and upward through the Maven Getting Started Guide...

Install the ANTLR 3 plugin for Maven 2

I'm going to be running ANTLR over and over as I develop it, so let's make Maven understand how to run ANTLR.

When you Google for "maven ANTLR", you may find these false positives:

Ignore those. You want Jim Idle's plugin at http://www.antlr.org/antlr3-maven-plugin/.

Follow the Overview->Usage link.

Then, add these dependencies to the dependencies section of the pom.xml file:
<dependency>
  <groupId>org.antlr</groupId>
  <artifactId>antlr-runtime</artifactId>
  <version>3.1.3</version>
</dependency>
<dependency>
  <groupId>org.antlr</groupId>
  <artifactId>stringtemplate</artifactId>
  <version>3.2</version>
</dependency>

Make maven use Java 6

To cause maven to use Java 6 when it compiles the Java that ANTLR produces, put this in the build/plugins section:
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <configuration>
    <source>1.6</source>
    <target>1.6</target>
  </configuration>
</plugin>
The book (in section 8.6.3) documents this, but it was written for Java 5. Not sure if this is necessary for Java 6.

Customize the TranslateCIM project

Move the TranslateCIM grammar into the TranslateCIM project

The bottom of the Usage page for the ANTLR plugin reads:

You will need the generated Java files to be created within the appropriate folder structure (i.e. com/example) otherwise the the Java compiler will report error messages.

To achieve the desired result, just put the source grammar file into a folder structure that matches the package structure, just as you would structure the folder containing a Java source file.

i.e. assuming the default source directory, the grammar with the header in the example above would need to be placed in the folder src/main/antlr/com/example.If there are other contributing sources to the artifact build, they would be under other subdirectories: for example src/main/antlr would contain Antlr grammar definition files.

My grammar will be in package com.kyben.translatecim, along with the other pieces of TranslateCIM. The antlr plugin for maven suggests that the grammar source file should live in ~/TranslateCIM/src/main/antlr/. That would work, but then the generated files would end up in ~/TranslateCIM/target/generated-sources/antlr. Eclipse wants them to be in ~/TranslateCIM/target/generated-sources/antlr/com/kyben/translatecim, which means the source has to be in ~/TranslateCIM/src/main/antlr/com/kyben/translatecim.

mkdir -p ~/TranslateCIM/src/main/antlr/com/kyben/translatecim
cp ???/TranslateCIM.g ~/TranslateCIM/src/main/antlr/com/kyben/translatecim

Move the parser driver into the TranslateCIM project

rm -rf ~/TranslateCIM/src/main/java/com/kyben/app
mkdir ~/TranslateCIM/src/main/java/com/kyben/translatecim
cp ???/TronslateCIM.java ~/TranslateCIM/src/main/java/com/kyben/translatecim/

Edit TranslateCIM/src/main/java/com/kyben/translatecim/TranslateCIM.java to:

  1. change "public class Test" to "public class TranslateCIM"
  2. change "Expr" to "TranslateCIM"
  3. change "prog" to "mofSpecification"
  4. there will lots of other changes :-)

How to add a dependency to a project

Find the dependency

Maven downloads a dependency when a project declares the dependency and the dependency is not present in the local repository. The first time Maven sees the dependency, Maven will download it from the central repository into the local repository.

For example, I wanted a command-line parsing function. I found "args4j" and the jakarta "commons-CLI" by Googling for, like "Java command line parse". Either package is probably fine, but args4j looked more modern (it uses annotations). The args4j website mentioned that args4j was available from "the Maven Repository at dev.java.net", and the "Maven Repository" link basically said to add this to my pom.xml file:

<repositories>
  <repository>
    <id>java.net</id>
    <url>http://download.java.net/maven/2</url>
  </repository>
</repositories>

Note that the above is slightly different than what the website suggested. It's important to specify "/2" in order to get Maven version 2 files. If you use "/1", you'll get Maven version 1 files, and when you compile you'll get "not a version 4.0.0 pom" errors.

With that, I was ready to use any dependencies in the dev.java.net repository. After some trial and error, I successfully defined the args4j dependency by adding this to the dependencies section of my pom:

<dependency>
  <groupId>args4j</groupId>
  <artifactId>args4j</artifactId>
  <version>2.0.8</version>
</dependency>

I was then able to use args4j in my project. Cool!

How to delete an artifact from the local repository

All you have to do is delete the artifact's subdirectory from ~/.m2/repository.

How to run a specific test only

To run only the test named TestCommandLine, do

mvn -Dtest=TestCommandLine package

Where to put data files needed by unit tests

I store test data (the CIM MOF files) in ~/TranslateCIM/src/test/data/.

How to use Maven from Eclipse

Following the suggestions in the "Java Power Tools" book, I did

mvn -Declipse.workspace=~/workspace eclipse:add-maven-repo

This seemed to work - when I restarted Eclipse and looked at Preferences->Java->Build Path->Classpath Variables, I saw M2-REPO. Note that at the Apache Maven Project website they say to use "eclipse:configure-workspace", dunno which is better.

Then, to generate the .project, .classpath and other files that Eclipse needs,

cd ~/TranslateCIM
mvn eclipse:m2eclipse

This added the files to the TranslateCIM directory, making it into an Eclipse "project" suitable for importing into an Eclipse workspace. To do so, in Eclipse, do File->Import->General->Maven Projects and import "/Users/siemsen/TranslateCIM".

When you start Eclipse, it will put several red warning messages it its "Console" view that say the Maven /Users/siemsen/.m2/settings.xml file doesn't exist. If you haven't customized Maven, you don't need such a file, so it doesn't exist. If you create an empty one, it'll fix the errors about file not found, but you'll still have errors that say the file has no contents. So you need the file to have contents. Here's how to create the file so that it sets location of the local repository to the default value, just so there's some contents:

cat >~/.m2/settings.xml
<localRepository>/Users/siemsen/.m2/repository</localRepository> ^D

To run a maven goal, do


Pete Siemsen