maven 在執(zhí)行package,install,deploy時使用clean與不使用clean的不同之處
有時候用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包也會導致新內(nèi)容不生效。定位到問題的原因應該是jar包沒有用最新的資源(java或者配置文件),那jar包 又是什么時候,誰去打的呢。
上面我們提到我們執(zhí)行mvn install的時候會先執(zhí)行mvn package,maven就是通過這個生命周期來根據(jù)用戶配置,進行打包(war、jar或者其他),這會在每個工程 pom.xml 文件中設置,類似如下:
<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 這個插件進行打包。
下面我們做一些實驗來看這個插件打包的時候的情況
1. 修改target目錄下打好的jar包中class以及配置文件的內(nèi)容,在運行命令mvn package
,結(jié)果target包中的內(nèi)容沒有被覆蓋。
2. 修改源代碼中的內(nèi)容,再運行命令mvn package
,結(jié)果target包中的內(nèi)容被覆蓋了,產(chǎn)生了新的包。
3. 修改target目錄下打好的jar包中的內(nèi)容,運行命令mvn package -Djar.forceCreation
,這個參數(shù)應該是強制創(chuàng)建jar包,所以結(jié)果target中的jar包內(nèi)容被覆蓋了,產(chǎn)生了新的jar包。
根據(jù)上面的實驗好像還是不能解釋什么時候應該用clean將target下面的內(nèi)容刪除重新生成,jar包,不過至少是明白了一些規(guī)則。
下面我們還是去看看maven-jar-plugin
的源碼吧。
之前,我提一點,maven的debugg信息非常完備,需要查看debug信息只要在命令后面添加 -X 參數(shù)即可,如:
mvn clean package -X
就能看到非常豐富的DEBUG信息。
回來,我們發(fā)現(xiàn)org.codehaus.plexus.archiver.AbstractArchiver
中的關鍵一段,用來判斷是否強制新建jar
protected boolean checkForced() throws ArchiverException { if ( !isForced() && isSupportingForced() && isUptodate() ) { getLogger().debug( "Archive " + getDestFile() + " is uptodate." ); return false; } return true; }
這個方法是校驗是否強制重新創(chuàng)建jar包,只有當
1. 沒有將 jar.forceCreation 參數(shù)設為true
2. 并且支持強制設置
3. up to date,意思就是被認為是最新的內(nèi)容,沒有改動
這個時候maven不進行新包的生成直接返回。
protected void execute() throws ArchiverException, IOException { if ( ! checkForced() ) { return; } if ( doubleFilePass ) { skipWriting = true; createArchiveMain(); skipWriting = false; createArchiveMain(); } else { createArchiveMain(); } finalizeZipOutputStream( zOut ); }
所以除了那個強制的參數(shù)以外,就是看什么時候 isUptodate 為true,查看關鍵代碼:
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; }
代碼中提到有這么幾個情況,會認為jar包不是最新的:
1. jar包不存在(其實就是mvn clean的效果)
2. 傳入比較的文件資源不存在
3. Resource with unknown modification date found,資源的修改時間未知
4. Resource with newer modification date found,jar包的最后修改時間比資源的最后修改時間早
總結(jié)
1. 理論上來講不做mvn clean 得到的jar包應該是最新的,除非其他方式修改jar包中的內(nèi)容而不修改源代碼。
2. 平時可以用mvn install,而不進行chean節(jié)省時間(如果你覺得節(jié)省時間多的話),但最保險還是用 mvn clean install 生成最新的jar包或其他包
3. 不想用mvn clean又想保證jar包最新,建議添加-Djar.forceCreation
參數(shù)
4. 由maven的生命周期可知,當使用deploy時同樣會有clean與不用clean的區(qū)別, 因此為了保險起見,建議package,install,deploy前均先clean
jar-plugin源代碼地址:http://svn.apache.org/repos/asf/maven/plugins/tags/maven-jar-plugin-2.4
到此這篇關于maven 在執(zhí)行package,install,deploy時使用clean與不使用clean的區(qū)別的文章就介紹到這了,更多相關maven 執(zhí)行package,install,deploy內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Java中MessageDigest來實現(xiàn)數(shù)據(jù)加密的方法
這篇文章主要介紹了Java中MessageDigest來實現(xiàn)數(shù)據(jù)加密的方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05手寫redis@Cacheable注解?參數(shù)java對象作為key值詳解
這篇文章主要介紹了手寫redis@Cacheable注解?參數(shù)java對象作為key值詳解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-01-01Java split函數(shù)拆分后變成null問題解決方案
這篇文章主要介紹了Java split函數(shù)拆分后變成null問題解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下2020-10-10Java線程操作的常見方法【線程名稱獲取、設置、線程啟動判斷等】
這篇文章主要介紹了Java線程操作的常見方法,結(jié)合實例形式總結(jié)分析了java線程的創(chuàng)建、線程名稱的獲取、設置以及線程啟動的判斷等相關操作實現(xiàn)技巧,需要的朋友可以參考下2019-10-10