skip to content

What are Maven properties, and how do you define and reference a custom property in a pom.xml?

level: juniorimportance: must knowfreq 70%

answer

  1. <properties> block = define once
  2. ${name} = interpolate
  3. project.* / settings.* / env.* built-ins
  4. -Dprop=val overrides
  5. inherited by children

basics

~10 s

Properties are named placeholders you set under <properties> in the pom and reference with ${name}. They let you avoid repeating values like version numbers in one central place.

solid answer

~30 s

Maven properties are key/value variables that get substituted (interpolated) wherever you write ${propertyName}. You declare your own under the <properties> element of the pom, typically to centralize version numbers or config so they are defined once. Maven resolves ${...} during the build by replacing the token with the property value. Beyond user-defined ones, Maven exposes built-in properties: project.* (e.g. ${project.version}, ${project.build.directory}), settings.* from settings.xml, env.* for environment variables, and JVM system properties. A common pattern is a property like <java.version>21</java.version> referenced by the compiler plugin. Properties are inherited by child modules and can be overridden on the command line with -D.

code

xml · 12 lines
xml
<properties>
  <java.version>21</java.version>
  <spring.version>6.1.0</spring.version>
</properties>

<dependencies>
  <dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-core</artifactId>
    <version>${spring.version}</version>
  </dependency>
</dependencies>

go deeper

for a junior

Knows you set <properties> and reference with ${name} to avoid repeating versions.

for a middle

Knows the built-in families (project., settings., env.*) and -D override.

for a senior

Centralizes versions in a parent pom, understands precedence of -D over pom values.

for a principal

Establishes org-wide conventions: parent BOM/property governance so version drift across modules is impossible.

## What a property is A Maven **property** is a named value — like a variable — that Maven substitutes into the build wherever you write the token `${propertyName}`. This substitution is called **interpolation**. Properties exist to remove duplication: instead of writing the same version string in five places, you write it once and reference it. ## Defining your own User-defined properties live in the `<properties>` block of the pom: ```xml <properties> <java.version>21</java.version> <spring.version>6.1.0</spring.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> ``` The element name *is* the property name. `<spring.version>` becomes `${spring.version}`. Dots in the name are just part of the name, not navigation. ## Referencing Anywhere a value is expected you can interpolate: ```xml <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${spring.version}</version> </dependency> ``` ## Built-in property families Maven supplies properties you did not define: - **project.\*** — reads from the POM's effective model: `${project.version}`, `${project.artifactId}`, `${project.groupId}`, `${project.basedir}`, `${project.build.directory}` (usually `target`), `${project.build.finalName}`. - **settings.\*** — values from `settings.xml`, e.g. `${settings.localRepository}`. - **env.\*** — operating-system environment variables, e.g. `${env.JAVA_HOME}`, `${env.PATH}`. - **System properties** — JVM `-D` flags and JVM-defined ones such as `${java.version}` (the runtime's version) and `${user.home}`. ## Overriding from the command line Any property can be supplied or overridden with `-D`: ```bash mvn -Dspring.version=6.2.0 package ``` A `-D` value wins over the pom-declared one for that build. ## Inheritance Properties defined in a parent pom are inherited by child modules, so a multi-module build can centralize all versions in the parent (the basis of dependency/version management).

  • How do you override a property without editing the pom?
    Pass it on the command line as a system property: mvn -Dspring.version=6.2.0 package. It takes precedence for that build.
  • Does ${project.version} require you to declare anything?
    No. project.* is a built-in family resolved from the effective POM model; you never define it under <properties>.

Like a constant at the top of a config file: change it in one place and every reference updates.

saying these in an interview costs you the question

  • Thinking dotted names like spring.version are nested objects rather than a single flat key.
  • Believing you must declare project.* or env.* properties yourself.

context