Spring Boot-Series Part 2: What is pom.xml in a maven based Spring Project?

In the last post we tried to build and setup a simple Spring boot project in STS. You can check the post – https://thewebspark.com/2020/04/18/spring-boot-series-part-1-setting-up-the-maven-based-spring-boot-application-in-sts-or-eclipse-ide/ if you have not done the setup yet.

So, now we will try to decode and learn each and every part of an Spring Boot application. In this part of the series we will start with pom.xml.

Let us get started…

pom.xml

  • The full form of POM is Project Object Model
  • It is a fundamental unit of work in Maven
  • pom is a XML file that contains information about the project and configuration details used by Maven to build the project.
  • When executing a task or goal, Maven looks for the POM in the current directory. It reads the POM, gets the needed configuration information, then executes the goal.
  • Configurations specified in the POM are the project dependencies, the plugins or goals that can be executed, the build profiles.

So this is a basic overall pom.xml from out setup

<?xml version="1.0" encoding="UTF-8"?>
<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.thewebspark</groupId>
	<artifactId>EmployeeRecords</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>EmployeeRecords</name>
	<description>First project for Spring Boot</description>
...
        <packaging>war</packaging>
...
	<properties>
		<java.version>11</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
    <groupId>xalan</groupId>
    <artifactId>serializer</artifactId>
    <version>2.7.1</version>
</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

Let us try go through each element:

<project></project>

<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">
  • project is root element of the pom.xml
  • It describes basic schema settings such as apache schema and w3.org specification.
  • xmlns:xsi=”http://www.w3.org/2001/XMLSchema&#8221; indicates that the elements and data types used in the schema come from the “http://www.w3.org/2001/XMLSchema” namespace. It also specifies that the elements and data types that come from the http://www.w3.org/2001/XMLSchema” namespace should be prefixed with xsi:
  • xmlns specifies the default namespace declaration. This declaration tells the schema-validator that all the elements used in this XML document are declared in the http://maven.apache.org/POM/4.0.0&#8221; namespace
  • The Java XML parser that spring uses will read the schemaLocation values and try to load them from the internet, in order to validate the XML file. Spring, in turn, intercepts those load requests and serves up versions from inside its own JAR files.
  • If you omit the schemaLocation, then the XML parser won’t know where to get the schema in order to validate the config.

Application description tags

<groupId>com.thewebspark</groupId>
<artifactId>EmployeeRecords</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>EmployeeRecords</name>
<description>First project for Spring Boot</description>
  • groupId: This is generally unique for a project. For example, all core Maven artifacts do should live under the groupId – org.apache.maven
  • artifactId: The artifactId is generally the name that the project is known by.
  • version: defines the version of the project
  • name: Name of the app
  • description: description of the app

packaging

...
        <packaging>war</packaging>
...	

When no packaging is declared, Maven assumes the packaging is the default: jar. but you can change it war or any other types such as pomjarmaven-pluginejbwarearrar.

POM Relationships

  • dependencies
  • inheritance
  • aggregation

Maven downloads and links the dependencies on compilation, as well as on other goals that require them.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>

Inside <dependency> – you define what all modules and jars you will require in your project framework.

Each dependency is simply an another maven project which is defined by the groupId, artifactId, version etc.

Apart from above three there are several more tags used which are as follows:

  • classifier: The classifier distinguishes artifacts that were built from the same POM but differ in content. It is some optional and arbitrary string that – if present – is appended to the artifact name just after the version number.
  • type:Corresponds to the chosen dependency type. This defaults to jar
  • scope: This element refers to the classpath of the task at hand (compiling and runtime, testing, etc.) as well as how to limit the transitivity of a dependency. There are five scopes available: compile, provided, runtime, test , system

systemPath: is used only if the dependency scope is system. Otherwise, the build will fail if this element is set. The path must be absolute, so it is recommended to use a property to specify the machine-specific path (more on properties below), such as ${java.home}/lib

optional: Marks a dependency optional when this project itself is a dependency.

Properties: Maven properties are value placeholder.

  <properties>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  </properties>

Inheritence in maven

The packaging type required to be pom for parent and aggregation (multi-module) projects.

<packaging>pom</packaging>

Dependency Management

Dependency Management allows to consolidate and centralize the management of dependency versions without adding dependencies which are inherited by all children. This is especially useful when you have a set of projects (i.e. more than one) that inherits a common parent.

Another extremely important use case of dependencyManagement is the control of versions of artifacts used in transitive dependencies. This is hard to explain without an example. Luckily, this is illustrated in the documentation.

mvn dependency:tree

dependencyManagement is used by a POM to help manage dependency information across all of its children.

Aggregation or Multi Module

A project with modules is known as a multi-module, or aggregator project. Modules are projects that this POM lists, and are executed as a group.

  <modules>
    <module>my-project</module>
    <module>another-project</module>
    <module>third-project/pom-example.xml</module>
  </modules>

Build

They are the build element handles things like declaring your project’s directory structure and managing plugins.

The build is conceptually divided into tow part – BaseBuild and profiles

 <!-- "Project Build" contains more elements than just the BaseBuild set -->
  <build>...</build>
 
  <profiles>
    <profile>
      <!-- "Profile Build" contains a subset of "Project Build"s elements -->
      <build>...</build>
    </profile>
  </profiles>

BaseBuild

the base set of elements between the two build elements in the POM.

<build>
  <defaultGoal>install</defaultGoal>
  <directory>${basedir}/target</directory>
  <finalName>${artifactId}-${version}</finalName>
  <filters>
    <filter>filters/filter1.properties</filter>
  </filters>
  ...
</build>

Resources

Another feature of build elements is specifying where resources exist within your project. Resources are not (usually) code.

They are not compiled, but are items meant to be bundled within your project or used for various other reasons, such as code generation.

<build>
    ...
    <resources>
      <resource>
        <targetPath>META-INF/plexus</targetPath>
        <filtering>false</filtering>
        <directory>${basedir}/src/main/plexus</directory>
        <includes>
          <include>configuration.xml</include>
        </includes>
        <excludes>
          <exclude>**/*.properties</exclude>
        </excludes>
      </resource>
    </resources>
    <testResources>
      ...
    </testResources>
    ...
  </build>

Plugins and PluginManagement

Plugins are the central feature of Maven that allow for the reuse of common build logic across multiple projects.

action: They do this by executing an “action” (i.e. creating a WAR file or compiling unit tests) in the context of a project’s description – the Project Object Model (POM). 

  <build>
    <plugins>
      <plugin>
        <artifactId>maven-antrun-plugin</artifactId>
        <version>1.1</version>
        <executions>
          <execution>
            <id>echodir</id>
            <goals>
              <goal>run</goal>
            </goals>
            <phase>verify</phase>
            <inherited>false</inherited>
            <configuration>
              <tasks>
                <echo>Build Dir: ${project.build.directory}</echo>
              </tasks>
            </configuration>
          </execution>
        </executions>
 
      </plugin>
    </plugins>
  </build>

One of the simplest plugins in Maven is the Clean Plugin. The Maven Clean plugin (maven-clean-plugin) is responsible for removing the target directory of a Maven project.

pluginManagement: is an element that is seen along side plugins. Plugin Management contains plugin elements in much the same way, except that rather than configuring plugin information for this particular project build, it is intended to configure project builds that inherit from this one

<build>
    ...
    <pluginManagement>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-jar-plugin</artifactId>
          <version>2.6</version>
          <executions>
            <execution>
              <id>pre-process-classes</id>
              <phase>compile</phase>
              <goals>
                <goal>jar</goal>
              </goals>
              <configuration>
                <classifier>pre-process</classifier>
              </configuration>
            </execution>
          </executions>
        </plugin>
      </plugins>
    </pluginManagement>
    ...
  </build>

There are more to pom.xml but the above points are major concepts.

To learn in details, please refer maven site: https://maven.apache.org/pom.html

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s