diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml
index b61dba0f60..9870105e2e 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/pom.xml
@@ -29,6 +29,12 @@
org.apache.commons
commons-compress
+
+ org.jetbrains.kotlin
+ kotlin-gradle-plugin
+ ${kotlin.version}
+ true
+
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc
index 22029c0124..420a74a68f 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/asciidoc/reacting.adoc
@@ -4,6 +4,8 @@
When another plugin is applied the Spring Boot plugin reacts by making various changes
to the project's configuration. This section describes those changes.
+
+
[[reacting-to-other-plugins-java]]
=== Reacting to the Java plugin
@@ -25,6 +27,18 @@ plugin:
+[[reacting-to-other-plugins-kotlin]]
+=== Reacting to the Kotlin plugin
+
+When {kotlin-plugin}[Kotlin's Gradle plugin] is applied to a project, the Spring Boot
+plugin:
+
+1. Aligns the Koltin version used in Spring Boot's dependency management with the version
+ of the plugin. This is achieved by setting the `kotlin.version` property with a value
+ that matches the version of the Kotlin plugin.
+
+
+
[[reacting-to-other-plugins-war]]
=== Reacting to the war plugin
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
new file mode 100644
index 0000000000..13c6e213ec
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/KotlinPluginAction.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2012-2018 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
+ *
+ * http://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.boot.gradle.plugin;
+
+import org.gradle.api.Plugin;
+import org.gradle.api.Project;
+import org.gradle.api.plugins.ExtraPropertiesExtension;
+import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper;
+
+/**
+ * {@link PluginApplicationAction} that reacts to Kotlin's Gradle plugin being applied by
+ * configuring a {@code kotlin.version} property to align the version used for dependency
+ * management for Kotlin with the version of its plugin.
+ *
+ * @author Andy Wilkinson
+ */
+class KotlinPluginAction implements PluginApplicationAction {
+
+ @Override
+ public void execute(Project project) {
+ String kotlinVersion = project.getPlugins().getPlugin(KotlinPluginWrapper.class)
+ .getKotlinPluginVersion();
+ ExtraPropertiesExtension extraProperties = project.getExtensions()
+ .getExtraProperties();
+ if (!extraProperties.has("kotlin.version")) {
+ extraProperties.set("kotlin.version", kotlinVersion);
+ }
+ }
+
+ @Override
+ @SuppressWarnings("unchecked")
+ public Class extends Plugin extends Project>> getPluginClass() {
+ try {
+ return (Class extends Plugin extends Project>>) Class
+ .forName("org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper");
+ }
+ catch (Throwable ex) {
+ return null;
+ }
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.java
index a02de18610..d43b354a09 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/PluginApplicationAction.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2012-2017 the original author or authors.
+ * Copyright 2012-2018 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.
@@ -30,9 +30,9 @@ interface PluginApplicationAction extends Action {
/**
* The class of the {@code Plugin} that, when applied, will trigger the execution of
- * this action.
+ * this action. May return {@code null} if the plugin class is not on the classpath.
*
- * @return the plugin class
+ * @return the plugin class or {@code null}
*/
Class extends Plugin extends Project>> getPluginClass();
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java
index ad0dc16624..dadf552596 100644
--- a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/plugin/SpringBootPlugin.java
@@ -108,10 +108,15 @@ public class SpringBootPlugin implements Plugin {
new JavaPluginAction(singlePublishedArtifact),
new WarPluginAction(singlePublishedArtifact),
new MavenPluginAction(bootArchives.getUploadTaskName()),
- new DependencyManagementPluginAction(), new ApplicationPluginAction());
+ new DependencyManagementPluginAction(), new ApplicationPluginAction(),
+ new KotlinPluginAction());
for (PluginApplicationAction action : actions) {
- project.getPlugins().withType(action.getPluginClass(),
- (plugin) -> action.execute(project));
+ Class extends Plugin extends Project>> pluginClass = action
+ .getPluginClass();
+ if (pluginClass != null) {
+ project.getPlugins().withType(pluginClass,
+ (plugin) -> action.execute(project));
+ }
}
}
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
new file mode 100644
index 0000000000..2df6955347
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2012-2018 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
+ *
+ * http://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.boot.gradle.plugin;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import org.springframework.boot.gradle.junit.GradleCompatibilitySuite;
+import org.springframework.boot.gradle.testkit.GradleBuild;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * Integration tests for {@link KotlinPluginAction}.
+ *
+ * @author Andy Wilkinson
+ */
+@RunWith(GradleCompatibilitySuite.class)
+public class KotlinPluginActionIntegrationTests {
+
+ @Rule
+ public GradleBuild gradleBuild;
+
+ @Test
+ public void noKotlinVersionPropertyWithoutKotlinPlugin() {
+ assertThat(this.gradleBuild.build("kotlinVersion").getOutput())
+ .contains("Kotlin version: none");
+ }
+
+ @Test
+ public void kotlinVersionMatchesKotlinPluginVersion() {
+ String output = this.gradleBuild
+ .build("kotlinVersion", "dependencies", "--configuration", "compile")
+ .getOutput();
+ assertThat(output).contains("Kotlin version: 1.2.10");
+ assertThat(output).contains("org.jetbrains.kotlin:kotlin-stdlib-jdk8: -> 1.2.10");
+ }
+
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinVersionMatchesKotlinPluginVersion.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinVersionMatchesKotlinPluginVersion.gradle
new file mode 100644
index 0000000000..561ae1d224
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-kotlinVersionMatchesKotlinPluginVersion.gradle
@@ -0,0 +1,39 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+plugins {
+ id 'org.jetbrains.kotlin.jvm' version '1.2.10'
+}
+
+
+apply plugin: 'org.springframework.boot'
+apply plugin: 'io.spring.dependency-management'
+
+dependencyManagement {
+ resolutionStrategy {
+ eachDependency {
+ if (it.requested.group == 'org.springframework.boot') {
+ it.useVersion project.bootVersion
+ }
+ }
+ }
+}
+
+repositories {
+ mavenCentral()
+ mavenLocal()
+}
+
+dependencies {
+ compile 'org.jetbrains.kotlin:kotlin-stdlib-jdk8'
+}
+
+task kotlinVersion {
+ doLast {
+ def kotlinVersion = project.hasProperty('kotlin.version') ? project.getProperty('kotlin.version') : 'none'
+ println "Kotlin version: ${kotlinVersion}"
+ }
+}
diff --git a/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-noKotlinVersionPropertyWithoutKotlinPlugin.gradle b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-noKotlinVersionPropertyWithoutKotlinPlugin.gradle
new file mode 100644
index 0000000000..1f34d0a34b
--- /dev/null
+++ b/spring-boot-project/spring-boot-tools/spring-boot-gradle-plugin/src/test/resources/org/springframework/boot/gradle/plugin/KotlinPluginActionIntegrationTests-noKotlinVersionPropertyWithoutKotlinPlugin.gradle
@@ -0,0 +1,14 @@
+buildscript {
+ dependencies {
+ classpath files(pluginClasspath.split(','))
+ }
+}
+
+apply plugin: 'org.springframework.boot'
+
+task kotlinVersion {
+ doLast {
+ def kotlinVersion = project.hasProperty('kotlin.version') ? project.getProperty('kotlin.version') : 'none'
+ println "Kotlin version: ${kotlinVersion}"
+ }
+}