[[features.kotlin]]
= Kotlin Support

https://kotlinlang.org[Kotlin] is a statically-typed language targeting the JVM (and other platforms) which allows writing concise and elegant code while providing {url-kotlin-docs}/java-interop.html[interoperability] with existing libraries written in Java.

Spring Boot provides Kotlin support by leveraging the support in other Spring projects such as Spring Framework, Spring Data, and Reactor.
See the {url-spring-framework-docs}/languages/kotlin.html[Spring Framework Kotlin support documentation] for more information.

The easiest way to start with Spring Boot and Kotlin is to follow https://spring.io/guides/tutorials/spring-boot-kotlin/[this comprehensive tutorial].
You can create new Kotlin projects by using https://start.spring.io/#!language=kotlin[start.spring.io].
Feel free to join the #spring channel of https://slack.kotlinlang.org/[Kotlin Slack] or ask a question with the `spring` and `kotlin` tags on https://stackoverflow.com/questions/tagged/spring+kotlin[Stack Overflow] if you need support.



[[features.kotlin.requirements]]
== Requirements

Spring Boot requires at least Kotlin 2.2.x and manages a suitable Kotlin version through dependency management.
To use Kotlin, `org.jetbrains.kotlin:kotlin-stdlib` and `org.jetbrains.kotlin:kotlin-reflect` must be present on the classpath.

Kotlin 2.2.x introduces https://kotlinlang.org/docs/whatsnew22.html#new-defaulting-rules-for-use-site-annotation-targets[new defaulting rules for propagating annotations to parameters, fields, and properties]. In order to avoid related warnings and use what will likely become the Kotlin default behavior in an upcoming version, it is recommended to configure the `-Xannotation-default-target=param-property` compiler flag.

Since https://discuss.kotlinlang.org/t/classes-final-by-default/166[Kotlin classes are final by default], you are likely to want to configure {url-kotlin-docs}/compiler-plugins.html#spring-support[kotlin-spring] plugin in order to automatically open Spring-annotated classes so that they can be proxied.

https://github.com/FasterXML/jackson-module-kotlin[Jackson's Kotlin module] is required for serializing / deserializing JSON data in Kotlin.
It is automatically registered when found on the classpath.

TIP: These dependencies and plugins are provided by default if one bootstraps a Kotlin project on https://start.spring.io/#!language=kotlin[start.spring.io].



[[features.kotlin.null-safety]]
== Null-safety

One of Kotlin's key features is {url-kotlin-docs}/null-safety.html[null-safety].
It deals with `null` values at compile time rather than deferring the problem to runtime and encountering a javadoc:java.lang.NullPointerException[].
This helps to eliminate a common source of bugs without paying the cost of wrappers like javadoc:java.util.Optional[].
Kotlin also allows using functional constructs with nullable values as described in this https://www.baeldung.com/kotlin-null-safety[comprehensive guide to null-safety in Kotlin].

Although Java does not let you express null-safety in its type-system, most Spring projects
provide {url-spring-framework-docs}/core/null-safety.html[null-safety] via https://jspecify.dev/[JSpecify] annotations.

As of Kotlin 2.1, Kotlin enforces strict handling of nullability annotations from the `org.jspecify.annotations` package.



[[features.kotlin.api]]
== Kotlin API



[[features.kotlin.api.run-application]]
=== runApplication

Spring Boot provides an idiomatic way to run an application with `runApplication<MyApplication>(*args)` as shown in the following example:

[source,kotlin]
----
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication
class MyApplication

fun main(args: Array<String>) {
	runApplication<MyApplication>(*args)
}
----

This is a drop-in replacement for `SpringApplication.run(MyApplication::class.java, *args)`.
It also allows customization of the application as shown in the following example:

[source,kotlin]
----
runApplication<MyApplication>(*args) {
	setBannerMode(OFF)
}
----



[[features.kotlin.api.extensions]]
=== Extensions

Kotlin {url-kotlin-docs}/extensions.html[extensions] provide the ability to extend existing classes with additional functionality.
The Spring Boot Kotlin API makes use of these extensions to add new Kotlin specific conveniences to existing APIs.

javadoc:org.springframework.boot.resttestclient.TestRestTemplate[] extensions, similar to those provided by Spring Framework for javadoc:org.springframework.web.client.RestOperations[] in Spring Framework, are provided.
Among other things, the extensions make it possible to take advantage of Kotlin reified type parameters.



[[features.kotlin.dependency-management]]
== Dependency Management

In order to avoid mixing different versions of Kotlin dependencies on the classpath, Spring Boot imports the Kotlin BOM.

With Maven, the Kotlin version can be customized by setting the `kotlin.version` property and plugin management is provided for `kotlin-maven-plugin`.
With Gradle, the Spring Boot plugin automatically aligns the `kotlin.version` with the version of the Kotlin plugin.

Spring Boot also manages the version of Coroutines dependencies by importing the Kotlin Coroutines BOM.
The version can be customized by setting the `kotlin-coroutines.version` property.

TIP: `org.jetbrains.kotlinx:kotlinx-coroutines-reactor` dependency is provided by default if one bootstraps a Kotlin project with at least one reactive dependency on https://start.spring.io/#!language=kotlin[start.spring.io].



[[features.kotlin.configuration-properties]]
== @ConfigurationProperties
javadoc:org.springframework.boot.context.properties.ConfigurationProperties[format=annotation] when used in combination with xref:features/external-config.adoc#features.external-config.typesafe-configuration-properties.constructor-binding[constructor binding] supports data classes with immutable `val` properties as shown in the following example:

[source,kotlin]
----
@ConfigurationProperties("example.kotlin")
data class KotlinExampleProperties(
		val name: String,
		val description: String,
		val myService: MyService
) {

	data class MyService(
			val apiToken: String,
			val uri: URI
	)
}
----

Due to the limitations of their interoperability with Java, support for value classes is limited.
In particular, relying upon a value class's default value will not work with configuration property binding.
In such cases, a data class should be used instead.

TIP: To generate xref:specification:configuration-metadata/annotation-processor.adoc[your own metadata] using the annotation processor, {url-kotlin-docs}/kapt.html[`kapt` should be configured] with the `spring-boot-configuration-processor` dependency.
Note that some features (such as detecting the default value or deprecated items) are not working due to limitations in the model kapt provides.



[[features.kotlin.testing]]
== Testing

While it is possible to use JUnit 4 to test Kotlin code, JUnit 6 is provided by default and is recommended.
JUnit 6 enables a test class to be instantiated once and reused for all of the class's tests.
This makes it possible to use javadoc:org.junit.jupiter.api.BeforeAll[format=annotation] and javadoc:org.junit.jupiter.api.AfterAll[format=annotation] annotations on non-static methods, which is a good fit for Kotlin.

To mock Kotlin classes, https://mockk.io/[MockK] is recommended.
If you need the `MockK` equivalent of the Mockito specific xref:testing/spring-boot-applications.adoc#testing.spring-boot-applications.mocking-beans[`@MockitoBean` and javadoc:org.springframework.test.context.bean.override.mockito.MockitoSpyBean[format=annotation] annotations], you can use https://github.com/Ninja-Squad/springmockk[SpringMockK] which provides similar `@MockkBean` and `@SpykBean` annotations.



[[features.kotlin.resources]]
== Resources



[[features.kotlin.resources.further-reading]]
=== Further Reading

* {url-kotlin-docs}[Kotlin language reference]
* https://kotlinlang.slack.com/[Kotlin Slack] (with a dedicated #spring channel)
* https://stackoverflow.com/questions/tagged/spring+kotlin[Stack Overflow with `spring` and `kotlin` tags]
* https://try.kotlinlang.org/[Try Kotlin in your browser]
* https://blog.jetbrains.com/kotlin/[Kotlin blog]
* https://kotlin.link/[Awesome Kotlin]
* https://spring.io/guides/tutorials/spring-boot-kotlin/[Tutorial: building web applications with Spring Boot and Kotlin]
* https://spring.io/blog/2016/02/15/developing-spring-boot-applications-with-kotlin[Developing Spring Boot applications with Kotlin]
* https://spring.io/blog/2016/03/20/a-geospatial-messenger-with-kotlin-spring-boot-and-postgresql[A Geospatial Messenger with Kotlin, Spring Boot and PostgreSQL]
* https://spring.io/blog/2017/01/04/introducing-kotlin-support-in-spring-framework-5-0[Introducing Kotlin support in Spring Framework 5.0]
* https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-way[Spring Framework 5 Kotlin APIs, the functional way]



[[features.kotlin.resources.examples]]
=== Examples

* https://github.com/sdeleuze/spring-boot-kotlin-demo[spring-boot-kotlin-demo]: regular Spring Boot + Spring Data JPA project
* https://github.com/mixitconf/mixit[mixit]: Spring Boot 2 + WebFlux + Reactive Spring Data MongoDB
* https://github.com/sdeleuze/spring-kotlin-fullstack[spring-kotlin-fullstack]: WebFlux Kotlin fullstack example with Kotlin2js for frontend instead of JavaScript or TypeScript
* https://github.com/spring-petclinic/spring-petclinic-kotlin[spring-petclinic-kotlin]: Kotlin version of the Spring PetClinic Sample Application
* https://github.com/sdeleuze/spring-kotlin-deepdive[spring-kotlin-deepdive]: a step by step migration for Boot 1.0 + Java to Boot 2.0 + Kotlin
* https://github.com/sdeleuze/spring-boot-coroutines-demo[spring-boot-coroutines-demo]: Coroutines sample project
