When maven-war-plugin builds a war file, it includes all artifact dependencies and put them into WEB-INF/lib folder, but maven-jar-plugin does not.
That is why excluding works perfectly for jar, but does not work for war.
This commit provides a new method Layout.getLibrariesLocation() that returns the location of the libraries within the archive.
The Jar Entries which are located in this Libraries Location should be filtered out, as the new libraries will be added at the end of the repackaging process.
fixes gh-15808
Comment From: nosan
Thanks,
I spent a lot of time to find a way to rework this to use getLibraryDestination(String, LibraryScope),
and telling the truth I don't know how it can be done at the moment.
this method will return the wrong location for a provided artifact in a war – it will return WEB-INF/lib when it should return WEB-INF/lib-provided.
maven-war-plugin does not include provided dependencies.
Here is a small background why excluding is not working for WAR.
RepackageMojo:
private void repackage() throws MojoExecutionException {
// (1)
Artifact source = getSourceArtifact();
File target = getTargetFile();
Repackager repackager = getRepackager(source.getFile());
// (2)
Set<Artifact> artifacts = filterDependencies(this.project.getArtifacts(), getFilters(getAdditionalFilters()));
//(3)
Libraries libraries = new ArtifactsLibraries(artifacts, this.requiresUnpack, getLog());
try {
LaunchScript launchScript = getLaunchScript();
repackager.repackage(target, libraries, launchScript);
}
catch (IOException ex) {
throw new MojoExecutionException(ex.getMessage(), ex);
}
updateArtifact(source, target, repackager.getBackupFile());
}
- a source
warhas already hadWEB-INF/libfolder which has been added bymaven-war-pluginbefore. RepackageMojofilters all dependencies using the filters. (such asexcludeGroupIds, )RepackageMojocreatesArtifactsLibrarieswhich includes only filtered libraries.
then, Repackager tries to repackage the sourceJar using the given libraries and other parameters:
Repackager:
```java
private void repackage(JarFile sourceJar, File destination, Libraries libraries, LaunchScript launchScript)
throws IOException {
// (1)
WritableLibraries writeableLibraries = new WritableLibraries(libraries);
try (JarWriter writer = new JarWriter(destination, launchScript)) {
writer.writeManifest(buildManifest(sourceJar));
writeLoaderClasses(writer);
if (this.layout instanceof RepackagingLayout) {
// (2)
writer.writeEntries(sourceJar,
new RenamingEntryTransformer(((RepackagingLayout) this.layout).getRepackagedClassesLocation()), writeableLibraries);
}
else {
// (2)
writer.writeEntries(sourceJar, writeableLibraries);
}
// (3)
writeableLibraries.write(writer);
}
}
```
- Source
jarhas already hadWEB-INF/libfolder with dependencies, asmaven-war-pluginincludes allcompiledependencies and put them beneathWEB-INF/libfolder. JarWriteradds all jar entries fromsourceJarinto thedestination. (includingWEB-INF/lib)- Write libraries
So, summarizing the above I can not understand how getLibraryDestination(String, LibraryScope) can help here.
In my opinion, JarWriter should avoid any libraries, because for this purpose WritableLibraries is responsible. Currently, there is no way to exclude/filter jar entries during the JarWriter.writeEntries process.
Comment From: wilkinsona
maven-war-plugindoes not include provided dependencies.
Unfortunately, I don't think that helps here. I really don't want to add a public API that only gives the right answer when used in one particular scenario.
It sounds like we need to find a different approach to solving this one. Thanks anyway for your efforts.