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
<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.
It 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.ibiblio.org/maven/</url> </repository> <repository> <id>PlanetMirror</id> <name>Planet Mirror</name> <url>http://public.planetmirror.com/pub/maven/</url> </repository> </repositories>
Building Multiple Projects using a Parent pom.xml
It'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
WebApplication submodule, so we need to declare them as dependencies. In this example, our
Utilities project depends on the
Common project, so we would need to add a dependency to the Utilities project for
Common. The same goes for our
Application submodule, because it would depend on
Utilities would depend on
Common. If there were 60 submodules in this example that all depend on each other, it would be difficult for a new developer to figure out what projects depend upon others, so this is precisely the reason we make sure that the order of the projects is clear in the parent pom.xml.
Here are the
Utility module's dependencies
<dependencies> <dependency> <groupId>com.oreilly</groupId> <artifactId>Common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies>
Here's how to state the
Application module's dependencies
<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>
WebApplication module dependencies are as follows:
<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
pom.xml file, we have our project directories: Common, Utilities, Application, and WebApplication. Now when we run mvn package in the directory with the master pom.xml file, each project will be built in turn as they depend upon one another.