From 19957ac6199abb6d5e7727d3e590c430b39c4b60 Mon Sep 17 00:00:00 2001 From: Chris Bono Date: Fri, 22 Mar 2024 10:51:10 -0500 Subject: [PATCH] Add Java 21 support for running tests (#622) This commit adds a Gradle property 'testToolchain' that when set will configure the Java toolchain plugin accordingly. Additionally: ------------- * Replace the custom toolchain plugin with the vanilla one provided by Gradle * Move the Java conventions from Java plugin to Groovy script * [CI] Add Java 21 to check-samples.yml --- .github/workflows/check-samples.yml | 8 +- build.gradle | 1 + .../pulsar/gradle/JavaConventionsPlugin.java | 36 --------- .../pulsar/gradle/RootProjectPlugin.java | 5 +- .../gradle/toolchain/ToolchainExtension.java | 56 ------------- .../gradle/toolchain/ToolchainPlugin.java | 81 ------------------- gradle/java-conventions.gradle | 26 ++++++ 7 files changed, 37 insertions(+), 176 deletions(-) delete mode 100644 buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainExtension.java delete mode 100644 buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainPlugin.java create mode 100644 gradle/java-conventions.gradle diff --git a/.github/workflows/check-samples.yml b/.github/workflows/check-samples.yml index 19813533..32ac6f11 100644 --- a/.github/workflows/check-samples.yml +++ b/.github/workflows/check-samples.yml @@ -39,7 +39,11 @@ jobs: needs: [prerequisites] strategy: matrix: - springBootVersion: [ "${{ needs.prerequisites.outputs.boot_version }}" ] + include: + - javaVersion: 17 + springBootVersion: "${{ needs.prerequisites.outputs.boot_version }}" + - javaVersion: 21 + springBootVersion: "${{ needs.prerequisites.outputs.boot_version }}" runs-on: ubuntu-latest if: needs.prerequisites.outputs.runjobs steps: @@ -50,6 +54,7 @@ jobs: LOCAL_REPOSITORY_PATH: ${{ github.workspace }}/build/publications/repos VERSION: ${{ needs.prerequisites.outputs.project_version }} BOOT_VERSION: ${{ matrix.springBootVersion }} + JAVA_VERSION: ${{ matrix.javaVersion }} run: | ./gradlew publishMavenJavaPublicationToLocalRepository ./gradlew \ @@ -57,5 +62,6 @@ jobs: -PlocalRepositoryPath="$LOCAL_REPOSITORY_PATH" \ -PspringPulsarVersion="$VERSION" \ -PspringBootVersion="$BOOT_VERSION" \ + -PtestToolchain="$JAVA_VERSION" \ -PsampleTests \ :runAllSampleTests diff --git a/build.gradle b/build.gradle index 9f62933c..744919bb 100644 --- a/build.gradle +++ b/build.gradle @@ -13,6 +13,7 @@ apply from: 'gradle/jacoco-conventions.gradle' apply from: 'gradle/aggregate-jacoco-report.gradle' apply from: 'gradle/update-copyrights.gradle' apply from: 'gradle/version-catalog-update.gradle' +apply from: 'gradle/java-conventions.gradle' allprojects { group = 'org.springframework.pulsar' diff --git a/buildSrc/src/main/java/org/springframework/pulsar/gradle/JavaConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/pulsar/gradle/JavaConventionsPlugin.java index f048c1e4..f7d7422f 100644 --- a/buildSrc/src/main/java/org/springframework/pulsar/gradle/JavaConventionsPlugin.java +++ b/buildSrc/src/main/java/org/springframework/pulsar/gradle/JavaConventionsPlugin.java @@ -18,13 +18,11 @@ import java.util.Arrays; import java.util.Collections; -import java.util.List; import java.util.Map; import java.util.Set; import java.util.TreeMap; import java.util.stream.Collectors; -import org.gradle.api.JavaVersion; import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.artifacts.Configuration; @@ -33,7 +31,6 @@ import org.gradle.api.artifacts.DependencySet; import org.gradle.api.plugins.JavaBasePlugin; import org.gradle.api.plugins.JavaPlugin; -import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.plugins.quality.Checkstyle; import org.gradle.api.plugins.quality.CheckstyleExtension; import org.gradle.api.plugins.quality.CheckstylePlugin; @@ -49,7 +46,6 @@ import org.springframework.pulsar.gradle.optional.OptionalDependenciesPlugin; import org.springframework.pulsar.gradle.testing.TestFailuresPlugin; -import org.springframework.pulsar.gradle.toolchain.ToolchainPlugin; import io.spring.javaformat.gradle.SpringJavaFormatPlugin; import io.spring.javaformat.gradle.tasks.CheckFormat; @@ -109,12 +105,10 @@ public class JavaConventionsPlugin implements Plugin { public void apply(Project project) { project.getPlugins().withType(JavaBasePlugin.class, (java) -> { configureSpringJavaFormat(project); - configureJavaConventions(project); configureJavadocConventions(project); configureTestConventions(project); configureJarManifestConventions(project); configureDependencyManagement(project); - configureToolchain(project); }); } @@ -131,32 +125,6 @@ private void configureSpringJavaFormat(Project project) { .add(project.getDependencies().create("io.spring.javaformat:spring-javaformat-checkstyle:" + version)); } - private void configureJavaConventions(Project project) { - if (!project.hasProperty("toolchainVersion")) { - JavaPluginExtension javaPluginExtension = project.getExtensions().getByType(JavaPluginExtension.class); - javaPluginExtension.setSourceCompatibility(JavaVersion.toVersion(SOURCE_AND_TARGET_COMPATIBILITY)); - } - project.getTasks().withType(JavaCompile.class, (compile) -> { - compile.getOptions().setEncoding("UTF-8"); - List args = compile.getOptions().getCompilerArgs(); - if (!args.contains("-parameters")) { - args.add("-parameters"); - } - if (project.hasProperty("toolchainVersion")) { - compile.setSourceCompatibility(SOURCE_AND_TARGET_COMPATIBILITY); - compile.setTargetCompatibility(SOURCE_AND_TARGET_COMPATIBILITY); - } - else if (buildingWithJava17(project)) { - args.addAll(Arrays.asList("-Werror", "-Xlint:unchecked", "-Xlint:deprecation", "-Xlint:rawtypes", - "-Xlint:varargs")); - } - }); - } - - private boolean buildingWithJava17(Project project) { - return !project.hasProperty("toolchainVersion") && JavaVersion.current() == JavaVersion.VERSION_17; - } - private void configureJavadocConventions(Project project) { project.getTasks().withType(Javadoc.class, (javadoc) -> { CoreJavadocOptions options = (CoreJavadocOptions) javadoc.getOptions(); @@ -245,8 +213,4 @@ private void configureDependencyManagement(Project project) { .getByName(OptionalDependenciesPlugin.OPTIONAL_CONFIGURATION_NAME).extendsFrom(dependencyManagement)); } - private void configureToolchain(Project project) { - project.getPlugins().apply(ToolchainPlugin.class); - } - } diff --git a/buildSrc/src/main/java/org/springframework/pulsar/gradle/RootProjectPlugin.java b/buildSrc/src/main/java/org/springframework/pulsar/gradle/RootProjectPlugin.java index ef1a4711..aa97ed06 100644 --- a/buildSrc/src/main/java/org/springframework/pulsar/gradle/RootProjectPlugin.java +++ b/buildSrc/src/main/java/org/springframework/pulsar/gradle/RootProjectPlugin.java @@ -16,8 +16,6 @@ package org.springframework.pulsar.gradle; -import io.spring.gradle.convention.ArtifactoryPlugin; - import org.gradle.api.Plugin; import org.gradle.api.Project; import org.gradle.api.Task; @@ -27,7 +25,10 @@ import org.springframework.pulsar.gradle.check.SonarQubeConventionsPlugin; import org.springframework.pulsar.gradle.publish.SpringNexusPublishPlugin; +import io.spring.gradle.convention.ArtifactoryPlugin; + /** + * Plugin for the root project. * @author Chris Bono */ public class RootProjectPlugin implements Plugin { diff --git a/buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainExtension.java b/buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainExtension.java deleted file mode 100644 index fffe6e2c..00000000 --- a/buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainExtension.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2012-2021 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 - * - * https://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.springframework.pulsar.gradle.toolchain; - -import org.gradle.api.Project; -import org.gradle.api.provider.ListProperty; -import org.gradle.api.provider.Property; -import org.gradle.jvm.toolchain.JavaLanguageVersion; - -/** - * DSL extension for {@link ToolchainPlugin}. - * - * @author Christoph Dreis - */ -public class ToolchainExtension { - - private final Property maximumCompatibleJavaVersion; - - private final ListProperty testJvmArgs; - - private final JavaLanguageVersion javaVersion; - - public ToolchainExtension(Project project) { - this.maximumCompatibleJavaVersion = project.getObjects().property(JavaLanguageVersion.class); - this.testJvmArgs = project.getObjects().listProperty(String.class); - String toolchainVersion = (String) project.findProperty("toolchainVersion"); - this.javaVersion = (toolchainVersion != null) ? JavaLanguageVersion.of(toolchainVersion) : null; - } - - public Property getMaximumCompatibleJavaVersion() { - return this.maximumCompatibleJavaVersion; - } - - public ListProperty getTestJvmArgs() { - return this.testJvmArgs; - } - - JavaLanguageVersion getJavaVersion() { - return this.javaVersion; - } - -} diff --git a/buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainPlugin.java b/buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainPlugin.java deleted file mode 100644 index e35ab65b..00000000 --- a/buildSrc/src/main/java/org/springframework/pulsar/gradle/toolchain/ToolchainPlugin.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2012-2022 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 - * - * https://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.springframework.pulsar.gradle.toolchain; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.gradle.api.Plugin; -import org.gradle.api.Project; -import org.gradle.api.plugins.JavaPluginExtension; -import org.gradle.api.tasks.compile.JavaCompile; -import org.gradle.api.tasks.javadoc.Javadoc; -import org.gradle.api.tasks.testing.Test; -import org.gradle.jvm.toolchain.JavaLanguageVersion; -import org.gradle.jvm.toolchain.JavaToolchainSpec; - -/** - * {@link Plugin} for customizing Gradle's toolchain support. - * - * @author Christoph Dreis - */ -public class ToolchainPlugin implements Plugin { - - @Override - public void apply(Project project) { - configureToolchain(project); - } - - private void configureToolchain(Project project) { - ToolchainExtension toolchain = project.getExtensions().create("toolchain", ToolchainExtension.class, project); - JavaLanguageVersion toolchainVersion = toolchain.getJavaVersion(); - if (toolchainVersion != null) { - project.afterEvaluate((evaluated) -> configure(evaluated, toolchain)); - } - } - - private void configure(Project project, ToolchainExtension toolchain) { - if (!isJavaVersionSupported(toolchain, toolchain.getJavaVersion())) { - disableToolchainTasks(project); - } - else { - JavaToolchainSpec toolchainSpec = project.getExtensions().getByType(JavaPluginExtension.class) - .getToolchain(); - toolchainSpec.getLanguageVersion().set(toolchain.getJavaVersion()); - configureTestToolchain(project, toolchain); - } - } - - private boolean isJavaVersionSupported(ToolchainExtension toolchain, JavaLanguageVersion toolchainVersion) { - return toolchain.getMaximumCompatibleJavaVersion().map((version) -> version.canCompileOrRun(toolchainVersion)) - .getOrElse(true); - } - - private void disableToolchainTasks(Project project) { - project.getTasks().withType(JavaCompile.class, (task) -> task.setEnabled(false)); - project.getTasks().withType(Javadoc.class, (task) -> task.setEnabled(false)); - project.getTasks().withType(Test.class, (task) -> task.setEnabled(false)); - } - - private void configureTestToolchain(Project project, ToolchainExtension toolchain) { - List jvmArgs = new ArrayList<>(); - jvmArgs.addAll(toolchain.getTestJvmArgs().getOrElse(Collections.emptyList())); - project.getTasks().withType(Test.class, (test) -> test.jvmArgs(jvmArgs)); - } - -} diff --git a/gradle/java-conventions.gradle b/gradle/java-conventions.gradle new file mode 100644 index 00000000..ff08b7e8 --- /dev/null +++ b/gradle/java-conventions.gradle @@ -0,0 +1,26 @@ +def toolchainVersion() { + if (project.hasProperty('testToolchain')) { + return project.property('testToolchain').toString().toInteger() + } + return 17 +} + +project.afterEvaluate { + subprojects { subproject -> + afterEvaluate { + if (subproject.plugins.hasPlugin(JavaPlugin.class)) { + java { + toolchain { + languageVersion = JavaLanguageVersion.of(toolchainVersion()) + } + } + tasks.withType(JavaCompile).configureEach { + options.encoding = "UTF-8" + options.compilerArgs.add("-parameters") + options.compilerArgs.addAll(["-Werror", "-Xlint:unchecked", "-Xlint:deprecation", "-Xlint:rawtypes", "-Xlint:varargs"]); + options.release.set(17) + } + } + } + } +}