DEV Community

Cover image for Kotlin with Spring Boot Setup
Ismaïl BENHALLAM
Ismaïl BENHALLAM

Posted on • Edited on

Kotlin with Spring Boot Setup

As we known, Kotlin has a compiler for the JVM platform, which means all the codes written in Kotlin can run on the JVM. Therefore, even though Spring itself is written entirely in Java, Spring applications could be written in Java or/and in Kotlin. However, Java and Kotlin are different languages, that means a Spring application written in Kotlin requires an extra configuration.

Additional dependencies

  • kotlin-stdlib-jdk8: This dependency includes a variant of the standard Java 8 library to Kotlin with the required classes (needed for compatibility of Java and Kotlin).
  • kotlin-reflect: Spring often uses reflection, for example, to create proxy classes, but Java and Kotlin objects are various. Therefore, we have to work with them differently. This dependency adds the ability for Spring to work with objects by reflection.
  • jackson-module-kotlin: Java and Kotlin objects have different internal structures. The standard Jackson serializer for Java may not handle Kotlin objects in some cases. Specifically, this library add support for introspection of Kotlin method/constructor parameter names, without having to add explicit property name annotation. Assuming we are using Gradle with Kotlin DSL, including these plugins would looks like:
dependencies {
    implementation("org.jetbrains.kotlin:kotlin-reflect:1.8.10")
    implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.8.10")
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2")
}
Enter fullscreen mode Exit fullscreen mode

Note: You can use shorthand for a dependency on a Kotlin module, for example, kotlin("test") for "org.jetbrains.kotlin:kotlin-test"

dependencies {
    implementation(kotlin("reflect:1.8.10"))
    implementation(kotlin("stdlib-jdk8:1.8.10"))
    implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.14.2")
}
Enter fullscreen mode Exit fullscreen mode

Additional plugins

all-open plugin

In Koltin, classes and their members are final by default. And as you may know, Spring inherits from our classes/interfaces to create proxy classes and overrides some methods at the runtime (ex: interfaces extending CrudRepository, classes using @Transactional annotation…).
This means, we need to mark almost “everything” with the open modifier, and that could be annoying.

all-open plugin is here to the rescue! It make Kotlin classes annotated with a specific annotation and their members open, without using the modifier open explicitly.

plugins {
    kotlin("plugin.allopen") version "1.8.10" // check the latest version
}
Enter fullscreen mode Exit fullscreen mode

Now we just need to specify these annotations in an allOpen block in the Gradle build file :

allOpen {
    annotation("org.springframework.stereotype.Repository")
    annotation("org.springframework.transaction.annotation.Transactional")
    annotation("org.springframework.context.annotation.Configuration")
    annotation("com.example.annotation.SuperAnnotation")
    //...
}
Enter fullscreen mode Exit fullscreen mode

Cool, right ?
Still, that’s boilerplate work, we will have to remember it whenever we create a new project, or we will end-up by copy/pasting it each time, or…
The ultimate solution for all this is called kotlin-spring plugin.

kotlin-spring plugin

plugins {
    kotlin("plugin.spring") version "1.8.10"
}
Enter fullscreen mode Exit fullscreen mode

The kotlin-spring plugin is a wrapper on top of all-open plugin. By using it, you can omit listing Spring annotations manually in an allOpen block. The plugin specifies the following annotations:

  • @Component
  • @Transactional
  • @Async
  • @Cacheable
  • @SpringBootTest

And thanks to meta-annotations support, classes annotated with : @Configuration, @Controller, @RestController, @Service, @Repository are automatically opened since these annotations are meta-annotated with @Component.
Moreover, we still can have an allOpen block and list other annotations if we need that.

Note: If you use the project template generated by start.spring.io, the kotlin-spring plugin will be enabled by default.

no-arg plugin

no-arg plugin generates an additional zero-argument constructor for some classes, the selection of these classes is done the same way it’s done with all-open plugin; The plugin is looking for classes annotated with a special annotation.
To use the plugin, we’ll have to start by including it in our build file :

plugins {
    kotlin("plugin.noarg") version "1.8.10"
}
Enter fullscreen mode Exit fullscreen mode

Then, similar to the allOpen block related to all-open plugin, we need to add a noArg block :

noArg {
    annotation("org.example.SomeAnnotation")
    //...
}
Enter fullscreen mode Exit fullscreen mode

This feature could be useful when we want to use Java Persistence API, it allows JPA to instantiate a class although it doesn’t have a zero-argument constructor. We just need to list the right annotations from JPA. Let’s see how we could do it in a better way with the next plugin.

kotlin-jpa plugin

As with the kotlin-spring plugin wrapped on top of all-open, kotlin-jp is wrapped on top of no-arg. The plugin specifies the following annotations as no-arg annotations automatically :

  • @Entity
  • @Embeddable
  • @MappedSuperclass
plugins {
    kotlin("plugin.jpa") version "1.8.10"
}
Enter fullscreen mode Exit fullscreen mode

I hope this was helpful. And thanks for reading.

Top comments (0)