Maven POM File

by Apr 1, 2015

This video describes the Maven POM file.  It was originally part of a larger unpublished video tutorial on creating JAXRS applications using Java.  The video was originally posted to YouTube on May 18, 2014.

Maven POM File

In this video we will talk about Maven coordinates, take a deeper look at the Maven POM file, and examine how we can modify it to include Java libraries specific to our project.


Hi. So far we’ve installed maven and we’re starting to get an idea of how we can create projects using Maven.

In this video we will talk about Maven coordinates, take a deeper look at the Maven POM file, and examine how we can modify it to include Java libraries specific to our project.

Lets start with Maven coordinates.

Maven coordinates define a specific project, similar to the way x, y and z define a point in space. A Maven coordinate is defined by a group id, artifact id, and version id.

The group id is usually a general id that references the company or organization that is creating the project. The group id is usually by convention a domain name something like com.yourorganization. This would be a domain name that you control. You shouldn’t use unless you’re Google. This also defines where the library exists in the Maven repository. com.yourorganization would exist in the $M2_REPO/com/yourorganization directory. The periods in the group id separate the directory names.

The artifact id is the name of the project. When you compile, the artifact id usually determines the name of your compiled jar, ear or war without the versio. The name can be anything you like, all lowercase letters, and no strange symbols.

Once you have a group id and artifact id, you still can’t determine the correct file. There might be multiple versions of the file. The version id specifies the particular version of your project. You should use numbers like 1.0.1 for the version. This should be major, minor, and build numbers.

With the group id, artifact id, and version, you can uniquely identify a particular project. This is what you use to add dependencies to your project’s POM file. Lets look at the POM file now.

The Maven POM file describes everything we need to know about our project and how to build it.

The POM file always has the same beginning parts. The first tag is the project tag. This simply lets an XML parser know how to parse the rest of the POM file. The model version is 4.0.0. It’s always 4.0.0, because that is the only version supported for Maven 2 and 3. There isn’t any other value for this tag, so it’s safe to just copy it.

The rest of the POM file consists of 4 main sections. These sections are the basics section, the build settings, environment settings, and additional project information.

The basics section describes relationships about the project. It contains the Maven coordinates for the project, what kind of artifact it should build, any dependencies the project has on other Java libraries, and properties the POM file needs to complete the build.

The Maven coordinates in this section are the same coordinates we just discussed, and it defines the maven coordinates for this project.

The packaging element determines the artifact we’re building. The value can be pom, jar, maven-plugin, ejb, war, ear, rar, or par. Pom packaging simply generates itself. A jar packaging creates a Java archive file. The Maven-plugin packaging is for generating maven plugins. EJB is for packaging an EJB module. WAR is for creating web archives. This is the one we’ll use most often. EAR is for packaging enterprise archive files. Rar packaging is for creating a type of compression files, and PAR is for creating process archive files. It’s just like building a jar, but it also generates a descriptor file, and modifies the repository data. You can also define your own packaging types, but that’s not something we will go into.

The dependencies element lists all the Maven coordinates required to compile our project. When we need to add a new dependency, we’ll add a new coordinate to this section. We will go into this more in a bit.

The parent element is used for project inheritance. It’s used when you want a project to inherit values from a parent POM. For example if you are building several similar projects as part of a larger system, you don’t want to repeat the dependencies. You can place all your dependencies in a parent POM, and then reference the parent POM in all the child POMs.

A child POM will inherit all identifiers, but you must change at least the group id or artifact id. It will inherit all dependencies, the developers and contributors, the plugin lists, report lists, plugin executions, and plugin configurations. We’ll go over some of these later, but that’s the complete list of inheritable values.

The modules element serves a similar purpose as the parent. The modules element serves as an aggregator for sub projects. Typically you create a POM file with a packaging type of POM, and then in the modules section of that POM you list all the POMs you want to aggregate. What this does is allow you manage a group of POMs as one POM. This will run your maven command on all the POM files listed in the modules element.

The properties element allows you to define properties specific to your project. To create a new property, you simply define a new sub element with any name you like. The property name is the sub element name, and it’s value is the value of the element. You can then refer to the property later in the POM file with the dollar sign notation. This is useful for specifying a version for several related dependencies at the top. Changing the version can be as simple as changing the property value.

The next section is the build section. This section allows you to customize the behavior of the Maven build. You can specify a different directory for your source and test files, or attach plugin goals to control how the build process flows. We won’t update this section much, because we will rely on the defaults.

Additional project information contains other general information about the project. This section can list a human readable name for the project, the developers involved in the project, contributors, and the software license for the file. The elements in this section are self descriptive.

The environment settings describe things like repositories to get dependencies for your build, continuous integration for the project, mailing lists, and other general project information. We will rely on little of this section as well. We will need to specify repositories to retrieve specific dependencies, but we won’t use much else.

When we need to use a dependency that isn’t in the default central Maven repository, we need to provide other repositories to search. The other repository can be a 3rd party private repository or maybe your company’s private repository. This additional repository is added in the environments section. We can specify a repository in the repositories section.

Now that we’ve covered the different sections, lets look at adding dependencies a bit closer.

If you look at the pom file included in the code package for this section, you’ll notice JUnit is added as a dependency under the dependencies element. This is how dependencies are added to a project. You simply add the Maven coordinates for the dependency you want to add, and you’re done.

If you look closer at the JUnit Maven coordinates, you will notice it also includes a new element we haven’t talked about yet – scope. Scope tells Maven when it should include the dependency in the classpath. The default is compile, but there are four other possibilities – provided, runtime, test, and system. Compile means it will use the dependency when you are compiling, and it will be included in any dependent projects. The dependency will be included in any deployment artifact. Provided means that you should use the dependency in the classpath, but you expect the JDK or application container to provide the dependency at runtime. It won’t be included in the deployment artifact. Runtime is similar to provided, but it means it’s not required for compilation. It’s only needed at runtime, and you expect the JDK or application container to provide it. Test means it’s only available for compiling and running tests. System is the same as provided, but the dependency isn’t found in the repository, Maven only verifies the file exists. If you use system as your scope, you also need to provide an absolute system path to the dependency.

You can also tell Maven to exclude dependencies. You would use this when you want to use a dependency, but you don’t want to use a dependency of a dependency. I run into this often when a dependency uses another dependency that conflicts with something I’m using. The solution is to simply exclude it.

This covers everything we’ll need to know about the POM file. We’ve looked at Maven coordinates, the POM file in depth, and we’ve looked at how to add dependencies to a POM file.

The most important thing to remember is how to add dependencies, since it’s a task you’ll do often. Everything else can be looked up. The main purpose here was to expose you to all the functionality of the POM file. Once you know that something can be done, it’s just a matter of reminding yourself how later when you need it by looking up the details. If you need more information, you can always go to the Maven website at

Adding a dependency is pretty important, so lets walk through the steps of adding one to a POM file. If we go back to our POM file for the hello world app, we can see there is one dependency for JUnit. Let’s add a dependency for Apache Commons IO library. It’s a common library for stream and file IO, but all we really want to do for this example is add it to our project. So where do we start? We need the maven coordinates for this dependency. I don’t have them memorize, and neither should you. We need to look it up.

First go to MVN Repository dot com. This is a great place to look up maven coordinates for popular libraries.

Search for apache commons io. You’ll see results to click on, and then you’ll see a list of versions. We’ll use 2.4, so click on that. On this page you’ll see the maven coordinates we need to add to our POM file. Copy and paste these into the POM file. Save, and lets see what happens when we run mvn install.

You’ll see in the command window that maven is downloading the dependency from the internet. This dependency will be added to our project, and included in the jar we create.

Tools Used

  • Java
  • NetBeans

Media Credits

All media created and owned by DJ Spiess unless listed below.

  • No infringement intended

Get the code

The source code for this video can be found on Github. If you have Git installed on your system, you can clone the repository by issuing the following command:

git clone

Go to the Support > Getting the Code page for more help.

If you find any errors in the code, feel free to let me know or issue a pull request in Git.

Don’t miss another video!

New videos come out every week. Make sure you subscribe!



DJ Spiess

DJ Spiess

Your personal instructor

My name is DJ Spiess and I’m a developer with a Masters degree in Computer Science working in Colorado, USA. I primarily work with Java server applications. I started programming as a kid in the 1980s, and I’ve programmed professionally since 1996. My main focus are REST APIs, large-scale data, and mobile development. The last six years I’ve worked on large National Science Foundation projects. You can read more about my development experience on my LinkedIn account.

Pin It on Pinterest

Share This