scope
scope
is used to confine the scope of dependencies. It affects the state of maven project importing different packages under different stages of lifecycle.
There’re 6 kinds of scope: compile
, provided
, runtime
, test
, system
, import
.
compile
: default scope; scope towards project compile, test, runtime. A profound dependency. Usually included when packaging.provided
: This scope assumes the dependency would be provided by the JDK or containers of this application, e.g.servletAPI
:1
2
3
4
5
6<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
This dependency can affect compile, test, runtime lifecycle, but not packaged in final artifact.
runtime
: scope only in test and runtime; skipped compile. E.g. JDBC driver. It’s for runtime and test phases. Say there’s a web app that would need to access MySQL database in runtime. Code is based only on JDBC API, i.e. only JDBC API Jar is needed in compile time, and JDBC driver is needed only in runtime.test
: scope only in testing. e.g.JUnit
. This dependency would not be packaged in final artifact.1
2
3
4
5
6<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
execution
has to be defined under test scope
.
system
: ~ provided scope. Different: you should tell maven how to find this dependency by specifyingsystemPath
property. It’s purely based on local machine system. If you’re going to use a dependency that is not in maven repository, you can use this scope. Since systemPath would vary on different machines,systemPath
is poorly transplantable. It’s not recommended.1
2
3
4
5
6
7<dependency>
<groupId>javax.sql</groupId>
<artifactId>jdbc-stdext</artifactId>
<version>2.0</version>
<scope>system</scope>
<systemPath>${java.home}/lib/rt.jar</systemPath>
</dependency>import
: import dependency config from otherpom.xml
. It’s used only under<dependencyManagement>
.
transitive dependencies
e.g.1
maven-01 --> spring-test --> spring-core
then maven-01
transitively depend on spring-core
.
Transitive dependency would automatically download transitive dependencies to rid further jar dependencies problems. But it could cause dependency conflicts, e.g. different version dependencies.
exclusions
exclusion
under exclusions
is a way to rid dependency conflicts, reducing unnecessary transitive dependencies. e.g.1
2
3project --> ehcache --> (exclusion ❌) slf4j-api-1.2
|
----> slf4j-api-1.2
conflicts
Transitive dependency property would implicitly cause many jar dependencies version conflicts.
To solve this problem, read pom.xml
explicit and implicit dependency jar files. Find undesired dependencies and delete them.
2 Rules in conflicts:
- shortest path
- first declarence
Shortest path:1
2
3maven-01 -> spring-test -> spring-core -> commons-loggings-1.2 (d:3)
maven-01 -> maven-02 -> commons-loggings-1.1.1 (d:2) ✅
first declarence1
2
3
4
5maven-01->spring-test->spring-core
maven-01->maven-02->commons-logging-1.1.1 ✅
maven-01->maven-03->commons-logging-1.1.3