Generic Top

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE

1. Overview

In this short tutorial, we are going to overview the differences between super, simplest, and effective POM using Maven.

2. What Is a POM?

POM stands for Project Object Model, and it is the core of a project's configuration in Maven. It is a single configuration XML file called pom.xml that contains the majority of the information required to build a project.

The role of a POM file is to describe the project, manage dependencies, and declare configuration details that help Maven to build the project.

3. Super POM

To understand super POM more easily, we can make an analogy with the Object class from Java: Every class from Java extends, by default, the Object class. Similarly, in the case of POM, every POM extends the super POM.

The super POM file defines all the default configurations. Hence, even the simplest form of a POM file will inherit all the configurations defined in the super POM file.

Depending on the Maven version that we use, the super POM can look slightly different. For instance, if we have Maven installed into our machine, we can visualize it at  ${M2_HOME}/lib, maven-model-builder-<version>.jar file. If we open this JAR file, we'll find it under the name org/apache/maven/model/pom-4.0.0.xml.

In the next sections, we'll go through the super POM configuration elements for version 3.6.3.

3.1. Repositories

Maven uses the repositories defined under the repositories section to download all the dependent artifacts during a Maven build.

Let's take a look at an example:

<repositories>
    <repository>
        <id>central</id>
        <name>Central Repository</name>
        <url>https://repo.maven.apache.org/maven2</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
    </repository>
</repositories>

3.2. Plugin Repositories

The default plugin repository is the central Maven repository. Let's look at how it's defined in the pluginRepository section:

<pluginRepositories>
    <pluginRepository>
        <id>central</id>
        <name>Central Repository</name>
        <url>https://repo.maven.apache.org/maven2</url>
        <layout>default</layout>
        <snapshots>
            <enabled>false</enabled>
        </snapshots>
        <releases>
            <updatePolicy>never</updatePolicy>
        </releases>
    </pluginRepository>
</pluginRepositories>

As we can see above, snapshots are disabled, and the updatePolicy is set to “never”. Therefore, with this configuration, Maven will never automatically update a plugin if a new version is released.

3.3. Build

The build configuration section includes all the information required to build a project.

Let's see an example of the default build section:

<build>
    <directory>${project.basedir}/target</directory>
    <outputDirectory>${project.build.directory}/classes</outputDirectory>
    <finalName>${project.artifactId}-${project.version}</finalName>
    <testOutputDirectory>${project.build.directory}/test-classes</testOutputDirectory>
    <sourceDirectory>${project.basedir}/src/main/java</sourceDirectory>
    <scriptSourceDirectory>${project.basedir}/src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>${project.basedir}/src/test/java</testSourceDirectory>
    <resources>
        <resource>
	    <directory>${project.basedir}/src/main/resources</directory>
	</resource>
    </resources>
    <testResources>
        <testResource>
	    <directory>${project.basedir}/src/test/resources</directory>
	</testResource>
    </testResources>
    <pluginManagement>
        <!-- NOTE: These plugins will be removed from future versions of the super POM -->
	<!-- They are kept for the moment as they are very unlikely to conflict 
		with lifecycle mappings (MNG-4453) -->
	<plugins>
	    <plugin>
		<artifactId>maven-antrun-plugin</artifactId>
		<version>1.3</version>
	    </plugin>
	    <plugin>
		<artifactId>maven-assembly-plugin</artifactId>
		<version>2.2-beta-5</version>
	    </plugin>
	    <plugin>
		<artifactId>maven-dependency-plugin</artifactId>
		<version>2.8</version>
	    </plugin>
	    <plugin>
		<artifactId>maven-release-plugin</artifactId>
	        <version>2.5.3</version>
	    </plugin>
	</plugins>
    </pluginManagement>
</build>

3.4. Reporting

For reporting, the super POM only provides a default value for the output directory:

<reporting>
    <outputDirectory>${project.build.directory}/site</outputDirectory>
</reporting>

3.5. Profiles

If we do not have defined profiles at the application level, the default build profile will be executed.

The default profiles section looks like:

<profiles>
    <!-- NOTE: The release profile will be removed from future versions of the super POM -->
    <profile>
        <id>release-profile</id>
	<activation>
	    <property>
		<name>performRelease</name>
		<value>true</value>
	    </property>
        </activation>
	<build>
	    <plugins>
		<plugin>
		    <inherited>true</inherited>
		    <artifactId>maven-source-plugin</artifactId>
		    <executions>
			    <execution>
			    <id>attach-sources</id>
			    <goals>
			        <goal>jar-no-fork</goal>
			    </goals>
			</execution>
		    </executions>
		</plugin>
		<plugin>
		    <inherited>true</inherited>
		    <artifactId>maven-javadoc-plugin</artifactId>
		    <executions>
			<execution>
			    <id>attach-javadocs</id>
			    <goals>
			        <goal>jar</goal>
			     </goals>
			</execution>
		    </executions>
		</plugin>
		<plugin>
		    <inherited>true</inherited>
		    <artifactId>maven-deploy-plugin</artifactId>
		    <configuration>
			<updateReleaseInfo>true</updateReleaseInfo>
		    </configuration>
		</plugin>
	    </plugins>
        </build>
    </profile>
</profiles>

4. Simplest POM

The simplest POM is the POM that you declare in your Maven project. In order to declare a POM, you will need to specify at least these four elements: modelVersion, groupId, artifactId, and version. The simplest POM will inherit all the configurations from the super POM.

Let's have a look at the minimum required elements for a Maven project:

<project>
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.baeldung</groupId>
    <artifactId>maven-pom-types</artifactId>
    <version>1.0-SNAPSHOT</version>
</project>

One main advantage of the POM hierarchy in Maven is that we can extend and override the configuration inherited from the top. Therefore, to override the configuration of a given element or an artifact in the POM hierarchy, Maven should be able to uniquely identify the corresponding artifact.

5. Effective POM

Effective POM combines all the default settings from the super POM file and the configuration defined in our application POM. Maven uses default values for configuration elements when they are not overridden in the application pom.xml. Hence, if we take the same sample POM file from the simplest POM section, we'll see that the effective POM file will be the merge between simplest and super POM. We can visualize it from the command line:

mvn help:effective-pom

This is also the best way to see the default values that Maven uses.

6. Conclusion

In this short tutorial, we discussed the differences between Project Object Models in Maven.

As always, the example shown in this tutorial is available over on GitHub.

Generic bottom

Get started with Spring 5 and Spring Boot 2, through the Learn Spring course:

>> CHECK OUT THE COURSE
Generic footer banner
Comments are closed on this article!