For each Maven scope, on which classpaths (compile, test, runtime) is the dependency available?
answer
- compile = all three
- provided/system = compile+test, no runtime
- runtime = test+runtime, no compile
- test = test only
- import = no classpath, versions only
basics
~10 scompile: all three (compile, test, runtime). provided: compile and test only. runtime: test and runtime only. test: test only. system: compile and test only (like provided). import: none of them (it only manages versions).
solid answer
~40 sMaven exposes three classpaths and each scope maps to a subset. compile is the broadest: it is on the compile, test, and runtime classpaths. provided and system are on compile and test but excluded from runtime (the environment supplies them). runtime is the mirror image: excluded from compile, present on test and runtime. test is the narrowest among the real scopes: only on the test compile and execution classpath. import is special and is on none of the classpaths because it only contributes managed versions to dependencyManagement. Note that the test classpath effectively includes compile and provided/system as well, since tests need to compile and run your main code against the same APIs. You can confirm what landed where with mvn dependency:build-classpath or mvn dependency:tree.
code
bash · 2 linesmvn dependency:build-classpath -Dmdep.outputFile=cp.txt
mvn dependency:treego deeper
Recall the classpath membership for the common scopes (compile/test/runtime/provided).
Reproduce the full table including system and import and explain packaging/transitivity columns.
Use the mapping to choose minimal scopes and avoid leakage into the shipped artifact.
Teach the model and enforce it via dependency:analyze in CI to catch wrongly-scoped or unused dependencies.
## The three classpaths - **compile classpath** — jars visible when compiling `src/main/java`. - **test classpath** — jars visible when compiling and running `src/test/java` (this is a superset that also includes the main-code dependencies, since tests exercise main code). - **runtime classpath** — jars needed to actually run the packaged application. ## Mapping table | Scope | compile | test | runtime | packaged | transitive | |-------|:------:|:----:|:------:|:-------:|:--------:| | compile | YES | YES | YES | YES | YES | | provided | YES | YES | no | no | no | | runtime | no | YES | YES | YES | YES (narrowed) | | test | no | YES | no | no | no | | system | YES | YES | no | no | no | | import | n/a | n/a | n/a | n/a | n/a | Notes: - **compile** is the only scope on all three; it is also the default. - **provided** and **system** are identical in classpath terms (compile + test, not runtime); they differ only in *how the jar is found* (repository vs `<systemPath>`). - **runtime** is deliberately absent from compile so you cannot reference its classes directly in main source. - **test** never reaches main compile or runtime — perfect for JUnit/Mockito. - **import** is not a classpath scope at all; it only feeds `<dependencyManagement>`. ## Inspecting it ```bash # Print the runtime classpath that will be used mvn dependency:build-classpath -Dmdep.outputFile=cp.txt # Show the tree with scope annotations mvn dependency:tree ``` ## Common pitfalls - Putting JUnit at `compile` so it leaks into the shipped artifact — use `test`. - Putting the Servlet API at `compile`, causing duplicate-class conflicts in the container — use `provided`. - Expecting a `runtime` jar to be importable in main source — it is not on the compile classpath.
- Which scope appears on every classpath?compile — and it is the default, so omitting <scope> gives compile.
- Why does the test classpath also contain compile-scoped jars?Because tests compile and run against your main code, which itself needs its compile-scoped dependencies; the test classpath is effectively a superset.
Think of three doors (compile, test, runtime). compile holds a master key; provided/system can open compile and test; runtime can open test and runtime; test only opens the test door; import has no key at all — it just posts the version list on the wall.
saying these in an interview costs you the question
- Saying runtime dependencies are on the compile classpath.
- Saying test dependencies are available at runtime.
- Listing import as one of the classpath scopes.