Profiles, properties and settings.xml

Maven · Practical · 10 min

CI servers, private repositories and environment-specific builds all rely on profiles and settings.

Properties are placeholders used throughout the POM: ${project.version}, ${project.basedir}, environment variables ${env.HOME}, system properties, and your own from <properties>. Override them from the command line with -Dname=value.

Profiles are blocks of POM configuration applied conditionally. A profile can add dependencies, plugins, properties and modules. Activate one:

  • Explicitly: mvn package -Pprod (or -P!prod to deactivate).
  • By property: <activation><property><name>env</name><value>ci</value></property></activation> matches -Denv=ci.
  • By JDK, OS, or a file's existence; or <activeByDefault>true</activeByDefault>, which is switched off as soon as any other profile is active (a common surprise).

mvn help:active-profiles lists what is active. Don't use profiles to produce different artifacts from the same version (a "prod jar" and a "dev jar" with the same coordinates); keep environment config outside the artifact.

settings.xml (~/.m2/settings.xml, or $MAVEN_HOME/conf globally) is personal and machine-specific, never committed:

  • <mirrors> redirect all repository traffic to a company proxy such as Nexus or Artifactory.
  • <servers> hold credentials for deploying or for private repositories, matched by <id>; encrypt passwords with mvn --encrypt-password.
  • <profiles> and <activeProfiles> for local defaults; <proxies> for HTTP proxies.

CI typically supplies a settings file with mvn -s ci-settings.xml and credentials from environment variables (${env.NEXUS_TOKEN}).

Example

<!-- pom.xml -->
<profiles>
  <profile>
    <id>ci</id>
    <activation>
      <property><name>env</name><value>ci</value></property>   <!-- mvn -Denv=ci -->
    </activation>
    <properties>
      <skipITs>false</skipITs>
    </properties>
  </profile>
  <profile>
    <id>jdk-preview</id>
    <activation><jdk>[25,)</jdk></activation>
    <properties><maven.compiler.enablePreview>true</maven.compiler.enablePreview></properties>
  </profile>
</profiles>
<!-- ~/.m2/settings.xml (not committed) -->
<settings>
  <mirrors>
    <mirror>
      <id>nexus</id>
      <mirrorOf>*</mirrorOf>
      <url>https://nexus.acme.com/repository/maven-public/</url>
    </mirror>
  </mirrors>
  <servers>
    <server><id>nexus</id><username>ci</username><password>${env.NEXUS_TOKEN}</password></server>
  </servers>
</settings>
<!-- mvn verify -Pci        mvn help:active-profiles -->

Remember

  • Properties parameterize the POM; override with -Dname=value
  • Profiles add configuration conditionally (-P, properties, JDK, OS)
  • activeByDefault switches off when another profile is active
  • settings.xml holds mirrors and credentials and stays uncommitted

Watch out for

  • Baking environment-specific values into the artifact through profiles, producing jars that differ by build machine.

Check yourself

  1. A profile is activeByDefault. You run mvn package -Pci. Is the default profile still active?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: maven.apache.org/guides/introduction/introduction-to-profiles.html