Maven dependency scopes defines the scope/boundary/availability of the dependency at various contexts like compile, test, and run. There are 6 scopes.

  • compile
    • Default scope of dependencies in Maven.
    • Available at compile time and runtime.
    • When preparing self-contained fat jar, dependencies with this scope are included.
  • provided
    • Available only at compile time
    • Generally JRE or container will provide the dependencies out of the box.
    • Example: Servlet API, which is provided by your Jakarta application server. It’s only added in pom.xml with provided scope so that your code resolves the lib’s API during development and testing in IDEs. However, idea is not to include dependencies with this scope in your artifact be it war or fat jar.
  • runtime
    • Available only at runtime, not available during compile time.
    • Dependency with this scope is available in test classpath, and runtime classpath as well.
    • When assembling, dependencies with this scope will be included in self-contained fat jar.
  • test
    • Only available for the test’s
      • Compilation
      • Execution phases.
    • Example:

        <!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-engine/ -->
        <dependency>
          <groupId>org.junit.jupiter</groupId>
          <artifactId>junit-jupiter-engine</artifactId>
          <version>x.x.x</version>
          <scope>test</scope>
        </dependency>
      
  • system
    • It’s just like adding an external jar as a dependency to your project during compile, test, and runtime
      • Think of it like adding dependency from file system to projects in Eclipse/Intellij/VsCode IDEs
    • Downside of having such dependencies in pom.xml results in setup issues for other developers, because the path may not be the same in their systems.
    • Example:

        <dependency>
          <groupId>xyz-groupid</groupId>
          <artifactId>xyz-artifactid</artifactId>
          <version>x.x.x</version>
          <scope>system</scope>
          <systemPath>./m2/local-repository/xyz.jar</systemPath>
        </dependency>
      
  • import
    • All the dependencies with this scope are of packaging type pom. Not jar
    • Example:
      • Reactor projects
      • Or projects having a parent pom.xml declared with pom as packaging type and child pom.xml having the parent pom.xml imported under <dependencyManagement> section or <parent> section

References:

  1. Maven Dependency Scopes
  2. Transitives dependencies scope for provided dependency