有時候用mvn install
后,新改的內(nèi)容不生效,一定要后來使用mvn clean install 才生效,由于之前沒有做記錄,以及記不清是什么情況下才會出現(xiàn)的問題,于是想看看clean和不clean的區(qū)別。
就如大家知道的,maven在執(zhí)行一個生命周期的命令的是時候?qū)?zhí)行之前的所有生命周期操作,比如執(zhí)行mvn install,會執(zhí)行前面一系列的動作包括 compile ,package , test 等,具體請查看maven的官方文檔。這個特性使maven的命令更加簡潔易用。
再來分析原來的問題,為什么修改的內(nèi)容不生效,肯定是最終打出來的war包中的內(nèi)容沒有更新,而war包中會依賴其他子工程的jar包,如果jar 包沒有更新過,那war包調(diào)用老的jar包也會導(dǎo)致新內(nèi)容不生效。定位到問題的原因應(yīng)該是jar包沒有用最新的資源(java或者配置文件),那jar包 又是什么時候,誰去打的呢。
上面我們提到我們執(zhí)行mvn install的時候會先執(zhí)行mvn package,maven就是通過這個生命周期來根據(jù)用戶配置,進(jìn)行打包(war、jar或者其他),這會在每個工程 pom.xml 文件中設(shè)置,類似如下:
1
2
3
4
5
6
7
8
9
10
|
<project xmlns= "http://maven.apache.org/POM/4.0.0" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http: //maven.apache.org/POM/4.0.0 http: //maven.apache.org/xsd/maven-4.0.0.xsd"> ... <packaging>war</packaging> ... </project> |
這里指定package的時候打成一個war包,改成jar,就會被打成jar包。
我們看jar形式的情況,mvn package 會調(diào)用 maven-jar-plugin 這個插件進(jìn)行打包。
下面我們做一些實(shí)驗(yàn)來看這個插件打包的時候的情況
1. 修改target目錄下打好的jar包中class以及配置文件的內(nèi)容,在運(yùn)行命令mvn package
,結(jié)果target包中的內(nèi)容沒有被覆蓋。
2. 修改源代碼中的內(nèi)容,再運(yùn)行命令mvn package
,結(jié)果target包中的內(nèi)容被覆蓋了,產(chǎn)生了新的包。
3. 修改target目錄下打好的jar包中的內(nèi)容,運(yùn)行命令mvn package -Djar.forceCreation
,這個參數(shù)應(yīng)該是強(qiáng)制創(chuàng)建jar包,所以結(jié)果target中的jar包內(nèi)容被覆蓋了,產(chǎn)生了新的jar包。
根據(jù)上面的實(shí)驗(yàn)好像還是不能解釋什么時候應(yīng)該用clean將target下面的內(nèi)容刪除重新生成,jar包,不過至少是明白了一些規(guī)則。
下面我們還是去看看maven-jar-plugin
的源碼吧。
之前,我提一點(diǎn),maven的debugg信息非常完備,需要查看debug信息只要在命令后面添加 -X 參數(shù)即可,如:
mvn clean package -X
就能看到非常豐富的DEBUG信息。
回來,我們發(fā)現(xiàn)org.codehaus.plexus.archiver.AbstractArchiver
中的關(guān)鍵一段,用來判斷是否強(qiáng)制新建jar
1
2
3
4
5
6
7
8
9
10
|
protected boolean checkForced() throws ArchiverException { if ( !isForced() && isSupportingForced() && isUptodate() ) { getLogger().debug( "Archive " + getDestFile() + " is uptodate." ); return false ; } return true ; } |
這個方法是校驗(yàn)是否強(qiáng)制重新創(chuàng)建jar包,只有當(dāng)
1. 沒有將 jar.forceCreation 參數(shù)設(shè)為true
2. 并且支持強(qiáng)制設(shè)置
3. up to date,意思就是被認(rèn)為是最新的內(nèi)容,沒有改動
這個時候maven不進(jìn)行新包的生成直接返回。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
protected void execute() throws ArchiverException, IOException { if ( ! checkForced() ) { return ; } if ( doubleFilePass ) { skipWriting = true ; createArchiveMain(); skipWriting = false ; createArchiveMain(); } else { createArchiveMain(); } finalizeZipOutputStream( zOut ); } |
所以除了那個強(qiáng)制的參數(shù)以外,就是看什么時候 isUptodate 為true,查看關(guān)鍵代碼:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
|
protected boolean isUptodate() throws ArchiverException { final File zipFile = getDestFile(); final long destTimestamp = zipFile.lastModified(); if ( destTimestamp == 0 ) { getLogger().debug( "isUp2date: false (Destination " + zipFile.getPath() + " not found.)" ); return false ; // File doesn't yet exist } final Iterator it = resources.iterator(); if ( !it.hasNext() ) { getLogger().debug( "isUp2date: false (No input files.)" ); return false ; // No timestamp to compare } while ( it.hasNext() ) { final Object o = it.next(); final long l; if ( o instanceof ArchiveEntry ) { l = ( (ArchiveEntry) o ).getResource() .getLastModified(); } else if ( o instanceof PlexusIoResourceCollection ) { try { l = ( (PlexusIoResourceCollection) o ).getLastModified(); } catch ( final IOException e ) { throw new ArchiverException( e.getMessage(), e ); } } else { throw new IllegalStateException( "Invalid object type: " + o.getClass() .getName() ); } if ( l == PlexusIoResource.UNKNOWN_MODIFICATION_DATE ) { // Don't know what to do. Safe thing is to assume not up2date. getLogger().debug( "isUp2date: false (Resource with unknown modification date found.)" ); return false ; } if ( l > destTimestamp ) { getLogger().debug( "isUp2date: false (Resource with newer modification date found.)" ); return false ; } } getLogger().debug( "isUp2date: true" ); return true ; } |
代碼中提到有這么幾個情況,會認(rèn)為jar包不是最新的:
1. jar包不存在(其實(shí)就是mvn clean的效果)
2. 傳入比較的文件資源不存在
3. Resource with unknown modification date found,資源的修改時間未知
4. Resource with newer modification date found,jar包的最后修改時間比資源的最后修改時間早
總結(jié)
1. 理論上來講不做mvn clean 得到的jar包應(yīng)該是最新的,除非其他方式修改jar包中的內(nèi)容而不修改源代碼。
2. 平時可以用mvn install,而不進(jìn)行chean節(jié)省時間(如果你覺得節(jié)省時間多的話),但最保險還是用 mvn clean install 生成最新的jar包或其他包
3. 不想用mvn clean又想保證jar包最新,建議添加-Djar.forceCreation
參數(shù)
4. 由maven的生命周期可知,當(dāng)使用deploy時同樣會有clean與不用clean的區(qū)別, 因此為了保險起見,建議package,install,deploy前均先clean
jar-plugin源代碼地址:http://svn.apache.org/repos/asf/maven/plugins/tags/maven-jar-plugin-2.4
到此這篇關(guān)于maven 在執(zhí)行package,install,deploy時使用clean與不使用clean的區(qū)別的文章就介紹到這了,更多相關(guān)maven 執(zhí)行package,install,deploy內(nèi)容請搜索服務(wù)器之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持服務(wù)器之家!
原文鏈接:https://www.cnblogs.com/kexianting/p/11459671.html