Maven (Part 5) - External Dependencies, Remote Repositories, and Documentation
Maven (Part 5) - External Dependencies, Remote Repositories, and Documentation

Maven (Part 5) - External Dependencies, Remote Repositories, and Documentation

in
  1. Introducing External Dependencies
  2. Deploying to a Remote Repository
  3. Creating Documentation

Introducing External Dependencies

You may have noticed the dependencies element in the POM we’ve been using as an example. Indeed, you’ve been using external dependencies all along, but here we’ll delve deeper into how they work. For a more comprehensive introduction, refer to our Introduction to Dependency Mechanism.

The “dependencies” section in the pom.xml lists all the external dependencies required for building the project (whether it’s during compile time, testing, runtime, or other phases). For now, our project only depends on JUnit (I’ve removed all resource filtering for clarity):

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</project>

For each external dependency, you need to define at least 4 elements: groupId, artifactId, version, and scope. groupId, artifactId, and version are the same as those given in the pom.xml of the project building the dependency. The scope element indicates how the project uses that dependency, with values like compile, test, and runtime. For more details on specifying contents for dependencies, refer to the Project Descriptor Reference.

With this information about dependencies, Maven can reference them during project builds. But where does Maven fetch dependencies from? Maven looks for all dependencies in the local repository (by default located at ${user.home}/.m2/repository). In the previous section, we installed the project’s artifact (my-app-1.0-SNAPSHOT.jar) into the local repository. After installation, other projects only need to add dependency information in their pom.xml to reference that jar as a dependency:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-other-app</artifactId>
  ...
  <dependencies>
    ...
    <dependency>
      <groupId>com.mycompany.app</groupId>
      <artifactId>my-app</artifactId>
      <version>1.0-SNAPSHOT</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

But what about dependencies built elsewhere? How do they get into my local repository? Whenever a project references a dependency that isn’t in the local repository, Maven will download that dependency from a remote repository to the local repository. When you build your first project, you might notice Maven downloading a lot of things (these downloads are dependencies for various plugins used in building the project).

By default, Maven uses a remote repository located at https://repo.maven.apache.org/maven2/. You can also configure your own remote repository (perhaps a central repository for your company) to supplement or replace the default remote repository. For more about repositories, see the Introduction to Repositories.

Let’s add another dependency to the project. Suppose we added some logging to the code and need to add log4j as a dependency. First, we need to know the groupId, artifactId, and version of log4j. The corresponding directory on Maven Central is /maven2/log4j/log4j. In that directory, there’s a file named maven-metadata.xml. Here’s the content of log4j’s maven-metadata.xml file:

<metadata>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.1.3</version>
  <versioning>
    <versions>
      <version>1.1.3</version>
      <version>1.2.4</version>
      <version>1.2.5</version>
      <version>1.2.6</version>
      <version>1.2.7</version>
      <version>1.2.8</version>
      <version>1.2.11</version>
      <version>1.2.9</version>
      <version>1.2.12</version>
    </versions>
  </versioning>
</metadata>

From this file, we can see the groupId we need is “log4j”, and the artifactId is “log4j”. We can see many different versions available.

Now, let’s use just the latest version 1.2.12 (some maven-metadata.xml files might also specify the version of the current release; see Repository Metadata Reference).

Next to the maven-metadata.xml file, we see directories corresponding to each version of the log4j library. Inside each directory, we find the actual jar file (like log4j-1.2.12.jar) and a pom file (this is the pom.xml for that dependency, specifying any other dependencies it might have and other information) and another maven-metadata.xml file. Each file also has a corresponding md5 file containing the MD5 hash of these files. You can use it to verify the library or to find out the version of a particular library you might be using.

Now that we have the necessary information, let’s add the dependency to pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd

/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>log4j</groupId>
      <artifactId>log4j</artifactId>
      <version>1.2.12</version>
      <scope>compile</scope>
    </dependency>
  </dependencies>
</project>

Now, when we compile the project (mvn compile), we’ll see Maven downloading the log4j dependency for us.

Deploying to a Remote Repository

To deploy jars to an external repository, you must configure the repository url in pom.xml and authentication information for connecting to the repository in settings.xml.

Below is an example using scp and username/password authentication:

POM.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
 
  <groupId>com.mycompany.app</groupId>
  <artifactId>my-app</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>
 
  <name>Maven Quick Start Archetype</name>
  <url>http://maven.apache.org</url>
 
  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.apache.codehaus.plexus</groupId>
      <artifactId>plexus-utils</artifactId>
      <version>1.0.4</version>
    </dependency>
  </dependencies>
 
  <build>
    <filters>
      <filter>src/main/filters/filters.properties</filter>
    </filters>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>
  <!--
   |
   |
   |
   -->
  <distributionManagement>
    <repository>
      <id>mycompany-repository</id>
      <name>MyCompany Repository</name>
      <url>scp://repository.mycompany.com/repository/maven2</url>
    </repository>
  </distributionManagement>
</project>

settings.xml:

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 https://maven.apache.org/xsd/settings-1.0.0.xsd">
  ...
  <servers>
    <server>
      <id>mycompany-repository</id>
      <username>jvanzyl</username>
      <!-- Default value is ~/.ssh/id_dsa -->
      <privateKey>/path/to/identity</privateKey> (default is ~/.ssh/id_dsa)
      <passphrase>my_key_passphrase</passphrase>
    </server>
  </servers>
  ...
</settings>

Note that if you’re connecting to an openssh ssh server with the PasswordAuthentication parameter set to no in sshd_config, you’ll need to type the password every time you authenticate with username/password (although you can type the username and password into another ssh client). In this case, you might prefer using public key authentication.

Be cautious when using passwords in settings.xml. For more information, see Password Encryption.

Creating Documentation

To quickly start using Maven’s documentation system, you can use the archetype mechanism to generate a site for an existing project with the following command:

mvn archetype:generate \
  -DarchetypeGroupId=org.apache.maven.archetypes \
  -DarchetypeArtifactId=maven-archetype-site \
  -DgroupId=com.mycompany.app \
  -DartifactId=my-app-site

Now head over to the Creating a Site Guide to learn how to create documentation for your project.