Maven pom.xml Explained: Structure, GAV, Properties, Packaging and Build - Quiz
Total: 5 questions
1. What elements make up pom.xml, which of them are required, and what does modelVersion mean?
What elements make up pom.xml, which of them are required, and what does modelVersion mean?
pom.xml is the XML file in the root of a Maven project that holds the POM (Project Object Model). Required are only the <project> root element, <modelVersion> and the coordinates groupId, artifactId, version (groupId and version can be inherited from a parent). Without them Maven cannot read the POM or reports an error such as 'groupId' is missing.
Optional are packaging, name/description/url, properties, dependencies, build and parent. Settings you leave out may be inherited from a parent and the Super POM (standard directories, resources, finalName, Maven Central) or come from the POM model (packaging = jar) or the plugins themselves, and an optional element may simply be absent. The default bindings of plugin goals to phases come from the lifecycle mapping for the chosen packaging. The order of elements does not affect the result, but by convention it is coordinates, description, properties, dependencies, build.
modelVersion = 4.0.0 tells Maven which version of the POM model the file follows; for Maven 3 it is the only valid value. Maven 4 introduces model 4.1.0 but still reads 4.0.0 files, so most projects use 4.0.0. The xmlns and xsi:schemaLocation attributes are optional but let your IDE validate and autocomplete tags; xmlns is a namespace identifier, not an address, so there is no need to change http to https in it.
2. What are GAV coordinates in pom.xml, and how does a SNAPSHOT version differ from a release?
What are GAV coordinates in pom.xml, and how does a SNAPSHOT version differ from a release?
GAV is the triple of groupId (the organization as a reversed domain name), artifactId (the project name) and version that uniquely identifies a project or library in the Maven world. The pair groupId + artifactId without a version identifies the project as a whole, not a specific build, and a specific file is further distinguished by its extension (type) and, if needed, a classifier (for example, the -sources jar). The coordinates determine the path and the file name: com.examclouds:shop:1.0-SNAPSHOT ends up in ~/.m2/repository/com/examclouds/shop/1.0-SNAPSHOT/shop-1.0-SNAPSHOT.jar after mvn install.
SNAPSHOT (the -SNAPSHOT suffix, for example 1.0-SNAPSHOT) is a version under development: its content may change. Maven looks for a newer build of a SNAPSHOT dependency in the remote repository during a build, when the repository's updatePolicy says it is due (the default is daily — at most once a day); mvn -U forces an update of SNAPSHOT dependencies. Maven Central is configured in the Super POM with snapshots disabled, so SNAPSHOT versions come from a separate (usually corporate) repository.
A release is a version without the suffix (1.0.0). A published release is treated as immutable, and on Maven Central it can be neither overwritten nor deleted, so a fix is published as a new version (1.0.1).
3. What does the packaging element in pom.xml define, and how do jar, war and pom differ?
What does the packaging element in pom.xml define, and how do jar, war and pom differ?
<packaging> defines what artifact the build produces and therefore the default bindings of plugin goals to lifecycle phases (the lifecycle mapping). The element is optional: if it is missing, jar is used — the default value of the POM model itself.
- jar —
target/artifactId-version.jar, built by maven-jar-plugin in the package phase; console applications, libraries, Spring Boot applications. - war — a web archive with the content of
src/main/webapp(maven-war-plugin), deployed to Tomcat or another servlet container. - pom — only the pom.xml itself, no code and no jar: nothing is compiled or packaged. Used for parent POMs, aggregators of a multi-module project (the
<modules>list), BOMs and other projects that publish only a POM. - maven-plugin, ear, ejb — a Maven plugin, a Jakarta EE enterprise archive, an EJB module; special cases with their own plugins.
Because of this binding, changing packaging changes the whole build: set it to pom in a project with code, and mvn package ends with BUILD SUCCESS without compiling a single class.
4. How do properties and ${...} expressions work in pom.xml?
How do properties and ${...} expressions work in pom.xml?
<properties> stores name-value pairs that can be substituted with ${name} into many POM elements, such as dependency versions and plugin configuration. Some fields have restrictions: the <parent> coordinates must be literal values in Maven 3. Properties remove duplication (one version for several libraries, for example ${junit.version}) and pass parameters to plugins: maven.compiler.release is the Java version, project.build.sourceEncoding is the source encoding. In Maven 3.9.x, if it is not set or inherited, plugins may use the platform encoding and print a warning; since Maven 3.10.0 UTF-8 is set in the Super POM. A custom property can have any name that is a valid XML element name; dots are simply part of the name.
Built-in values: ${project.version}, ${project.groupId}, ${project.artifactId}, ${project.basedir}, ${project.build.directory}, ${project.build.finalName}; environment variables with the env. prefix (${env.JAVA_HOME}); JVM system properties (${java.version}, ${user.home}).
Overriding: mvn package -Djunit.version=5.12.0 — a value from -D wins over properties, and the file is not changed. The short forms ${pom.version} and ${version} are deprecated (warning is deprecated) — write ${project.version}.
A typo in ${...} does not always cause an immediate error: in a dependency version it is a model validation error (invalid version), in a filtered resource the expression may stay unreplaced, and in plugin configuration the outcome depends on the parameter and the plugin. The effective POM shows what expressions in the model resolved to.
5. What are parent, Super POM and effective POM in Maven, and how do you see the final project configuration?
What are parent, Super POM and effective POM in Maven, and how do you see the final project configuration?
Every pom.xml inherits settings from a parent, explicit or implicit.
- parent — an explicit parent POM with
packaging= pom. A child project references it by GAV in<parent>(by default the parent is looked up in../pom.xml) and inherits groupId, version, properties, dependencies and pluginManagement.artifactIdis not inherited: every module declares its own, otherwise modules would have identical coordinates. This is how multi-module projects and Spring Boot (spring-boot-starter-parent) work. - Super POM — the implicit parent of every project, built into Maven: the standard directories
src/main/javaandtarget, resources, finalName, the Maven Central repository. That is why a minimal pom.xml of a few lines can already build a project. But not every default comes from it: packaging = jar is a default of the POM model, and plugin bindings to phases come from the lifecycle mapping for the packaging. - Effective POM — the final model Maven builds after inheritance, profile activation and property interpolation: paths are absolute, properties are resolved, default plugin versions and inherited dependencies are visible. It is not every actual plugin execution parameter (defaults defined inside a plugin are not shown) and not the contents of filtered files.
To see it: mvn help:effective-pom; to save it to a file: mvn help:effective-pom -Doutput=effective-pom.xml. It is your main tool when you cannot tell where a setting comes from or why a property was not applied.