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 adeb6f544958..d1d8e78a4143 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.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 @@ private Jar findArtifactTask() { 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 f2cbd8e1adb9..343d9935abf7 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.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 LaunchScriptConfiguration() { 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 cc7615d8e493..0207668f2057 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.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 @@ * * @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 @@ void basicJar() throws IOException { 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 @@ void jarWithCustomName() throws IOException { 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 @@ void basicWar() throws IOException { 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 @@ void warWithCustomName() throws IOException { 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 @@ void additionalProperties() throws IOException { 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 97928fd2108c..e8ccfe4f7ed7 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 a2d6e344c97b..89dc86cb9039 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 void bootJarCanBeUploaded() throws FileNotFoundException, IOException { @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 6978bd825053..b41e1a04d306 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 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.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 GradleBuild script(String script) { 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 5abe1e05195c..04953cce3f59 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 9239a0a84f7e..611946af9121 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 {