Maven 2.0: Compile, Test, Run, Deploy, and Moreby Chris Hardin03/29/2006 The hardest part of getting started with a Java application is, well, getting started. So many logistical decisions have to be made up front. Where should the Java source files go? Where do I place unit testing? Where will we store dependency .jars? How will the project be built, documented, tested, and deployed? The choices made at this stage will follow a developer for the rest of the project. It's up to you whether those choices will haunt you or prove you to be a master Java architect later on. We'll assume the latter is the goal we are striving for, and now we just need a starting point. There are many tools out there for building a Java project, including Ant. Ant has been on the top of many a developer's list as the revolutionary tool that got them out of the world of Maven is the new kid on the block, much like Ant was just a few short years ago. Maven 1.0 has been around for a few years and it was accepted by a wide audience of developers as an Ant replacement, but it offered very little relief from the old Ant build.xml file. Maven 1.0 was slow and clunky and using it was almost as difficult as getting started on a project with Ant. In fact, it was Ant at its core, and after an almost complete rewrite, Maven 2.0 was born. The Benefits of Maven 2.0The benefits of Maven 2.0 are numerous, as it does more than merely build your projects. If you are just starting a new Java project and you need to get started fast, Maven 2.0 will have you up an running in minutes. The following are some of the advantages of Maven 2.0:
The list above is just a short list of the features available in Maven 2.0. These alone make Maven 2.0 a solid choice for a build management system. Now that we know what Maven is, let's look at how to get started. Getting StartedThe first thing we want to do is set up our directory structure.
Wait--there is no need to do it by hand. Maven can do it for you,
depending on the type of project that you are developing. Once you have
downloaded and extracted the latest distribution of Maven 2.0, you should add the bin directory of the Maven distribution to your system path. You can run Now that we have the tool installed, let's look at the example of creating a simple Java project. Maven uses archetypes to determine how the directory structure will be laid out. There are several built-in archetypes or you can write one of your own.
Voila! We now have our project layout.
Yes, it's that easy. It should be noted that this directory structure can be overridden by creating a new archetype, but deviating from the structure is not recommended, since one of the benefits of Maven is the standard directory structure. The directory structure contains two source trees: one for your Java application source code and one for your unit test code. You may also have noticed that the first time you ran Maven, it did some downloading. Maven will update itself with the appropriate functionality based on what plugin you use when you invoke the tool. Maven, by default, will get its updates from the Ibiblio repository. You can override Maven's choice of a remote repository in the conf directory of the Maven distribution or in the project itself. You should also have noticed that Maven created a pom.xml file in the my-app directory. This is the meat and potatoes of your project. The pom.xml file is a set of instructions for Maven that tells it how to build the project and includes other special instructions. (POM is an acronym for "project object model.") By default, Maven also includes the JUnit dependency to encourage unit testing.
Now that we have our project created, we can add in our code and utilize a whole new bag of Maven tricks. Note that the following commands must run in the same directory as the pom.xml file.
Let's look at something a little more complex. Starting a Java web project by hand can be even more time-consuming than starting a simple Java project by hand, but Maven makes it just as easy. The example below (ordinarily a single line, but wrapped to suit the web page format) sets up the project structure. mvn archetype:create -DgroupId=com.oreilly
-DartifactId=Oreilly
-DarchetypeArtifactId=maven-archetype-webapp
The resulting structure looks like this: Oreilly
----src
----main
----resources
----webapp
----WEB-INF
This time, our project was set up a little differently to support web resources that we will include in the .war file. The pom.xml file will contain a line that indicates that the project should be packaged into a .war file: <build>
<finalName>PromoteC</finalName>
</build>
Dependency ManagementNow that we have created our project structure, written some code, and tested and compiled our application, we can move on look at how Maven handles dependencies. In order to add a dependency to your project, you need to add it to your pom.xml; the next time you run Maven, it will get that dependency from the Ibiblio repository and add it to your build path. There are some very important things to remember about dependencies. The biggest inconvenience currently with Maven is that Sun .jars are not available through a Maven repository at the time of this writing. This is due to the licensing restrictions that Sun places on its code. To work around this issue, you have to download and install the code into your local repository or make a external declaration for a dependency location at a point on your file system. Hopefully, Sun will create their own Maven repository soon, but Maven will have to be updated to prompt the user to accept the licensing agreement before Maven can download the resource. Another inconvenience is that sometimes you might be using a library that is very recent and might not exist in a remote repository. Another possibility is that you just might be developing with no internet access and just want to have all of your dependencies available locally. The best solution for these issues is to install the .jar in your local repository. It is also convenient to store your local repository on a web server, so that your entire development team can benefit and everyone doesn't have to manage his or her own repository. Changing the Maven repository path is as simple as editing the settings.xml file in the conf directory of the Maven distribution. Using dependencies in Maven is simple. Let's look at adding a dependency to our pom.xml file above. We already have JUnit, but let's add the powerful Quartz library to our project. Quartz is an open source scheduling mechanism written entirely in Java and is a great choice for all of your scheduling needs. <dependency>
<groupId>quartz</groupId>
<artifactId>quartz</artifactId>
<version>1.5.1</version>
<scope>compile</scope>
</dependency>
That is all we need to add to the
Now, what about those pesky Sun .jars or the .jars that we need that we can't find in a remote repository? We have to install those .jars into our local repository manually with Maven. Don't worry--this is nowhere near as hard as it sounds. For the sake of example, we'll install the Java Activation Framework .jar. First we have to download it from Sun, and then we can use Maven to import it into our local repository. It is also possible to install a missing .jar into Ibiblio yourself using some instructions in the Maven guide to uploading artifacts to Ibiblio. mvn install:install-file -Dfile=activation.jar
-DgroupId=javax.activation -DartifactId=activation
-Dversion=1.0 -Dpackaging=jar
Now the .jar is installed in our local repository just like any other dependency for our project. We only need to add the dependency declaration and we are all set. Remember to make sure your version information is correct when adding .jars and when declaring them as dependencies. A mismatch will cause Maven to fail when it tries to find the resource. If you need help with the standard naming parameters when importing Sun .jars, you can refer to Maven's list of standard Sun .jar names. Remember, you cannot publicly distribute these .jars through a repository at this time without violating Sun's terms of use. <dependency>
<groupId>javax.activation</groupId>
<artifactId>activation</artifactId>
<version>1.0</version>
<scope>compile</scope>
</dependency>
You may be tempted to store dependencies in a source control repository; source control was never meant for this task. Dependencies are transient and are generally versioned by a number scheme. That being said, you definitely would want to make sure you back up your internal remote repository, if you have one, to make sure you don't lose all of the custom additions you've made, in case the repository server crashes and cannot be recovered. Not storing dependencies in source control will also save vast amounts of disk space on the source-control repository server. Configuring RepositoriesIt would be inconvenient for every developer on a project to have to configure a repository in his or her conf directory, so Maven has the ability to look at multiple repositories at the same time and configure them all in the pom.xml file. Let's look at an example of how we could use multiple repositories with our application. In the following excerpt from pom.xml, we set up two repositories for Maven to be able to find dependencies. Ibiblio is always the default for Maven, but we have added Planet Mirror as a backup. We might also want to make the second repository our local web server that our team is using as a repository. <repositories>
<repository>
<id>Ibiblio</id>
<name>Ibiblio</name>
<url>http://www./maven/</url>
</repository>
<repository>
<id>PlanetMirror</id>
<name>Planet Mirror</name>
<url>http://public./pub/maven/</url>
</repository>
</repositories>
Building Multiple Projects using a Parent pom.xmlIt's fairly common for software companies to have multiple projects that are built into the main product. Maintaining the dependency chain and building the entire product at one time can be a challenge, but with Maven, it's simple. If you create a parent pom.xml that refers to other submodules, Maven will handle the complete build for you. The dependency mechanism works by analyzing each submodule's pom.xml for dependencies and building the projects in the order in which they depend on each other. The order that you place the submodules in the parent would not matter if each project called out its dependencies explicitly, but for the sake of other developers, it is best to make sure that the order in the parent pom.xml is the same order in which you want the subprojects to be built. Let's look at an example. The master pom.xml is as follows: <project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.oreilly</groupId>
<version>1.0-SNAPSHOT</version>
<artifactId>my-app</artifactId>
<packaging>pom</packaging>
<modules>
<module>Common</module>
<module>Utilities</module>
<module>Application</module>
<module>WebApplication</module>
</modules>
</project>
We need to make sure that all three of the dependency .jars are included in the Here are the <dependencies>
<dependency>
<groupId>com.oreilly</groupId>
<artifactId>Common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
Here's how to state the <dependencies>
<dependency>
<groupId>com.oreilly</groupId>
<artifactId>Common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.oreilly</groupId>
<artifactId>Utilities</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
Finally, the <dependencies>
<dependency>
<groupId>com.oreilly</groupId>
<artifactId>Common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.oreilly</groupId>
<artifactId>Utilities</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.oreilly</groupId>
<artifactId>Application</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
Now we just need to add an element to each submodule's pom.xml file declaring that they are part of one logical build. <parent>
<groupId>com.oreilly</groupId>
<artifactId>my-app</artifactId>
<version>1.0-SNAPSHOT</version>
</parent>
In the same directory as the master Plugins and ReportsMaven 2.0 has a wide array of plugins that are available. Unfortunately, since Maven was rewritten, Maven 1.0 plugins won't work and cannot be used with Maven 2.0. However, there are several Maven 2.0 plugins already available for use. The following plugin configuration for pom.xml is an example straight from the Maven 2.0 website. This plugin is used to configure compiler options.
The Maven reporting plugins can be used to generate different reports
that will be available when you generate the project website using
The Maven Plugin Matrix is really useful for figuring out what Maven plugins are available for which version of Maven. Maven and EclipseHow could the world's greatest IDE get any better? With a Maven 2
plugin that assists in searching for dependencies and adds them to pom.xml
automatically. Maven has an Eclipse plugin that will enable Maven for
any project, although it is best to create your project with Maven first
and then generate your Eclipse project file with You can install the Eclipse plugin through the updater in Eclipse itself using http://m2eclipse./ as the site for the plugin. After installing and restarting the IDE, you need to configure the Maven plugin in Eclipse's preferences by filling in the location of the local repository. This is an important step, because if the default repository for Eclipse doesn't match your default, Maven will re-download your dependencies. After configuration, import the project into Eclipse, right-click on the project, and choose Maven 2 -> Enable. Now you can go back through that step and you'll have more options like Add Dependency, which will bring up a search box so you can search for dependencies and add them; the plugin will edit your pom.xml file for you. The plugin will build your project using Maven in much the same way that Eclipse can handle building with Ant. If you would like more information on Eclipse integration with Maven, check out the guide to using Eclipse with Maven 2.x on the Maven site. On the other hand, if you are an IntelliJ fan, you can accomplish the same task by running ConclusionMaven 2.0 has many useful features and performs extremely well. The most laudable part of Maven is the use of standard directory structures and deployments. This allows developers to move from project to project and not have to learn anything new about the structure or go through special instructions on how to build it. Practical applications for Maven also extend into custom build systems for large software engineering shops. Maven can be fully scripted and queued to run nightly and deploy distributions as well as send out notifications to users. From the documentation side, it's extremely handy to have the project website tools built in so that when the project build is complete, you can see a current status of all development. There is no doubt that Maven 2.0 blows Ant out of the water when it comes to scalable build configurations, ease of use, and project management. In the next few years, we'll see more adoption of Maven as the standard in build technology until someone comes along and builds the proverbial "better mousetrap." You can download Maven from the Maven project website listed below. ResourcesChris Hardin is a Senior Java Architect in Birmingham, Alabama. Return to ONJava.com. ![]() Showing messages 1 through 6 of 6.
|
|
[Ok which imbecile would use ejbs nowadays? I use SLSB ejb for the "distributedness" of the application and cluster support from JBoss application server. Using tomcat alone is not an option as I get out-of-the-box clustering with JBoss...so much for sidenote]
What archetype should I use with Maven? A quickie example would be great.