Coordinates, Dependencies, Repositories, Metadata, Transitivity, and Version Selection: Diagnostics, Failure Modes, Security, and Performance
Diagnose missing modules, metadata/artifact failures, version conflicts, cache masking, and repository-origin surprises using evidence before changing configuration or deleting state.
Learning objectives
- Apply a repeatable evidence-first sequence to dependency and repository failures.
- Differentiate coordinate-not-found, metadata failure, artifact-download failure, and version-conflict/runtime failure.
- Use isolated Maven/Gradle state to detect cache masking without deleting normal user caches.
- Diagnose repository-origin and ordering surprises from effective configuration instead of adding arbitrary repositories.
- Connect dependency-resolution performance to cold/warm state, metadata checks, and network/repository behavior without hiding correctness problems.
org.apache.commons:commons-text:1.10.0, whose published
POM declares org.apache.commons:commons-lang3:3.12.0,
plus a deliberate direct request for commons-lang3:3.9.
Re-check current versions and metadata before reusing these examples
in production.
1. Diagnostic sequence: preserve the resolver’s story before changing it
A dependency failure often tempts teams to delete caches, add repositories, or force a version. Those actions destroy evidence or widen the trust boundary. Start by capturing the exact command, wrapper/tool/JDK identity, first causal resolver message, declared/effective repository configuration, and current graph/insight output.
1. Preserve exact failing command + first causal error
2. Confirm ./mvnw -v or ./gradlew -version
3. Inspect declared/effective dependency + repository model
4. Inspect tree/dependencyInsight and requested vs selected versions
5. Classify failure: coordinate | metadata | artifact | auth/TLS | conflict | cache | runtime
6. Reproduce with a new isolated local repository/User Home if cache is suspect
7. Apply the smallest correction at the owning layer
8. Resolve/build again and verify graph + artifact identity
2. Failure A — wrong coordinate or wrong repository
Suppose the artifact ID is mistyped as commons-texxt.
The resolver may report that it cannot find the POM/artifact in the
configured repository. The first correction is the coordinate—not
adding JCenter, a random mirror, or disabling TLS checks.
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-texxt</artifactId>
<version>1.10.0</version>
</dependency>
dependencies {
implementation("org.apache.commons:commons-texxt:1.10.0")
}
Repair by restoring the canonical coordinate and rerun in the same isolated state. Preserve the original error in the lab record so the causal chain is visible.
3. Failure B — metadata resolves but artifact bytes fail
A repository can serve a POM or module metadata but fail when the resolver requests the JAR: incomplete proxy synchronization, authorization differences, storage corruption, or a broken hosted repository can cause this. Do not rewrite the version merely because the final file download failed.
| Observation | Likely layer | Next evidence |
|---|---|---|
| POM/module metadata 200; JAR 404 | repository content/synchronization | repository URL/origin + artifact path |
| metadata 401/403 | credentials/repository authorization | server/repository ID and secret-store mapping—never print credential |
| TLS/certificate failure | network/trust store/proxy | certificate chain + approved proxy configuration |
| checksum/verification mismatch | artifact integrity/origin | stop; compare expected metadata and repository origin; do not bypass |
4. Failure C — build compiles, runtime behavior changes after version mediation
Conflict resolution can produce a valid classpath that is
incompatible with one caller. For example, Gradle selecting a higher
transitive version may expose a binary/API behavior change; Maven
selecting a nearer older version may deprive another library of a
method it expects. The build file can look “valid” while runtime
throws NoSuchMethodError or
NoClassDefFoundError.
# Maven
./mvnw org.apache.maven.plugins:maven-dependency-plugin:3.10.0:tree -Dincludes=org.apache.commons:commons-lang3
# Gradle
./gradlew dependencyInsight --dependency commons-lang3 --configuration runtimeClasspath
Fix by choosing a compatible version intentionally—often by upgrading the requesting libraries together or applying managed/constraint policy—and run tests that exercise the affected runtime path. Do not treat “force whatever makes the error disappear” as a durable solution.
5. Failure D — local cache masks upstream removal or changed metadata
A warm machine can resolve from local state while a new CI agent fails. That discrepancy is evidence. Create a new disposable repository/home and repeat the exact model command. If the isolated run fails, you have proven the build depends on something not currently obtainable under the declared repository contract.
./mvnw -Dmaven.repo.local=.diag-m2 org.apache.maven.plugins:maven-dependency-plugin:3.10.0:tree
GRADLE_USER_HOME="$PWD/.diag-gradle-home" ./gradlew dependencies --configuration runtimeClasspath
~/.m2/repository, ~/.gradle/caches,
wrapper distributions, or organization-shared CI caches. Isolation
preserves evidence and prevents collateral damage.
6. Failure E — unexpected repository supplies the module
Repository sprawl can make origin surprising. In Maven, inspect effective settings/POMs and mirror application. In Gradle, inspect settings-level and project-level repositories plus content filters. A repository earlier in one lookup path can supply metadata that determines where artifact bytes are subsequently fetched.
./mvnw help:effective-settings -Doutput=effective-settings.xml
./mvnw help:effective-pom -Doutput=effective-pom.xml
# Review repository IDs/URLs and mirrors; do not print server passwords.
./gradlew dependencies --configuration runtimeClasspath --info
# Use --info only for a disposable/synthetic lab and review output before sharing.
# Never add --debug around real repository credentials without understanding leakage risk.
7. Performance: distinguish resolution work from build execution
A cold isolated resolver may spend most of its time on metadata and artifact downloads. A warm resolver can reuse cached immutable artifacts and metadata. Dynamic/changing versions add periodic metadata checks; shortening their TTL can increase network traffic. Repository managers/proxies can improve locality but introduce their own availability and policy dependencies.
| Timing component | What changes it | Correct optimization question |
|---|---|---|
| metadata lookup | repository count, dynamic versions, TTL, latency | can we reduce mutable discovery and repository sprawl? |
| artifact download | cold cache, artifact size, proxy/CDN | can governed proxy/cache serve immutable bytes closer? |
| graph computation | graph size, rules/constraints | is graph unnecessarily large/complex? |
| compile/test/package | not dependency resolution itself | optimize separately; do not attribute every slow build to downloads |
8. Security-sensitive corrections
-
Do not put repository tokens/passwords in POMs, Gradle build
scripts, committed
gradle.properties, or command history. - Do not bypass checksum/signature/dependency-verification failures to “unblock” CI.
- Do not add unreviewed public repositories or plugin repositories during incident response.
- Do not enable broad debug logging around real credentials without checking what the tool/plugin emits.
- When a repository credential may be exposed, rotate/revoke first; cache cleanup does not invalidate the credential.
9. Intentionally broken exercise — diagnose before repair
Change only the Maven or Gradle coordinate from
commons-text to commons-texxt. Predict the
failure layer. Run the graph command in isolated state. Capture the
first meaningful “could not find”/resolution message. Restore the
correct coordinate and rerun. Your evidence should show that no
repository was added and no global cache was deleted.
Knowledge check
A dependency works on a developer laptop but fails on a brand-new CI agent. What is the first useful hypothesis to test?
The warm machine may be relying on cached metadata/artifacts or different effective repository configuration. Compare tool/model identity and reproduce with isolated state.
Metadata is found but the JAR download fails. Why should you avoid immediately changing the version?
The selected module may be correct; the failure belongs to artifact availability, authorization, integrity, or repository origin. Changing version hides the real repository problem.
What does NoSuchMethodError after a dependency update often suggest?
A runtime binary/version mismatch: inspect the resolved runtime graph and selection reasons before changing code or caches.
Why is adding another public repository a security-sensitive change?
It expands the set of authorities allowed to supply build metadata/code and can create same-coordinate/dependency-confusion ambiguity.
Why is isolated cache testing superior to deleting ~/.m2 or ~/.gradle?
It preserves the original state for comparison, avoids collateral damage, and answers whether a clean resolver can reproduce the build.
Summary
Dependency failures become tractable when you preserve the resolver’s story: identity, effective repositories, graph requests, selection reason, cache state, and artifact origin. Correct the owning layer with the smallest change, then verify from isolated state. Cache deletion and repository sprawl are not diagnostic methods.
Official references and version notes
These lessons were finalized against current primary documentation on 2026-08-23. Dependency metadata, plugin versions, repository policies, Gradle resolution behavior, and Maven/Gradle releases are version-sensitive. Verify the exact tool versions and repository policy used by your project and CI before applying production controls.
- Apache Maven — Releases History
- Maven — Introduction to the Dependency Mechanism
- Maven — Setting up Multiple Repositories
- Maven — Using Mirrors for Repositories
- Apache Maven Dependency Plugin
- Gradle 9.7.1 — Dependency Resolution
- Gradle 9.7.1 — Graph Resolution
- Gradle 9.7.1 — Viewing and Debugging Dependencies
- Gradle 9.7.1 — Declaring Versions and Ranges
- Gradle 9.7.1 — Dependency Caching
- Maven Central — commons-text 1.10.0 metadata
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.
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0
Send only Ethereum/ERC-20 compatible assets to this
address.