From d7cf6684cab465d3a54c713327ca4560ed7b0c1b Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Fri, 6 Oct 2017 10:58:50 +0200 Subject: [PATCH 1/3] Add Kotlin main artifacts to dependency management This commit adds Kotlin main artifacts to Spring Boot dependency management and will be replaced by Kotlin BOM when it will be available (see KT-18398). gh-9486 --- .../spring-boot-dependencies/pom.xml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index 6c7c111be801..8342feb2a560 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -107,6 +107,7 @@ 4.12 5.0.1 1.0.1 + 1.1.51 5.0.0.RELEASE 3.5.3 2.9.1 @@ -2264,6 +2265,26 @@ jooq-codegen ${jooq.version} + + org.jetbrains.kotlin + kotlin-reflect + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jre7 + ${kotlin.version} + + + org.jetbrains.kotlin + kotlin-stdlib-jre8 + ${kotlin.version} + org.liquibase liquibase-core From 844e6ff13e56ad8e19ba9defd6fd75965ab86b0e Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Fri, 20 Oct 2017 11:44:44 +0200 Subject: [PATCH 2/3] Add runApplication() Kotlin top level function Since Kotlin extensions do not apply to static methods, this commit introduces a runApplication() Kotlin top level function that acts as a Kotlin shortcut for SpringApplication.run(). This shortcut avoids to require using non-idiomatic code like SpringApplication.run(FooApplication::class.java) and provides a runApplication() alternative (as well as an array of KClass based alternative when multiple classes need to be passed as parameter). It is possible to customize the application with the following syntax: runApplication() { setEnvironment(environment) } Closes gh-8511 --- spring-boot-project/spring-boot/pom.xml | 83 ++++++++++++ .../boot/SpringApplicationExtensions.kt | 53 ++++++++ .../boot/SpringApplicationExtensionsTests.kt | 118 ++++++++++++++++++ 3 files changed, 254 insertions(+) create mode 100644 spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/SpringApplicationExtensions.kt create mode 100644 spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt diff --git a/spring-boot-project/spring-boot/pom.xml b/spring-boot-project/spring-boot/pom.xml index e757a0e45710..ceed9c208c00 100644 --- a/spring-boot-project/spring-boot/pom.xml +++ b/spring-boot-project/spring-boot/pom.xml @@ -13,6 +13,79 @@ ${basedir}/../.. + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + + ${java.version} + + + + compile + compile + + compile + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/main/java + + + + + test-compile + test-compile + + test-compile + + + + ${project.basedir}/src/test/kotlin + ${project.basedir}/src/test/java + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + + ${java.version} + ${java.version} + true + + + + default-compile + none + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + @@ -264,6 +337,16 @@ snakeyaml true + + org.jetbrains.kotlin + kotlin-stdlib + true + + + org.jetbrains.kotlin + kotlin-reflect + true + org.springframework.boot diff --git a/spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/SpringApplicationExtensions.kt b/spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/SpringApplicationExtensions.kt new file mode 100644 index 000000000000..84ce0569968a --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/SpringApplicationExtensions.kt @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2017 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 + +import org.springframework.context.ConfigurableApplicationContext +import kotlin.reflect.KClass + + +/** + * Top level function acting as a Kotlin shortcut allowing to write `runApplication(arg1, arg2)` + * instead of `SpringApplication.run(FooApplication::class.java, arg1, arg2)`. + * + * @author Sebastien Deleuze + * @since 2.0.0 + */ +inline fun runApplication(vararg args: String): ConfigurableApplicationContext = + SpringApplication.run(T::class.java, *args) + +/** + * Top level function acting as a Kotlin shortcut allowing to write `runApplication(arg1, arg2) { // SpringApplication customization ... }` + * instead of instantiating `SpringApplication` class, customize it and then invoking `run(arg1, arg2)`. + * + * @author Sebastien Deleuze + * @since 2.0.0 + */ +inline fun runApplication(vararg args: String, init: SpringApplication.() -> Unit): ConfigurableApplicationContext = + SpringApplication(T::class.java).apply(init).run(*args) + + +/** + * Top level function acting as a Kotlin shortcut allowing to write + * `runApplication(arrayOf(FooApplication::class, FooConfiguration::class), arg1, arg2) { // Optional SpringApplication customization ... }` + * instead of instantiating `SpringApplication` class, customize it and then invoking `run(arrayOf(arg1, arg2))`.` + * + * @author Sebastien Deleuze + * @since 2.0.0 + */ +fun runApplication(primarySources: Array>, vararg args: String, init: SpringApplication.() -> Unit = {}): ConfigurableApplicationContext = + SpringApplication(*primarySources.map { it.java }.toTypedArray()).apply(init).run(*args) diff --git a/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt b/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt new file mode 100644 index 000000000000..979367899d65 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt @@ -0,0 +1,118 @@ +/* + * Copyright 2002-2017 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 + +import org.junit.Assert.* +import org.junit.Test +import org.springframework.beans.factory.getBean +import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.core.env.StandardEnvironment + +/** + * Tests for `SpringApplicationExtensions`. + * + * @author Sebastien Deleuze + */ +class SpringApplicationExtensionsTests { + + @Test + fun `Kotlin runApplication() top level function`() { + val context = runApplication() + assertNotNull(context) + } + + @Test + fun `Kotlin runApplication() top level function with a custom environment`() { + val environment = StandardEnvironment() + val context = runApplication { + setEnvironment(environment) + } + assertNotNull(context) + assertEquals(environment, context.environment) + } + + @Test + fun `Kotlin runApplication(arg1, arg2) top level function`() { + val context = runApplication("--debug", "spring", "boot") + val args = context.getBean() + assertArrayEquals(arrayOf("spring", "boot"), args.nonOptionArgs.toTypedArray()) + assertTrue(args.containsOption("debug")) + } + + @Test + fun `Kotlin runApplication(arg1, arg2) top level function with a custom environment`() { + val environment = StandardEnvironment() + val context = runApplication("--debug", "spring", "boot") { + setEnvironment(environment) + } + val args = context.getBean() + assertArrayEquals(arrayOf("spring", "boot"), args.nonOptionArgs.toTypedArray()) + assertTrue(args.containsOption("debug")) + assertEquals(environment, context.environment) + } + + @Test + fun `Kotlin runApplication(array of KClass) top level function`() { + val context = runApplication(arrayOf(ExampleConfig::class, ExampleWebConfig::class)) + assertNotNull(context) + } + + @Test + fun `Kotlin runApplication(array of KClass) top level function with a custom environment`() { + val environment = StandardEnvironment() + val context = runApplication(arrayOf(ExampleConfig::class, ExampleWebConfig::class)) { + setEnvironment(environment) + } + assertNotNull(context) + assertEquals(environment, context.environment) + } + + @Test + fun `Kotlin runApplication(array of KClass, arg1, arg2) top level function`() { + val context = runApplication(arrayOf(ExampleConfig::class, ExampleWebConfig::class), "--debug", "spring", "boot") + val args = context.getBean() + assertArrayEquals(arrayOf("spring", "boot"), args.nonOptionArgs.toTypedArray()) + assertTrue(args.containsOption("debug")) + } + + @Test + fun `Kotlin runApplication(array of KClass, arg1, arg2) top level function with a custom environment`() { + val environment = StandardEnvironment() + val context = runApplication(arrayOf(ExampleConfig::class, ExampleWebConfig::class), "--debug", "spring", "boot") { + setEnvironment(environment) + } + val args = context.getBean() + assertArrayEquals(arrayOf("spring", "boot"), args.nonOptionArgs.toTypedArray()) + assertTrue(args.containsOption("debug")) + assertEquals(environment, context.environment) + } + + + @Configuration + internal open class ExampleConfig + + @Configuration + internal open class ExampleWebConfig { + + @Bean + open fun webServer(): TomcatServletWebServerFactory { + return TomcatServletWebServerFactory(0) + } + } + +} From a92e7de08e9c5c5f020a412b6daa2a6fac60459f Mon Sep 17 00:00:00 2001 From: Sebastien Deleuze Date: Wed, 25 Oct 2017 09:57:39 +0200 Subject: [PATCH 3/3] Specify kotlin-maven-plugin version for plugin management gh-9486 --- spring-boot-project/spring-boot-dependencies/pom.xml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index 8342feb2a560..9b2f6c8b39ef 100644 --- a/spring-boot-project/spring-boot-dependencies/pom.xml +++ b/spring-boot-project/spring-boot-dependencies/pom.xml @@ -3024,6 +3024,11 @@ flyway-maven-plugin ${flyway.version} + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + pl.project13.maven git-commit-id-plugin