Maven Dependency Scopes: Deep Analysis of compile vs provided

Nov 20, 2025 · Programming · 25 views · 7.8

Keywords: Maven | Dependency Scope | compile scope | provided scope | JAR packaging | Dependency Transitivity

Abstract: This article provides an in-depth examination of the core differences between compile and provided dependency scopes in Maven. Through analysis of dependency transitivity, classpath availability, packaging behavior, and other key dimensions, it explains their distinct behaviors in JAR and WAR projects. Combining official documentation with practical examples, it clarifies the special用途 of provided dependencies in container environments to help developers configure project dependencies correctly.

Fundamental Concepts of Maven Dependency Scopes

In the Maven project management tool, dependency scopes define the availability of dependencies during different lifecycle phases. Among these, compile and provided are two common scopes that exhibit significant differences in project building and runtime behavior.

Detailed Analysis of compile Scope

compile is the default dependency scope in Maven. When no scope is explicitly specified, dependencies automatically adopt this scope. From a classpath perspective, compile dependencies are available in all project classpaths, including compilation classpath, test classpath, and runtime classpath.

Regarding dependency transitivity, compile dependencies possess full transitivity. This means if project A depends on project B, and project B declares a compile-scoped dependency C, project A will automatically inherit dependency C with compile scope. This transitive mechanism simplifies dependency management in multi-module projects.

Concerning packaging behavior, in JAR packaging scenarios, although dependencies themselves are not included in the final JAR file, compile dependencies require these dependencies to be available in the runtime classpath. For WAR projects, compile dependencies are packaged into the WEB-INF/lib directory, ensuring the web application can run properly.

Core Characteristics of provided Scope

The provided scope indicates that a dependency is required during compilation and testing phases, but is provided by the target environment at runtime. This design pattern is particularly suitable for container environments, such as Java EE application servers or Servlet containers.

In terms of classpath availability, provided dependencies are only available in the compilation classpath and test classpath, and do not appear in the runtime classpath. This restriction ensures no conflicts with identical dependencies provided by the container during deployment.

Dependency transitivity is an important limiting characteristic of the provided scope. Unlike compile dependencies, provided dependencies are not transitive. This means if project A depends on project B, and project B declares a provided-scoped dependency C, project A will not automatically inherit dependency C.

In packaging processing, provided dependencies are not included in any type of packaging file. Whether JAR or WAR packages, these dependencies are not packaged because they are expected to be provided by the runtime environment.

Practical Application Scenario Comparison

Consider the dependency configuration case for Servlet API. In web application development, Servlet API is needed during development for compilation, but is provided by the Servlet container (such as Tomcat) during deployment. Therefore, the correct configuration should be:

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>servlet-api</artifactId>
    <version>3.1.0</version>
    <scope>provided</scope>
</dependency>

This configuration avoids packaging Servlet API into the WAR file, preventing conflicts with the version provided by the container, while ensuring compilation and testing can proceed normally.

Another typical case is the use of Lombok library. As mentioned in the reference article, development teams often configure Lombok with provided scope because Lombok primarily functions through annotation processors during compilation and is not needed as a JAR file at runtime. This configuration can:

Impact Differences in JAR vs WAR Projects

Although the question mentions that dependency scope seems "unimportant" in JAR packaging, this understanding is actually inaccurate. In JAR projects, dependency scope still affects:

For WAR projects, the differences are more pronounced: compile dependencies are packaged into WEB-INF/lib, while provided dependencies are completely excluded from the WAR file.

Best Practice Recommendations

Based on deep understanding of both scopes, developers are recommended to:

  1. Carefully analyze whether dependencies are provided by the environment at runtime
  2. Consider the impact of dependency transitivity on multi-module projects
  3. Prioritize provided scope in container environments to avoid conflicts
  4. Regularly review dependency scope configurations to ensure alignment with project requirements

Proper use of dependency scopes not only optimizes project building but also improves deployment stability and runtime efficiency of applications. Through deep understanding of the core differences between compile and provided, developers can make more precise dependency management decisions.

Copyright Notice: All rights in this article are reserved by the operators of DevGex. Reasonable sharing and citation are welcome; any reproduction, excerpting, or re-publication without prior permission is prohibited.