diff --git a/spring-boot-project/spring-boot-dependencies/pom.xml b/spring-boot-project/spring-boot-dependencies/pom.xml index e14244b7d9e..c547fdafdbb 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 @@ -2244,6 +2245,26 @@ jdom2 ${jdom2.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.jolokia jolokia-core @@ -2860,6 +2881,11 @@ + + kotlin-maven-plugin + org.jetbrains.kotlin + ${kotlin.version} + org.jooq jooq-codegen-maven diff --git a/spring-boot-project/spring-boot-parent/pom.xml b/spring-boot-project/spring-boot-parent/pom.xml index 6ba2ad07e17..93ea49e2d6c 100644 --- a/spring-boot-project/spring-boot-parent/pom.xml +++ b/spring-boot-project/spring-boot-parent/pom.xml @@ -268,6 +268,14 @@ + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + ${java.version} + + org.asciidoctor asciidoctor-maven-plugin diff --git a/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/pom.xml b/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/pom.xml index 1da8f07d80c..9aae5b2590d 100644 --- a/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/pom.xml +++ b/spring-boot-project/spring-boot-starters/spring-boot-starter-parent/pom.xml @@ -60,6 +60,30 @@ + + org.jetbrains.kotlin + kotlin-maven-plugin + ${kotlin.version} + + ${java.version} + + + + compile + compile + + compile + + + + test-compile + test-compile + + test-compile + + + + org.apache.maven.plugins maven-compiler-plugin diff --git a/spring-boot-project/spring-boot/pom.xml b/spring-boot-project/spring-boot/pom.xml index e757a0e4571..beace20ba59 100644 --- a/spring-boot-project/spring-boot/pom.xml +++ b/spring-boot-project/spring-boot/pom.xml @@ -264,6 +264,16 @@ snakeyaml true + + org.jetbrains.kotlin + kotlin-stdlib + true + + + org.jetbrains.kotlin + kotlin-reflect + true + org.springframework.boot @@ -377,4 +387,68 @@ test + + + + org.jetbrains.kotlin + kotlin-maven-plugin + + + 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 + + + default-compile + none + + + default-testCompile + none + + + java-compile + compile + + compile + + + + java-test-compile + test-compile + + testCompile + + + + + + 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 00000000000..e64c6a1e4b4 --- /dev/null +++ b/spring-boot-project/spring-boot/src/main/kotlin/org/springframework/boot/SpringApplicationExtensions.kt @@ -0,0 +1,58 @@ +/* + * 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 00000000000..963e0308f10 --- /dev/null +++ b/spring-boot-project/spring-boot/src/test/kotlin/org/springframework/boot/SpringApplicationExtensionsTests.kt @@ -0,0 +1,122 @@ +/* + * 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.assertArrayEquals +import org.junit.Assert.assertEquals +import org.junit.Assert.assertNotNull +import org.junit.Assert.assertTrue +import org.junit.Test + +import org.springframework.beans.factory.getBean +import org.springframework.boot.web.servlet.server.MockServletWebServerFactory +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(): MockServletWebServerFactory { + return MockServletWebServerFactory() + } + } + +}