Commit 5fc0e1ca authored by Phillip Webb's avatar Phillip Webb

Merge branch '2.5.x'

Closes gh-27057
parents aa3d72cb af37f591
...@@ -198,7 +198,7 @@ abstract class ArchiveCommand extends OptionParsingCommand { ...@@ -198,7 +198,7 @@ abstract class ArchiveCommand extends OptionParsingCommand {
List<Library> libraries = new ArrayList<>(); List<Library> libraries = new ArrayList<>();
for (URL dependency : dependencies) { for (URL dependency : dependencies) {
File file = new File(dependency.toURI()); File file = new File(dependency.toURI());
libraries.add(new Library(file, getLibraryScope(file))); libraries.add(new Library(null, file, getLibraryScope(file), null, false, false, true));
} }
return libraries; return libraries;
} }
...@@ -256,7 +256,7 @@ abstract class ArchiveCommand extends OptionParsingCommand { ...@@ -256,7 +256,7 @@ abstract class ArchiveCommand extends OptionParsingCommand {
List<Library> libraries = new ArrayList<>(); List<Library> libraries = new ArrayList<>();
for (MatchedResource entry : entries) { for (MatchedResource entry : entries) {
if (entry.isRoot()) { if (entry.isRoot()) {
libraries.add(new Library(entry.getFile(), LibraryScope.COMPILE)); libraries.add(new Library(null, entry.getFile(), LibraryScope.COMPILE, null, false, false, true));
} }
else { else {
writeClasspathEntry(writer, entry); writeClasspathEntry(writer, entry);
......
...@@ -37,7 +37,7 @@ public class MyBuildTool { ...@@ -37,7 +37,7 @@ public class MyBuildTool {
private void getLibraries(LibraryCallback callback) throws IOException { private void getLibraries(LibraryCallback callback) throws IOException {
// Build system specific implementation, callback for each dependency // Build system specific implementation, callback for each dependency
for (File nestedJar : getCompileScopeJars()) { for (File nestedJar : getCompileScopeJars()) {
callback.library(new Library(nestedJar, LibraryScope.COMPILE)); callback.library(new Library(null, nestedJar, LibraryScope.COMPILE, null, false, false, true));
} }
// ... // ...
} }
......
...@@ -24,6 +24,7 @@ import org.gradle.api.specs.Spec; ...@@ -24,6 +24,7 @@ import org.gradle.api.specs.Spec;
import org.springframework.boot.gradle.tasks.bundling.ResolvedDependencies.DependencyDescriptor; import org.springframework.boot.gradle.tasks.bundling.ResolvedDependencies.DependencyDescriptor;
import org.springframework.boot.loader.tools.Layer; import org.springframework.boot.loader.tools.Layer;
import org.springframework.boot.loader.tools.Library; import org.springframework.boot.loader.tools.Library;
import org.springframework.boot.loader.tools.LibraryCoordinates;
/** /**
* Resolver backed by a {@link LayeredSpec} that provides the destination {@link Layer} * Resolver backed by a {@link LayeredSpec} that provides the destination {@link Layer}
...@@ -77,9 +78,12 @@ class LayerResolver { ...@@ -77,9 +78,12 @@ class LayerResolver {
private Library asLibrary(FileCopyDetails details) { private Library asLibrary(FileCopyDetails details) {
File file = details.getFile(); File file = details.getFile();
DependencyDescriptor dependency = this.resolvedDependencies.find(file); DependencyDescriptor dependency = this.resolvedDependencies.find(file);
return (dependency != null) if (dependency == null) {
? new Library(null, file, null, dependency.getCoordinates(), false, dependency.isProjectDependency()) return new Library(null, file, null, null, false, false, true);
: new Library(file, null); }
LibraryCoordinates coordinates = dependency.getCoordinates();
boolean projectDependency = dependency.isProjectDependency();
return new Library(null, file, null, coordinates, false, projectDependency, true);
} }
} }
...@@ -30,7 +30,7 @@ import java.util.Collection; ...@@ -30,7 +30,7 @@ import java.util.Collection;
import java.util.Enumeration; import java.util.Enumeration;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.function.Predicate; import java.util.function.Function;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.JarInputStream; import java.util.jar.JarInputStream;
...@@ -89,24 +89,33 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { ...@@ -89,24 +89,33 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
* Write all entries from the specified jar file. * Write all entries from the specified jar file.
* @param jarFile the source jar file * @param jarFile the source jar file
* @throws IOException if the entries cannot be written * @throws IOException if the entries cannot be written
* @deprecated since 2.4.8 for removal in 2.6.0
*/ */
@Deprecated
public void writeEntries(JarFile jarFile) throws IOException { public void writeEntries(JarFile jarFile) throws IOException {
writeEntries(jarFile, EntryTransformer.NONE, UnpackHandler.NEVER, (name) -> false); writeEntries(jarFile, EntryTransformer.NONE, UnpackHandler.NEVER, (entry) -> null);
} }
final void writeEntries(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler, final void writeEntries(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler,
Predicate<String> libraryPredicate) throws IOException { Function<JarEntry, Library> libraryLookup) throws IOException {
Enumeration<JarEntry> entries = jarFile.entries(); Enumeration<JarEntry> entries = jarFile.entries();
while (entries.hasMoreElements()) { while (entries.hasMoreElements()) {
JarArchiveEntry entry = new JarArchiveEntry(entries.nextElement()); JarEntry entry = entries.nextElement();
setUpEntry(jarFile, entry); Library library = libraryLookup.apply(entry);
try (ZipHeaderPeekInputStream inputStream = new ZipHeaderPeekInputStream(jarFile.getInputStream(entry))) { if (library == null || library.isIncluded()) {
EntryWriter entryWriter = new InputStreamEntryWriter(inputStream); writeEntry(jarFile, entryTransformer, unpackHandler, new JarArchiveEntry(entry), library);
JarArchiveEntry transformedEntry = entryTransformer.transform(entry); }
if (transformedEntry != null) { }
boolean updateLayerIndex = !libraryPredicate.test(entry.getName()); }
writeEntry(transformedEntry, entryWriter, unpackHandler, updateLayerIndex);
} private void writeEntry(JarFile jarFile, EntryTransformer entryTransformer, UnpackHandler unpackHandler,
JarArchiveEntry entry, Library library) 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, library, entryWriter, unpackHandler);
} }
} }
} }
...@@ -160,15 +169,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { ...@@ -160,15 +169,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
entry.setTime(getNestedLibraryTime(library)); entry.setTime(getNestedLibraryTime(library));
new CrcAndSize(library::openStream).setupStoredEntry(entry); new CrcAndSize(library::openStream).setupStoredEntry(entry);
try (InputStream inputStream = library.openStream()) { try (InputStream inputStream = library.openStream()) {
writeEntry(entry, new InputStreamEntryWriter(inputStream), new LibraryUnpackHandler(library), false); writeEntry(entry, library, new InputStreamEntryWriter(inputStream), new LibraryUnpackHandler(library));
updateLayerIndex(entry.getName(), library);
}
}
private void updateLayerIndex(String name, Library library) {
if (this.layers != null) {
Layer layer = this.layers.getLayer(library);
this.layersIndex.add(layer, name);
} }
} }
...@@ -249,20 +250,20 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { ...@@ -249,20 +250,20 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
} }
private void writeEntry(JarArchiveEntry entry, EntryWriter entryWriter) throws IOException { private void writeEntry(JarArchiveEntry entry, EntryWriter entryWriter) throws IOException {
writeEntry(entry, entryWriter, UnpackHandler.NEVER, true); writeEntry(entry, null, entryWriter, UnpackHandler.NEVER);
} }
/** /**
* Perform the actual write of a {@link JarEntry}. All other write methods delegate to * Perform the actual write of a {@link JarEntry}. All other write methods delegate to
* this one. * this one.
* @param entry the entry to write * @param entry the entry to write
* @param library the library for the entry or {@code null}
* @param entryWriter the entry writer or {@code null} if there is no content * @param entryWriter the entry writer or {@code null} if there is no content
* @param unpackHandler handles possible unpacking for the entry * @param unpackHandler handles possible unpacking for the entry
* @param updateLayerIndex if the layer index should be updated
* @throws IOException in case of I/O errors * @throws IOException in case of I/O errors
*/ */
private void writeEntry(JarArchiveEntry entry, EntryWriter entryWriter, UnpackHandler unpackHandler, private void writeEntry(JarArchiveEntry entry, Library library, EntryWriter entryWriter,
boolean updateLayerIndex) throws IOException { UnpackHandler unpackHandler) throws IOException {
String name = entry.getName(); String name = entry.getName();
writeParentDirectoryEntries(name); writeParentDirectoryEntries(name);
if (this.writtenEntries.add(name)) { if (this.writtenEntries.add(name)) {
...@@ -273,16 +274,14 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { ...@@ -273,16 +274,14 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
entry.setSize(entryWriter.size()); entry.setSize(entryWriter.size());
} }
entryWriter = addUnpackCommentIfNecessary(entry, entryWriter, unpackHandler); entryWriter = addUnpackCommentIfNecessary(entry, entryWriter, unpackHandler);
if (updateLayerIndex) { updateLayerIndex(entry, library);
updateLayerIndex(entry);
}
writeToArchive(entry, entryWriter); writeToArchive(entry, entryWriter);
} }
} }
private void updateLayerIndex(JarArchiveEntry entry) { private void updateLayerIndex(JarArchiveEntry entry, Library library) {
if (this.layers != null && !entry.getName().endsWith("/")) { if (this.layers != null && !entry.getName().endsWith("/")) {
Layer layer = this.layers.getLayer(entry.getName()); Layer layer = (library != null) ? this.layers.getLayer(library) : this.layers.getLayer(entry.getName());
this.layersIndex.add(layer, entry.getName()); this.layersIndex.add(layer, entry.getName());
} }
} }
...@@ -294,7 +293,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter { ...@@ -294,7 +293,7 @@ public abstract class AbstractJarWriter implements LoaderClassesWriter {
while (parent.lastIndexOf('/') != -1) { while (parent.lastIndexOf('/') != -1) {
parent = parent.substring(0, parent.lastIndexOf('/')); parent = parent.substring(0, parent.lastIndexOf('/'));
if (!parent.isEmpty()) { if (!parent.isEmpty()) {
writeEntry(new JarArchiveEntry(parent + "/"), null, UnpackHandler.NEVER, false); writeEntry(new JarArchiveEntry(parent + "/"), null, null, UnpackHandler.NEVER);
} }
} }
} }
......
...@@ -42,7 +42,7 @@ public class JarModeLibrary extends Library { ...@@ -42,7 +42,7 @@ public class JarModeLibrary extends Library {
} }
public JarModeLibrary(LibraryCoordinates coordinates) { 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) { private static LibraryCoordinates createCoordinates(String artifactId) {
......
...@@ -43,11 +43,16 @@ public class Library { ...@@ -43,11 +43,16 @@ public class Library {
private final boolean local; private final boolean local;
private final boolean included;
/** /**
* Create a new {@link Library}. * Create a new {@link Library}.
* @param file the source file * @param file the source file
* @param scope the scope of the library * @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) { public Library(File file, LibraryScope scope) {
this(file, scope, false); this(file, scope, false);
} }
...@@ -57,7 +62,10 @@ public class Library { ...@@ -57,7 +62,10 @@ public class Library {
* @param file the source file * @param file the source file
* @param scope the scope of the library * @param scope the scope of the library
* @param unpackRequired if the library needs to be unpacked before it can be used * @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) { public Library(File file, LibraryScope scope, boolean unpackRequired) {
this(null, file, scope, unpackRequired); this(null, file, scope, unpackRequired);
} }
...@@ -69,7 +77,10 @@ public class Library { ...@@ -69,7 +77,10 @@ public class Library {
* @param file the source file * @param file the source file
* @param scope the scope of the library * @param scope the scope of the library
* @param unpackRequired if the library needs to be unpacked before it can be used * @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) { public Library(String name, File file, LibraryScope scope, boolean unpackRequired) {
this(name, file, scope, null, unpackRequired); this(name, file, scope, null, unpackRequired);
} }
...@@ -82,7 +93,10 @@ public class Library { ...@@ -82,7 +93,10 @@ public class Library {
* @param scope the scope of the library * @param scope the scope of the library
* @param coordinates the library coordinates or {@code null} * @param coordinates the library coordinates or {@code null}
* @param unpackRequired if the library needs to be unpacked before it can be used * @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) { public Library(String name, File file, LibraryScope scope, LibraryCoordinates coordinates, boolean unpackRequired) {
this(name, file, scope, coordinates, unpackRequired, false); this(name, file, scope, coordinates, unpackRequired, false);
} }
...@@ -98,15 +112,37 @@ public class Library { ...@@ -98,15 +112,37 @@ public class Library {
* @param local if the library is local (part of the same build) to the application * @param local if the library is local (part of the same build) to the application
* that is being packaged * that is being packaged
* @since 2.4.0 * @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, public Library(String name, File file, LibraryScope scope, LibraryCoordinates coordinates, boolean unpackRequired,
boolean local) { 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.name = (name != null) ? name : file.getName();
this.file = file; this.file = file;
this.scope = scope; this.scope = scope;
this.coordinates = coordinates; this.coordinates = coordinates;
this.unpackRequired = unpackRequired; this.unpackRequired = unpackRequired;
this.local = local; this.local = local;
this.included = included;
} }
/** /**
...@@ -172,4 +208,12 @@ public class Library { ...@@ -172,4 +208,12 @@ public class Library {
return this.local; 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; ...@@ -25,7 +25,9 @@ import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.jar.Attributes; import java.util.jar.Attributes;
import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.Manifest; import java.util.jar.Manifest;
import java.util.stream.Collectors; import java.util.stream.Collectors;
...@@ -191,14 +193,18 @@ public abstract class Packager { ...@@ -191,14 +193,18 @@ public abstract class Packager {
protected final void write(JarFile sourceJar, Libraries libraries, AbstractJarWriter writer) throws IOException { protected final void write(JarFile sourceJar, Libraries libraries, AbstractJarWriter writer) throws IOException {
Assert.notNull(libraries, "Libraries must not be null"); 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()) { if (isLayered()) {
writer.useLayers(this.layers, this.layersIndex); writer.useLayers(this.layers, this.layersIndex);
} }
writer.writeManifest(buildManifest(sourceJar)); writer.writeManifest(buildManifest(sourceJar));
writeLoaderClasses(writer); writeLoaderClasses(writer);
writer.writeEntries(sourceJar, getEntityTransformer(), writeableLibraries, writeableLibraries::containsEntry); writer.writeEntries(sourceJar, getEntityTransformer(), libraries.getUnpackHandler(),
writeableLibraries.write(writer); libraries.getLibraryLookup());
libraries.write(writer);
if (isLayered()) { if (isLayered()) {
writeLayerIndex(writer); writeLayerIndex(writer);
} }
...@@ -451,11 +457,15 @@ public abstract class Packager { ...@@ -451,11 +457,15 @@ public abstract class Packager {
* An {@link UnpackHandler} that determines that an entry needs to be unpacked if a * An {@link UnpackHandler} that determines that an entry needs to be unpacked if a
* library that requires unpacking has a matching entry name. * 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<>(); private final Map<String, Library> libraries = new LinkedHashMap<>();
WritableLibraries(Libraries libraries) throws IOException { private final UnpackHandler unpackHandler;
private final Function<JarEntry, Library> libraryLookup;
PackagedLibraries(Libraries libraries) throws IOException {
libraries.doWithLibraries((library) -> { libraries.doWithLibraries((library) -> {
if (isZip(library::openStream)) { if (isZip(library::openStream)) {
addLibrary(library); addLibrary(library);
...@@ -464,6 +474,8 @@ public abstract class Packager { ...@@ -464,6 +474,8 @@ public abstract class Packager {
if (isLayered() && Packager.this.includeRelevantJarModeJars) { if (isLayered() && Packager.this.includeRelevantJarModeJars) {
addLibrary(JarModeLibrary.LAYER_TOOLS); addLibrary(JarModeLibrary.LAYER_TOOLS);
} }
this.unpackHandler = new PackagedLibrariesUnpackHandler();
this.libraryLookup = this::lookup;
} }
private void addLibrary(Library library) { private void addLibrary(Library library) {
...@@ -475,41 +487,57 @@ public abstract class Packager { ...@@ -475,41 +487,57 @@ public abstract class Packager {
} }
} }
@Override private Library lookup(JarEntry entry) {
public boolean requiresUnpack(String name) { return this.libraries.get(entry.getName());
Library library = this.libraries.get(name);
return library != null && library.isUnpackRequired();
} }
@Override UnpackHandler getUnpackHandler() {
public String sha1Hash(String name) throws IOException { return this.unpackHandler;
Library library = this.libraries.get(name);
Assert.notNull(library, () -> "No library found for entry name '" + name + "'");
return Digest.sha1(library::openStream);
} }
boolean containsEntry(String name) { Function<JarEntry, Library> getLibraryLookup() {
return this.libraries.containsKey(name); return this.libraryLookup;
} }
private void write(AbstractJarWriter writer) throws IOException { void write(AbstractJarWriter writer) throws IOException {
List<String> writtenPaths = new ArrayList<>();
for (Entry<String, Library> entry : this.libraries.entrySet()) { for (Entry<String, Library> entry : this.libraries.entrySet()) {
String path = entry.getKey(); String path = entry.getKey();
Library library = entry.getValue(); Library library = entry.getValue();
String location = path.substring(0, path.lastIndexOf('/') + 1); if (library.isIncluded()) {
writer.writeNestedLibrary(location, library); String location = path.substring(0, path.lastIndexOf('/') + 1);
writer.writeNestedLibrary(location, library);
writtenPaths.add(path);
}
} }
if (Packager.this.layout instanceof RepackagingLayout) { if (getLayout() instanceof RepackagingLayout) {
writeClasspathIndex(getLayout(), writer); writeClasspathIndex(writtenPaths, (RepackagingLayout) getLayout(), writer);
} }
} }
private void writeClasspathIndex(Layout layout, AbstractJarWriter writer) throws IOException { private void writeClasspathIndex(List<String> paths, RepackagingLayout layout, AbstractJarWriter writer)
List<String> names = this.libraries.keySet().stream().map((path) -> "- \"" + path + "\"") throws IOException {
.collect(Collectors.toList()); List<String> names = paths.stream().map((path) -> "- \"" + path + "\"").collect(Collectors.toList());
writer.writeIndexFile(layout.getClasspathIndexFileLocation(), names); 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> { ...@@ -197,9 +197,9 @@ abstract class AbstractPackagerTests<P extends Packager> {
libJarFile.setLastModified(JAN_1_1980); libJarFile.setLastModified(JAN_1_1980);
P packager = createPackager(); P packager = createPackager();
execute(packager, (callback) -> { execute(packager, (callback) -> {
callback.library(new Library(libJarFile, LibraryScope.COMPILE)); callback.library(newLibrary(libJarFile, LibraryScope.COMPILE, false));
callback.library(new Library(libJarFileToUnpack, LibraryScope.COMPILE, true)); callback.library(newLibrary(libJarFileToUnpack, LibraryScope.COMPILE, true));
callback.library(new Library(libNonJarFile, LibraryScope.COMPILE)); callback.library(newLibrary(libNonJarFile, LibraryScope.COMPILE, false));
}); });
assertThat(hasPackagedEntry("BOOT-INF/lib/" + libJarFile.getName())).isTrue(); assertThat(hasPackagedEntry("BOOT-INF/lib/" + libJarFile.getName())).isTrue();
assertThat(hasPackagedEntry("BOOT-INF/lib/" + libJarFileToUnpack.getName())).isTrue(); assertThat(hasPackagedEntry("BOOT-INF/lib/" + libJarFileToUnpack.getName())).isTrue();
...@@ -226,9 +226,9 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -226,9 +226,9 @@ abstract class AbstractPackagerTests<P extends Packager> {
File file = this.testJarFile.getFile(); File file = this.testJarFile.getFile();
P packager = createPackager(file); P packager = createPackager(file);
execute(packager, (callback) -> { execute(packager, (callback) -> {
callback.library(new Library(libJarFile1, LibraryScope.COMPILE)); callback.library(newLibrary(libJarFile1, LibraryScope.COMPILE, false));
callback.library(new Library(libJarFile2, LibraryScope.COMPILE)); callback.library(newLibrary(libJarFile2, LibraryScope.COMPILE, false));
callback.library(new Library(libJarFile3, LibraryScope.COMPILE)); callback.library(newLibrary(libJarFile3, LibraryScope.COMPILE, false));
}); });
assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue(); assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue();
String index = getPackagedEntryContent("BOOT-INF/classpath.idx"); String index = getPackagedEntryContent("BOOT-INF/classpath.idx");
...@@ -258,9 +258,9 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -258,9 +258,9 @@ abstract class AbstractPackagerTests<P extends Packager> {
packager.setLayers(layers); packager.setLayers(layers);
packager.setIncludeRelevantJarModeJars(false); packager.setIncludeRelevantJarModeJars(false);
execute(packager, (callback) -> { execute(packager, (callback) -> {
callback.library(new Library(libJarFile1, LibraryScope.COMPILE)); callback.library(newLibrary(libJarFile1, LibraryScope.COMPILE, false));
callback.library(new Library(libJarFile2, LibraryScope.COMPILE)); callback.library(newLibrary(libJarFile2, LibraryScope.COMPILE, false));
callback.library(new Library(libJarFile3, LibraryScope.COMPILE)); callback.library(newLibrary(libJarFile3, LibraryScope.COMPILE, false));
}); });
assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue(); assertThat(hasPackagedEntry("BOOT-INF/classpath.idx")).isTrue();
String classpathIndex = getPackagedEntryContent("BOOT-INF/classpath.idx"); String classpathIndex = getPackagedEntryContent("BOOT-INF/classpath.idx");
...@@ -316,8 +316,8 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -316,8 +316,8 @@ abstract class AbstractPackagerTests<P extends Packager> {
this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class); this.testJarFile.addClass("a/b/C.class", ClassWithMainMethod.class);
P packager = createPackager(); P packager = createPackager();
assertThatIllegalStateException().isThrownBy(() -> execute(packager, (callback) -> { assertThatIllegalStateException().isThrownBy(() -> execute(packager, (callback) -> {
callback.library(new Library(libJarFile, LibraryScope.COMPILE, false)); callback.library(newLibrary(libJarFile, LibraryScope.COMPILE, false));
callback.library(new Library(libJarFile, LibraryScope.COMPILE, false)); callback.library(newLibrary(libJarFile, LibraryScope.COMPILE, false));
})).withMessageContaining("Duplicate library"); })).withMessageContaining("Duplicate library");
} }
...@@ -334,7 +334,7 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -334,7 +334,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
given(layout.getLibraryLocation(anyString(), eq(scope))).willReturn("test/"); given(layout.getLibraryLocation(anyString(), eq(scope))).willReturn("test/");
given(layout.getLibraryLocation(anyString(), eq(LibraryScope.COMPILE))).willReturn("test-lib/"); given(layout.getLibraryLocation(anyString(), eq(LibraryScope.COMPILE))).willReturn("test-lib/");
packager.setLayout(layout); 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(hasPackagedEntry("test/" + libJarFile.getName())).isTrue();
assertThat(getPackagedManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo("test-lib/"); assertThat(getPackagedManifest().getMainAttributes().getValue("Spring-Boot-Lib")).isEqualTo("test-lib/");
assertThat(getPackagedManifest().getMainAttributes().getValue("Main-Class")).isEqualTo("testLauncher"); assertThat(getPackagedManifest().getMainAttributes().getValue("Main-Class")).isEqualTo("testLauncher");
...@@ -351,7 +351,7 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -351,7 +351,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
LibraryScope scope = mock(LibraryScope.class); LibraryScope scope = mock(LibraryScope.class);
given(layout.getLauncherClassName()).willReturn("testLauncher"); given(layout.getLauncherClassName()).willReturn("testLauncher");
packager.setLayout(layout); 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("Spring-Boot-Lib")).isNull();
assertThat(getPackagedManifest().getMainAttributes().getValue("Main-Class")).isEqualTo("testLauncher"); assertThat(getPackagedManifest().getMainAttributes().getValue("Main-Class")).isEqualTo("testLauncher");
} }
...@@ -405,7 +405,7 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -405,7 +405,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
this.testJarFile.addFile("test/nested.jar", nestedFile); this.testJarFile.addFile("test/nested.jar", nestedFile);
this.testJarFile.addClass("A.class", ClassWithMainMethod.class); this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
P packager = createPackager(); 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/lib/" + nestedFile.getName()).getMethod()).isEqualTo(ZipEntry.STORED);
assertThat(getPackagedEntry("BOOT-INF/classes/test/nested.jar").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> { ...@@ -419,7 +419,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
this.testJarFile.addFile(name, nested.getFile()); this.testJarFile.addFile(name, nested.getFile());
this.testJarFile.addClass("A.class", ClassWithMainMethod.class); this.testJarFile.addClass("A.class", ClassWithMainMethod.class);
P packager = createPackager(); 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:"); assertThat(getPackagedEntry(name).getComment()).startsWith("UNPACK:");
} }
...@@ -437,7 +437,7 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -437,7 +437,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
File toZip = new File(this.tempDir, "to-zip"); File toZip = new File(this.tempDir, "to-zip");
toZip.createNewFile(); toZip.createNewFile();
ZipUtil.packEntry(toZip, nestedFile); 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); assertThat(getPackagedEntry("BOOT-INF/lib/" + nestedFile.getName()).getSize()).isEqualTo(sourceLength);
} }
...@@ -498,14 +498,14 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -498,14 +498,14 @@ abstract class AbstractPackagerTests<P extends Packager> {
@Test @Test
void loaderIsWrittenFirstThenApplicationClassesThenLibraries() throws IOException { void loaderIsWrittenFirstThenApplicationClassesThenLibraries() throws IOException {
this.testJarFile.addClass("com/example/Application.class", ClassWithMainMethod.class); this.testJarFile.addClass("com/example/Application.class", ClassWithMainMethod.class);
File libraryOne = createLibrary(); File libraryOne = createLibraryJar();
File libraryTwo = createLibrary(); File libraryTwo = createLibraryJar();
File libraryThree = createLibrary(); File libraryThree = createLibraryJar();
P packager = createPackager(); P packager = createPackager();
execute(packager, (callback) -> { execute(packager, (callback) -> {
callback.library(new Library(libraryOne, LibraryScope.COMPILE, false)); callback.library(newLibrary(libraryOne, LibraryScope.COMPILE, false));
callback.library(new Library(libraryTwo, LibraryScope.COMPILE, true)); callback.library(newLibrary(libraryTwo, LibraryScope.COMPILE, true));
callback.library(new Library(libraryThree, LibraryScope.COMPILE, false)); callback.library(newLibrary(libraryThree, LibraryScope.COMPILE, false));
}); });
assertThat(getPackagedEntryNames()).containsSubsequence("org/springframework/boot/loader/", assertThat(getPackagedEntryNames()).containsSubsequence("org/springframework/boot/loader/",
"BOOT-INF/classes/com/example/Application.class", "BOOT-INF/lib/" + libraryOne.getName(), "BOOT-INF/classes/com/example/Application.class", "BOOT-INF/lib/" + libraryOne.getName(),
...@@ -514,12 +514,12 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -514,12 +514,12 @@ abstract class AbstractPackagerTests<P extends Packager> {
@Test @Test
void existingEntryThatMatchesUnpackLibraryIsMarkedForUnpack() throws IOException { void existingEntryThatMatchesUnpackLibraryIsMarkedForUnpack() throws IOException {
File library = createLibrary(); File library = createLibraryJar();
this.testJarFile.addClass("WEB-INF/classes/com/example/Application.class", ClassWithMainMethod.class); this.testJarFile.addClass("WEB-INF/classes/com/example/Application.class", ClassWithMainMethod.class);
this.testJarFile.addFile("WEB-INF/lib/" + library.getName(), library); this.testJarFile.addFile("WEB-INF/lib/" + library.getName(), library);
P packager = createPackager(this.testJarFile.getFile("war")); P packager = createPackager(this.testJarFile.getFile("war"));
packager.setLayout(new Layouts.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/", assertThat(getPackagedEntryNames()).containsSubsequence("org/springframework/boot/loader/",
"WEB-INF/classes/com/example/Application.class", "WEB-INF/lib/" + library.getName()); "WEB-INF/classes/com/example/Application.class", "WEB-INF/lib/" + library.getName());
ZipEntry unpackLibrary = getPackagedEntry("WEB-INF/lib/" + library.getName()); ZipEntry unpackLibrary = getPackagedEntry("WEB-INF/lib/" + library.getName());
...@@ -536,7 +536,7 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -536,7 +536,7 @@ abstract class AbstractPackagerTests<P extends Packager> {
Layout layout = mock(Layout.class); Layout layout = mock(Layout.class);
LibraryScope scope = mock(LibraryScope.class); LibraryScope scope = mock(LibraryScope.class);
packager.setLayout(layout); 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/", assertThat(getPackagedEntryNames()).containsExactly("META-INF/", "META-INF/MANIFEST.MF", "a/", "a/b/",
"a/b/C.class"); "a/b/C.class");
} }
...@@ -583,12 +583,39 @@ abstract class AbstractPackagerTests<P extends Packager> { ...@@ -583,12 +583,39 @@ abstract class AbstractPackagerTests<P extends Packager> {
assertThat(getPackagedEntry("BOOT-INF/classes/META-INF/test.kotlin_module")).isNotNull(); 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); TestJarFile library = new TestJarFile(this.tempDir);
library.addClass("com/example/library/Library.class", ClassWithoutMainMethod.class); library.addClass("com/example/library/Library.class", ClassWithoutMainMethod.class);
return library.getFile(); 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 { protected final P createPackager() throws IOException {
return createPackager(this.testJarFile.getFile()); return createPackager(this.testJarFile.getFile());
} }
......
...@@ -190,4 +190,13 @@ class WarIntegrationTests extends AbstractArchiveIntegrationTests { ...@@ -190,4 +190,13 @@ class WarIntegrationTests extends AbstractArchiveIntegrationTests {
}); });
} }
@TestTemplate
void whenEntryIsExcludedItShouldNotBePresentInTheRepackagedWar(MavenBuild mavenBuild) {
mavenBuild.project("war-exclude-entry").execute((project) -> {
File war = new File(project, "target/war-exclude-entry-0.0.1.BUILD-SNAPSHOT.war");
assertThat(jar(war)).hasEntryWithNameStartingWith("WEB-INF/lib/spring-context")
.doesNotHaveEntryWithNameStartingWith("WEB-INF/lib/spring-core");
});
}
} }
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.springframework.boot.maven.it</groupId>
<artifactId>war-exclude-entry</artifactId>
<version>0.0.1.BUILD-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>@java.version@</maven.compiler.source>
<maven.compiler.target>@java.version@</maven.compiler.target>
</properties>
<build>
<plugins>
<plugin>
<groupId>@project.groupId@</groupId>
<artifactId>@project.artifactId@</artifactId>
<version>@project.version@</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclude>
</excludes>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>@maven-war-plugin.version@</version>
<configuration>
<archive>
<manifestEntries>
<Not-Used>Foo</Not-Used>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>@spring-framework.version@</version>
</dependency>
<dependency>
<groupId>jakarta.servlet</groupId>
<artifactId>jakarta.servlet-api</artifactId>
<version>@jakarta-servlet.version@</version>
<scope>provided</scope>
</dependency>
</dependencies>
</project>
/*
* Copyright 2012-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.test;
public class SampleApplication {
public static void main(String[] args) {
}
}
...@@ -76,7 +76,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo { ...@@ -76,7 +76,7 @@ public abstract class AbstractDependencyFilterMojo extends AbstractMojo {
this.excludeGroupIds = excludeGroupIds; this.excludeGroupIds = excludeGroupIds;
} }
protected Set<Artifact> filterDependencies(Set<Artifact> dependencies, FilterArtifacts filters) protected final Set<Artifact> filterDependencies(Set<Artifact> dependencies, FilterArtifacts filters)
throws MojoExecutionException { throws MojoExecutionException {
try { try {
Set<Artifact> filtered = new LinkedHashSet<>(dependencies); Set<Artifact> filtered = new LinkedHashSet<>(dependencies);
......
...@@ -182,11 +182,9 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo ...@@ -182,11 +182,9 @@ public abstract class AbstractPackagerMojo extends AbstractDependencyFilterMojo
* @throws MojoExecutionException on execution error * @throws MojoExecutionException on execution error
*/ */
protected final Libraries getLibraries(Collection<Dependency> unpacks) throws MojoExecutionException { protected final Libraries getLibraries(Collection<Dependency> unpacks) throws MojoExecutionException {
String packaging = this.project.getPackaging(); Set<Artifact> artifacts = this.project.getArtifacts();
Set<Artifact> projectArtifacts = this.project.getArtifacts(); Set<Artifact> includedArtifacts = filterDependencies(artifacts, getFilters(getAdditionalFilters()));
Set<Artifact> artifacts = ("war".equals(packaging)) ? projectArtifacts return new ArtifactsLibraries(artifacts, includedArtifacts, this.session.getProjects(), unpacks, getLog());
: filterDependencies(projectArtifacts, getFilters(getAdditionalFilters()));
return new ArtifactsLibraries(artifacts, this.session.getProjects(), unpacks, getLog());
} }
private ArtifactsFilter[] getAdditionalFilters() { private ArtifactsFilter[] getAdditionalFilters() {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
package org.springframework.boot.maven; package org.springframework.boot.maven;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
...@@ -59,6 +60,8 @@ public class ArtifactsLibraries implements Libraries { ...@@ -59,6 +60,8 @@ public class ArtifactsLibraries implements Libraries {
private final Set<Artifact> artifacts; private final Set<Artifact> artifacts;
private final Set<Artifact> includedArtifacts;
private final Collection<MavenProject> localProjects; private final Collection<MavenProject> localProjects;
private final Collection<Dependency> unpacks; private final Collection<Dependency> unpacks;
...@@ -89,7 +92,23 @@ public class ArtifactsLibraries implements Libraries { ...@@ -89,7 +92,23 @@ public class ArtifactsLibraries implements Libraries {
*/ */
public ArtifactsLibraries(Set<Artifact> artifacts, Collection<MavenProject> localProjects, public ArtifactsLibraries(Set<Artifact> artifacts, Collection<MavenProject> localProjects,
Collection<Dependency> unpacks, Log log) { Collection<Dependency> unpacks, Log log) {
this(artifacts, artifacts, localProjects, unpacks, log);
}
/**
* Creates a new {@code ArtifactsLibraries} from the given {@code artifacts}.
* @param artifacts all artifacts that can be represented as libraries
* @param includedArtifacts the actual artifacts to include in the fat jar
* @param localProjects projects for which {@link Library#isLocal() local} libraries
* should be created
* @param unpacks artifacts that should be unpacked on launch
* @param log the log
* @since 2.4.8
*/
public ArtifactsLibraries(Set<Artifact> artifacts, Set<Artifact> includedArtifacts,
Collection<MavenProject> localProjects, Collection<Dependency> unpacks, Log log) {
this.artifacts = artifacts; this.artifacts = artifacts;
this.includedArtifacts = includedArtifacts;
this.localProjects = localProjects; this.localProjects = localProjects;
this.unpacks = unpacks; this.unpacks = unpacks;
this.log = log; this.log = log;
...@@ -99,18 +118,22 @@ public class ArtifactsLibraries implements Libraries { ...@@ -99,18 +118,22 @@ public class ArtifactsLibraries implements Libraries {
public void doWithLibraries(LibraryCallback callback) throws IOException { public void doWithLibraries(LibraryCallback callback) throws IOException {
Set<String> duplicates = getDuplicates(this.artifacts); Set<String> duplicates = getDuplicates(this.artifacts);
for (Artifact artifact : this.artifacts) { for (Artifact artifact : this.artifacts) {
String name = getFileName(artifact);
File file = artifact.getFile();
LibraryScope scope = SCOPES.get(artifact.getScope()); LibraryScope scope = SCOPES.get(artifact.getScope());
if (scope != null && artifact.getFile() != null) { if (scope == null || file == null) {
String name = getFileName(artifact); continue;
if (duplicates.contains(name)) { }
this.log.debug("Duplicate found: " + name); if (duplicates.contains(name)) {
name = artifact.getGroupId() + "-" + name; this.log.debug("Duplicate found: " + name);
this.log.debug("Renamed to: " + name); name = artifact.getGroupId() + "-" + name;
} this.log.debug("Renamed to: " + name);
LibraryCoordinates coordinates = new ArtifactLibraryCoordinates(artifact);
callback.library(new Library(name, artifact.getFile(), scope, coordinates, isUnpackRequired(artifact),
isLocal(artifact)));
} }
LibraryCoordinates coordinates = new ArtifactLibraryCoordinates(artifact);
boolean unpackRequired = isUnpackRequired(artifact);
boolean local = isLocal(artifact);
boolean included = this.includedArtifacts.contains(artifact);
callback.library(new Library(name, file, scope, coordinates, unpackRequired, local, included));
} }
} }
......
...@@ -189,8 +189,8 @@ public class BuildImageMojo extends AbstractPackagerMojo { ...@@ -189,8 +189,8 @@ public class BuildImageMojo extends AbstractPackagerMojo {
} }
/** /**
* Return the layout factory that will be used to determine the {@link LayoutType} if * Return the layout factory that will be used to determine the
* no explicit layout is set. * {@link AbstractPackagerMojo.LayoutType} if no explicit layout is set.
* @return the value of the {@code layoutFactory} parameter, or {@code null} if the * @return the value of the {@code layoutFactory} parameter, or {@code null} if the
* parameter is not provided * parameter is not provided
*/ */
......
...@@ -183,8 +183,8 @@ public class RepackageMojo extends AbstractPackagerMojo { ...@@ -183,8 +183,8 @@ public class RepackageMojo extends AbstractPackagerMojo {
} }
/** /**
* Return the layout factory that will be used to determine the {@link LayoutType} if * Return the layout factory that will be used to determine the
* no explicit layout is set. * {@link AbstractPackagerMojo.LayoutType} if no explicit layout is set.
* @return the value of the {@code layoutFactory} parameter, or {@code null} if the * @return the value of the {@code layoutFactory} parameter, or {@code null} if the
* parameter is not provided * parameter is not provided
*/ */
......
...@@ -144,6 +144,7 @@ class ArtifactsLibrariesTests { ...@@ -144,6 +144,7 @@ class ArtifactsLibrariesTests {
this.artifacts = Collections.singleton(snapshotArtifact); this.artifacts = Collections.singleton(snapshotArtifact);
new ArtifactsLibraries(this.artifacts, Collections.emptyList(), null, mock(Log.class)) new ArtifactsLibraries(this.artifacts, Collections.emptyList(), null, mock(Log.class))
.doWithLibraries((library) -> { .doWithLibraries((library) -> {
assertThat(library.isIncluded()).isTrue();
assertThat(library.isLocal()).isFalse(); assertThat(library.isLocal()).isFalse();
assertThat(library.getCoordinates().getVersion()).isEqualTo("1.0-SNAPSHOT"); assertThat(library.getCoordinates().getVersion()).isEqualTo("1.0-SNAPSHOT");
}); });
...@@ -181,4 +182,19 @@ class ArtifactsLibrariesTests { ...@@ -181,4 +182,19 @@ class ArtifactsLibrariesTests {
.doWithLibraries((library) -> assertThat(library.isLocal()).isTrue()); .doWithLibraries((library) -> assertThat(library.isLocal()).isTrue());
} }
@Test
void nonIncludedArtifact() throws IOException {
Artifact artifact = mock(Artifact.class);
given(artifact.getScope()).willReturn("compile");
given(artifact.getArtifactId()).willReturn("artifact");
given(artifact.getBaseVersion()).willReturn("1.0-SNAPSHOT");
given(artifact.getFile()).willReturn(new File("a"));
given(artifact.getArtifactHandler()).willReturn(this.artifactHandler);
MavenProject mavenProject = mock(MavenProject.class);
given(mavenProject.getArtifact()).willReturn(artifact);
this.artifacts = Collections.singleton(artifact);
new ArtifactsLibraries(this.artifacts, Collections.emptySet(), Collections.singleton(mavenProject), null,
mock(Log.class)).doWithLibraries((library) -> assertThat(library.isIncluded()).isFalse());
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment