Understanding Maven’s compile, provided, runtime, and test scopes
This article explains the four Maven dependency scopes—compile, provided, runtime, and test—by describing when each jar is available during development, testing, runtime, and packaging, illustrating each with concrete examples and a helpful movie‑production analogy.
1. compile (default)
Definition : Available in all phases and included in the final artifact.
When no <scope> tag is specified, Maven uses compile as the default.
Effective phases : compilation, unit testing, runtime; the jar is packaged into the final WAR/JAR.
Typical examples : spring-core, commons-lang3, fastjson —common libraries that the application code, tests, and runtime all need.
Movie analogy : The lead actors and core props appear in shooting, preview, and the final screening; they are always part of the final film.
2. provided
Definition : Needed for compilation and testing, but not required at runtime because the container supplies it; it is omitted from the packaged artifact.
Effective phases : compilation and testing only; excluded from runtime and final packaging.
Classic examples : servlet-api: required to compile Servlets, but Tomcat already provides it at runtime, so packaging it would cause class‑loading conflicts. Lombok: used only at compile time to generate boilerplate code; the generated classes run without Lombok.
Movie analogy : Temporary scaffolding or lighting rigs needed on set but never appear in the final cut; the theater already provides the projection equipment.
3. runtime
Definition : Not needed for compilation, but required when the application runs; therefore it must be packaged.
Effective phases : testing and runtime; excluded from compilation of main code; included in the final artifact.
Classic examples : mysql-connector-java: the JDBC API is part of the JDK, but the MySQL driver is only needed when the program connects to a MySQL database at runtime. logback-classic: code depends on the SLF4J API, while the concrete logging implementation is required only when the application actually logs.
Movie analogy : Special effects or subtitles that are unnecessary during shooting but must be present for preview and the final screening, and therefore are included in the final film.
4. test
Definition : Used exclusively for unit testing; never needed for compilation of main code, runtime, or packaging.
Effective phases : only during test execution; omitted from compilation of production code, runtime, and final artifact.
Typical examples : JUnit, Mockito —testing frameworks that are irrelevant to the production build.
Movie analogy : Screening tools and internal review notes used only during a private preview; they never appear in the version shown to the audience.
Comparison table
Dependency Scope | Compile? | Test? | Runtime? | Packaged? | Typical jars
-----------------|----------|-------|----------|-----------|--------------------------
compile (default)| ✅ | ✅ | ✅ | ✅ | Spring core, commons‑lang3
provided | ✅ | ✅ | ❌ | ❌ | servlet‑api, Lombok
runtime | ❌ | ✅ | ✅ | ✅ | mysql‑connector‑java, logback‑classic
test | ❌ | ✅ | ❌ | ❌ | JUnit, MockitoCommon pitfalls & how to avoid them
Confusing provided with runtime : Remember that provided means the runtime environment supplies the jar (e.g., servlet‑api from Tomcat), while runtime means you must bundle the jar yourself (e.g., database driver).
Setting servlet‑api to compile : Leads to duplicate classes at deployment, causing ClassCastException and startup failure. Solution: always mark servlet‑api and related web libraries as provided.
Marking MySQL driver as provided : Results in No suitable driver errors at startup. Solution: use runtime (or compile)—the industry convention prefers runtime.
Including test libraries in compile scope : Inflates the production package and may introduce security risks. Solution: declare all test‑only dependencies with test scope.
Mis‑setting essential tools as provided : If a required library is marked provided, it won’t be packaged, causing ClassNotFoundException in production. Rule of thumb: when unsure, keep it as compile.
Quick cheat‑sheet
compile: needed everywhere, packaged by default. provided: needed for compile & test, supplied by the runtime container, not packaged. runtime: not needed for compile, required at runtime, must be packaged. test: only for test execution, never packaged.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
CTO Full-Stack Academy
15 years of IT industry experience, sharing practical insights on pre-sales, product design, architecture, technology development, software testing, project management, IT consulting, and operations management.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
