Add group discriminant in case of conflict
Prior to this commit, the repackage goal silently ignored the case of two libraries having the same name and version but a different group. As a result, the second library was overwriting the first one in the repackaged jar. This commit adds support for custom Library names and updates the Maven and Gradle plugins so that the name includes the group ID when there would otherwise be a duplicate. Fixes gh-1475
This commit is contained in:
committed by
Phillip Webb
parent
449752c9e2
commit
f46fe32264
@@ -128,7 +128,7 @@ public class JarWriter {
|
||||
public void writeNestedLibrary(String destination, Library library)
|
||||
throws IOException {
|
||||
File file = library.getFile();
|
||||
JarEntry entry = new JarEntry(destination + file.getName());
|
||||
JarEntry entry = new JarEntry(destination + library.getName());
|
||||
if (library.isUnpackRequired()) {
|
||||
entry.setComment("UNPACK:" + FileUtils.sha1Hash(file));
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import java.io.File;
|
||||
*/
|
||||
public class Library {
|
||||
|
||||
private final String name;
|
||||
|
||||
private final File file;
|
||||
|
||||
private final LibraryScope scope;
|
||||
@@ -49,11 +51,31 @@ public class Library {
|
||||
* @param unpackRequired if the library needs to be unpacked before it can be used
|
||||
*/
|
||||
public Library(File file, LibraryScope scope, boolean unpackRequired) {
|
||||
this(null, file, scope, unpackRequired);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link Library}.
|
||||
* @param name the name of the library as it should be written or {@code null} to use
|
||||
* the file name
|
||||
* @param file the source file
|
||||
* @param scope the scope of the library
|
||||
* @param unpackRequired if the library needs to be unpacked before it can be used
|
||||
*/
|
||||
public Library(String name, File file, LibraryScope scope, boolean unpackRequired) {
|
||||
this.name = (name == null ? file.getName() : name);
|
||||
this.file = file;
|
||||
this.scope = scope;
|
||||
this.unpackRequired = unpackRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the name of file as it should be written
|
||||
*/
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the library file
|
||||
*/
|
||||
|
||||
@@ -20,6 +20,8 @@ import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
@@ -153,17 +155,22 @@ public class Repackager {
|
||||
throws IOException {
|
||||
final JarWriter writer = new JarWriter(destination);
|
||||
try {
|
||||
final Set<String> seen = new HashSet<String>();
|
||||
writer.writeManifest(buildManifest(sourceJar));
|
||||
writer.writeEntries(sourceJar);
|
||||
|
||||
libraries.doWithLibraries(new LibraryCallback() {
|
||||
@Override
|
||||
public void library(Library library) throws IOException {
|
||||
File file = library.getFile();
|
||||
if (isZip(file)) {
|
||||
String destination = Repackager.this.layout
|
||||
.getLibraryDestination(file.getName(), library.getScope());
|
||||
.getLibraryDestination(library.getName(),
|
||||
library.getScope());
|
||||
if (destination != null) {
|
||||
if (!seen.add(destination + library.getName())) {
|
||||
throw new IllegalStateException("Duplicate library "
|
||||
+ library.getName());
|
||||
}
|
||||
writer.writeNestedLibrary(destination, library);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -299,6 +299,25 @@ public class RepackagerTests {
|
||||
assertThat(entry.getComment().length(), equalTo(47));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void duplicateLibraries() throws Exception {
|
||||
TestJarFile libJar = new TestJarFile(this.temporaryFolder);
|
||||
libJar.addClass("a/b/C.class", ClassWithoutMainMethod.class);
|
||||
final File libJarFile = libJar.getFile();
|
||||
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
|
||||
File file = this.testJarFile.getFile();
|
||||
Repackager repackager = new Repackager(file);
|
||||
this.thrown.expect(IllegalStateException.class);
|
||||
this.thrown.expectMessage("Duplicate library");
|
||||
repackager.repackage(new Libraries() {
|
||||
@Override
|
||||
public void doWithLibraries(LibraryCallback callback) throws IOException {
|
||||
callback.library(new Library(libJarFile, LibraryScope.COMPILE, false));
|
||||
callback.library(new Library(libJarFile, LibraryScope.COMPILE, false));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
public void customLayout() throws Exception {
|
||||
TestJarFile libJar = new TestJarFile(this.temporaryFolder);
|
||||
|
||||
Reference in New Issue
Block a user