Chapter 08Lesson 03~125 minutes

Maven Properties, Profiles, settings.xml, Mirrors, Proxies, Servers, and Environment-Specific Builds: Configuration, Design Choices, and Tradeoffs

Choose deliberately between explicit and automatic profiles, POM portability and settings-based infrastructure policy, narrow and broad mirror rules, and environment-variable versus settings-based credential handling.

Profile PolicyMirror ScopeCredentialsPortabilityTradeoffs

Learning objectives

  • Choose explicit profile activation over automatic activation when reproducibility and auditability outweigh convenience.
  • Decide which values belong in POM/project state and which belong in user/CI settings or secret injection.
  • Select mirror scopes intentionally and explain the consequences of central, external:*, *, and exclusions.
  • Compare environment variables, Maven server settings, and external secret injection without treating any one mechanism as universally safest.
  • Use a worked team scenario to justify choices through observable effective-model and repository behavior.
Current baseline — verified 2026-08-23. Labs use Maven 3.9.16 via Maven Wrapper 3.3.4, JDK 21 to run Maven, Java 17 as the compiler release target, Help Plugin 3.5.2, Dependency Plugin 3.11.0, Compiler Plugin 3.15.0, Resources Plugin 3.5.0, Surefire 3.5.6, and JAR Plugin 3.5.1. Lab resolution uses project-relative isolated local repositories. No normal ~/.m2, global settings, shared CI settings, or real credentials are modified.

1. Design question — what kind of difference is this?

Before choosing a property, profile, settings element, or CI variable, classify the variation. Is it project semantics (for example, enabling a documented optional build feature), tool/runtime policy (JDK/Maven versions), repository/network policy (mirror/proxy), identity/secrets (server credentials), or deployment runtime configuration that should not affect the build artifact at all?

Most brittle Maven estates started by solving all five with profiles. Avoid that collapse.

2. Explicit profile activation versus automatic environment activation

An explicit -Pci is visible in the command line and can be recorded in CI evidence. JDK, OS, property, or file-based activation can be appropriate when the condition itself is genuinely part of the build contract, but the cost is hidden branching: the same source command can build a different effective model on another machine.

Choice Maintainability Reproducibility Developer experience Recommended use
Explicit -Pfeature High visibility Strong when recorded Requires conscious selection Optional build features / deliberate variants.
JDK activation Compact Depends on runtime identity Automatic Narrow compatibility shims, with tests.
OS activation Can fork build logic Lower portability Convenient locally Only when OS-specific work is unavoidable.
Environment-property activation CI-friendly if documented Good when input is explicit Simple Policy selector, but record value.
File activation Hard to discover Weak across clean agents Convenient but fragile Avoid for core production behavior.

3. Settings infrastructure policy versus POM portability

A repository coordinate and dependency version are part of the project's supply-chain declaration. The credentials, corporate proxy, and routing through an approved repository manager are environment infrastructure. The POM may name a repository ID when necessary; settings can mirror that ID to the environment's endpoint.

Put in POM/project Put in settings/CI environment
Dependency/plugin coordinates and versions Repository credentials keyed by ID
Portable repository IDs when project truly needs a non-Central source Mirror URL/pattern and proxy routing
Build feature profile definitions User/global profile activation policy when environment-owned
Compiler/toolchain intent Actual installed JDK locations / CI image selection
Secret-free plugin/build configuration Secret values or references supplied by trusted runtime

4. Mirror policy breadth is a supply-chain decision

mirrorOf controls which declared repositories are replaced by a mirror. Maven's official mirror guide documents exact IDs, *, external:*, external:http:*, comma-separated lists, and ! exclusions. The first broad pattern that matches can determine the actual source.

Pattern What it catches Tradeoff
central Only Central Narrow and predictable; other declared repositories bypass it.
external:* Non-local/file external repositories Common centralized-control policy while preserving localhost/file test fixtures.
* All repository IDs Strong centralization but can unexpectedly capture local/test/special repositories.
*,!fixture Everything except one ID Useful when exception is explicit, reviewed, and stable.
Exact ID such as academy-remote One logical repository Best for a narrowly scoped lab or dedicated route.
Anti-pattern: widening mirrorOf until a failing build “works” changes artifact-source policy. Diagnose the intended repository IDs first.

5. Environment variables versus Maven settings credential storage

Both mechanisms can be used safely or unsafely. A literal password in a committed POM is clearly wrong. A literal password in a developer settings file is better separated from source but still sensitive local state. Maven supports encrypted server passwords; CI systems commonly inject secrets at runtime. Environment variables are convenient, but can leak through debug scripts, child processes, or accidental logging.

The production requirement is stronger than “use env vars”: secrets must be scoped, short-lived where possible, unavailable to untrusted jobs, never printed, and tied to the correct server ID. Maven's settings file can reference environment variables so the routing/identity mapping is inspectable without containing the secret value.

6. Properties are not a substitute for configuration ownership

A property is only a value transport mechanism. It does not decide whether a value belongs in the build. For example, -Ddatabase.password=... may technically interpolate into a plugin, but that does not make the command line a good secret store. Likewise, -Ddeployment.region=... can accidentally make artifact bytes environment-dependent if resource filtering consumes it.

Build-once principle: if a value only matters after deployment, prefer runtime configuration rather than building separate JAR bytes per environment. Use Maven profiles for build semantics, not as a universal application-configuration system.

7. Why activeByDefault can surprise teams

A profile marked activeByDefault is not a permanent baseline. Maven deactivates default-active profiles when another profile in the same POM becomes active through explicit or implicit activation. If a critical plugin/property lives only in the default profile, activating an unrelated profile can remove it. Put unconditional project policy outside profiles; use profiles only for actual conditional differences.

8. Global versus user settings

Global settings travel with the Maven installation or controlled build image; user settings belong to the invoking identity. Maven merges them with user settings dominant. This can be useful—developers can add credentials for a centrally defined mirror—but it also means a user setting can change effective behavior relative to the platform image. CI should therefore treat settings provisioning as versioned infrastructure policy and capture a non-secret policy identifier/hash.

9. Worked scenario — 40 services, three execution contexts

A team has 40 Maven services. Developers build on laptops, pull-request CI builds untrusted contributions, and release CI publishes trusted artifacts. All projects depend on public Central artifacts plus a private internal library.

Decision Selected approach Observable consequence
Maven/JDK version Committed wrapper + CI JDK image Same Maven runtime; JDK identity captured with -v.
Public dependency routing external:* mirror in managed settings External repositories flow through approved manager; local fixtures remain possible.
Private library identity Coordinate/repository ID in project/parent policy Dependency identity reviewable in source.
Developer credentials User settings / credential helper or injected secret No secret in POM; server ID maps to repository/mirror.
PR CI credentials None unless strictly required Untrusted code cannot exfiltrate release credentials.
Release credentials Short-lived CI secret injected only into trusted job Same POM, stronger identity context.
Build profile Explicit only when a build feature changes CI logs show deliberate model branch.
Deployment environment config Runtime platform, not Maven artifact profile Same promoted artifact across environments.

10. Decision table

Use this as a review heuristic, not a mechanical rule.

Question Prefer project/POM Prefer settings/CI
Does it define what source compiles/tests/packages? Yes Only if it is genuinely environment capability.
Does it identify dependency/plugin versions? Yes No.
Does it route traffic through a mirror/proxy? No Yes.
Does it contain authentication material? Never Yes, through protected/injected mechanism.
Would changing it alter artifact bytes? Only if intentional build semantics Avoid hidden environment change.
Must it differ by developer/agent identity? Usually no Usually yes.

11. Performance tradeoffs — keep causality clear

A repository manager/mirror may improve download locality and reduce upstream traffic, but a warm local repository can dominate observed timings. Measure cold resolution with an isolated repository separately from model construction, compilation, tests, and packaging. Do not attribute a faster second run to “profile optimization” if it merely reused cached artifacts.

Knowledge check

A release-region property changes only runtime deployment behavior. Should Maven build a separate JAR per region?

Why might external:* be safer than * for a team that runs localhost repository fixtures?

What is the main audit advantage of explicit -Pfeature?

Can environment variables leak even if they are not committed?

Why should unconditional plugin/version policy not live only in an activeByDefault profile?

12. Bridge to diagnostics

Good design reduces invisible variation, but production failures still happen. Lesson 4 uses the same boundaries to diagnose profile drift, mirror/proxy mistakes, server-ID authentication failures, cache masking, and secret exposure without changing multiple controls at once.

Official references and version notes

Version-sensitive statements in this lesson were checked against Apache Maven primary documentation on 2026-08-23. The mandatory path uses Maven 3.9.16 through Maven Wrapper 3.3.4, JDK 21 to run Maven, Java 17 as the project release target, Help Plugin 3.5.2, Dependency Plugin 3.11.0, Compiler Plugin 3.15.0, Resources Plugin 3.5.0, Surefire 3.5.6, and JAR Plugin 3.5.1. Maven 4-only profile syntax and preview behavior are not required here.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0 Send only Ethereum/ERC-20 compatible assets to this address.