Fixup various spring-boot-loader-tools issues

Fix compression of existing jars to detect nested zip entries and
use the STORED method.

Also fixed various test errors.

Issue: #53129653
This commit is contained in:
Phillip Webb
2013-07-29 22:21:23 -07:00
parent 14062964e0
commit d1c31445ec
4 changed files with 193 additions and 47 deletions

View File

@@ -20,6 +20,7 @@ import java.io.File;
import java.io.IOException;
import java.util.jar.JarFile;
import java.util.jar.Manifest;
import java.util.zip.ZipEntry;
import org.junit.Before;
import org.junit.Rule;
@@ -82,7 +83,7 @@ public class RepackagerTests {
@Test
public void specificMainClass() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithoutMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithoutMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
repackager.setMainClass("a.b.C");
@@ -97,7 +98,7 @@ public class RepackagerTests {
@Test
public void mainClassFromManifest() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithoutMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithoutMainMethod.class);
Manifest manifest = new Manifest();
manifest = new Manifest();
manifest.getMainAttributes().putValue("Manifest-Version", "1.0");
@@ -116,7 +117,7 @@ public class RepackagerTests {
@Test
public void mainClassFound() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
repackager.repackage(NO_LIBRARIES);
@@ -130,7 +131,7 @@ public class RepackagerTests {
@Test
public void noMainClass() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithoutMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithoutMainMethod.class);
this.thrown.expect(IllegalStateException.class);
this.thrown.expectMessage("Unable to find main class");
new Repackager(this.testJarFile.getFile()).repackage(NO_LIBRARIES);
@@ -138,7 +139,7 @@ public class RepackagerTests {
@Test
public void sameSourceAndDestinationWithBackup() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
repackager.repackage(NO_LIBRARIES);
@@ -149,7 +150,7 @@ public class RepackagerTests {
@Test
public void sameSourceAndDestinationWithoutBackup() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
repackager.setBackupSource(false);
@@ -161,7 +162,7 @@ public class RepackagerTests {
@Test
public void differentDestination() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File source = this.testJarFile.getFile();
File dest = this.temporaryFolder.newFile("different.jar");
Repackager repackager = new Repackager(source);
@@ -175,7 +176,7 @@ public class RepackagerTests {
@Test
public void nullDestination() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
Repackager repackager = new Repackager(this.testJarFile.getFile());
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Invalid destination");
@@ -184,7 +185,7 @@ public class RepackagerTests {
@Test
public void destinationIsDirectory() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
Repackager repackager = new Repackager(this.testJarFile.getFile());
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Invalid destination");
@@ -193,7 +194,7 @@ public class RepackagerTests {
@Test
public void overwriteDestination() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
Repackager repackager = new Repackager(this.testJarFile.getFile());
File dest = this.temporaryFolder.newFile("dest.jar");
dest.createNewFile();
@@ -203,7 +204,7 @@ public class RepackagerTests {
@Test
public void nullLibraries() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
this.thrown.expect(IllegalArgumentException.class);
@@ -214,9 +215,9 @@ public class RepackagerTests {
@Test
public void libraries() throws Exception {
TestJarFile libJar = new TestJarFile(this.temporaryFolder);
libJar.addClass("a.b.C.class", ClassWithoutMainMethod.class);
libJar.addClass("a/b/C.class", ClassWithoutMainMethod.class);
final File libJarFile = libJar.getFile();
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
repackager.repackage(new Libraries() {
@@ -231,9 +232,9 @@ public class RepackagerTests {
@Test
public void customLayout() throws Exception {
TestJarFile libJar = new TestJarFile(this.temporaryFolder);
libJar.addClass("a.b.C.class", ClassWithoutMainMethod.class);
libJar.addClass("a/b/C.class", ClassWithoutMainMethod.class);
final File libJarFile = libJar.getFile();
this.testJarFile.addClass("a.b.C.class", ClassWithMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
Layout layout = mock(Layout.class);
@@ -254,13 +255,42 @@ public class RepackagerTests {
@Test
public void nullCustomLayout() throws Exception {
this.testJarFile.addClass("a.b.C.class", ClassWithoutMainMethod.class);
this.testJarFile.addClass("a/b/C.class", ClassWithoutMainMethod.class);
Repackager repackager = new Repackager(this.testJarFile.getFile());
this.thrown.expect(IllegalArgumentException.class);
this.thrown.expectMessage("Layout must not be null");
repackager.setLayout(null);
}
@Test
public void dontRecompressZips() throws Exception {
TestJarFile nested = new TestJarFile(this.temporaryFolder);
nested.addClass("a/b/C.class", ClassWithoutMainMethod.class);
final File nestedFile = nested.getFile();
this.testJarFile.addFile("test/nested.jar", nestedFile);
this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
repackager.repackage(new Libraries() {
@Override
public void doWithLibraries(LibraryCallback callback) throws IOException {
callback.library(nestedFile, LibraryScope.COMPILE);
}
});
JarFile jarFile = new JarFile(file);
try {
assertThat(jarFile.getEntry("lib/" + nestedFile.getName()).getMethod(),
equalTo(ZipEntry.STORED));
assertThat(jarFile.getEntry("test/nested.jar").getMethod(),
equalTo(ZipEntry.STORED));
}
finally {
jarFile.close();
}
}
private boolean hasLauncherClasses(File file) throws IOException {
return hasEntry(file, "org/springframework/boot/")
&& hasEntry(file, "org/springframework/boot/loader/JarLauncher.class");

View File

@@ -17,6 +17,8 @@
package org.springframework.boot.launcher.tools;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -44,20 +46,22 @@ public class TestJarFile {
}
public void addClass(String filename, Class<?> classToCopy) throws IOException {
String[] paths = filename.split("\\/");
File file = this.jarSource;
for (String path : paths) {
file = new File(file, path);
}
File file = getFilePath(filename);
file.getParentFile().mkdirs();
InputStream inputStream = getClass().getResourceAsStream(
"/" + classToCopy.getName().replace(".", "/") + ".class");
OutputStream outputStream = new FileOutputStream(file);
copyToFile(inputStream, file);
}
public void addFile(String filename, File fileToCopy) throws IOException {
File file = getFilePath(filename);
file.getParentFile().mkdirs();
InputStream inputStream = new FileInputStream(fileToCopy);
try {
copy(inputStream, outputStream);
copyToFile(inputStream, file);
}
finally {
outputStream.close();
inputStream.close();
}
}
@@ -73,6 +77,26 @@ public class TestJarFile {
}
}
private File getFilePath(String filename) {
String[] paths = filename.split("\\/");
File file = this.jarSource;
for (String path : paths) {
file = new File(file, path);
}
return file;
}
private void copyToFile(InputStream inputStream, File file)
throws FileNotFoundException, IOException {
OutputStream outputStream = new FileOutputStream(file);
try {
copy(inputStream, outputStream);
}
finally {
outputStream.close();
}
}
private void copy(InputStream in, OutputStream out) throws IOException {
int bytesRead = -1;
while ((bytesRead = in.read(this.buffer)) != -1) {