在一个maven项目中,若是存在编译须要而发布不须要的jar包,能够用scope标签,值设为provided。以下:java
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
<classifier />
</dependency>web
scope的其余参数以下:api
compile
默认的scope,表示 dependency 均可以在生命周期中使用。并且,这些dependencies 会传递到依赖的项目中。适用于全部阶段,会随着项目一块儿发布
provided
跟compile类似,可是代表了dependency 由JDK或者容器提供,例如Servlet AP和一些Java EE APIs。这个scope 只能做用在编译和测试时,同时没有传递性。????????
runtime
表示dependency不做用在编译时,但会做用在运行和测试时,如JDBC驱动,适用运行和测试阶段。
test
表示dependency做用在测试时,不做用在运行时。 只在测试时使用,用于编译和运行测试代码。不会随项目发布。
system
跟provided 类似,可是在系统中要之外部JAR包的形式提供,maven不会在repository查找它。
---------------------
做者:daihui05
来源:CSDN
原文:https://blog.csdn.net/daihui05/article/details/7476976
版权声明:本文为博主原创文章,转载请附上博文连接!tomcat
问题再现:服务器
上次这边朋友问我一个问题,就是他们在pom.xml中的dependency中,看到有一些是<scope>provided</scope>的状况,好比以下:app
他们问我scope在何种状况下要设置为provided,以及和scope设置为compile的区别。webapp
解释:jsp
其实这个问题很简单。maven
对于scope=compile的状况(默认scope),也就是说这个项目在编译,测试,运行阶段都须要这个artifact对应的jar包在classpath中。ide
而对于scope=provided的状况,则能够认为这个provided是目标容器已经provide这个artifact。换句话说,它只影响到编译,测试阶段。在编译测试阶段,咱们须要这个artifact对应的jar包在classpath中,而在运行阶段,假定目标的容器(好比咱们这里的liferay容器)已经提供了这个jar包,因此无需咱们这个artifact对应的jar包了。
听起来很玄乎,对吧,其实一点也不难理解。举个scope=provided的例子。
好比说,假定咱们本身的项目ProjectABC 中有一个类叫C1,而这个C1中会import这个portal-impl的artifact中的类B1,那么在编译阶段,咱们确定须要这个B1,不然C1通不过编译,由于咱们的scope设置为provided了,因此编译阶段起做用,因此C1正确的经过了编译。测试阶段相似,故忽略。
那么最后咱们要吧ProjectABC部署到Liferay服务器上了,这时候,咱们到$liferay-tomcat-home\webapps\ROOT\WEB-INF\lib下发现,里面已经有了一个portal-impl.jar了,换句话说,容器已经提供了这个artifact对应的jar,因此,咱们在运行阶段,这个C1类直接能够用容器提供的portal-impl.jar中的B1类,而不会出任何问题。
实际插件的行为:
刚才咱们讲述的是理论部分,如今咱们看下,实际插件在运行时候,是如何来区别对待scope=compile和scope=provided的状况的。
作一个实验就能够很容易发现,当咱们用maven install生成最终的构件包ProjectABC.war后,在其下的WEB-INF/lib中,会包含咱们被标注为scope=compile的构件的jar包,而不会包含咱们被标注为scope=provided的构件的jar包。这也避免了此类构件当部署到目标容器后产生包依赖冲突。