Multiple Artifacts from a Single Source
Maven restricts projects to one artifact per ‘pom’ file. While we can argue whether this is the right approach, there is a simple solution. If you have a project called ‘sample-service’ that produces a WAR and you want to create a JAR from the same source code then you need to create a second package containing a single pom file.
|_sample-service |_src |_pom.xml |_sample-client |_pom.xml
The ‘sample-client’ pom is configured to point to ‘sample-service’ for it’s source files. This should be added to the ‘build-helper-maven-plugin’ configuration. Please refer to http://mojo.codehaus.org/build-helper-maven-plugin/usage.html for more information.
<configuration> <sources> <source>**/src/main/java/**</source> <source>**/src/main/resources/**</source> </sources> </configuration>
This is a very powerful plugin. If you’ve ever released a project by hand you will appreciate this plugin. One of my favorite features is that it checks to see if all of the dependencies refer to released versions. Without this automatic check you are forced to search through all of the dependency management configurations for unreleased dependencies. Depending on the size of your hierarchy this can be quite painful.
Along with this dependency check it also runs all of the tests, tags the code with the release name, and publishes the artifacts in the Maven repository. This plugin embodies the best standards for releasing within our industry. Standards that I easily forget and/or mess up. I highly recommend that you use this plugin to release your projects. Please refer to http://maven.apache.org/plugins/maven-release-plugin for more information.
An aggregate POM joins multiple modules together.
_pom.xml (aggregate) |_sample-service |_pom.xml (module 1) |_sample-client |_pom.xml (module 2)
The aggregate pom configures multiple modules in the modules section.
<project> <modelVersion>4.0.0</modelVersion> <groupId>com.mycompany.app</groupId> <artifactId>sample-app</artifactId> <version>1</version> <packaging>pom</packaging> <modules> <module>sample-service</module> <module>sample-client</module> </modules> </project>
When you execute a Maven command at the aggregate level it will execute the same command on all of the configured modules. If any of these modules depends on another module Maven builds them in the correct order. This is a simple way to break up a large project into focused modules without loosing a coordinated project management strategy. While this could be replicated with Ant and Ivy it would be painful to configure and maintain. Aggregate projects are first class citizens in Maven.
The ‘dependencymanagement’ section defines the acceptable versions for a project. This configuration does not result in a JAR being downloaded and included in the project. On the other hand, this is a directive specifying which version of a dependency should be used if a project depends on it. This is a simple way to force Maven to select a specific dependency version. In the case of an aggregate project it is best to add this to the aggregate pom. Configure the dependency versions in one place for all of the modules.
<dependencyManagement> <dependencies> <dependency> <groupId>test</groupId> <artifactId>a</artifactId> <version>1.2</version> </dependency> <dependency> <groupId>test</groupId> <artifactId>b</artifactId> <version>1.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>test</groupId> <artifactId>c</artifactId> <version>1.0</version> <scope>compile</scope> </dependency> <dependency> <groupId>test</groupId> <artifactId>d</artifactId> <version>1.2</version> </dependency> </dependencies> </dependencyManagement>
Maven provides a simple way to package all of your artifacts in a single zip file. This simplifies the deployment process and increases traceability. For example I have used this feature to package my WAR, SQL, and external PDF files in the same zip file. Our deployment team extracted the WAR and PDF files and deployed them. Then they passed the SQL on to the DBA’s to run the scripts. All of the files necessary to deploy our project were packaged together and published to our Maven repository. Please refer to http://maven.apache.org/plugins/maven-assembly-plugin for more information.
Maven provides a holistic approach to project management. Maven provides standard conventions that can be easily modified and extended. When our development team switched from Ant/Ivy to Maven we spent less time focusing on how to build our projects. In the end Maven provided industry project management standards that we could depend on. Even when we spent hours trying to perfect our Ant build process we were getting some things wrong. We were focused on deploying the product at that moment. Unfortunately companies need to insure that deployments are traceable, dependable, and reproducible. Maven freed us up to focus on getting the product out while protecting our companies interests right out of the box.