From 76f03a8cadad8a6aafb8d80a8c8856eed86e4e42 Mon Sep 17 00:00:00 2001 From: Andy Wilkinson Date: Wed, 27 Nov 2019 12:45:23 +0000 Subject: [PATCH] Fix reflective access to archiveBaseName property Previously, reflective access to the archiveBaseName property incorrectly treated the property as a String. It should have been treated as a Property. This caused an exception to be thrown and the deprecated baseName property to be used as a fallback. This commit corrects the reflective access to the archiveBaseName property. It also updates the tests to fail if a build outputs a deprecation warning. Tests that use Gradle's Maven plugin have been updated to expect deprecation warnings when run with Gradle 6.0 where the plugin is deprecated. Tests that configure an archive's base name have been updated to use archiveBaseName when running with Gradle 6.0 and later. Closes gh-18663 --- .../boot/gradle/dsl/SpringBootExtension.java | 4 +++- .../bundling/LaunchScriptConfiguration.java | 4 +++- .../dsl/BuildInfoDslIntegrationTests.java | 20 +++++++++---------- .../MavenPluginActionIntegrationTests.java | 3 ++- .../tasks/bundling/MavenIntegrationTests.java | 6 ++++-- .../boot/gradle/testkit/GradleBuild.java | 17 +++++++++++++++- ...lIntegrationTests-jarWithCustomName.gradle | 9 ++++++++- ...lIntegrationTests-warWithCustomName.gradle | 9 ++++++++- 8 files changed, 54 insertions(+), 18 deletions(-) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java index adeb6f5449..d1d8e78a41 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/dsl/SpringBootExtension.java @@ -24,6 +24,7 @@ import org.gradle.api.Project; import org.gradle.api.plugins.BasePlugin; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginConvention; +import org.gradle.api.provider.Property; import org.gradle.api.tasks.SourceSet; import org.gradle.api.tasks.bundling.AbstractArchiveTask; import org.gradle.jvm.tasks.Jar; @@ -128,11 +129,12 @@ public class SpringBootExtension { return (Jar) this.project.getTasks().findByName("bootJar"); } + @SuppressWarnings("unchecked") private static String getArchiveBaseName(AbstractArchiveTask task) { try { Method method = findMethod(task.getClass(), "getArchiveBaseName"); if (method != null) { - return (String) method.invoke(task); + return ((Property) method.invoke(task)).get(); } } catch (Exception ex) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LaunchScriptConfiguration.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LaunchScriptConfiguration.java index f2cbd8e1ad..343d9935ab 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LaunchScriptConfiguration.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/LaunchScriptConfiguration.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.regex.Pattern; import org.gradle.api.Project; +import org.gradle.api.provider.Property; import org.gradle.api.tasks.bundling.AbstractArchiveTask; import org.springframework.boot.loader.tools.FileUtils; @@ -57,11 +58,12 @@ public class LaunchScriptConfiguration implements Serializable { putIfMissing(this.properties, "initInfoDescription", augmentLineBreaks(project.getDescription()), baseName); } + @SuppressWarnings("unchecked") private static String getArchiveBaseName(AbstractArchiveTask task) { try { Method method = findMethod(task.getClass(), "getArchiveBaseName"); if (method != null) { - return (String) method.invoke(task); + return ((Property) method.invoke(task)).get(); } } catch (Exception ex) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests.java index cc7615d8e4..0207668f20 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests.java @@ -22,12 +22,12 @@ import java.io.IOException; import java.util.Properties; import org.gradle.testkit.runner.TaskOutcome; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; +import org.springframework.boot.gradle.junit.GradleCompatibilityExtension; import org.springframework.boot.gradle.tasks.buildinfo.BuildInfo; import org.springframework.boot.gradle.testkit.GradleBuild; -import org.springframework.boot.gradle.testkit.GradleBuildExtension; import static org.assertj.core.api.Assertions.assertThat; @@ -37,12 +37,12 @@ import static org.assertj.core.api.Assertions.assertThat; * * @author Andy Wilkinson */ -@ExtendWith(GradleBuildExtension.class) +@ExtendWith(GradleCompatibilityExtension.class) class BuildInfoDslIntegrationTests { - final GradleBuild gradleBuild = new GradleBuild(); + GradleBuild gradleBuild; - @Test + @TestTemplate void basicJar() throws IOException { assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome()) .isEqualTo(TaskOutcome.SUCCESS); @@ -53,7 +53,7 @@ class BuildInfoDslIntegrationTests { assertThat(properties).containsEntry("build.version", "1.0"); } - @Test + @TestTemplate void jarWithCustomName() throws IOException { assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome()) .isEqualTo(TaskOutcome.SUCCESS); @@ -64,7 +64,7 @@ class BuildInfoDslIntegrationTests { assertThat(properties).containsEntry("build.version", "1.0"); } - @Test + @TestTemplate void basicWar() throws IOException { assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome()) .isEqualTo(TaskOutcome.SUCCESS); @@ -75,7 +75,7 @@ class BuildInfoDslIntegrationTests { assertThat(properties).containsEntry("build.version", "1.0"); } - @Test + @TestTemplate void warWithCustomName() throws IOException { assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome()) .isEqualTo(TaskOutcome.SUCCESS); @@ -86,7 +86,7 @@ class BuildInfoDslIntegrationTests { assertThat(properties).containsEntry("build.version", "1.0"); } - @Test + @TestTemplate void additionalProperties() throws IOException { assertThat(this.gradleBuild.build("bootBuildInfo", "--stacktrace").task(":bootBuildInfo").getOutcome()) .isEqualTo(TaskOutcome.SUCCESS); @@ -99,7 +99,7 @@ class BuildInfoDslIntegrationTests { assertThat(properties).containsEntry("build.b", "bravo"); } - @Test + @TestTemplate void classesDependency() throws IOException { assertThat(this.gradleBuild.build("classes", "--stacktrace").task(":bootBuildInfo").getOutcome()) .isEqualTo(TaskOutcome.SUCCESS); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/MavenPluginActionIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/MavenPluginActionIntegrationTests.java index 97928fd210..e8ccfe4f7e 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/MavenPluginActionIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/MavenPluginActionIntegrationTests.java @@ -36,7 +36,8 @@ public class MavenPluginActionIntegrationTests { @TestTemplate public void clearsConf2ScopeMappingsOfUploadBootArchivesTask() { - assertThat(this.gradleBuild.build("conf2ScopeMappings").getOutput()).contains("Conf2ScopeMappings = 0"); + assertThat(this.gradleBuild.expectDeprecationWarningsWithAtLeastVersion("6.0.0").build("conf2ScopeMappings") + .getOutput()).contains("Conf2ScopeMappings = 0"); } } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/MavenIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/MavenIntegrationTests.java index a2d6e344c9..89dc86cb90 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/MavenIntegrationTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/MavenIntegrationTests.java @@ -42,7 +42,8 @@ public class MavenIntegrationTests { @TestTemplate public void bootJarCanBeUploaded() throws FileNotFoundException, IOException { - BuildResult result = this.gradleBuild.build("uploadBootArchives"); + BuildResult result = this.gradleBuild.expectDeprecationWarningsWithAtLeastVersion("6.0.0") + .build("uploadBootArchives"); assertThat(result.task(":uploadBootArchives").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); assertThat(artifactWithSuffix("jar")).isFile(); assertThat(artifactWithSuffix("pom")).is(pomWith().groupId("com.example") @@ -51,7 +52,8 @@ public class MavenIntegrationTests { @TestTemplate public void bootWarCanBeUploaded() throws IOException { - BuildResult result = this.gradleBuild.build("uploadBootArchives"); + BuildResult result = this.gradleBuild.expectDeprecationWarningsWithAtLeastVersion("6.0.0") + .build("uploadBootArchives"); assertThat(result.task(":uploadBootArchives").getOutcome()).isEqualTo(TaskOutcome.SUCCESS); assertThat(artifactWithSuffix("war")).isFile(); assertThat(artifactWithSuffix("pom")) diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java index 6978bd8250..b41e1a04d3 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/GradleBuild.java @@ -32,6 +32,7 @@ import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension; import org.apache.commons.compress.archivers.ArchiveEntry; import org.gradle.testkit.runner.BuildResult; import org.gradle.testkit.runner.GradleRunner; +import org.gradle.util.GradleVersion; import org.jetbrains.kotlin.cli.common.PropertiesKt; import org.jetbrains.kotlin.compilerRunner.KotlinLogger; import org.jetbrains.kotlin.daemon.client.KotlinCompilerClient; @@ -44,6 +45,8 @@ import org.springframework.boot.loader.tools.LaunchScript; import org.springframework.util.FileCopyUtils; import org.springframework.util.FileSystemUtils; +import static org.assertj.core.api.Assertions.assertThat; + /** * A {@code GradleBuild} is used to run a Gradle build using {@link GradleRunner}. * @@ -59,6 +62,8 @@ public class GradleBuild { private String gradleVersion; + private GradleVersion expectDeprecationWarnings; + public GradleBuild() { this(Dsl.GROOVY); } @@ -100,9 +105,19 @@ public class GradleBuild { return this; } + public GradleBuild expectDeprecationWarningsWithAtLeastVersion(String gradleVersion) { + this.expectDeprecationWarnings = GradleVersion.version(gradleVersion); + return this; + } + public BuildResult build(String... arguments) { try { - return prepareRunner(arguments).build(); + BuildResult result = prepareRunner(arguments).build(); + if (this.gradleVersion != null && this.expectDeprecationWarnings != null + && this.expectDeprecationWarnings.compareTo(GradleVersion.version(this.gradleVersion)) > 0) { + assertThat(result.getOutput()).doesNotContain("Deprecated").doesNotContain("deprecated"); + } + return result; } catch (Exception ex) { throw new RuntimeException(ex); diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-jarWithCustomName.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-jarWithCustomName.gradle index 5abe1e0519..04953cce3f 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-jarWithCustomName.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-jarWithCustomName.gradle @@ -1,3 +1,5 @@ +import org.gradle.util.GradleVersion + plugins { id 'java' id 'org.springframework.boot' version '{version}' @@ -7,7 +9,12 @@ group = 'com.example' version = '1.0' bootJar { - baseName = 'foo' + if (GradleVersion.current().compareTo(GradleVersion.version('6.0.0')) < 0) { + baseName = 'foo' + } + else { + archiveBaseName = 'foo' + } } springBoot { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-warWithCustomName.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-warWithCustomName.gradle index 9239a0a84f..611946af91 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-warWithCustomName.gradle +++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/dsl/BuildInfoDslIntegrationTests-warWithCustomName.gradle @@ -1,3 +1,5 @@ +import org.gradle.util.GradleVersion + plugins { id 'war' id 'org.springframework.boot' version '{version}' @@ -7,7 +9,12 @@ group = 'com.example' version = '1.0' bootWar { - baseName = 'foo' + if (GradleVersion.current().compareTo(GradleVersion.version('6.0.0')) < 0) { + baseName = 'foo' + } + else { + archiveBaseName = 'foo' + } } springBoot {