Merge branch '1.2.x'

pull/3706/head
Andy Wilkinson 9 years ago
commit a2d58030dd

@ -20,7 +20,9 @@ import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.Manifest; import java.util.jar.Manifest;
@ -166,29 +168,30 @@ public class Repackager {
private void repackage(JarFile sourceJar, File destination, Libraries libraries, private void repackage(JarFile sourceJar, File destination, Libraries libraries,
LaunchScript launchScript) throws IOException { LaunchScript launchScript) throws IOException {
final JarWriter writer = new JarWriter(destination, launchScript); JarWriter writer = new JarWriter(destination, launchScript);
try { try {
final Set<String> seen = new HashSet<String>(); final List<Library> unpackLibraries = new ArrayList<Library>();
writer.writeManifest(buildManifest(sourceJar)); final List<Library> standardLibraries = new ArrayList<Library>();
libraries.doWithLibraries(new LibraryCallback() { libraries.doWithLibraries(new LibraryCallback() {
@Override @Override
public void library(Library library) throws IOException { public void library(Library library) throws IOException {
File file = library.getFile(); File file = library.getFile();
if (isZip(file)) { if (isZip(file)) {
String destination = Repackager.this.layout if (library.isUnpackRequired()) {
.getLibraryDestination(library.getName(), unpackLibraries.add(library);
library.getScope());
if (destination != null) {
if (!seen.add(destination + library.getName())) {
throw new IllegalStateException("Duplicate library "
+ library.getName());
} }
writer.writeNestedLibrary(destination, library); else {
standardLibraries.add(library);
} }
} }
} }
}); });
writer.writeManifest(buildManifest(sourceJar));
Set<String> seen = new HashSet<String>();
writeNestedLibraries(unpackLibraries, seen, writer);
writer.writeEntries(sourceJar); writer.writeEntries(sourceJar);
writeNestedLibraries(standardLibraries, seen, writer);
if (this.layout.isExecutable()) { if (this.layout.isExecutable()) {
writer.writeLoaderClasses(); writer.writeLoaderClasses();
} }
@ -203,6 +206,21 @@ public class Repackager {
} }
} }
private void writeNestedLibraries(List<Library> libraries, Set<String> alreadySeen,
JarWriter writer) throws IOException {
for (Library library : libraries) {
String destination = Repackager.this.layout.getLibraryDestination(
library.getName(), library.getScope());
if (destination != null) {
if (!alreadySeen.add(destination + library.getName())) {
throw new IllegalStateException("Duplicate library "
+ library.getName());
}
writer.writeNestedLibrary(destination, library);
}
}
}
private boolean isZip(File file) { private boolean isZip(File file) {
try { try {
FileInputStream fileInputStream = new FileInputStream(file); FileInputStream fileInputStream = new FileInputStream(file);

@ -35,6 +35,7 @@ import org.junit.rules.TemporaryFolder;
import org.springframework.boot.loader.tools.sample.ClassWithMainMethod; import org.springframework.boot.loader.tools.sample.ClassWithMainMethod;
import org.springframework.boot.loader.tools.sample.ClassWithoutMainMethod; import org.springframework.boot.loader.tools.sample.ClassWithoutMainMethod;
import org.springframework.util.FileCopyUtils; import org.springframework.util.FileCopyUtils;
import org.zeroturnaround.zip.ZipUtil;
import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasItem; import static org.hamcrest.Matchers.hasItem;
@ -429,6 +430,69 @@ public class RepackagerTests {
} }
} }
@Test
public void unpackLibrariesTakePrecedenceOverExistingSourceEntries() throws Exception {
final TestJarFile nested = new TestJarFile(this.temporaryFolder);
nested.addClass("a/b/C.class", ClassWithoutMainMethod.class);
final File nestedFile = nested.getFile();
this.testJarFile.addFile("lib/" + nestedFile.getName(), nested.getFile());
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(new Library(nestedFile, LibraryScope.COMPILE, true));
}
});
JarFile jarFile = new JarFile(file);
try {
assertThat(jarFile.getEntry("lib/" + nestedFile.getName()).getComment(),
startsWith("UNPACK:"));
}
finally {
jarFile.close();
}
}
@Test
public void existingSourceEntriesTakePrecedenceOverStandardLibraries()
throws Exception {
final TestJarFile nested = new TestJarFile(this.temporaryFolder);
nested.addClass("a/b/C.class", ClassWithoutMainMethod.class);
final File nestedFile = nested.getFile();
this.testJarFile.addFile("lib/" + nestedFile.getName(), nested.getFile());
this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
File file = this.testJarFile.getFile();
Repackager repackager = new Repackager(file);
long sourceLength = nestedFile.length();
repackager.repackage(new Libraries() {
@Override
public void doWithLibraries(LibraryCallback callback) throws IOException {
nestedFile.delete();
File toZip = RepackagerTests.this.temporaryFolder.newFile();
ZipUtil.packEntry(toZip, nestedFile);
callback.library(new Library(nestedFile, LibraryScope.COMPILE));
}
});
JarFile jarFile = new JarFile(file);
try {
assertThat(jarFile.getEntry("lib/" + nestedFile.getName()).getSize(),
equalTo(sourceLength));
}
finally {
jarFile.close();
}
}
private boolean hasLauncherClasses(File file) throws IOException { private boolean hasLauncherClasses(File file) throws IOException {
return hasEntry(file, "org/springframework/boot/") return hasEntry(file, "org/springframework/boot/")
&& hasEntry(file, "org/springframework/boot/loader/JarLauncher.class"); && hasEntry(file, "org/springframework/boot/loader/JarLauncher.class");

Loading…
Cancel
Save