Apply exclusions to existing war entries
Update `RepackageMojo` and supporting classes so that `exclusions` on the repackage goal apply to both the contributed libraries and any existing jar entries already contained in the original war. Prior to this commit, exclusions would apply to contributed jars (for example, those in `WEB-INF/lib-provided`) but not jars that were packaged directly into `WEB-INF/lib` by the war plugin Fixes gh-15808 Co-authored-by: Phillip Webb <pwebb@vmware.com>
This commit is contained in:
committed by
Phillip Webb
parent
4d694ddaa8
commit
b790c82732
@@ -30,6 +30,7 @@ import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.JarInputStream;
|
||||
@@ -88,23 +89,42 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
|
||||
* Write all entries from the specified jar file.
|
||||
* @param jarFile the source jar file
|
||||
* @throws IOException if the entries cannot be written
|
||||
* @deprecated since 2.4.8 for removal in 2.6.0 in favor of
|
||||
* {@link #writeEntries(JarFile, EntryTransformer, UnpackHandler, Predicate)}
|
||||
*/
|
||||
@Deprecated
|
||||
public void writeEntries(JarFile jarFile) throws IOException {
|
||||
writeEntries(jarFile, EntryTransformer.NONE, UnpackHandler.NEVER);
|
||||
writeEntries(jarFile, EntryTransformer.NONE, UnpackHandler.NEVER, (entry) -> true);
|
||||
}
|
||||
|
||||
final void writeEntries(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler)
|
||||
throws IOException {
|
||||
/**
|
||||
* Write required entries from the specified jar file.
|
||||
* @param jarFile the source jar file
|
||||
* @param entryTransformer the entity transformer used to change the entry
|
||||
* @param unpackHandler the unpack handler
|
||||
* @param entryFilter a predicate used to filter the written entries
|
||||
* @throws IOException if the entries cannot be written
|
||||
* @since 2.4.8
|
||||
*/
|
||||
public void writeEntries(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler,
|
||||
Predicate<JarEntry> entryFilter) throws IOException {
|
||||
Enumeration<JarEntry> entries = jarFile.entries();
|
||||
while (entries.hasMoreElements()) {
|
||||
JarArchiveEntry entry = new JarArchiveEntry(entries.nextElement());
|
||||
setUpEntry(jarFile, entry);
|
||||
try (ZipHeaderPeekInputStream inputStream = new ZipHeaderPeekInputStream(jarFile.getInputStream(entry))) {
|
||||
EntryWriter entryWriter = new InputStreamEntryWriter(inputStream);
|
||||
JarArchiveEntry transformedEntry = entryTransformer.transform(entry);
|
||||
if (transformedEntry != null) {
|
||||
writeEntry(transformedEntry, entryWriter, unpackHandler, true);
|
||||
}
|
||||
JarEntry entry = entries.nextElement();
|
||||
if (entryFilter.test(entry)) {
|
||||
writeEntry(jarFile, entryTransformer, unpackHandler, new JarArchiveEntry(entry));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void writeEntry(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler,
|
||||
JarArchiveEntry entry) throws IOException {
|
||||
setUpEntry(jarFile, entry);
|
||||
try (ZipHeaderPeekInputStream inputStream = new ZipHeaderPeekInputStream(jarFile.getInputStream(entry))) {
|
||||
EntryWriter entryWriter = new InputStreamEntryWriter(inputStream);
|
||||
JarArchiveEntry transformedEntry = entryTransformer.transform(entry);
|
||||
if (transformedEntry != null) {
|
||||
writeEntry(transformedEntry, entryWriter, unpackHandler, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ public class JarModeLibrary extends Library {
|
||||
}
|
||||
|
||||
public JarModeLibrary(LibraryCoordinates coordinates) {
|
||||
super(getJarName(coordinates), null, LibraryScope.RUNTIME, coordinates, false);
|
||||
super(getJarName(coordinates), null, LibraryScope.RUNTIME, coordinates, false, false, true);
|
||||
}
|
||||
|
||||
private static LibraryCoordinates createCoordinates(String artifactId) {
|
||||
|
||||
@@ -43,11 +43,16 @@ public class Library {
|
||||
|
||||
private final boolean local;
|
||||
|
||||
private final boolean included;
|
||||
|
||||
/**
|
||||
* Create a new {@link Library}.
|
||||
* @param file the source file
|
||||
* @param scope the scope of the library
|
||||
* @deprecated since 2.4.8 for removal in 2.6.0 in favor of
|
||||
* {@link #Library(String, File, LibraryScope, LibraryCoordinates, boolean, boolean, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Library(File file, LibraryScope scope) {
|
||||
this(file, scope, false);
|
||||
}
|
||||
@@ -57,7 +62,10 @@ public class Library {
|
||||
* @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
|
||||
* @deprecated since 2.4.8 for removal in 2.6.0 in favor of
|
||||
* {@link #Library(String, File, LibraryScope, LibraryCoordinates, boolean, boolean, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Library(File file, LibraryScope scope, boolean unpackRequired) {
|
||||
this(null, file, scope, unpackRequired);
|
||||
}
|
||||
@@ -69,7 +77,10 @@ public class Library {
|
||||
* @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
|
||||
* @deprecated since 2.4.8 for removal in 2.6.0 in favor of
|
||||
* {@link #Library(String, File, LibraryScope, LibraryCoordinates, boolean, boolean, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Library(String name, File file, LibraryScope scope, boolean unpackRequired) {
|
||||
this(name, file, scope, null, unpackRequired);
|
||||
}
|
||||
@@ -82,7 +93,10 @@ public class Library {
|
||||
* @param scope the scope of the library
|
||||
* @param coordinates the library coordinates or {@code null}
|
||||
* @param unpackRequired if the library needs to be unpacked before it can be used
|
||||
* @deprecated since 2.4.8 for removal in 2.6.0 in favor of
|
||||
* {@link #Library(String, File, LibraryScope, LibraryCoordinates, boolean, boolean, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Library(String name, File file, LibraryScope scope, LibraryCoordinates coordinates, boolean unpackRequired) {
|
||||
this(name, file, scope, coordinates, unpackRequired, false);
|
||||
}
|
||||
@@ -98,15 +112,37 @@ public class Library {
|
||||
* @param local if the library is local (part of the same build) to the application
|
||||
* that is being packaged
|
||||
* @since 2.4.0
|
||||
* @deprecated since 2.4.8 for removal in 2.6.0 in favor of
|
||||
* {@link #Library(String, File, LibraryScope, LibraryCoordinates, boolean, boolean, boolean)}
|
||||
*/
|
||||
@Deprecated
|
||||
public Library(String name, File file, LibraryScope scope, LibraryCoordinates coordinates, boolean unpackRequired,
|
||||
boolean local) {
|
||||
this(name, file, scope, coordinates, unpackRequired, local, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 coordinates the library coordinates or {@code null}
|
||||
* @param unpackRequired if the library needs to be unpacked before it can be used
|
||||
* @param local if the library is local (part of the same build) to the application
|
||||
* that is being packaged
|
||||
* @param included if the library is included in the fat jar
|
||||
* @since 2.4.8
|
||||
*/
|
||||
public Library(String name, File file, LibraryScope scope, LibraryCoordinates coordinates, boolean unpackRequired,
|
||||
boolean local, boolean included) {
|
||||
this.name = (name != null) ? name : file.getName();
|
||||
this.file = file;
|
||||
this.scope = scope;
|
||||
this.coordinates = coordinates;
|
||||
this.unpackRequired = unpackRequired;
|
||||
this.local = local;
|
||||
this.included = included;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -172,4 +208,12 @@ public class Library {
|
||||
return this.local;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return if the library is included in the fat jar.
|
||||
* @return if the library is included
|
||||
*/
|
||||
public boolean isIncluded() {
|
||||
return this.included;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -25,7 +25,9 @@ import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
import java.util.jar.Manifest;
|
||||
import java.util.stream.Collectors;
|
||||
@@ -191,14 +193,18 @@ public abstract class Packager {
|
||||
|
||||
protected final void write(JarFile sourceJar, Libraries libraries, AbstractJarWriter writer) throws IOException {
|
||||
Assert.notNull(libraries, "Libraries must not be null");
|
||||
WritableLibraries writeableLibraries = new WritableLibraries(libraries);
|
||||
write(sourceJar, writer, new PackagedLibraries(libraries));
|
||||
}
|
||||
|
||||
private void write(JarFile sourceJar, AbstractJarWriter writer, PackagedLibraries libraries) throws IOException {
|
||||
if (isLayered()) {
|
||||
writer.useLayers(this.layers, this.layersIndex);
|
||||
}
|
||||
writer.writeManifest(buildManifest(sourceJar));
|
||||
writeLoaderClasses(writer);
|
||||
writer.writeEntries(sourceJar, getEntityTransformer(), writeableLibraries);
|
||||
writeableLibraries.write(writer);
|
||||
writer.writeEntries(sourceJar, getEntityTransformer(), libraries.getUnpackHandler(),
|
||||
libraries.getEntryFilter());
|
||||
libraries.write(writer);
|
||||
if (isLayered()) {
|
||||
writeLayerIndex(writer);
|
||||
}
|
||||
@@ -456,11 +462,15 @@ public abstract class Packager {
|
||||
* An {@link UnpackHandler} that determines that an entry needs to be unpacked if a
|
||||
* library that requires unpacking has a matching entry name.
|
||||
*/
|
||||
private final class WritableLibraries implements UnpackHandler {
|
||||
private final class PackagedLibraries {
|
||||
|
||||
private final Map<String, Library> libraries = new LinkedHashMap<>();
|
||||
|
||||
WritableLibraries(Libraries libraries) throws IOException {
|
||||
private final UnpackHandler unpackHandler;
|
||||
|
||||
private final Predicate<JarEntry> entryFilter;
|
||||
|
||||
PackagedLibraries(Libraries libraries) throws IOException {
|
||||
libraries.doWithLibraries((library) -> {
|
||||
if (isZip(library::openStream)) {
|
||||
addLibrary(library);
|
||||
@@ -469,6 +479,8 @@ public abstract class Packager {
|
||||
if (isLayered() && Packager.this.includeRelevantJarModeJars) {
|
||||
addLibrary(JarModeLibrary.LAYER_TOOLS);
|
||||
}
|
||||
this.unpackHandler = new PackagedLibrariesUnpackHandler();
|
||||
this.entryFilter = this::isIncluded;
|
||||
}
|
||||
|
||||
private void addLibrary(Library library) {
|
||||
@@ -480,37 +492,58 @@ public abstract class Packager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean requiresUnpack(String name) {
|
||||
Library library = this.libraries.get(name);
|
||||
return library != null && library.isUnpackRequired();
|
||||
private boolean isIncluded(JarEntry entry) {
|
||||
Library library = this.libraries.get(entry.getName());
|
||||
return library == null || library.isIncluded();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sha1Hash(String name) throws IOException {
|
||||
Library library = this.libraries.get(name);
|
||||
Assert.notNull(library, () -> "No library found for entry name '" + name + "'");
|
||||
return Digest.sha1(library::openStream);
|
||||
UnpackHandler getUnpackHandler() {
|
||||
return this.unpackHandler;
|
||||
}
|
||||
|
||||
private void write(AbstractJarWriter writer) throws IOException {
|
||||
Predicate<JarEntry> getEntryFilter() {
|
||||
return this.entryFilter;
|
||||
}
|
||||
|
||||
void write(AbstractJarWriter writer) throws IOException {
|
||||
List<String> writtenPaths = new ArrayList<>();
|
||||
for (Entry<String, Library> entry : this.libraries.entrySet()) {
|
||||
String path = entry.getKey();
|
||||
Library library = entry.getValue();
|
||||
String location = path.substring(0, path.lastIndexOf('/') + 1);
|
||||
writer.writeNestedLibrary(location, library);
|
||||
if (library.isIncluded()) {
|
||||
String location = path.substring(0, path.lastIndexOf('/') + 1);
|
||||
writer.writeNestedLibrary(location, library);
|
||||
writtenPaths.add(path);
|
||||
}
|
||||
}
|
||||
if (getLayout() instanceof RepackagingLayout) {
|
||||
writeClasspathIndex((RepackagingLayout) getLayout(), writer);
|
||||
writeClasspathIndex(writtenPaths, (RepackagingLayout) getLayout(), writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeClasspathIndex(RepackagingLayout layout, AbstractJarWriter writer) throws IOException {
|
||||
List<String> names = this.libraries.keySet().stream().map((path) -> "- \"" + path + "\"")
|
||||
.collect(Collectors.toList());
|
||||
private void writeClasspathIndex(List<String> paths, RepackagingLayout layout, AbstractJarWriter writer)
|
||||
throws IOException {
|
||||
List<String> names = paths.stream().map((path) -> "- \"" + path + "\"").collect(Collectors.toList());
|
||||
writer.writeIndexFile(layout.getClasspathIndexFileLocation(), names);
|
||||
}
|
||||
|
||||
private class PackagedLibrariesUnpackHandler implements UnpackHandler {
|
||||
|
||||
@Override
|
||||
public boolean requiresUnpack(String name) {
|
||||
Library library = PackagedLibraries.this.libraries.get(name);
|
||||
return library != null && library.isUnpackRequired();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String sha1Hash(String name) throws IOException {
|
||||
Library library = PackagedLibraries.this.libraries.get(name);
|
||||
Assert.notNull(library, () -> "No library found for entry name '" + name + "'");
|
||||
return Digest.sha1(library::openStream);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -197,9 +197,9 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
libJarFile.setLastModified(JAN_1_1980);
|
||||
P packager = createPackager();
|
||||
execute(packager, (callback) -> {
|
||||
callback.library(new Library(libJarFile, LibraryScope.COMPILE));
|
||||
callback.library(new Library(libJarFileToUnpack, LibraryScope.COMPILE, true));
|
||||
callback.library(new Library(libNonJarFile, LibraryScope.COMPILE));
|
||||
callback.library(newLibrary(libJarFile, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libJarFileToUnpack, LibraryScope.COMPILE, true));
|
||||
callback.library(newLibrary(libNonJarFile, LibraryScope.COMPILE, false));
|
||||
});
|
||||
assertThat(hasPackagedEntry("BOOT-INF/lib/" + libJarFile.getName())).isTrue();
|
||||
assertThat(hasPackagedEntry("BOOT-INF/lib/" + libJarFileToUnpack.getName())).isTrue();
|
||||
@@ -226,9 +226,9 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
File file = this.testJarFile.getFile();
|
||||
P packager = createPackager(file);
|
||||
execute(packager, (callback) -> {
|
||||
callback.library(new Library(libJarFile1, LibraryScope.COMPILE));
|
||||
callback.library(new Library(libJarFile2, LibraryScope.COMPILE));
|
||||
callback.library(new Library(libJarFile3, LibraryScope.COMPILE));
|
||||
callback.library(newLibrary(libJarFile1, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libJarFile2, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libJarFile3, LibraryScope.COMPILE, false));
|
||||
});
|
||||
assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue();
|
||||
String index = getPackagedEntryContent("BOOT-INF/classpath.idx");
|
||||
@@ -258,9 +258,9 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
packager.setLayers(layers);
|
||||
packager.setIncludeRelevantJarModeJars(false);
|
||||
execute(packager, (callback) -> {
|
||||
callback.library(new Library(libJarFile1, LibraryScope.COMPILE));
|
||||
callback.library(new Library(libJarFile2, LibraryScope.COMPILE));
|
||||
callback.library(new Library(libJarFile3, LibraryScope.COMPILE));
|
||||
callback.library(newLibrary(libJarFile1, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libJarFile2, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libJarFile3, LibraryScope.COMPILE, false));
|
||||
});
|
||||
assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue();
|
||||
String classpathIndex = getPackagedEntryContent("BOOT-INF/classpath.idx");
|
||||
@@ -316,8 +316,8 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
|
||||
P packager = createPackager();
|
||||
assertThatIllegalStateException().isThrownBy(() -> execute(packager, (callback) -> {
|
||||
callback.library(new Library(libJarFile, LibraryScope.COMPILE, false));
|
||||
callback.library(new Library(libJarFile, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libJarFile, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libJarFile, LibraryScope.COMPILE, false));
|
||||
})).withMessageContaining("Duplicate library");
|
||||
}
|
||||
|
||||
@@ -334,7 +334,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
given(layout.getLibraryLocation(anyString(), eq(scope))).willReturn("test/");
|
||||
given(layout.getLibraryLocation(anyString(), eq(LibraryScope.COMPILE))).willReturn("test-lib/");
|
||||
packager.setLayout(layout);
|
||||
execute(packager, (callback) -> callback.library(new Library(libJarFile, scope)));
|
||||
execute(packager, (callback) -> callback.library(newLibrary(libJarFile, scope, false)));
|
||||
assertThat(hasPackagedEntry("test/" + libJarFile.getName())).isTrue();
|
||||
assertThat(getPackagedManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo("test-lib/");
|
||||
assertThat(getPackagedManifest().getMainAttributes().getValue("Main-Class")).isEqualTo("testLauncher");
|
||||
@@ -351,7 +351,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
LibraryScope scope = mock(LibraryScope.class);
|
||||
given(layout.getLauncherClassName()).willReturn("testLauncher");
|
||||
packager.setLayout(layout);
|
||||
execute(packager, (callback) -> callback.library(new Library(libJarFile, scope)));
|
||||
execute(packager, (callback) -> callback.library(newLibrary(libJarFile, scope, false)));
|
||||
assertThat(getPackagedManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isNull();
|
||||
assertThat(getPackagedManifest().getMainAttributes().getValue("Main-Class")).isEqualTo("testLauncher");
|
||||
}
|
||||
@@ -405,7 +405,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
this.testJarFile.addFile("test/nested.jar", nestedFile);
|
||||
this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
|
||||
P packager = createPackager();
|
||||
execute(packager, (callback) -> callback.library(new Library(nestedFile, LibraryScope.COMPILE)));
|
||||
execute(packager, (callback) -> callback.library(newLibrary(nestedFile, LibraryScope.COMPILE, false)));
|
||||
assertThat(getPackagedEntry("BOOT-INF/lib/" + nestedFile.getName()).getMethod()).isEqualTo(ZipEntry.STORED);
|
||||
assertThat(getPackagedEntry("BOOT-INF/classes/test/nested.jar").getMethod()).isEqualTo(ZipEntry.STORED);
|
||||
}
|
||||
@@ -419,7 +419,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
this.testJarFile.addFile(name, nested.getFile());
|
||||
this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
|
||||
P packager = createPackager();
|
||||
execute(packager, (callback) -> callback.library(new Library(nestedFile, LibraryScope.COMPILE, true)));
|
||||
execute(packager, (callback) -> callback.library(newLibrary(nestedFile, LibraryScope.COMPILE, true)));
|
||||
assertThat(getPackagedEntry(name).getComment()).startsWith("UNPACK:");
|
||||
}
|
||||
|
||||
@@ -437,7 +437,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
File toZip = new File(this.tempDir, "to-zip");
|
||||
toZip.createNewFile();
|
||||
ZipUtil.packEntry(toZip, nestedFile);
|
||||
callback.library(new Library(nestedFile, LibraryScope.COMPILE));
|
||||
callback.library(newLibrary(nestedFile, LibraryScope.COMPILE, false));
|
||||
});
|
||||
assertThat(getPackagedEntry("BOOT-INF/lib/" + nestedFile.getName()).getSize()).isEqualTo(sourceLength);
|
||||
}
|
||||
@@ -498,14 +498,14 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
@Test
|
||||
void loaderIsWrittenFirstThenApplicationClassesThenLibraries() throws IOException {
|
||||
this.testJarFile.addClass("com/example/Application.class", ClassWithMainMethod.class);
|
||||
File libraryOne = createLibrary();
|
||||
File libraryTwo = createLibrary();
|
||||
File libraryThree = createLibrary();
|
||||
File libraryOne = createLibraryJar();
|
||||
File libraryTwo = createLibraryJar();
|
||||
File libraryThree = createLibraryJar();
|
||||
P packager = createPackager();
|
||||
execute(packager, (callback) -> {
|
||||
callback.library(new Library(libraryOne, LibraryScope.COMPILE, false));
|
||||
callback.library(new Library(libraryTwo, LibraryScope.COMPILE, true));
|
||||
callback.library(new Library(libraryThree, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libraryOne, LibraryScope.COMPILE, false));
|
||||
callback.library(newLibrary(libraryTwo, LibraryScope.COMPILE, true));
|
||||
callback.library(newLibrary(libraryThree, LibraryScope.COMPILE, false));
|
||||
});
|
||||
assertThat(getPackagedEntryNames()).containsSubsequence("org/springframework/boot/loader/",
|
||||
"BOOT-INF/classes/com/example/Application.class", "BOOT-INF/lib/" + libraryOne.getName(),
|
||||
@@ -514,12 +514,12 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
|
||||
@Test
|
||||
void existingEntryThatMatchesUnpackLibraryIsMarkedForUnpack() throws IOException {
|
||||
File library = createLibrary();
|
||||
File library = createLibraryJar();
|
||||
this.testJarFile.addClass("WEB-INF/classes/com/example/Application.class", ClassWithMainMethod.class);
|
||||
this.testJarFile.addFile("WEB-INF/lib/" + library.getName(), library);
|
||||
P packager = createPackager(this.testJarFile.getFile("war"));
|
||||
packager.setLayout(new Layouts.War());
|
||||
execute(packager, (callback) -> callback.library(new Library(library, LibraryScope.COMPILE, true)));
|
||||
execute(packager, (callback) -> callback.library(newLibrary(library, LibraryScope.COMPILE, true)));
|
||||
assertThat(getPackagedEntryNames()).containsSubsequence("org/springframework/boot/loader/",
|
||||
"WEB-INF/classes/com/example/Application.class", "WEB-INF/lib/" + library.getName());
|
||||
ZipEntry unpackLibrary = getPackagedEntry("WEB-INF/lib/" + library.getName());
|
||||
@@ -536,7 +536,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
Layout layout = mock(Layout.class);
|
||||
LibraryScope scope = mock(LibraryScope.class);
|
||||
packager.setLayout(layout);
|
||||
execute(packager, (callback) -> callback.library(new Library(libJarFile, scope)));
|
||||
execute(packager, (callback) -> callback.library(newLibrary(libJarFile, scope, false)));
|
||||
assertThat(getPackagedEntryNames()).containsExactly("META-INF/", "META-INF/MANIFEST.MF", "a/", "a/b/",
|
||||
"a/b/C.class");
|
||||
}
|
||||
@@ -583,12 +583,39 @@ abstract class AbstractPackagerTests<P extends Packager> {
|
||||
assertThat(getPackagedEntry("BOOT-INF/classes/META-INF/test.kotlin_module")).isNotNull();
|
||||
}
|
||||
|
||||
private File createLibrary() throws IOException {
|
||||
@Test
|
||||
void entryFiltering() throws Exception {
|
||||
File webLibrary = createLibraryJar();
|
||||
File libraryOne = createLibraryJar();
|
||||
File libraryTwo = createLibraryJar();
|
||||
this.testJarFile.addClass("WEB-INF/classes/com/example/Application.class", ClassWithMainMethod.class);
|
||||
this.testJarFile.addFile("WEB-INF/lib/" + webLibrary.getName(), webLibrary);
|
||||
P packager = createPackager(this.testJarFile.getFile("war"));
|
||||
packager.setLayout(new Layouts.War());
|
||||
execute(packager, (callback) -> {
|
||||
callback.library(newLibrary(webLibrary, LibraryScope.COMPILE, false, false));
|
||||
callback.library(newLibrary(libraryOne, LibraryScope.COMPILE, false, false));
|
||||
callback.library(newLibrary(libraryTwo, LibraryScope.COMPILE, false, true));
|
||||
});
|
||||
Collection<String> packagedEntryNames = getPackagedEntryNames();
|
||||
packagedEntryNames.removeIf((name) -> !name.endsWith(".jar"));
|
||||
assertThat(packagedEntryNames).containsExactly("WEB-INF/lib/" + libraryTwo.getName());
|
||||
}
|
||||
|
||||
private File createLibraryJar() throws IOException {
|
||||
TestJarFile library = new TestJarFile(this.tempDir);
|
||||
library.addClass("com/example/library/Library.class", ClassWithoutMainMethod.class);
|
||||
return library.getFile();
|
||||
}
|
||||
|
||||
private Library newLibrary(File file, LibraryScope scope, boolean unpackRequired) {
|
||||
return new Library(null, file, scope, null, unpackRequired, false, true);
|
||||
}
|
||||
|
||||
private Library newLibrary(File file, LibraryScope scope, boolean unpackRequired, boolean included) {
|
||||
return new Library(null, file, scope, null, unpackRequired, false, included);
|
||||
}
|
||||
|
||||
protected final P createPackager() throws IOException {
|
||||
return createPackager(this.testJarFile.getFile());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user