Chapter 08Lesson 04~150 minutes

Maven Properties, Profiles, settings.xml, Mirrors, Proxies, Servers, and Environment-Specific Builds: Diagnostics, Failure Modes, Security, and Performance

Diagnose environment drift from evidence: unexpected profile activation, over-broad mirrors, mirror/server ID mismatches, proxy failures, leaked secrets, command-line overrides, and warm-cache masking.

Diagnostics401 FailureProxy & MirrorSecret HygieneCache Masking

Learning objectives

  • Apply a fixed evidence-first sequence to profile/settings/repository failures.
  • Diagnose an unexpected profile, an over-broad mirror, a proxy/mirror transport error, and a CLI property override without guessing.
  • Reproduce a mirror/server-ID authentication failure in a fresh isolated repository and repair only the ID mapping.
  • Explain how warm caches can hide upstream removal, authentication, or routing problems.
  • Protect credentials during effective-settings and debug-log collection.
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.
Cross-platform note: POSIX examples use ./mvnw, grep, sha256sum, and shell environment variables. On Windows use mvnw.cmd, Select-String, Get-FileHash, and $env:NAME. Maven profile/settings semantics are cross-platform; file paths and shell quoting are not.

1. Diagnostic sequence — preserve the original cause

Use one sequence repeatedly:

  1. Preserve concise evidence and exact command.
  2. Confirm wrapper, Maven, and JDK identity.
  3. Inspect declared POM and effective POM/settings.
  4. List active profiles and evaluate the suspect property.
  5. Inspect dependency/repository IDs and mirror/proxy/server mapping.
  6. Reproduce with an isolated local repository if cache state is suspect.
  7. Interpret the first relevant transport/model/plugin error.
  8. Change one control only.
  9. Rebuild from controlled state and compare evidence.

This prevents a settings incident from turning into a dependency-version change, cache purge, repository expansion, and credential rewrite all at once.

2. Failure mode — a profile activates unexpectedly on CI

Symptoms may include a changed property, repository, dependency, or plugin execution even though the POM diff looks unrelated. Do not immediately disable profiles globally. Capture activation evidence:

HELP=org.apache.maven.plugins:maven-help-plugin:3.5.2
./mvnw "$HELP:active-profiles" -Doutput=evidence/active-profiles.txt
./mvnw "$HELP:effective-pom" -Dverbose -Doutput=evidence/effective-pom.xml
./mvnw "$HELP:evaluate" -Dexpression=academy.environment -q -DforceStdout

Then inspect whether activation came from -P, settings activeProfiles, JDK/OS/property/file activation, or activeByDefault. The fix is to make the intended condition explicit—not to delete every profile.

3. Failure mode — mirrorOf captures more than intended

A mirror of * can intercept a repository that was supposed to remain localhost/file-based. A pattern typo such as whitespace in a comma-separated expression can also produce surprising matching. Inspect the effective settings and the repository IDs named by the effective POM.

./mvnw org.apache.maven.plugins:maven-help-plugin:3.5.2:effective-settings   -Doutput=evidence/effective-settings.xml
./mvnw org.apache.maven.plugins:maven-help-plugin:3.5.2:effective-pom   -Dverbose -Doutput=evidence/effective-pom.xml
grep -nE '<mirror>|<mirrorOf>|<repository>|<id>|<url>'   evidence/effective-settings.xml evidence/effective-pom.xml

Do not “fix” this by adding another public repository. Tighten the mirror expression to the intended IDs or explicitly reviewed exclusions.

4. Intentionally broken example — mirror/server ID mismatch

Reuse Lesson 2's localhost authenticated repository. Keep the server running and create the intentionally broken settings below. The credentials are correct but attached to academy-remote; Maven is actually connecting as mirror academy-mirror.

<settings xmlns="http://maven.apache.org/SETTINGS/1.2.0"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.2.0 https://maven.apache.org/xsd/settings-1.2.0.xsd">
  <mirrors>
    <mirror>
      <id>academy-mirror</id>
      <url>http://127.0.0.1:18080/</url>
      <mirrorOf>academy-remote</mirrorOf>
    </mirror>
  </mirrors>
  <servers>
    <!-- Intentionally wrong: credentials are keyed to the original repository ID,
         but Maven authenticates to the selected mirror using the mirror ID. -->
    <server>
      <id>academy-remote</id>
      <username>${env.ACADEMY_REPO_USER}</username>
      <password>${env.ACADEMY_REPO_PASSWORD}</password>
    </server>
  </servers>
</settings>
export REPO_BROKEN="$PWD/.lab-m2-broken/repository"
rm -rf "$PWD/.lab-m2-broken"  # disposable lab state only
mkdir -p "$REPO_BROKEN" evidence
set -o pipefail
./mvnw -s lab/settings-broken.xml -Dmaven.repo.local="$REPO_BROKEN"   clean package 2>&1 | tee evidence/broken-server-id.log

Expected evidence is an authentication/401-style transfer failure for the mirrored localhost endpoint. Do not hide it with || true. The failure proves transport reached the expected mirror but did not receive credentials keyed to that mirror ID.

Why an empty repository matters: if academy-fixture:1.0.0 were already cached, Maven might not contact the mirror and the broken credential mapping could remain invisible.

5. Repair the identity mapping, not the dependency

Change only the <server><id> to academy-mirror, or restore settings-good.xml. Keep the same POM coordinates, dependency version, mirror URL, username, and password. Re-run with another fresh isolated repository.

export REPO_REPAIRED="$PWD/.lab-m2-repaired/repository"
mkdir -p "$REPO_REPAIRED"
set -o pipefail
./mvnw -s lab/settings-good.xml -Dmaven.repo.local="$REPO_REPAIRED"   clean package 2>&1 | tee evidence/repaired-server-id.log

find "$REPO_REPAIRED/dev/academy/fixture/academy-fixture/1.0.0"   -maxdepth 1 -type f -print

The success is meaningful because only the identity mapping changed. If the “repair” also changed repository URLs, dependency versions, or cache contents, the root cause would remain ambiguous.

6. Failure mode — proxy or mirror creates misleading resolution errors

Common signals include connection refused, DNS failure, TLS failure, 401/403, or 407 proxy authentication. Interpret the transport layer before changing Maven coordinates. Confirm whether the failing URL is the declared repository, a mirror, or a proxy hop.

Evidence Likely layer First check
401/403 from mirror URL Server credentials / authorization Mirror ID ↔ server ID and credential scope.
407 Proxy authentication Active proxy ID/credentials/nonProxyHosts.
TLS/certificate failure Transport/trust store/proxy interception JDK trust/runtime + approved endpoint, not dependency version.
DNS/connection refused Network/endpoint Effective mirror/proxy URL and local fixture process.
Artifact not found (404) Coordinate/repository content Dependency tree and repository content after routing verified.

7. Failure mode — a secret is committed or printed

Stop treating the build log as harmless. Effective settings hide passwords by default, but shell scripts can echo environment variables and debug logs can expose sensitive context. If a real credential was committed or printed, rotation/revocation is an incident-response action outside the build fix; deleting the Git line is not sufficient.

git grep -nE '(BEGIN [A-Z ]*PRIVATE KEY|AKIA[0-9A-Z]{16}|<password>[^$<])' -- . || true

grep -R -nF --exclude-dir=.git --exclude-dir=.lab-m2   "$ACADEMY_REPO_PASSWORD" evidence .   && echo "Unexpected: disposable secret appeared in files"   || echo "PASS: disposable secret not found in captured files"
Do not print the secret itself as part of diagnostics. Search for its value programmatically and report only pass/fail. If a real secret leaked, rotate it through the owning system.

8. Failure mode — command-line property silently overrides intended value

A CI template may append -D flags far from the project repository. Capture the exact invocation and evaluate the value under that invocation:

HELP=org.apache.maven.plugins:maven-help-plugin:3.5.2
./mvnw -s lab/settings-good.xml -Pdev "$HELP:evaluate"   -Dexpression=academy.channel -q -DforceStdout
./mvnw -s lab/settings-good.xml -Pdev "$HELP:evaluate"   -Dexpression=academy.channel -Dacademy.channel=unexpected-ci-value   -q -DforceStdout

The second command should report the CLI value. Fix the CI/template input if that override is unintended; editing the POM default will not beat a higher-precedence invocation property.

9. Failure mode — local cache masks upstream failure

Never begin by deleting normal user state. Create .lab-m2-diagnostic/repository and reproduce there. If warm succeeds and isolated fails, you have learned something concrete: the build depends on local cached state or the current remote route is unavailable. Preserve both outcomes.

10. Performance — separate resolution from compilation/tests

Mirror/proxy changes primarily affect network resolution. Warm-cache builds may show almost no network time. Compare cold versus warm resolution, then separately measure model construction, compilation, tests, and packaging. A slow proxy should not trigger a compiler tuning change.

11. Compact failure playbook

Symptom Evidence Narrow correction
Unexpected profile active-profiles + effective POM Fix activation source/condition.
Wrong mirror selected effective settings + repository IDs Narrow/reorder mirror rule.
401 at mirror mirror ID + server IDs Match server credential ID to selected mirror.
407 proxy auth effective proxy config Correct proxy identity/credential source.
Only warm cache works warm vs isolated repo Restore remote policy/source; do not bless cache as source of truth.
Property differs only in CI exact command + help:evaluate Remove/record unintended -D override.
Secret in log/repo secret scan / incident evidence Rotate/revoke, then remove exposure path.

Knowledge check

Why does the broken mirror/server lab use an empty local repository?

A build gets HTTP 401 from academy-mirror. What should you inspect before changing the dependency version?

What does a successful warm-cache build prove about current upstream availability?

Why is enabling password display in effective settings a poor default diagnostic step?

A CI-only -D value changes behavior. Where is the root cause?

12. Bridge to checkpoint

The diagnostic method now has one job left: integrate the controls. Lesson 5 builds dev and CI variants from the same project, records effective state, proves dependency identity, breaks authentication by ID only, repairs it, and audits evidence for secret leakage.

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.