diff --git a/buildSrc/build.gradle b/buildSrc/build.gradle
index d998c7306783..5e624a776058 100644
--- a/buildSrc/build.gradle
+++ b/buildSrc/build.gradle
@@ -42,7 +42,6 @@ dependencies {
implementation("org.apache.maven:maven-embedder:${mavenVersion}")
implementation("org.antora:gradle-antora-plugin:1.0.0")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:${kotlinVersion}")
- implementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:${kotlinVersion}")
implementation("org.springframework:spring-context")
implementation("org.springframework:spring-core")
implementation("org.springframework:spring-web")
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/ConventionsPlugin.java b/buildSrc/src/main/java/org/springframework/boot/build/ConventionsPlugin.java
index 8bd7f2fb21d1..740d120884a2 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/ConventionsPlugin.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/ConventionsPlugin.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2024 the original author or authors.
+ * Copyright 2012-2025 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.
@@ -35,6 +35,9 @@
* When the {@link AntoraPlugin} is applied, the conventions in {@link AntoraConventions}
* are applied.
*
+ * When the {@code org.jetbrains.kotlin.jvm} plugin is applied, the conventions in
+ * {@link KotlinConventions} are applied.
+ *
* @author Andy Wilkinson
* @author Christoph Dreis
* @author Mike Smithson
diff --git a/buildSrc/src/main/java/org/springframework/boot/build/KotlinConventions.java b/buildSrc/src/main/java/org/springframework/boot/build/KotlinConventions.java
index 32b38af396de..3f65957dec14 100644
--- a/buildSrc/src/main/java/org/springframework/boot/build/KotlinConventions.java
+++ b/buildSrc/src/main/java/org/springframework/boot/build/KotlinConventions.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2024 the original author or authors.
+ * Copyright 2012-2025 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.
@@ -25,7 +25,9 @@
import org.gradle.api.Project;
import org.gradle.api.tasks.SourceSet;
import org.gradle.api.tasks.SourceSetContainer;
-import org.jetbrains.kotlin.gradle.dsl.KotlinJvmOptions;
+import org.jetbrains.kotlin.gradle.dsl.JvmTarget;
+import org.jetbrains.kotlin.gradle.dsl.KotlinJvmCompilerOptions;
+import org.jetbrains.kotlin.gradle.dsl.KotlinVersion;
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile;
/**
@@ -35,7 +37,7 @@
*
* - {@link KotlinCompile} tasks are configured to:
*
- * - Use {@code apiVersion} and {@code languageVersion} 1.7.
+ *
- Use {@code apiVersion} and {@code languageVersion} 2.1.
*
- Use {@code jvmTarget} 17.
*
- Treat all warnings as errors
*
- Suppress version warnings
@@ -56,14 +58,14 @@ void apply(Project project) {
}
private void configure(KotlinCompile compile) {
- KotlinJvmOptions kotlinOptions = compile.getKotlinOptions();
- kotlinOptions.setApiVersion("1.7");
- kotlinOptions.setLanguageVersion("1.7");
- kotlinOptions.setJvmTarget("17");
- kotlinOptions.setAllWarningsAsErrors(true);
- List freeCompilerArgs = new ArrayList<>(kotlinOptions.getFreeCompilerArgs());
+ KotlinJvmCompilerOptions kotlinOptions = compile.getCompilerOptions();
+ kotlinOptions.getApiVersion().set(KotlinVersion.KOTLIN_2_1);
+ kotlinOptions.getLanguageVersion().set(KotlinVersion.KOTLIN_2_1);
+ kotlinOptions.getJvmTarget().set(JvmTarget.JVM_17);
+ kotlinOptions.getAllWarningsAsErrors().set(true);
+ List freeCompilerArgs = new ArrayList<>(kotlinOptions.getFreeCompilerArgs().get());
freeCompilerArgs.add("-Xsuppress-version-warnings");
- kotlinOptions.setFreeCompilerArgs(freeCompilerArgs);
+ kotlinOptions.getFreeCompilerArgs().set(freeCompilerArgs);
}
private void configureDokkatoo(Project project) {
diff --git a/gradle.properties b/gradle.properties
index b6c6c18e84ed..196765b300ed 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -14,7 +14,7 @@ hamcrestVersion=3.0
jacksonVersion=2.18.2
javaFormatVersion=0.0.43
junitJupiterVersion=5.11.4
-kotlinVersion=1.9.25
+kotlinVersion=2.1.10
mavenVersion=3.9.4
mockitoVersion=5.15.2
nativeBuildToolsVersion=0.10.5
diff --git a/spring-boot-project/spring-boot-dependencies/build.gradle b/spring-boot-project/spring-boot-dependencies/build.gradle
index 42d409ed12d8..4caa28a3bc89 100644
--- a/spring-boot-project/spring-boot-dependencies/build.gradle
+++ b/spring-boot-project/spring-boot-dependencies/build.gradle
@@ -1193,8 +1193,9 @@ bom {
}
library("Kotlin", "${kotlinVersion}") {
prohibit {
- versionRange "[2.0.0-Beta1,)"
- because "it exceeds our baseline"
+ contains "-Beta"
+ contains "-RC"
+ because "we don't want betas or release candidates"
}
group("org.jetbrains.kotlin") {
imports = [
diff --git a/spring-boot-project/spring-boot-docs/build.gradle b/spring-boot-project/spring-boot-docs/build.gradle
index d51787e6355c..0854092ff999 100644
--- a/spring-boot-project/spring-boot-docs/build.gradle
+++ b/spring-boot-project/spring-boot-docs/build.gradle
@@ -1,3 +1,5 @@
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
+
plugins {
id "dev.adamko.dokkatoo-html"
id "java"
@@ -304,6 +306,26 @@ task runLoggingFormatExample(type: org.springframework.boot.build.docs.Applicati
normalizeTomcatPort()
}
+// To avoid a redeclaration error with Kotlin compiler
+tasks.withType(KotlinCompile) {
+ javaSources.from = [
+ "src/main/java/org/springframework/boot/docs/data/nosql/cassandra/connecting/User.java",
+ "src/main/java/org/springframework/boot/docs/features/devservices/testcontainers/atdevelopmenttime/importingcontainerdeclarations/MyContainers.java",
+ "src/main/java/org/springframework/boot/docs/features/externalconfig/typesafeconfigurationproperties/usingannotatedtypes/Server.java",
+ "src/main/java/org/springframework/boot/docs/features/springapplication/applicationavailability/managing/CacheCompletelyBrokenException.java",
+ "src/main/java/org/springframework/boot/docs/packaging/nativeimage/advanced/nestedconfigurationproperties/Nested.java",
+ "src/main/java/org/springframework/boot/docs/using/springbeansanddependencyinjection/multipleconstructors/AccountService.java",
+ "src/main/java/org/springframework/boot/docs/using/springbeansanddependencyinjection/multipleconstructors/RiskAssessor.java",
+ "src/main/java/org/springframework/boot/docs/using/springbeansanddependencyinjection/singleconstructor/AccountService.java",
+ "src/main/java/org/springframework/boot/docs/using/springbeansanddependencyinjection/singleconstructor/RiskAssessor.java",
+ "src/main/java/org/springframework/boot/docs/using/usingthespringbootapplicationannotation/individualannotations/AnotherConfiguration.java",
+ "src/main/java/org/springframework/boot/docs/using/usingthespringbootapplicationannotation/individualannotations/SomeConfiguration.java",
+ "src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyErrorBody.java",
+ "src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/MyException.java",
+ "src/main/java/org/springframework/boot/docs/web/servlet/springmvc/errorhandling/SomeController.java",
+ ]
+}
+
def getRelativeExamplesPath(var outputs) {
def fileName = outputs.files.singleFile.name
'example$example-output/' + fileName
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle
index 4819bf526e2e..32e6fcb01931 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/build.gradle
@@ -54,7 +54,6 @@ dependencies {
testImplementation("org.assertj:assertj-core")
testImplementation("org.graalvm.buildtools:native-gradle-plugin")
testImplementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
- testImplementation("org.jetbrains.kotlin:kotlin-compiler-embeddable:$kotlinVersion")
testImplementation("org.jetbrains.kotlin:kotlin-compiler-runner:$kotlinVersion")
testImplementation("org.jetbrains.kotlin:kotlin-daemon-client:$kotlinVersion")
testImplementation("org.junit.jupiter:junit-jupiter")
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java
index afb5eefac115..30ce7061e2dd 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2023 the original author or authors.
+ * Copyright 2012-2025 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.
@@ -49,7 +49,7 @@ private String getKotlinVersion(Project project) {
private void enableJavaParametersOption(Project project) {
project.getTasks()
.withType(KotlinCompile.class)
- .configureEach((compile) -> compile.getKotlinOptions().setJavaParameters(true));
+ .configureEach((compile) -> compile.getCompilerOptions().getJavaParameters().set(true));
}
@Override
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java
index 8afa6036f967..4ed6e4b44a47 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2024 the original author or authors.
+ * Copyright 2012-2025 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.
@@ -83,7 +83,7 @@ void taskConfigurationIsAvoided() throws IOException {
configured.add(line.substring("Configuring :".length()));
}
}
- assertThat(configured).containsExactlyInAnyOrder("help", "compileJava", "clean");
+ assertThat(configured).containsExactlyInAnyOrder("help", "clean");
}
}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/PluginClasspathGradleBuild.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/PluginClasspathGradleBuild.java
index 14d1700b433a..2fc9832144c6 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/PluginClasspathGradleBuild.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/testkit/PluginClasspathGradleBuild.java
@@ -18,6 +18,7 @@
import java.io.File;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -33,9 +34,12 @@
import org.apache.hc.core5.http.HttpRequest;
import org.apache.hc.core5.http2.HttpVersionPolicy;
import org.gradle.testkit.runner.GradleRunner;
+import org.gradle.util.GradleVersion;
+import org.jetbrains.kotlin.buildtools.api.jvm.ClassSnapshotGranularity;
import org.jetbrains.kotlin.gradle.model.KotlinProject;
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilerPluginSupportPlugin;
import org.jetbrains.kotlin.gradle.plugin.KotlinPlatformJvmPlugin;
+import org.jetbrains.kotlin.konan.target.HostManager;
import org.jetbrains.kotlin.project.model.LanguageSettings;
import org.jetbrains.kotlin.tooling.core.KotlinToolingVersion;
import org.tomlj.Toml;
@@ -55,6 +59,8 @@
*/
public class PluginClasspathGradleBuild extends GradleBuild {
+ private static final GradleVersion GRADLE_VERSION_8_10 = GradleVersion.version("8.10");
+
public PluginClasspathGradleBuild() {
super();
}
@@ -69,6 +75,15 @@ public GradleRunner prepareRunner(String... arguments) throws IOException {
}
private List pluginClasspath() {
+ List pluginClasspath = new ArrayList<>(basePluginClasspath());
+ if (this.getGradleVersion() == null
+ || GradleVersion.version(this.getGradleVersion()).compareTo(GRADLE_VERSION_8_10) > 0) {
+ pluginClasspath.addAll(classpathAdditionsForGradleVersionsWithEmbeddedKotlin2());
+ }
+ return pluginClasspath;
+ }
+
+ private List basePluginClasspath() {
return Arrays.asList(new File("bin/main"), new File("build/classes/java/main"),
new File("build/resources/main"), new File(pathOfJarContaining(LaunchScript.class)),
new File(pathOfJarContaining(ClassVisitor.class)),
@@ -94,6 +109,12 @@ private List pluginClasspath() {
new File(pathOfJarContaining("org.graalvm.buildtools.utils.SharedConstants")));
}
+ private List classpathAdditionsForGradleVersionsWithEmbeddedKotlin2() {
+ return Arrays.asList(new File(pathOfJarContaining(ClassSnapshotGranularity.class)),
+ new File(pathOfJarContaining("org.jetbrains.kotlin.build.report.metrics.GradleBuildTime")),
+ new File(pathOfJarContaining(HostManager.class)));
+ }
+
private String pathOfJarContaining(String className) {
try {
return pathOfJarContaining(Class.forName(className));
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksCanOverrideDefaultJavaParametersFlag.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksCanOverrideDefaultJavaParametersFlag.gradle
index 625f97ccd43b..54676cd9a4a3 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksCanOverrideDefaultJavaParametersFlag.gradle
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksCanOverrideDefaultJavaParametersFlag.gradle
@@ -4,16 +4,16 @@ plugins {
apply plugin: 'org.jetbrains.kotlin.jvm'
-import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
tasks.withType(KotlinCompile) {
- kotlinOptions.javaParameters = false
+ compilerOptions.javaParameters = false
}
task('kotlinCompileTasksJavaParameters') {
doFirst {
tasks.withType(KotlinCompile) {
- println "${name} java parameters: ${kotlinOptions.javaParameters}"
+ println "${name} java parameters: ${compilerOptions.javaParameters.get()}"
}
}
}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksUseJavaParametersFlagByDefault.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksUseJavaParametersFlagByDefault.gradle
index f5be02c186bd..1058b326845d 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksUseJavaParametersFlagByDefault.gradle
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinCompileTasksUseJavaParametersFlagByDefault.gradle
@@ -4,12 +4,12 @@ plugins {
apply plugin: 'org.jetbrains.kotlin.jvm'
-import org.jetbrains.kotlin.gradle.dsl.KotlinCompile
+import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
task('kotlinCompileTasksJavaParameters') {
doFirst {
tasks.withType(KotlinCompile) {
- println "${name} java parameters: ${kotlinOptions.javaParameters}"
+ println "${name} java parameters: ${compilerOptions.javaParameters.get()}"
}
}
}