在一個maven項目中,如果存在編譯需要而發布不需要的jar包,可以用scope標簽,值設為provided。如下:
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
<classifier />
</dependency>
scope的其他參數如下:
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
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
問題再現:
上次這邊朋友問我一個問題,就是他們在pom.xml中的dependency中,看到有一些是<scope>provided</scope>的情況,比如如下:
- <dependency>
- <groupId>com.liferay.portal</groupId>
- <artifactId>portal-impl</artifactId>
- <version>6.1.0</version>
- <scope>provided</scope>
- </dependency>
他們問我scope在何種情況下要設置為provided,以及和scope設置為compile的區別。
解釋:
其實這個問題很簡單。
對於scope=compile的情況(默認scope),也就是說這個項目在編譯,測試,運行階段都需要這個artifact對應的jar包在classpath中。
而對於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包。這也避免了此類構件當部署到目標容器后產生包依賴沖突。