Skip to content

Commit c543035

Browse files
Malandrilaloubyansky
authored andcommitted
Set filtered jar's manifest time to epoch
(cherry picked from commit a7aa354)
1 parent fb18562 commit c543035

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

core/deployment/src/main/java/io/quarkus/deployment/pkg/steps/JarResultBuildStep.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1290,7 +1290,13 @@ static void filterJarFile(Path resolvedDep, Path targetPath, Set<String> transfo
12901290
} else {
12911291
manifest = new Manifest();
12921292
}
1293-
try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(targetPath), manifest)) {
1293+
try (JarOutputStream out = new JarOutputStream(Files.newOutputStream(targetPath))) {
1294+
JarEntry manifestEntry = new JarEntry(JarFile.MANIFEST_NAME);
1295+
// Set manifest time to epoch to always make the same jar
1296+
manifestEntry.setTime(0);
1297+
out.putNextEntry(manifestEntry);
1298+
manifest.write(out);
1299+
out.closeEntry();
12941300
Enumeration<JarEntry> entries = in.entries();
12951301
while (entries.hasMoreElements()) {
12961302
JarEntry entry = entries.nextElement();
@@ -1306,6 +1312,8 @@ static void filterJarFile(Path resolvedDep, Path targetPath, Set<String> transfo
13061312
while ((r = inStream.read(buffer)) > 0) {
13071313
out.write(buffer, 0, r);
13081314
}
1315+
} finally {
1316+
out.closeEntry();
13091317
}
13101318
} else {
13111319
log.debugf("Removed %s from %s", entryName, resolvedDep);

core/deployment/src/test/java/io/quarkus/deployment/pkg/steps/JarResultBuildStepTest.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,26 @@ void should_unsign_jar_when_filtered(@TempDir Path tempDir) throws Exception {
6868
}
6969
}
7070

71+
@Test
72+
void manifestTimeShouldAlwaysBeSetToEpoch(@TempDir Path tempDir) throws Exception {
73+
JavaArchive archive = ShrinkWrap.create(JavaArchive.class, "myarchive.jar")
74+
.addClasses(Integer.class)
75+
.addManifest();
76+
Path initialJar = tempDir.resolve("initial.jar");
77+
Path filteredJar = tempDir.resolve("filtered.jar");
78+
archive.as(ZipExporter.class).exportTo(new File(initialJar.toUri()), true);
79+
JarResultBuildStep.filterJarFile(initialJar, filteredJar, Set.of("java/lang/Integer.class"));
80+
try (JarFile jarFile = new JarFile(filteredJar.toFile())) {
81+
assertThat(jarFile.stream())
82+
.filteredOn(jarEntry -> jarEntry.getName().equals(JarFile.MANIFEST_NAME))
83+
.isNotEmpty()
84+
.allMatch(jarEntry -> jarEntry.getTime() == 0);
85+
// Check that the manifest is still has attributes
86+
Manifest manifest = jarFile.getManifest();
87+
assertThat(manifest.getMainAttributes()).isNotEmpty();
88+
}
89+
}
90+
7191
private static KeyStore.PrivateKeyEntry createPrivateKeyEntry()
7292
throws NoSuchAlgorithmException, CertificateException, OperatorCreationException, CertIOException {
7393
KeyPairGenerator ky = KeyPairGenerator.getInstance("RSA");

0 commit comments

Comments
 (0)