Skip to content

Commit 1bc41ec

Browse files
committed
Stop developmentOnly from removing too much from executable jars and wars
Fixes gh-21288
1 parent 66e8968 commit 1bc41ec

File tree

8 files changed

+37
-10
lines changed

8 files changed

+37
-10
lines changed

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/JavaPluginAction.java

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,13 @@ private TaskProvider<BootJar> configureBootJarTask(Project project) {
9494
bootJar.setGroup(BasePlugin.BUILD_GROUP);
9595
SourceSet mainSourceSet = javaPluginConvention(project).getSourceSets()
9696
.getByName(SourceSet.MAIN_SOURCE_SET_NAME);
97-
bootJar.classpath((Callable<FileCollection>) () -> mainSourceSet.getRuntimeClasspath().minus(
98-
project.getConfigurations().getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME)));
97+
bootJar.classpath((Callable<FileCollection>) () -> {
98+
Configuration developmentOnly = project.getConfigurations()
99+
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
100+
Configuration productionRuntimeClasspath = project.getConfigurations()
101+
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
102+
return mainSourceSet.getRuntimeClasspath().minus((developmentOnly.minus(productionRuntimeClasspath)));
103+
});
99104
bootJar.conventionMapping("mainClassName", new MainClassConvention(project, bootJar::getClasspath));
100105
});
101106
}
@@ -165,8 +170,13 @@ private void configureDevelopmentOnlyConfiguration(Project project) {
165170
.create(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
166171
developmentOnly
167172
.setDescription("Configuration for development-only dependencies such as Spring Boot's DevTools.");
168-
project.getConfigurations().getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME)
169-
.extendsFrom(developmentOnly);
173+
Configuration runtimeClasspath = project.getConfigurations()
174+
.getByName(JavaPlugin.RUNTIME_CLASSPATH_CONFIGURATION_NAME);
175+
Configuration productionRuntimeClasspath = project.getConfigurations()
176+
.create(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
177+
productionRuntimeClasspath.setVisible(false);
178+
productionRuntimeClasspath.setExtendsFrom(runtimeClasspath.getExtendsFrom());
179+
runtimeClasspath.extendsFrom(developmentOnly);
170180
}
171181

172182
/**

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ public class SpringBootPlugin implements Plugin<Project> {
7676
*/
7777
public static final String DEVELOPMENT_ONLY_CONFIGURATION_NAME = "developmentOnly";
7878

79+
static final String PRODUCTION_RUNTIME_CLASSPATH_NAME = "productionRuntimeClasspath";
80+
7981
/**
8082
* The coordinates {@code (group:name:version)} of the
8183
* {@code spring-boot-dependencies} bom.

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/WarPluginAction.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.gradle.api.Action;
2020
import org.gradle.api.Plugin;
2121
import org.gradle.api.Project;
22+
import org.gradle.api.artifacts.Configuration;
2223
import org.gradle.api.artifacts.ConfigurationContainer;
2324
import org.gradle.api.file.FileCollection;
2425
import org.gradle.api.internal.artifacts.dsl.LazyPublishArtifact;
@@ -64,8 +65,11 @@ private TaskProvider<BootWar> configureBootWarTask(Project project) {
6465
bootWar.setDescription("Assembles an executable war archive containing webapp"
6566
+ " content, and the main classes and their dependencies.");
6667
bootWar.providedClasspath(providedRuntimeConfiguration(project));
67-
bootWar.setClasspath(bootWar.getClasspath().minus(
68-
project.getConfigurations().getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME)));
68+
Configuration developmentOnly = project.getConfigurations()
69+
.getByName(SpringBootPlugin.DEVELOPMENT_ONLY_CONFIGURATION_NAME);
70+
Configuration productionRuntimeClasspath = project.getConfigurations()
71+
.getByName(SpringBootPlugin.PRODUCTION_RUNTIME_CLASSPATH_NAME);
72+
bootWar.setClasspath(bootWar.getClasspath().minus((developmentOnly.minus(productionRuntimeClasspath))));
6973
bootWar.conventionMapping("mainClassName", new MainClassConvention(project, bootWar::getClasspath));
7074
});
7175
}

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/AbstractBootArchiveIntegrationTests.java

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,14 @@ abstract class AbstractBootArchiveIntegrationTests {
4646

4747
private final String libPath;
4848

49+
private final String classesPath;
50+
4951
GradleBuild gradleBuild;
5052

51-
protected AbstractBootArchiveIntegrationTests(String taskName, String libPath) {
53+
protected AbstractBootArchiveIntegrationTests(String taskName, String libPath, String classesPath) {
5254
this.taskName = taskName;
5355
this.libPath = libPath;
56+
this.classesPath = classesPath;
5457
}
5558

5659
@TestTemplate
@@ -142,12 +145,18 @@ void duplicatesAreHandledGracefully() throws IOException {
142145

143146
@TestTemplate
144147
void developmentOnlyDependenciesAreNotIncludedInTheArchiveByDefault() throws IOException {
148+
File srcMainResources = new File(this.gradleBuild.getProjectDir(), "src/main/resources");
149+
srcMainResources.mkdirs();
150+
new File(srcMainResources, "resource").createNewFile();
145151
assertThat(this.gradleBuild.build(this.taskName).task(":" + this.taskName).getOutcome())
146152
.isEqualTo(TaskOutcome.SUCCESS);
147153
try (JarFile jarFile = new JarFile(new File(this.gradleBuild.getProjectDir(), "build/libs").listFiles()[0])) {
148154
Stream<String> libEntryNames = jarFile.stream().filter((entry) -> !entry.isDirectory())
149155
.map(JarEntry::getName).filter((name) -> name.startsWith(this.libPath));
150156
assertThat(libEntryNames).containsExactly(this.libPath + "commons-io-2.6.jar");
157+
Stream<String> classesEntryNames = jarFile.stream().filter((entry) -> !entry.isDirectory())
158+
.map(JarEntry::getName).filter((name) -> name.startsWith(this.classesPath));
159+
assertThat(classesEntryNames).containsExactly(this.classesPath + "resource");
151160
}
152161
}
153162

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
class BootJarIntegrationTests extends AbstractBootArchiveIntegrationTests {
5959

6060
BootJarIntegrationTests() {
61-
super("bootJar", "BOOT-INF/lib/");
61+
super("bootJar", "BOOT-INF/lib/", "BOOT-INF/classes/");
6262
}
6363

6464
@TestTemplate

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootWarIntegrationTests.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2012-2019 the original author or authors.
2+
* Copyright 2012-2020 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,7 +24,7 @@
2424
class BootWarIntegrationTests extends AbstractBootArchiveIntegrationTests {
2525

2626
BootWarIntegrationTests() {
27-
super("bootWar", "WEB-INF/lib/");
27+
super("bootWar", "WEB-INF/lib/", "WEB-INF/classes/");
2828
}
2929

3030
}

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootJarIntegrationTests-developmentOnlyDependenciesAreNotIncludedInTheArchiveByDefault.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ repositories {
1313

1414
dependencies {
1515
developmentOnly("org.apache.commons:commons-lang3:3.9")
16+
developmentOnly("commons-io:commons-io:2.6")
1617
implementation("commons-io:commons-io:2.6")
1718
}

spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/tasks/bundling/BootWarIntegrationTests-developmentOnlyDependenciesAreNotIncludedInTheArchiveByDefault.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,6 @@ repositories {
1313

1414
dependencies {
1515
developmentOnly("org.apache.commons:commons-lang3:3.9")
16+
developmentOnly("commons-io:commons-io:2.6")
1617
implementation("commons-io:commons-io:2.6")
1718
}

0 commit comments

Comments
 (0)