Skip to content

Commit 69c61d0

Browse files
committed
Include transitive file dependencies during Gradle repackaging
Previously, ProjectLibraries only considered a configuration's direct file dependencies. This meant that a transitive file dependency that should have been pulled in via a project dependency was not included in the repackaged jar's lib directory. ProjectLibraries has been updated to walk down the tree of project dependencies and create libraries for any file dependencies that are found. Fixes gh-1368
1 parent c7045f5 commit 69c61d0

File tree

6 files changed

+129
-4
lines changed

6 files changed

+129
-4
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright 2012-2014 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.gradle;
18+
19+
import java.io.File;
20+
import java.io.IOException;
21+
import java.util.jar.JarFile;
22+
23+
import org.gradle.tooling.ProjectConnection;
24+
import org.junit.BeforeClass;
25+
import org.junit.Test;
26+
import org.springframework.boot.dependency.tools.ManagedDependencies;
27+
import org.springframework.util.FileCopyUtils;
28+
29+
import static org.hamcrest.Matchers.notNullValue;
30+
import static org.junit.Assert.assertThat;
31+
32+
/**
33+
* Integration tests for Gradle repackaging with a multi-project build.
34+
*
35+
* @author Andy Wilkinson
36+
*/
37+
public class MultiProjectRepackagingTests {
38+
39+
private static final String BOOT_VERSION = ManagedDependencies.get()
40+
.find("spring-boot").getVersion();
41+
42+
private static ProjectConnection project;
43+
44+
@BeforeClass
45+
public static void createProject() throws IOException {
46+
project = new ProjectCreator().createProject("multi-project-repackage");
47+
}
48+
49+
@Test
50+
public void repackageWithTransitiveFileDependency() throws Exception {
51+
FileCopyUtils.copy(new File("src/test/resources/foo.jar"), new File(
52+
"target/multi-project-repackage/foo.jar"));
53+
project.newBuild().forTasks("clean", "build")
54+
.withArguments("-PbootVersion=" + BOOT_VERSION, "-Prepackage=true").run();
55+
File buildLibs = new File("target/multi-project-repackage/main/build/libs");
56+
JarFile jarFile = new JarFile(new File(buildLibs, "main.jar"));
57+
assertThat(jarFile.getEntry("lib/commons-logging-1.1.3.jar"), notNullValue());
58+
assertThat(jarFile.getEntry("lib/foo.jar"), notNullValue());
59+
jarFile.close();
60+
}
61+
}

spring-boot-integration-tests/src/test/java/org/springframework/boot/gradle/ProjectCreator.java

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import org.gradle.tooling.ProjectConnection;
2424
import org.gradle.tooling.internal.consumer.DefaultGradleConnector;
2525
import org.springframework.util.FileCopyUtils;
26+
import org.springframework.util.FileSystemUtils;
2627

2728
/**
2829
* @author Andy Wilkinson
@@ -34,8 +35,15 @@ public ProjectConnection createProject(String name) throws IOException {
3435
projectDirectory.mkdirs();
3536

3637
File gradleScript = new File(projectDirectory, "build.gradle");
37-
FileCopyUtils.copy(new File("src/test/resources/" + name + ".gradle"),
38-
gradleScript);
38+
39+
if (new File("src/test/resources", name).isDirectory()) {
40+
FileSystemUtils.copyRecursively(new File("src/test/resources", name),
41+
projectDirectory);
42+
}
43+
else {
44+
FileCopyUtils.copy(new File("src/test/resources/" + name + ".gradle"),
45+
gradleScript);
46+
}
3947

4048
GradleConnector gradleConnector = GradleConnector.newConnector();
4149
((DefaultGradleConnector) gradleConnector).embedded(true);

spring-boot-integration-tests/src/test/java/org/springframework/boot/gradle/RepackagingTests.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,5 +132,4 @@ public void repackageWithFileDependency() throws Exception {
132132
assertThat(jarFile.getEntry("lib/foo.jar"), notNullValue());
133133
jarFile.close();
134134
}
135-
136135
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
buildscript {
2+
repositories {
3+
mavenLocal()
4+
}
5+
dependencies {
6+
classpath "org.springframework.boot:spring-boot-gradle-plugin:${project.bootVersion}"
7+
}
8+
}
9+
10+
project('main') {
11+
apply plugin: 'spring-boot'
12+
apply plugin: 'java'
13+
14+
repositories {
15+
mavenLocal()
16+
mavenCentral()
17+
}
18+
19+
dependencies {
20+
compile project(':common')
21+
}
22+
23+
springBoot {
24+
mainClass = 'foo.bar.Baz'
25+
}
26+
}
27+
28+
project('common') {
29+
apply plugin: 'java'
30+
31+
repositories {
32+
mavenLocal()
33+
mavenCentral()
34+
}
35+
36+
dependencies {
37+
compile "commons-logging:commons-logging:1.1.3"
38+
compile files { "lib/foo.jar" }
39+
}
40+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
2+
include 'main'
3+
include 'common'

spring-boot-tools/spring-boot-gradle-plugin/src/main/groovy/org/springframework/boot/gradle/repackage/ProjectLibraries.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.gradle.api.artifacts.Dependency;
2828
import org.gradle.api.artifacts.FileCollectionDependency;
2929
import org.gradle.api.artifacts.ModuleVersionIdentifier;
30+
import org.gradle.api.artifacts.ProjectDependency;
3031
import org.gradle.api.artifacts.ResolvedArtifact;
3132
import org.springframework.boot.gradle.SpringBootPluginExtension;
3233
import org.springframework.boot.loader.tools.Libraries;
@@ -109,13 +110,26 @@ private Set<Library> getLibraries(String configurationName, LibraryScope scope)
109110
.getResolvedArtifacts()) {
110111
libraries.add(new ResolvedArtifactLibrary(artifact, scope));
111112
}
113+
libraries.addAll(getLibrariesForFileDependencies(configuration, scope));
114+
115+
return libraries;
116+
}
117+
118+
private Set<Library> getLibrariesForFileDependencies(Configuration configuration,
119+
LibraryScope scope) {
120+
Set<Library> libraries = new LinkedHashSet<Library>();
112121
for (Dependency dependency : configuration.getIncoming().getDependencies()) {
113122
if (dependency instanceof FileCollectionDependency) {
114123
FileCollectionDependency fileDependency = (FileCollectionDependency) dependency;
115124
for (File file : fileDependency.resolve()) {
116125
libraries.add(new Library(file, scope));
117126
}
118127
}
128+
else if (dependency instanceof ProjectDependency) {
129+
ProjectDependency projectDependency = (ProjectDependency) dependency;
130+
libraries.addAll(getLibrariesForFileDependencies(
131+
projectDependency.getProjectConfiguration(), scope));
132+
}
119133
}
120134
return libraries;
121135
}
@@ -161,7 +175,7 @@ public ResolvedArtifactLibrary(ResolvedArtifact artifact, LibraryScope scope) {
161175
@Override
162176
public boolean isUnpackRequired() {
163177
if (ProjectLibraries.this.extension.getRequiresUnpack() != null) {
164-
ModuleVersionIdentifier id = artifact.getModuleVersion().getId();
178+
ModuleVersionIdentifier id = this.artifact.getModuleVersion().getId();
165179
return ProjectLibraries.this.extension.getRequiresUnpack().contains(
166180
id.getGroup() + ":" + id.getName());
167181
}

0 commit comments

Comments
 (0)