What are Maven properties, and how do you define and reference a custom property in a pom.xml?
answer
- <properties> block = define once
- ${name} = interpolate
- project.* / settings.* / env.* built-ins
- -Dprop=val overrides
- inherited by children
basics
~10 sProperties 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 sMaven 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<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
Knows you set <properties> and reference with ${name} to avoid repeating versions.
Knows the built-in families (project., settings., env.*) and -D override.
Centralizes versions in a parent pom, understands precedence of -D over pom values.
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.