最近由于不清楚maven(2.2.x)增量編譯的機(jī)制,導(dǎo)致應(yīng)用出現(xiàn)了一個(gè)當(dāng)時(shí)覺得非常詭異的一個(gè)問(wèn)題。先描述一下問(wèn)題。 背景是應(yīng)用A有一個(gè)公用的base包,版本為1.6.6-SNAPSHOT,應(yīng)用B依賴于這個(gè)公用的base包。我在base包中修改了一個(gè)字符串變量的值,該變量是一個(gè)緩存的key(如下面代碼的Constants類,中的CACHE_KEY)。然后使用mvn deploy 命令把base包上傳到中心庫(kù)中。出現(xiàn)的問(wèn)題是應(yīng)用B打包部署,應(yīng)用上線后,使用后臺(tái)功能刪除"cache.key.new"對(duì)應(yīng)的緩存值,提示刪除成功。但是前臺(tái)展示的還是老的值(前臺(tái)展示取的數(shù)據(jù)是從緩存取出的,簡(jiǎn)化代碼后,參考下面的CategoryManager的showCategory()方法,根據(jù)key在緩存中取出值,然后前臺(tái)展示)。
public Interface Constants{ public interface Cache{ String CACHE_KEY = “cache.key.new”;//舊值為"cache.key" } }
一開始懷疑是包沒(méi)有成功deploy到中心庫(kù)中,然后在中心庫(kù)中把1.6.6-SNAPSHOT的源碼包拉了下來(lái),發(fā)現(xiàn)里面的代碼是新的。
我的印象中deploy是maven生命周期的最后一步,執(zhí)行deploy命令是會(huì)執(zhí)行compile編譯操作的,當(dāng)時(shí)懷疑自己記錯(cuò)了,以為base包deploy的時(shí)候沒(méi)有走到compile,就把包發(fā)到中心庫(kù)中了,后續(xù)把base包的1.6.6-SNAPSHOT的編譯后的文件拉下來(lái),并且反編譯Constants類,發(fā)現(xiàn)CACHE_KEY的確是新的值"cache.key.new",證明這塊是被重新編譯過(guò)了。(后續(xù)翻閱了下資料”http://maven./guides/introduction/introduction-to-the-lifecycle.html maven生命周期“發(fā)現(xiàn)自己記的的確沒(méi)錯(cuò))
最后把CategoryManager.class反編譯過(guò)來(lái)一看,發(fā)現(xiàn)里面的部分代碼是這樣的:
public Class CategoryManager{ private static Map<int, String> keyMaps = new HashMap<String, String>(); static { keyMaps.put(1, "cache.key");//問(wèn)題出在這里,這個(gè)"cache.key"沒(méi)有替換成新的值"cache.key.new" ......... } ........ }
發(fā)現(xiàn)問(wèn)題了,這里的"cache.key"并沒(méi)有替換成新值。也就是說(shuō)CategoryManager類并沒(méi)有重新編譯。這里的原因是maven的增量編譯機(jī)制。
后續(xù)找了些資料表明,默認(rèn)情況下maven是增量編譯的,maven在編譯的時(shí)候會(huì)先去比較源文件(.java)文件的修改時(shí)間和對(duì)應(yīng)類文件(.class)的修改時(shí)間,如果源文件的修改時(shí)間比類文件的修改時(shí)間要晚的話,重新編譯原文件否則不做處理(另外,如果刪除了一個(gè)java文件,對(duì)應(yīng)的class文件在增量編譯時(shí)是不會(huì)被移除的)。 在這里CategoryManager的源文件并沒(méi)有發(fā)生過(guò)改變,所以不會(huì)重新編譯。并且這個(gè)地方恰好是靜態(tài)代碼塊,這段代碼 keyMaps.put(1, Constants. Cache. CACHE_KEY); 編譯時(shí)直接被替換成 keyMaps.put(1, "cache.key"); ,如果是在非靜態(tài)代碼塊里面使用的話,這塊地方是不會(huì)出問(wèn)題的。所以之前一直使用mvn deploy都沒(méi)有出現(xiàn)過(guò)問(wèn)題。 那要怎么避免這個(gè)問(wèn)題呢,使用mvn clean deploy。clean會(huì)做一些清理的工作,包括移除上一次構(gòu)建的文件。這樣就能很好的解決這個(gè)問(wèn)題了。
參考:
http://blog./teamcity/2012/03/incremental-building-with-maven-and-teamcity/ 部分有關(guān)于maven的 incremental building
|
|
來(lái)自: liang1234_ > 《maven》