使用maven打包後,在META-INF目錄下會生成pom.properties檔案(當然可以使其不生成)。這個檔案包含了包的Id資訊,此外它最開始有兩行注釋,看起來是這樣的
#Generated by Maven
#Sat Jun 25 09:40:37 CST 2016
第一行 是固定的,第二行是打包時候的時間戳。
第二行的存在有一個嚴重的問題,就是我們完全不修改代碼,然後兩次打包由于時間戳不一樣,導緻生成的兩個包不一樣。如果你不在乎可能覺得沒有什麼,但是對于大型項目,代碼沒變包卻不同導緻不能進行增量部署。
這個代碼的出現是由于java.util.Properties類的store(Writer writer, String comments)方法中有一行
bw.write("#" + new Date().toString());
這個問題在困擾大家的同時,也困擾着Maven的開發者。與之相關的有兩個issue:
MSHARED-494 MSHARED-505maven人員郁悶的說
Oracle's implementation of store() does write the stupid new Date().toString()
由于大家需求強烈,目前該特性據說已被修正。
在今年5月21号送出的代碼中,時間這一行注釋被移除了:移除方法是把生成後的檔案對行疊代,看到是注釋就删除。
Stupid hack: write the properties to a StringWriter,
iterate with a BufferedReader and drop all comments,
finall write real content to the target file.
我們看一下中心庫中的版本和時間:

3.0.x版本最晚是4月份送出的,是以它不包含這個改動。3.1.x最早是6月份送出的,現在已經有兩個小版本了,但是引用次數還是0.
我們對比一下3.0和3.1中的代碼。首先是3.0.2中的:
75 private void createPropertiesFile( MavenSession session, Properties properties, File outputFile,
76 boolean forceCreation )
77 throws IOException
78 {
79 File outputDir = outputFile.getParentFile();
80 if ( outputDir != null && !outputDir.isDirectory() && !outputDir.mkdirs() )
81 {
82 throw new IOException( "Failed to create directory: " + outputDir );
83 }
84 if ( !forceCreation && sameContents( properties, outputFile ) )
85 {
86 return;
87 }
88 OutputStream os = new FileOutputStream( outputFile );
89 try
90 {
91 String createdBy = CREATED_BY_MAVEN;
92 if ( session != null ) // can be null due to API backwards compatibility
93 {
94 String mavenVersion = session.getSystemProperties().getProperty( "maven.version" );
95 if ( mavenVersion != null )
96 {
97 createdBy += " " + mavenVersion;
98 }
99 }
100
101 properties.store( os, createdBy );
102 os.close(); // stream is flushed but not closed by Properties.store()
103 os = null;
104 }
105 finally
106 {
107 IOUtil.close( os );
108 }
109 }
下面是3.1.1的(左邊是在檔案内的行号):
77 private void createPropertiesFile( MavenSession session, Properties properties, File outputFile,
78 boolean forceCreation )
79 throws IOException
80 {
81 File outputDir = outputFile.getParentFile();
82 if ( outputDir != null && !outputDir.isDirectory() && !outputDir.mkdirs() )
83 {
84 throw new IOException( "Failed to create directory: " + outputDir );
85 }
86 if ( !forceCreation && sameContents( properties, outputFile ) )
87 {
88 return;
89 }
90 PrintWriter pw = new PrintWriter( outputFile, "ISO-8859-1" );
91 try
92 {
93 String createdBy = CREATED_BY_MAVEN;
94 if ( session != null ) // can be null due to API backwards compatibility
95 {
96 String mavenVersion = session.getSystemProperties().getProperty( "maven.version" );
97 if ( mavenVersion != null )
98 {
99 createdBy += " " + mavenVersion;
100 }
101 }
102
103 StringWriter sw = new StringWriter();
104 properties.store( sw, null );
105
106 BufferedReader r = new BufferedReader( new StringReader( sw.toString() ) );
107
108 pw.println( "#" + createdBy );
109 String line;
110 while ( ( line = r.readLine() ) != null )
111 {
112 if ( !line.startsWith( "#" ) )
113 {
114 pw.println( line );
115 }
116 }
117
118 r.close();
119 r = null;
120 sw.close();
121 sw = null;
122 pw.close();
123 pw = null;
124 }
125 finally
126 {
127 IOUtil.close( pw );
128 }
129 }
這裡主要是對注釋的處理,正文内容的處理在方法public void createPomProperties()中。
下面版本比上面多了一個流程,就是臨時變量sw寫入後,再逐行讀出來,不是注釋就寫入pw中(疊代前已經把maven資訊寫好了)。這樣就把時間删掉了。