Monday, July 2, 2007

Setting Command Line Arguments for JVM in Maven

The problem:

You want to set JVM args for the Maven application (such heap memory).

The solution:

On a Linux/Unix machine the "mvn" command will use a shell variable "MAVEN_OPTS" to pass in options. This is useful if you want to give Maven more memory. In your .profile or .bash_profile put a line like this in:
export MAVEN_OPTS=-Xmx1024m
Now every time you run "mvn" you will have up to 1024 megs of heap space! Use this to set other JVM arguments.

SCM control

The problem:

You would like to integrate your source control management directly into a Maven 2 project.

The solution:

Source control is needed to maintain the health of any mid to large size project. Maven knows this! Maven has very broad source control management support. Have you heard of Mercurial? Well you can integrate Mercurial SCM support right into a Maven 2 project. Or Subversion, CVS, Perforce, etc. To get started is easy, you will need to configure an "scm" section in your projects pom.xml file. I will give an example:
<scm>
<connection>scm:svn:https://svn.oreilly.com/RobUtils/trunk</connection>
<developerConnection>scm:svn:https://svn.oreilly.com/RobUtils/trunk</developerConnection>
<url>https://svn.oreilly.com/RobUtils</url>
</scm>

Once you have configured your scm section other plug ins (such as release) will be able to leverage it's information. You should see the documentation on SCM configuration to get up and running with your SCM implementation.

Run a specific test

The problem:

You have a group of unit tests that you run through the Maven Surefire plugin. You do not want Surefire to run all the tests, rather you want only one specific test to run.

The solution:

This one is easy, all you need to do is put a little something into your command to tell the Surefire plugin "run just this one test". What does this look like? Here is an example: "mvn -Dtest=FunTest package". Here you want to package your applicaiton, but you are going to run the FunTest first. Notice you don't put a ".java" or ".class" extension onto the name. Thats it, you can use the "-Dtest=..." to run a single test anytime that the Surefire plugin will be run.

Import Maven Project into Eclipse w/ Style (Maven + Eclipse pt. 3)

The problem:

You have a Maven 2 project, and would like to work on it in Eclipse. Oh, and you want the Maven plug in for Eclipse configured on this project too!

The solution:

The first thing I do when I check out a Maven project is generate the Eclipse project files. Start by going to the project's root folder and typing:
mvn eclipse:eclipse

This will create the files Eclipse uses to understand the project, .project and .classpath. There are links to the jars configured via the pom in the .classpath file. You will want to get rid of these, because the Maven plug in will handle dependency configuration. Go into the .classpath file and delete all "classpathentry" nodes that have "M2_REPO" in the path attribute value. Now save this file.

At this point your project should have errors. Eclipse cannot find the jars needed to build properly. Worry not. Now we will enable the Maven plug in. Right click on the project root node in the package explorer to bring up the menu. Select "Maven" and then "enable". After a bit of processing your project should rebuild. Now you have the benefits of the Maven plug in!

Eclipse Plugin for Maven 2 Development (Maven + Eclipse pt. 2)

The problem:

You use the Maven 2 system for your projects. You use Eclipse to write your Java code, and things like running and debugging applications.

The solution:

Get the Maven 2 plug in for Eclipse! This is a very nice plugin. This plug in will handle configuring your projects class path. It will add the dependencies defined in your pom to the class path. It will also add and remove dependencies from the class path as you add or remove them in the pom file. It comes with a nice little wizard allowing searching of dependencies, with the ability to add them into your pom with a simple click. This wizard can also be configured to search on the dependencies installed in your local repository.

You can find the plugin here. If you like using the Eclipse plugin manager use this url: http://m2eclipse.codehaus.org/update/

Once you have installed the plug in you can create "Maven 2" projects that are configured in the Maven standard format (you know "src/main/java", "src/test/java" folders etc.). You can also right click a project select the "Maven2" option and select "enable". This will configure your project's class path using the project's pom. Note that this means your project must have a pom! Now Eclipse will have access to all classes contained within the jars managed by Maven.

This is great, but wait there is more. You of course will want to run Maven commands from within Eclipse, because having to go back and forth between the IDE and command line is just too much work. Worry not, just go to the "Run" menu, select "External Tools" and select the "External Tools..." menu item. This will bring up a menu where you should see a category called "m2 build". By clicking on this category you can create new launchers for doing Maven commands. One word of caution I've found some, more complex, Maven commands did not work great this way. The one in particular was the "jetty:run" command.

Click this image to see a bigger version

Clean project

The problem:

Your project creates a collection of output like classes, jars, websites and more. You want to delete this output!

The solution:

Ok this is kinda a joke. Simply type "mvn clean" and your project's output is gone. How does this work? Well Maven works like a 70 year old man on an all bran diet, very regular. Java source files go into "src/main/java" while testing sources go in "src/test/java". In the same vein plug ins such as site, generate their output into a folder called "target".

Any Maven project will share this convention, since you know when looking at a Maven project folder that "src" contains sources, resources and such, and "target" contains output created from the sources. So think about it this way: sources (in "src" folder) are transformed via Maven plug ins into output (in "target" folder).

I will mention that these conventions can be overridden, but.... that is not a good idea and you should never do so.

Generate Website and View It Locally

The problem:

You are using Maven to create documentation on your project. You want to use the site plug in to generate this documentation into a website. What you need is a quick way to proof your changes, seeing how they look on the website.

The solution:

This one blew me away. When you are working on your documentation you can easily view changes, just run this command:
mvn site:run
This will get a Jetty web server going with your web site running on it. Now just go to localhost:8080 to see your site. This technique is really helpful when configuring reports, as you can quickly test them out.

If a project is configured with the Javadoc report there are some nice uses here. you can pop up a site while working on a project and view the Javadoc. This is a useful technique when first checking out a project, so that you may better familiarize yourself with it.

Generate website

The problem:

Keeping your project documented can interfere with the ten other roles you must fill. I'm speaking from a perspective of the small software shop were you cannot afford to have one or more paid documentation experts (or QA or project management for that matter :)

The solution:

Maven can be a god send to a small software shop. I feel Maven often gives people the notion it is for use in big software shops. Not true. Just because large Apache Java projects are using it does not mean it is too much for a small library or application type project. Maven can create for you a full website, including reports on things such as test coverage, JavaDoc, PMD information, dependencies, email lists, etc. etc. This sounds pretty complex, eh? Well worry not it is simple, and I will show you how to generate such wonders... but in later posts. Let's KISS here. So you have a Maven project and you want a site generated, so just type the following and you will have a full site in the target folder of your project:
mvn site
Done!

Release Plugin "Dry Run"

The problem:

Running the "release:prepare" command in Maven does a number of caustic things. It will check in and tag your code in the SCM you use. It will also change the projects pom, rolling the version number up. If you have any "SNAPSHOT" dependencies it will fail.

The solution:


Maybe you want to do a "dry run" before executing a command that could muck up your SCM and pom? By "dry run" I mean the release plug in goes through the motions, but nothing is changed in the SCM, and your pom doesn't get messed up. Here is what you do:
mvn release:prepare -DdryRun
The "-DdryRun" tells the plug in to not fully perform the preparation. You will find this generates some temporary files in the project folder. These include:
  • pom.xml.next : what the projects pom looks like after the release
  • pom.xml.releaseBackup : what the pom looked like before
  • pom.xml.tag : the pom for the tagged version of project
  • release.properties : the information about the release of the project
It is not likely you want to keep these files around for too long. You can remove these file by running this command:
mvn release:clean
I recommend you use this whenever you are getting ready to release. It will save you a lot of time, because just one botched release attempt could take minutes to clean up. The dry run will take seconds to run.

Release plugin

The problem:

Your project uses some sort of Source Control Management (SCM). Being that your project is using Maven there are considerations such as project version to take into account when tagging releases of your project. You want a simple way to "release" a version of your project. Normally you would edit the POM changing to a new release version (from snapshot), then tag the release in your SCM, then change the pom version to the newest version, and finally check in the new pom. Another consideration is the dependencies you are using, you do not want to have snapshot dependencies in your "released" project.

The solution:

Maven developers quickly experienced the difficulty of rolling a version of a project. Thats why we now have the release plug in. When you are ready to do a release simply issue the command:
mvn release:prepare
This plug in makes short work to releasing a version of your project. You must have configured the SCM section of the pom. This section is used by the release plugin to know how to interact with your SCM.

Once you issue the command above you will be asked to give a tag name and the new version for the pom. You can also just hit enter to have the plug in use default values. Thats it, check your pom and you will see the new version. Check the source control and you will see the tag.