[MEAR-283] enforce timestamp of repackaged skinny war
Timestamp of repackaged EAR modules following same rules / value as
timestamp of packaged modules to support reproducible builds when
skinnyWar option is turned on
diff --git a/src/it/basic/verify.bsh b/src/it/basic/verify.bsh
index 0e96a92..d5e9275 100644
--- a/src/it/basic/verify.bsh
+++ b/src/it/basic/verify.bsh
@@ -35,13 +35,28 @@
"META-INF/application.xml",
"META-INF/appserver-application.xml",
};
+
+// Reproducible Builds: check that every entry has the same timestamp
+long entryTime = -1;
+
for ( String included : includedEntries )
{
System.out.println( "Checking for existence of " + included );
- if ( jar.getEntry( included ) == null )
+ JarEntry jarEntry = jar.getEntry( included );
+ if ( jarEntry == null )
{
throw new IllegalStateException( "Missing archive entry: " + included );
}
+ if ( entryTime < 0 )
+ {
+ entryTime = jarEntry.getTime();
+ }
+ if ( entryTime != jarEntry.getTime() )
+ {
+ throw new IllegalStateException( "Invalid jar entry time: " + jarEntry.getTime()
+ + " of archive entry: " + included
+ + ", expected: " + entryTime );
+ }
}
jar.close();
diff --git a/src/it/skinny-wars/ear-module/pom.xml b/src/it/skinny-wars/ear-module/pom.xml
index 24981aa..6f9911a 100644
--- a/src/it/skinny-wars/ear-module/pom.xml
+++ b/src/it/skinny-wars/ear-module/pom.xml
@@ -27,6 +27,10 @@
<version>1.0</version>
<packaging>ear</packaging>
+ <properties>
+ <project.build.outputTimestamp>2020-05-01T12:12:12Z</project.build.outputTimestamp>
+ </properties>
+
<dependencies>
<dependency>
<groupId>commons-lang</groupId>
diff --git a/src/it/skinny-wars/verify.bsh b/src/it/skinny-wars/verify.bsh
index f501413..279331b 100644
--- a/src/it/skinny-wars/verify.bsh
+++ b/src/it/skinny-wars/verify.bsh
@@ -35,12 +35,27 @@
"WEB-INF/web.xml",
"META-INF/MANIFEST.MF"
};
+
+// Reproducible Builds: check that every entry has the same timestamp
+long entryTime = -1;
+
for ( String included : includedEntries )
{
System.out.println( "Checking for included archive entry " + included );
- if ( jar.getEntry( included ) == null )
+ JarEntry jarEntry = jar.getEntry( included );
+ if ( jarEntry == null )
{
- throw new IllegalStateException( "Missing archive entry: " + included );
+ throw new IllegalStateException( "Missing WAR entry: " + included );
+ }
+ if ( entryTime < 0 )
+ {
+ entryTime = jarEntry.getTime();
+ }
+ if ( entryTime != jarEntry.getTime() )
+ {
+ throw new IllegalStateException( "Invalid jar entry time: " + jarEntry.getTime()
+ + " of archive entry: " + included
+ + ", expected: " + entryTime );
}
}
diff --git a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
index 374339b..4d1841e 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
@@ -33,6 +33,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Date;
import java.util.List;
import java.util.zip.ZipException;
@@ -284,7 +285,33 @@
// Initializes ear modules
super.execute();
+ final File earFile;
+ final MavenArchiver archiver;
+ final Date reproducibleLastModifiedDate;
+ try
+ {
+ earFile = getEarFile( outputDirectory, finalName, classifier );
+ archiver = new EarMavenArchiver( getModules() );
+ final JarArchiver theJarArchiver = getJarArchiver();
+ getLog().debug( "Jar archiver implementation [" + theJarArchiver.getClass().getName() + "]" );
+ archiver.setArchiver( theJarArchiver );
+ archiver.setOutputFile( earFile );
+
+ archiver.setCreatedBy( "Maven EAR Plugin", "org.apache.maven.plugins", "maven-ear-plugin" );
+
+ // configure for Reproducible Builds based on outputTimestamp value
+ reproducibleLastModifiedDate = archiver.configureReproducible( outputTimestamp );
+ }
+ catch ( Exception e )
+ {
+ throw new MojoExecutionException( "Error assembling EAR", e );
+ }
+
zipArchiver.setUseJvmChmod( useJvmChmod );
+ if ( reproducibleLastModifiedDate != null )
+ {
+ zipArchiver.configureReproducible( reproducibleLastModifiedDate );
+ }
zipUnArchiver.setUseJvmChmod( useJvmChmod );
final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );
@@ -381,18 +408,6 @@
try
{
- File earFile = getEarFile( outputDirectory, finalName, classifier );
- final MavenArchiver archiver = new EarMavenArchiver( getModules() );
- final JarArchiver theJarArchiver = getJarArchiver();
- getLog().debug( "Jar archiver implementation [" + theJarArchiver.getClass().getName() + "]" );
- archiver.setArchiver( theJarArchiver );
- archiver.setOutputFile( earFile );
-
- archiver.setCreatedBy( "Maven EAR Plugin", "org.apache.maven.plugins", "maven-ear-plugin" );
-
- // configure for Reproducible Builds based on outputTimestamp value
- archiver.configureReproducible( outputTimestamp );
-
getLog().debug( "Excluding " + Arrays.asList( getPackagingExcludes() ) + " from the generated EAR." );
getLog().debug( "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated EAR." );