Prevent a jar from being repackaged more than once

Previously, Repackager would repackage a jar file as many times as
it was asked to do so. This lead to problems if a user made a mistake
when using Maven that led to the package phase being driven twice,
for example by running "mvn clean install package".

This commit updates Repackager so that a repackage call becomes a
no-op if the source jar's manifest already contains the
Spring-Boot-Version attribute which is added by repackaging.

Fixes #1251
This commit is contained in:
Andy Wilkinson 2014-07-30 11:07:41 +01:00
parent b7299708f8
commit 6f8d4778ad
2 changed files with 35 additions and 1 deletions

View File

@ -107,6 +107,11 @@ public class Repackager {
if (libraries == null) {
throw new IllegalArgumentException("Libraries must not be null");
}
if (alreadyRepackaged()) {
return;
}
destination = destination.getAbsoluteFile();
File workingSource = this.source;
if (this.source.equals(destination)) {
@ -132,6 +137,19 @@ public class Repackager {
}
}
private boolean alreadyRepackaged() throws IOException {
JarFile jarFile = new JarFile(this.source);
try {
Manifest manifest = jarFile.getManifest();
return manifest != null
&& manifest.getMainAttributes().getValue(BOOT_VERSION_ATTRIBUTE) != null;
}
finally {
jarFile.close();
}
}
private void repackage(JarFile sourceJar, File destination, Libraries libraries)
throws IOException {
final JarWriter writer = new JarWriter(destination);
@ -208,7 +226,7 @@ public class Repackager {
String launcherClassName = this.layout.getLauncherClassName();
if (launcherClassName != null) {
manifest.getMainAttributes()
.putValue(MAIN_CLASS_ATTRIBUTE, launcherClassName);
.putValue(MAIN_CLASS_ATTRIBUTE, launcherClassName);
if (startClass == null) {
throw new IllegalStateException("Unable to find main class");
}

View File

@ -134,6 +134,22 @@ public class RepackagerTests {
assertThat(hasLauncherClasses(file), equalTo(true));
}
@Test
public void jarIsOnlyRepackagedOnce() throws Exception {
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
repackager.repackage(NO_LIBRARIES);
repackager.repackage(NO_LIBRARIES);
Manifest actualManifest = getManifest(file);
assertThat(actualManifest.getMainAttributes().getValue("Main-Class"),
equalTo("org.springframework.boot.loader.JarLauncher"));
assertThat(actualManifest.getMainAttributes().getValue("Start-Class"),
equalTo("a.b.C"));
assertThat(hasLauncherClasses(file), equalTo(true));
}
@Test
public void multipleMainClassFound() throws Exception {
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);