Coordinates

This lesson talks about Maven coordinates defined by groupId, projectId, and version.

We'll cover the following

Projects don’t exist in isolation. Any substantial project will have dependencies on other projects. The POM file for a project defines the list of projects the current one depends on. But how do we uniquely identify projects? Projects need to be unambiguously identifiable so that they can be referred to in other projects. Maven makes this possible through a combination of fields defined in a POM file called the Maven coordinates. These are:

  1. groupId: This can be the group, company, or department responsible for creating the project. The convention is to use the domain name in reverse order. For instance, for our company the groupdId would be io.datajek.

  2. artifactId: A unique name for the project under the groupId. A team in your company that produces several jar libraries for other teams to consume will have a unique artifactId for each library, but the same groupId.

  3. version: The version specifies a particular release of the project. Imagine your team releases improvements to a particular library on a quarterly basis, each release would get a different version number.

The relationship between these identifiers is shown below:

An example of the three values for a project is shown below:

  <groupId>io.datajek</groupId>
  <artifactId>maven-course</artifactId>
  <version>1.0-SNAPSHOT</version>

Together these three attributes uniquely identify a project. No two projects can have the same values for all three attributes. Furthermore, two more POM fields are listed as Maven coordinates but don’t participate in uniquely identifying a project. These are:

  1. packaging: Defines the type of a project. A project with packaging set to jar will produce a jar archive, while one with war will produce a web application.
  2. classifier: Consider you are writing a Java application that you intend to support on Java versions 8 and 11. One way to distinguish between the artifacts you produce for the two versions is to use the classifier. The classifier is an optional arbitrary string that, if present, is appended to the artifact name after the version number. The classifier allows us to distinguish between artifacts built from the same POM that differ in content. In our hypothetical example we can set the classifier to be jdk8 and jdk11 for the two artifacts and let consumers chose according to their available Java version.

Maven coordinates are expressed in the following format using colons as the delimiter:

groupId:artifactId:packaging:version

An example for our project will be:

io.datajek:maven-course:jar:1.0-SNAPSHOT

Using coordinates, it becomes trivial to express the dependencies of a project in its POM file. In later lessons, we’ll learn how to define dependencies.

Repositories

So far we have learned that projects can be uniquely identified in the Maven world. But where do these projects live? There’s no point in uniquely identifying an object if we can’t retrieve it. In the Maven ecosystem, projects live in repositories, which are stores for the products produced by Maven projects. There are two kinds of repositories and it’s important to understand how they work with each other. These are:

  1. Local Repository
  2. Remote Repository

The local repository acts as a local cache for artifacts and dependencies your project may need and also for the artifacts produced by your project. The local repository lives on your local machine and is created the first time you execute a Maven command. As mentioned before, Maven ships with a limited skeleton and downloads core plugins from a remote repository and places them in the local repository for later use.

By default, the local repository is created at the path (Unix systems) /<username>/.m2/repository or ~/.m2/repository. We’ll install a sample project in our local repository with the following exercise. Follow the steps listed in the code widget below:

# Verify the .m2 directory doesn't exist
ls ~/.m2/repository
# Run any Maven command even if it fails
mvn
# Now See the .m2 directory has been created but is empty
ls ~/.m2/repository
# Now install any project. We'll install Project1 as an example
cd /Project1
mvn install
# Now examine the artifact Maven has installed in the local repository
ls ~/.m2/repository/io/datajek/project1/1/
Terminal 1
Terminal
Loading...

Remember Maven always looks for an artifact in the local repository before looking elsewhere. The structure of the repository deserves attention too. The artifact of our project in the previous exercise is installed at the path io/datajek/maven-course/. In general, artifacts are installed at the path with the following format relative to the repository’s root:

<groupId>/<artifactId>/<version>/<artifactId>-<version>.<packaging>

In the previous example, we worked with the local repository. Initially, Maven downloads core plugins and dependencies from a remote repository. The location for this remote repository comes configured with Maven and is set to https://repo1.maven.org/maven2/. It is known as the Central Repository. In fact, you can navigate to this URL and examine the various directories under it. For example, we randomly selected the following Google jar artifact:

https://repo1.maven.org/maven2/com/google/apis/google-api-services-admob/v1-rev10-1.18.0-rc/

Here the groupId is com.google.apis, the artifactId is google-api-services-admob, and the version is v1-rev10-1.18.0-rc. If you navigate to the above URL, you’ll see the various jar artifacts available for download.

Note that in this case, the repository is publicly available, and artifacts can be downloaded by anyone. However, not all organizations want to distribute their code publicly or have their developers refer to a publicly available repository for downloading artifacts. In such scenarios, organizations usually set-up their own repository, possibly a mirror of Maven’s public repository, within the organization’s network that is accessible only within the organization. The remote repository location can be configured in a settings.xml file under the .m2 directory.