Skip to content

Commit 6f8d477

Browse files
committed
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
1 parent b729970 commit 6f8d477

File tree

2 files changed

+35
-1
lines changed
  • spring-boot-tools/spring-boot-loader-tools/src

2 files changed

+35
-1
lines changed

spring-boot-tools/spring-boot-loader-tools/src/main/java/org/springframework/boot/loader/tools/Repackager.java

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ public void repackage(File destination, Libraries libraries) throws IOException
107107
if (libraries == null) {
108108
throw new IllegalArgumentException("Libraries must not be null");
109109
}
110+
111+
if (alreadyRepackaged()) {
112+
return;
113+
}
114+
110115
destination = destination.getAbsoluteFile();
111116
File workingSource = this.source;
112117
if (this.source.equals(destination)) {
@@ -132,6 +137,19 @@ public void repackage(File destination, Libraries libraries) throws IOException
132137
}
133138
}
134139

140+
private boolean alreadyRepackaged() throws IOException {
141+
JarFile jarFile = new JarFile(this.source);
142+
143+
try {
144+
Manifest manifest = jarFile.getManifest();
145+
return manifest != null
146+
&& manifest.getMainAttributes().getValue(BOOT_VERSION_ATTRIBUTE) != null;
147+
}
148+
finally {
149+
jarFile.close();
150+
}
151+
}
152+
135153
private void repackage(JarFile sourceJar, File destination, Libraries libraries)
136154
throws IOException {
137155
final JarWriter writer = new JarWriter(destination);
@@ -208,7 +226,7 @@ private Manifest buildManifest(JarFile source) throws IOException {
208226
String launcherClassName = this.layout.getLauncherClassName();
209227
if (launcherClassName != null) {
210228
manifest.getMainAttributes()
211-
.putValue(MAIN_CLASS_ATTRIBUTE, launcherClassName);
229+
.putValue(MAIN_CLASS_ATTRIBUTE, launcherClassName);
212230
if (startClass == null) {
213231
throw new IllegalStateException("Unable to find main class");
214232
}

spring-boot-tools/spring-boot-loader-tools/src/test/java/org/springframework/boot/loader/tools/RepackagerTests.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,22 @@ public void mainClassFound() throws Exception {
134134
assertThat(hasLauncherClasses(file), equalTo(true));
135135
}
136136

137+
@Test
138+
public void jarIsOnlyRepackagedOnce() throws Exception {
139+
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
140+
File file = this.testJarFile.getFile();
141+
Repackager repackager = new Repackager(file);
142+
repackager.repackage(NO_LIBRARIES);
143+
repackager.repackage(NO_LIBRARIES);
144+
145+
Manifest actualManifest = getManifest(file);
146+
assertThat(actualManifest.getMainAttributes().getValue("Main-Class"),
147+
equalTo("org.springframework.boot.loader.JarLauncher"));
148+
assertThat(actualManifest.getMainAttributes().getValue("Start-Class"),
149+
equalTo("a.b.C"));
150+
assertThat(hasLauncherClasses(file), equalTo(true));
151+
}
152+
137153
@Test
138154
public void multipleMainClassFound() throws Exception {
139155
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);

0 commit comments

Comments
 (0)