- Installing Maven
- A Sample Project
- Building the Project
- Conclusion
A Sample Project
To best demonstrate the basic functionality of Maven, I build a simple project that utilizes external libraries. One of the strengths of Maven is its ability to keep a repository of libraries that are being used by your project and reference them directly during the build cycle. This helps to eliminate having multiple copies of the exact same library on your development machine and completely eliminates the need to store these libraries in your version control system.
In this example, I create a new project and avoid migrating an existing project over to Maven. In my project directory, I created a new directory named mavenExample. Inside of this directory, I will store all the files for this project. In this project, I created the following folder structure:
src --main --java --com --dzrealms --example --test --java --com --dzrealms --test
Some of this structure may or may not be familiar to you, but the basic premise is that test code is separated out from the project's main code, and all of it is stored under the directory src. In this example project, I created a single class file logically named HelloWorld.java. In this example, I will access two different libraries: log4j and jGoodies' plastic look and feel. Note that in the directory structure listed above there is no directory to store the libraries in. The source code for my HelloWorld class is as follows:
package com.dzrealms.example; import org.apache.log4j.Logger; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.UIManager; import javax.swing.LookAndFeel; import java.awt.BorderLayout; public class HelloWorld extends JFrame { private static final Logger log = Logger.getLogger(HelloWorld.class); private static String lnf = "com.jgoodies.plaf.plastic.PlasticLookAndFeel"; public HelloWorld() { JLabel lblHello = new JLabel("Hello World"); getContentPane().setLayout(new BorderLayout()); getContentPane().add(lblHello, BorderLayout.CENTER); pack(); log.debug("Init of the gui is complete"); } public static void main(String args[]) { try { Class c = Class.forName(lnf); UIManager.setLookAndFeel((LookAndFeel)c.newInstance()); } catch (Exception e) { e.printStackTrace(); } HelloWorld hw = new HelloWorld(); hw.setVisible(true); log.debug("main complete"); } }
Maven, like Ant, requires an xml file to describe the project structure so that it can process it properly. However, unlike Ant, the project descriptor is very simple. The file is normally named project.xml—although you can name it something else and point Maven to it. The project.xml file for this example project is as follows:
<project> <groupId>dzrealms</groupId> <artifactId>HelloWorld</artifactId> <version>1.0</version> <dependencies> <dependency> <groupId>jgoodies</groupId> <artifactId>plastic</artifactId> <version>1.2.0</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.8</version> </dependency> </dependencies> <build> <sourceDirectory>src/main/java</sourceDirectory> <unitTestSourceDirectory>src/test/java</unitTestSourceDirectory> <unitTest> <includes> <include>**/*Test.java</include> </includes> </unitTest> </build> </project>
The file breaks down as described in the following sections.
groupId
This tag represents what name this project is grouped under. A company name, or even the name of the team developing this project, would be an appropriate groupId. As an example, JBoss uses a groupId of "jboss" to identify all of its projects. Each project is further broken down under the group by the artifactId.
artifactId
This tag represents the name of this project and/or library. In the example above for JBoss, one of its artifacts is called jboss-j2ee, which is the implementation of the j2ee libraries. The artifact could have easily been named just j2ee because the jboss in the artifactId is redundant. Nevertheless, the combination of the groupId and artifactId represents a unique identification of this library.
version
Each build of a project/library needs to have a version number. With Maven, this is extremely important—more so than under Ant. Because it is quite possible to have multiple projects referencing different versions of a library, each library/project must have a unique version number so that Maven can properly reference the correct libraries.
dependencies
This, as they say, is where the magic is. This tag tells Maven which external libraries are being used in this project. Moreover, it specifically defines which versions of those libraries are being used. So even if the library gets updated, there are no version skew issues. For each external library that is referenced, the library needs to be described via its groupId, artifactId, and version. Each dependency is listed under its own <dependency> tag. As you can see from the project.xml above, I listed log4j-1.2.8 and plastics-1.2.0 as dependencies. When I go to build the project, Maven will check my local repository to see whether I have these exact versions of these libraries already; if not, it will retrieve them from a remote repository. The default remote repository is located here, but it is possible to point Maven to another repository.
build
This tag defines where all the source code and resources reside. In this example, I have defined two sections: The first section tells Maven that the source code for the project is under src/main/java, and the second section tells Maven that all the unit test code is stored under src/test/java. When Maven compiles the project, it will look to these tags to find all the source code for the project.