From c51d836a152839075671f6f1254beb19f0bee9a4 Mon Sep 17 00:00:00 2001 From: Stephane Nicoll Date: Mon, 28 Nov 2016 17:41:10 +0100 Subject: [PATCH] Use standard file name for Maven dependencies This commit uses standard files for libraries managed by the repackage goal of the Maven plugin. Previously, only the name of the file was used which could lead to duplicate libraries if the name of the target file deviates from the default. This typically happens when the `build.finalName` property is specified on a dependent module. Note that the `maven-war-plugin` has an additional mechanism to customize the file name structure of dependencies. This feature isn't supported by the repackage goal so an explicit mention has been added in the documentation. Closes gh-7389 --- .../src/it/war-reactor/jar/pom.xml | 18 ++++++ .../src/it/war-reactor/pom.xml | 16 +++++ .../src/it/war-reactor/verify.groovy | 29 +++++++++ .../src/it/war-reactor/war/pom.xml | 61 +++++++++++++++++++ .../java/com/example/SampleApplication.java | 24 ++++++++ .../war/src/main/webapp/index.html | 1 + .../boot/maven/ArtifactsLibraries.java | 19 +++++- .../src/site/apt/usage.apt.vm | 2 + .../boot/maven/ArtifactsLibrariesTests.java | 18 +++++- 9 files changed, 183 insertions(+), 5 deletions(-) create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/jar/pom.xml create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/pom.xml create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/verify.groovy create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/pom.xml create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/java/com/example/SampleApplication.java create mode 100644 spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/webapp/index.html diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/jar/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/jar/pom.xml new file mode 100644 index 00000000000..897420ea934 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/jar/pom.xml @@ -0,0 +1,18 @@ + + + 4.0.0 + + org.springframework.boot.maven.it + war-reactor + 0.0.1.BUILD-SNAPSHOT + + jar + jar + jar + Jar dependency + + + jar + + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/pom.xml new file mode 100644 index 00000000000..8acb5538b01 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/pom.xml @@ -0,0 +1,16 @@ + + + 4.0.0 + org.springframework.boot.maven.it + war-reactor + 0.0.1.BUILD-SNAPSHOT + pom + + UTF-8 + + + jar + war + + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/verify.groovy b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/verify.groovy new file mode 100644 index 00000000000..b63174c8f70 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/verify.groovy @@ -0,0 +1,29 @@ +/* + * Copyright 2012-2015 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 + * + * http://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. + */ + +import java.io.*; +import org.springframework.boot.maven.*; + +File f = new File( basedir, "war/target/war-0.0.1.BUILD-SNAPSHOT.war") +new Verify.WarArchiveVerification(f) { + @Override + protected void verifyZipEntries(Verify.ArchiveVerifier verifier) throws Exception { + super.verifyZipEntries(verifier) + verifier.assertHasEntryNameStartingWith("WEB-INF/lib/jar-0.0.1.BUILD-SNAPSHOT.jar") + verifier.assertHasNoEntryNameStartingWith("WEB-INF/lib/jar.jar") + } +}.verify() + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/pom.xml b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/pom.xml new file mode 100644 index 00000000000..3b2d0d710e9 --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/pom.xml @@ -0,0 +1,61 @@ + + + 4.0.0 + + org.springframework.boot.maven.it + war-reactor + 0.0.1.BUILD-SNAPSHOT + + war + war + war + + + + @project.groupId@ + @project.artifactId@ + @project.version@ + + + + repackage + + + + + + org.apache.maven.plugins + maven-war-plugin + 2.3 + + false + + + Foo + + + + + + + + + org.springframework.boot.maven.it + jar + 0.0.1.BUILD-SNAPSHOT + + + org.springframework + spring-context + @spring.version@ + + + javax.servlet + javax.servlet-api + @servlet-api.version@ + provided + + + + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/java/com/example/SampleApplication.java b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/java/com/example/SampleApplication.java new file mode 100644 index 00000000000..e8784d4593d --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/java/com/example/SampleApplication.java @@ -0,0 +1,24 @@ +/* + * Copyright 2012-2014 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 + * + * http://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) { + } + +} diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/webapp/index.html b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/webapp/index.html new file mode 100644 index 00000000000..18ecdcb795c --- /dev/null +++ b/spring-boot-tools/spring-boot-maven-plugin/src/it/war-reactor/war/src/main/webapp/index.html @@ -0,0 +1 @@ + diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java index 3d478e7f652..77e7bdaa77f 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/main/java/org/springframework/boot/maven/ArtifactsLibraries.java @@ -38,6 +38,7 @@ import org.springframework.boot.loader.tools.LibraryScope; * * @author Phillip Webb * @author Andy Wilkinson + * @author Stephane Nicoll */ public class ArtifactsLibraries implements Libraries { @@ -71,7 +72,7 @@ public class ArtifactsLibraries implements Libraries { for (Artifact artifact : this.artifacts) { LibraryScope scope = SCOPES.get(artifact.getScope()); if (scope != null && artifact.getFile() != null) { - String name = artifact.getFile().getName(); + String name = getFileName(artifact); if (duplicates.contains(name)) { this.log.debug("Duplicate found: " + name); name = artifact.getGroupId() + "-" + name; @@ -87,8 +88,9 @@ public class ArtifactsLibraries implements Libraries { Set duplicates = new HashSet(); Set seen = new HashSet(); for (Artifact artifact : artifacts) { - if (artifact.getFile() != null && !seen.add(artifact.getFile().getName())) { - duplicates.add(artifact.getFile().getName()); + String fileName = getFileName(artifact); + if (artifact.getFile() != null && !seen.add(fileName)) { + duplicates.add(fileName); } } return duplicates; @@ -106,4 +108,15 @@ public class ArtifactsLibraries implements Libraries { return false; } + private String getFileName(Artifact artifact) { + StringBuilder sb = new StringBuilder(); + sb.append(artifact.getArtifactId()).append("-").append(artifact.getVersion()); + String classifier = artifact.getClassifier(); + if (classifier != null) { + sb.append("-").append(classifier); + } + sb.append(".").append(artifact.getArtifactHandler().getExtension()); + return sb.toString(); + } + } diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm index 4d819ee9139..5e501a2ada1 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm +++ b/spring-boot-tools/spring-boot-maven-plugin/src/site/apt/usage.apt.vm @@ -57,6 +57,8 @@ Usage including any <<>> dependencies that are defined in the project. If some of these dependencies need to be excluded, you can use one of the exclude options, see {{{./examples/exclude-dependency.html}Exclude a dependency}} for more details. + Please note that the <<>> feature of the <<>> + is currently not supported. The original (i.e. non executable) artifact is renamed to <<<.original>>> by default but it is also possible to keep the original artifact using a custom classifier. diff --git a/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ArtifactsLibrariesTests.java b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ArtifactsLibrariesTests.java index e36f21ffde1..df636e2120e 100644 --- a/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ArtifactsLibrariesTests.java +++ b/spring-boot-tools/spring-boot-maven-plugin/src/test/java/org/springframework/boot/maven/ArtifactsLibrariesTests.java @@ -23,6 +23,7 @@ import java.util.LinkedHashSet; import java.util.Set; import org.apache.maven.artifact.Artifact; +import org.apache.maven.artifact.handler.ArtifactHandler; import org.apache.maven.model.Dependency; import org.apache.maven.plugin.logging.Log; import org.junit.Before; @@ -52,6 +53,9 @@ public class ArtifactsLibrariesTests { @Mock private Artifact artifact; + @Mock + private ArtifactHandler artifactHandler; + private Set artifacts; private File file = new File("."); @@ -70,6 +74,8 @@ public class ArtifactsLibrariesTests { this.artifacts = Collections.singleton(this.artifact); this.libs = new ArtifactsLibraries(this.artifacts, null, mock(Log.class)); given(this.artifact.getFile()).willReturn(this.file); + given(this.artifactHandler.getExtension()).willReturn("jar"); + given(this.artifact.getArtifactHandler()).willReturn(this.artifactHandler); } @Test @@ -107,17 +113,25 @@ public class ArtifactsLibrariesTests { given(artifact1.getType()).willReturn("jar"); given(artifact1.getScope()).willReturn("compile"); given(artifact1.getGroupId()).willReturn("g1"); + given(artifact1.getArtifactId()).willReturn("artifact"); + given(artifact1.getVersion()).willReturn("1.0"); given(artifact1.getFile()).willReturn(new File("a")); + given(artifact1.getArtifactHandler()).willReturn(this.artifactHandler); given(artifact2.getType()).willReturn("jar"); given(artifact2.getScope()).willReturn("compile"); given(artifact2.getGroupId()).willReturn("g2"); + given(artifact2.getArtifactId()).willReturn("artifact"); + given(artifact2.getVersion()).willReturn("1.0"); given(artifact2.getFile()).willReturn(new File("a")); + given(artifact2.getArtifactHandler()).willReturn(this.artifactHandler); this.artifacts = new LinkedHashSet(Arrays.asList(artifact1, artifact2)); this.libs = new ArtifactsLibraries(this.artifacts, null, mock(Log.class)); this.libs.doWithLibraries(this.callback); verify(this.callback, times(2)).library(this.libraryCaptor.capture()); - assertThat(this.libraryCaptor.getAllValues().get(0).getName()).isEqualTo("g1-a"); - assertThat(this.libraryCaptor.getAllValues().get(1).getName()).isEqualTo("g2-a"); + assertThat(this.libraryCaptor.getAllValues().get(0).getName()).isEqualTo( + "g1-artifact-1.0.jar"); + assertThat(this.libraryCaptor.getAllValues().get(1).getName()).isEqualTo( + "g2-artifact-1.0.jar"); } }