What problem does dependency:go-offline solve, and when would you use it in a build pipeline?
answer
- pre-download deps + plugins
- populate .m2
- Docker layer cache on pom
- then build with -o
- best-effort, ranges/SNAPSHOT leak
basics
~20 smvn dependency:go-offline pre-downloads every dependency and plugin your build needs into the local .m2 repository, so a later build can run with -o (offline) without hitting the network — ideal for Docker layer caching and air-gapped CI.
solid answer
~40 s`dependency:go-offline` resolves and downloads all artifacts required to build the project fully offline: project dependencies (all scopes), plugin dependencies, and the plugins themselves, populating the local repository (`~/.m2/repository`). The classic use is Docker build caching: you `COPY` only the pom, run `go-offline`, and that layer is cached as long as the pom is unchanged — then copying source and compiling reuses the warm cache, so source changes don't re-download the world. It's also used to prime air-gapped or network-restricted CI agents before running the real build with `mvn -o`. Caveat: it isn't perfect — plugins that resolve dependencies dynamically at runtime, or version ranges/SNAPSHOTs, can still trigger downloads later, so 'fully offline' is a best-effort guarantee.
code
bash · 1 linemvn -B dependency:go-offline && mvn -B -o packagego deeper
Knows it pre-downloads dependencies into .m2 for offline use.
Applies the Docker caching pattern and follows it with mvn -o.
Understands the best-effort caveats (dynamic plugins, ranges/SNAPSHOTs) and designs caching around them.
Architects org build-cache/air-gap strategy and chooses between go-offline, repo mirrors, and shared cache mounts.
## The problem Maven downloads dependencies and plugins on demand during a build. In CI and especially Docker, this means every build can re-fetch from remote repositories — slow and flaky, and impossible on air-gapped machines. ## go-offline `mvn dependency:go-offline` (the `go-offline` goal) eagerly resolves and downloads **everything the build will need**: - all project dependencies across scopes - the build plugins themselves - those plugins' own dependencies All of it lands in the **local repository** (`~/.m2/repository`). Afterward you can run the build with `mvn -o` (offline) and it should not need the network. ## Primary use cases 1. **Docker layer caching** — the canonical pattern: ```dockerfile COPY pom.xml . RUN mvn -B dependency:go-offline COPY src ./src RUN mvn -B -o package ``` The `go-offline` layer is keyed on `pom.xml`; as long as the pom doesn't change, Docker reuses the cached layer with all dependencies, so editing source code doesn't re-download anything. 2. **Air-gapped / restricted CI** — prime the local repo on a connected machine or earlier stage, then build offline. ## Caveats - It is **best-effort**. Some plugins resolve artifacts dynamically during execution (not declared statically), so they can still hit the network later. - **Version ranges** and **SNAPSHOT** dependencies may re-check remotes for updates. - Multi-module reactors: run at the aggregator with `-pl`/`-am` considerations so all modules are primed. ## Related - `-o` / `--offline` forces offline mode for any goal. - `-Dmaven.repo.local=...` points at an alternate local repo location (useful for cache mounts).
- Why pair go-offline with the Docker COPY pom step?So the download layer is cached against the pom only; source-code changes invalidate later layers but not the dependency layer, avoiding re-downloads on every build.
- Why is go-offline not a 100% guarantee of offline builds?Some plugins resolve artifacts dynamically at runtime, and version ranges/SNAPSHOTs may re-check remote repositories, so later goals can still attempt downloads.
Like grocery shopping for the whole week before a snowstorm so you never have to leave the house mid-recipe.
saying these in an interview costs you the question
- Claiming it guarantees a fully offline build in all cases
- Confusing go-offline (downloads) with -o/--offline (forbids network)
- Putting go-offline after copying source, defeating the cache