diff --git a/build.gradle b/build.gradle
index e7671f6d014e..b1dfde00bd67 100644
--- a/build.gradle
+++ b/build.gradle
@@ -310,14 +310,13 @@ configure([rootProject] + javaProjects) { project ->
apply plugin: "java-test-fixtures"
apply plugin: "checkstyle"
apply plugin: 'org.springframework.build.compile'
- apply from: "${rootDir}/gradle/custom-java-home.gradle"
+ apply from: "${rootDir}/gradle/toolchains.gradle"
apply from: "${rootDir}/gradle/ide.gradle"
pluginManager.withPlugin("kotlin") {
apply plugin: "org.jetbrains.dokka"
compileKotlin {
kotlinOptions {
- jvmTarget = "1.8"
languageVersion = "1.3"
apiVersion = "1.3"
freeCompilerArgs = ["-Xjsr305=strict"]
@@ -326,7 +325,6 @@ configure([rootProject] + javaProjects) { project ->
}
compileTestKotlin {
kotlinOptions {
- jvmTarget = "1.8"
freeCompilerArgs = ["-Xjsr305=strict"]
}
}
diff --git a/buildSrc/README.md b/buildSrc/README.md
index f48339e6d61f..ada387cf7144 100644
--- a/buildSrc/README.md
+++ b/buildSrc/README.md
@@ -8,16 +8,10 @@ They are declared in the `build.gradle` file in this folder.
### Compiler conventions
The `org.springframework.build.compile` plugin applies the Java compiler conventions to the build.
-By default, the build compiles sources with Java `1.8` source and target compatibility.
-You can test a different source compatibility version on the CLI with a project property like:
-
-```
-./gradlew test -PjavaSourceVersion=11
-```
## Build Plugins
-## Optional dependencies
+### Optional dependencies
The `org.springframework.build.optional-dependencies` plugin creates a new `optional`
Gradle configuration - it adds the dependencies to the project's compile and runtime classpath
@@ -25,7 +19,7 @@ but doesn't affect the classpath of dependent projects.
This plugin does not provide a `provided` configuration, as the native `compileOnly` and `testCompileOnly`
configurations are preferred.
-## API Diff
+### API Diff
This plugin uses the [Gradle JApiCmp](https://github.com/melix/japicmp-gradle-plugin) plugin
to generate API Diff reports for each Spring Framework module. This plugin is applied once on the root
diff --git a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java
index db51666f74b5..5284df28f124 100644
--- a/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java
+++ b/buildSrc/src/main/java/org/springframework/build/compile/CompilerConventionsPlugin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2002-2020 the original author or authors.
+ * Copyright 2002-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.
@@ -20,31 +20,21 @@
import java.util.Arrays;
import java.util.List;
-import org.gradle.api.JavaVersion;
import org.gradle.api.Plugin;
import org.gradle.api.Project;
+import org.gradle.api.plugins.JavaLibraryPlugin;
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.plugins.JavaPluginConvention;
import org.gradle.api.tasks.compile.JavaCompile;
/**
* {@link Plugin} that applies conventions for compiling Java sources in Spring Framework.
- *
One can override the default Java source compatibility version
- * with a dedicated property on the CLI: {@code "./gradlew test -PjavaSourceVersion=11"}.
*
* @author Brian Clozel
* @author Sam Brannen
*/
public class CompilerConventionsPlugin implements Plugin {
- /**
- * The project property that can be used to switch the Java source
- * compatibility version for building source and test classes.
- */
- public static final String JAVA_SOURCE_VERSION_PROPERTY = "javaSourceVersion";
-
- public static final JavaVersion DEFAULT_COMPILER_VERSION = JavaVersion.VERSION_1_8;
-
private static final List COMPILER_ARGS;
private static final List TEST_COMPILER_ARGS;
@@ -69,7 +59,7 @@ public class CompilerConventionsPlugin implements Plugin {
@Override
public void apply(Project project) {
- project.getPlugins().withType(JavaPlugin.class, javaPlugin -> applyJavaCompileConventions(project));
+ project.getPlugins().withType(JavaLibraryPlugin.class, javaPlugin -> applyJavaCompileConventions(project));
}
/**
@@ -79,15 +69,6 @@ public void apply(Project project) {
*/
private void applyJavaCompileConventions(Project project) {
JavaPluginConvention java = project.getConvention().getPlugin(JavaPluginConvention.class);
- if (project.hasProperty(JAVA_SOURCE_VERSION_PROPERTY)) {
- JavaVersion javaSourceVersion = JavaVersion.toVersion(project.property(JAVA_SOURCE_VERSION_PROPERTY));
- java.setSourceCompatibility(javaSourceVersion);
- }
- else {
- java.setSourceCompatibility(DEFAULT_COMPILER_VERSION);
- }
- java.setTargetCompatibility(DEFAULT_COMPILER_VERSION);
-
project.getTasks().withType(JavaCompile.class)
.matching(compileTask -> compileTask.getName().equals(JavaPlugin.COMPILE_JAVA_TASK_NAME))
.forEach(compileTask -> {
diff --git a/ci/images/ci-image-jdk11/Dockerfile b/ci/images/ci-image-jdk11/Dockerfile
deleted file mode 100644
index 6de48e0f1cbc..000000000000
--- a/ci/images/ci-image-jdk11/Dockerfile
+++ /dev/null
@@ -1,8 +0,0 @@
-FROM ubuntu:focal-20210119
-
-ADD setup.sh /setup.sh
-ADD get-jdk-url.sh /get-jdk-url.sh
-RUN ./setup.sh java11
-
-ENV JAVA_HOME /opt/openjdk
-ENV PATH $JAVA_HOME/bin:$PATH
diff --git a/ci/images/ci-image-jdk15/Dockerfile b/ci/images/ci-image-jdk15/Dockerfile
deleted file mode 100644
index 71b47fbe07a7..000000000000
--- a/ci/images/ci-image-jdk15/Dockerfile
+++ /dev/null
@@ -1,8 +0,0 @@
-FROM ubuntu:focal-20210119
-
-ADD setup.sh /setup.sh
-ADD get-jdk-url.sh /get-jdk-url.sh
-RUN ./setup.sh java15
-
-ENV JAVA_HOME /opt/openjdk
-ENV PATH $JAVA_HOME/bin:$PATH
diff --git a/ci/images/ci-image/Dockerfile b/ci/images/ci-image/Dockerfile
index 2952402431ac..1ce41f37a932 100644
--- a/ci/images/ci-image/Dockerfile
+++ b/ci/images/ci-image/Dockerfile
@@ -4,5 +4,8 @@ ADD setup.sh /setup.sh
ADD get-jdk-url.sh /get-jdk-url.sh
RUN ./setup.sh java8
-ENV JAVA_HOME /opt/openjdk
+ENV JAVA_HOME /opt/openjdk/java8
+ENV JDK11 /opt/openjdk/java11
+ENV JDK15 /opt/openjdk/java15
+
ENV PATH $JAVA_HOME/bin:$PATH
diff --git a/ci/images/setup.sh b/ci/images/setup.sh
index 87c3fbc2cc77..1fca196502dc 100755
--- a/ci/images/setup.sh
+++ b/ci/images/setup.sh
@@ -19,13 +19,20 @@ curl --output /opt/concourse-release-scripts.jar https://repo.spring.io/release/
###########################################################
# JAVA
###########################################################
-JDK_URL=$( ./get-jdk-url.sh $1 )
mkdir -p /opt/openjdk
-cd /opt/openjdk
-curl -L ${JDK_URL} | tar zx --strip-components=1
-test -f /opt/openjdk/bin/java
-test -f /opt/openjdk/bin/javac
+pushd /opt/openjdk > /dev/null
+for jdk in java8 java11 java15
+do
+ JDK_URL=$( /get-jdk-url.sh $jdk )
+ mkdir $jdk
+ pushd $jdk > /dev/null
+ curl -L ${JDK_URL} | tar zx --strip-components=1
+ test -f bin/java
+ test -f bin/javac
+ popd > /dev/null
+done
+popd
###########################################################
# GRADLE ENTERPRISE
diff --git a/ci/pipeline.yml b/ci/pipeline.yml
index e93bed5235f0..0de0158368c4 100644
--- a/ci/pipeline.yml
+++ b/ci/pipeline.yml
@@ -85,18 +85,6 @@ resources:
source:
<<: *docker-resource-source
repository: ((docker-hub-organization))/spring-framework-ci
-- name: ci-image-jdk11
- type: docker-image
- icon: docker
- source:
- <<: *docker-resource-source
- repository: ((docker-hub-organization))/spring-framework-ci-jdk11
-- name: ci-image-jdk15
- type: docker-image
- icon: docker
- source:
- <<: *docker-resource-source
- repository: ((docker-hub-organization))/spring-framework-ci-jdk15
- name: artifactory-repo
type: artifactory-resource
icon: package-variant
@@ -161,14 +149,6 @@ jobs:
params:
build: ci-images-git-repo/ci/images
dockerfile: ci-images-git-repo/ci/images/ci-image/Dockerfile
- - put: ci-image-jdk11
- params:
- build: ci-images-git-repo/ci/images
- dockerfile: ci-images-git-repo/ci/images/ci-image-jdk11/Dockerfile
- - put: ci-image-jdk15
- params:
- build: ci-images-git-repo/ci/images
- dockerfile: ci-images-git-repo/ci/images/ci-image-jdk15/Dockerfile
- name: build
serial: true
public: true
@@ -227,7 +207,7 @@ jobs:
serial: true
public: true
plan:
- - get: ci-image-jdk11
+ - get: ci-image
- get: git-repo
- get: every-morning
trigger: true
@@ -235,8 +215,11 @@ jobs:
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
- image: ci-image-jdk11
+ image: ci-image
file: git-repo/ci/tasks/check-project.yml
+ params:
+ MAIN_TOOLCHAIN: 8
+ TEST_TOOLCHAIN: 11
<<: *build-project-task-params
on_failure:
do:
@@ -251,7 +234,7 @@ jobs:
serial: true
public: true
plan:
- - get: ci-image-jdk15
+ - get: ci-image
- get: git-repo
- get: every-morning
trigger: true
@@ -259,8 +242,11 @@ jobs:
params: { state: "pending", commit: "git-repo" }
- do:
- task: check-project
- image: ci-image-jdk15
+ image: ci-image
file: git-repo/ci/tasks/check-project.yml
+ params:
+ MAIN_TOOLCHAIN: 8
+ TEST_TOOLCHAIN: 15
<<: *build-project-task-params
on_failure:
do:
diff --git a/ci/scripts/check-project.sh b/ci/scripts/check-project.sh
index 94c4e8df65b4..f2bf454e3597 100755
--- a/ci/scripts/check-project.sh
+++ b/ci/scripts/check-project.sh
@@ -4,5 +4,6 @@ set -e
source $(dirname $0)/common.sh
pushd git-repo > /dev/null
-./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false --no-daemon --max-workers=4 check
+./gradlew -Dorg.gradle.internal.launcher.welcomeMessageEnabled=false -Dorg.gradle.java.installations.fromEnv=JDK11,JDK15 \
+ -PmainToolchain=$MAIN_TOOLCHAIN -PtestToolchain=$TEST_TOOLCHAIN --no-daemon --max-workers=4 check
popd > /dev/null
diff --git a/ci/tasks/check-project.yml b/ci/tasks/check-project.yml
index ea6d6ddb94c8..bea1185231b9 100644
--- a/ci/tasks/check-project.yml
+++ b/ci/tasks/check-project.yml
@@ -10,6 +10,8 @@ caches:
params:
BRANCH:
CI: true
+ MAIN_TOOLCHAIN:
+ TEST_TOOLCHAIN:
GRADLE_ENTERPRISE_ACCESS_KEY:
GRADLE_ENTERPRISE_CACHE_USERNAME:
GRADLE_ENTERPRISE_CACHE_PASSWORD:
diff --git a/gradle/custom-java-home.gradle b/gradle/custom-java-home.gradle
deleted file mode 100644
index 54d1de1eb8f9..000000000000
--- a/gradle/custom-java-home.gradle
+++ /dev/null
@@ -1,80 +0,0 @@
-// -----------------------------------------------------------------------------
-//
-// This script adds support for the following two JVM system properties
-// that control the build for alternative JDKs (i.e., a JDK other than
-// the one used to launch the Gradle process).
-//
-// - customJavaHome: absolute path to the alternate JDK installation to
-// use to compile Java code and execute tests. This system property
-// is also used in spring-oxm.gradle to determine whether JiBX is
-// supported.
-//
-// - customJavaSourceVersion: Java version supplied to the `--release`
-// command line flag to control the Java source and target
-// compatibility version. Supported versions include 9 or higher.
-// Do not set this system property if Java 8 should be used.
-//
-// Examples:
-//
-// ./gradlew -DcustomJavaHome=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home test
-//
-// ./gradlew --no-build-cache -DcustomJavaHome=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home test
-//
-// ./gradlew -DcustomJavaHome=/Library/Java/JavaVirtualMachines/jdk-14.jdk/Contents/Home -DcustomJavaSourceVersion=14 test
-//
-//
-// Credits: inspired by work from Marc Philipp and Stephane Nicoll
-//
-// -----------------------------------------------------------------------------
-
-import org.gradle.internal.os.OperatingSystem
-// import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompile
-
-def customJavaHome = System.getProperty("customJavaHome")
-
-if (customJavaHome) {
- def customJavaHomeDir = new File(customJavaHome)
- def customJavaSourceVersion = System.getProperty("customJavaSourceVersion")
-
- tasks.withType(JavaCompile) {
- logger.info("Java home for " + it.name + " task in " + project.name + ": " + customJavaHomeDir)
- options.forkOptions.javaHome = customJavaHomeDir
- inputs.property("customJavaHome", customJavaHome)
- if (customJavaSourceVersion) {
- options.compilerArgs += [ "--release", customJavaSourceVersion]
- inputs.property("customJavaSourceVersion", customJavaSourceVersion)
- }
- }
-
- tasks.withType(GroovyCompile) {
- logger.info("Java home for " + it.name + " task in " + project.name + ": " + customJavaHomeDir)
- options.forkOptions.javaHome = customJavaHomeDir
- inputs.property("customJavaHome", customJavaHome)
- if (customJavaSourceVersion) {
- options.compilerArgs += [ "--release", customJavaSourceVersion]
- inputs.property("customJavaSourceVersion", customJavaSourceVersion)
- }
- }
-
- /*
- tasks.withType(KotlinJvmCompile) {
- logger.info("Java home for " + it.name + " task in " + project.name + ": " + customJavaHome)
- kotlinOptions.jdkHome = customJavaHomeDir
- inputs.property("customJavaHome", customJavaHome)
- }
- */
-
- tasks.withType(Test) {
- def javaExecutable = customJavaHome + "/bin/java"
- if (OperatingSystem.current().isWindows()) {
- javaExecutable += ".exe"
- }
- logger.info("Java executable for " + it.name + " task in " + project.name + ": " + javaExecutable)
- executable = javaExecutable
- inputs.property("customJavaHome", customJavaHome)
- if (customJavaSourceVersion) {
- inputs.property("customJavaSourceVersion", customJavaSourceVersion)
- }
- }
-
-}
diff --git a/gradle/spring-module.gradle b/gradle/spring-module.gradle
index 51b18007f832..49efaeae84dc 100644
--- a/gradle/spring-module.gradle
+++ b/gradle/spring-module.gradle
@@ -1,3 +1,4 @@
+apply plugin: 'java-library'
apply plugin: 'org.springframework.build.compile'
apply plugin: 'org.springframework.build.optional-dependencies'
// Uncomment the following for Shadow support in the jmhJar block.
diff --git a/gradle/toolchains.gradle b/gradle/toolchains.gradle
new file mode 100644
index 000000000000..2ae10a0581fa
--- /dev/null
+++ b/gradle/toolchains.gradle
@@ -0,0 +1,127 @@
+/**
+ * Apply the JVM Toolchain conventions
+ * See https://docs.gradle.org/current/userguide/toolchains.html
+ *
+ * One can choose the toolchain to use for compiling the MAIN sources and/or compiling
+ * and running the TEST sources. These options apply to Java, Kotlin and Groovy sources
+ * when available.
+ * {@code "./gradlew check -PmainToolchain=8 -PtestToolchain=11"} will use:
+ *
+ * - a JDK8 toolchain for compiling the main SourceSet
+ *
- a JDK11 toolchain for compiling and running the test SourceSet
+ *
+ *
+ * Gradle will automatically detect JDK distributions in well-known locations.
+ * The following command will list the detected JDKs on the host.
+ * {@code
+ * $ ./gradlew -q javaToolchains
+ * }
+ *
+ * We can also configure ENV variables and let Gradle know about them:
+ * {@code
+ * $ echo JDK11
+ * /opt/openjdk/java11
+ * $ echo JDK15
+ * /opt/openjdk/java15
+ * $ ./gradlew -Dorg.gradle.java.installations.fromEnv=JDK11,JDK15 check
+ * }
+ *
+ * @author Brian Clozel
+ */
+def mainToolchain = 'mainToolchain'
+def testToolchain = 'testToolchain'
+
+plugins.withType(JavaPlugin) {
+ // Configure the Java Toolchain if the 'mainToolchain' property is defined
+ if (project.hasProperty(mainToolchain)) {
+ def mainLanguageVersion = JavaLanguageVersion.of(project.property(mainToolchain).toString())
+ java {
+ toolchain {
+ languageVersion = mainLanguageVersion
+ }
+ }
+ }
+ else {
+ // Fallback to JDK8
+ java {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ }
+ }
+ // Configure a specific Java Toolchain for compiling and running tests if the 'testToolchain' property is defined
+ if (project.hasProperty(testToolchain)) {
+ def testLanguageVersion = JavaLanguageVersion.of(project.property(testToolchain).toString());
+ tasks.withType(JavaCompile).matching { it.name.contains("Test") }.configureEach {
+ javaCompiler = javaToolchains.compilerFor {
+ languageVersion = testLanguageVersion
+ }
+ }
+ tasks.withType(Test).configureEach{
+ javaLauncher = javaToolchains.launcherFor {
+ languageVersion = testLanguageVersion
+ }
+ }
+ }
+}
+
+plugins.withType(GroovyPlugin) {
+ // Fallback to JDK8
+ if (!project.hasProperty(mainToolchain)) {
+ compileGroovy {
+ sourceCompatibility = JavaVersion.VERSION_1_8
+ }
+ }
+}
+
+// Configure the Kotlin compiler if the 'mainToolchain' property is defined
+pluginManager.withPlugin("kotlin") {
+ if (project.hasProperty(mainToolchain)) {
+ def mainLanguageVersion = JavaLanguageVersion.of(project.property(mainToolchain).toString());
+ def compiler = javaToolchains.compilerFor {
+ languageVersion = mainLanguageVersion
+ }
+ // See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm
+ def javaVersion = mainLanguageVersion.toString() == '8' ? '1.8' : mainLanguageVersion.toString()
+ compileKotlin {
+ kotlinOptions {
+ jvmTarget = javaVersion
+ jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
+ }
+ }
+ // Compile the test classes with the same version, 'testToolchain' will override if defined
+ compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = javaVersion
+ jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
+ }
+ }
+ }
+ else {
+ compileKotlin {
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ }
+ }
+
+ if (project.hasProperty(testToolchain)) {
+ def testLanguageVersion = JavaLanguageVersion.of(project.property(testToolchain).toString());
+ def compiler = javaToolchains.compilerFor {
+ languageVersion = testLanguageVersion
+ }
+ // See https://kotlinlang.org/docs/gradle.html#attributes-specific-for-jvm
+ def javaVersion = testLanguageVersion.toString() == '8' ? '1.8' : testLanguageVersion.toString()
+ compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = javaVersion
+ jdkHome = compiler.get().metadata.installationPath.asFile.absolutePath
+ }
+ }
+ }
+ else {
+ compileTestKotlin {
+ kotlinOptions {
+ jvmTarget = '1.8'
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
index be0672db505e..d852c01eb91a 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -45,11 +45,11 @@ rootProject.children.each {project ->
settings.gradle.projectsLoaded {
gradleEnterprise {
buildScan {
- if (settings.gradle.rootProject.hasProperty('customJavaHome')) {
- value("Custom JAVA_HOME", settings.gradle.rootProject.getProperty('customJavaHome'))
+ if (settings.gradle.rootProject.hasProperty('mainToolchain')) {
+ value("Main toolchain", 'JDK' + settings.gradle.rootProject.getProperty('mainToolchain'))
}
- if (settings.gradle.rootProject.hasProperty('customJavaSourceVersion')) {
- value("Custom Java Source Version", settings.gradle.rootProject.getProperty('customJavaSourceVersion'))
+ if (settings.gradle.rootProject.hasProperty('testToolchain')) {
+ value("Test toolchain", 'JDK' + settings.gradle.rootProject.getProperty('testToolchain'))
}
File buildDir = settings.gradle.rootProject.getBuildDir()
buildDir.mkdirs()
diff --git a/spring-beans/spring-beans.gradle b/spring-beans/spring-beans.gradle
index 73e9942f8ef6..db894e8b83bc 100644
--- a/spring-beans/spring-beans.gradle
+++ b/spring-beans/spring-beans.gradle
@@ -23,8 +23,6 @@ sourceSets {
}
compileGroovy {
- sourceCompatibility = 1.8
- targetCompatibility = 1.8
options.compilerArgs += "-Werror"
}