1. Overview
In Kotlin, all classes are final by default which, beyond its clear advantages, can be problematic in Spring applications. Simply put, some areas in Spring only work with non-final classes.
The natural solution is to manually open Kotlin classes using the open keyword or to use the kotlin-allopen plugin – which automatically opens all classes that are necessary for Spring to work.
2. Maven Dependencies
Let’s start by adding the Kotlin-Allopen dependency:
<dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-allopen</artifactId> <version>1.1.4-3</version> </dependency>
To enable the plugin, we need to configure the kotlin-allopen in the build section:
<build> ... <plugins> ... <plugin> <artifactId>kotlin-maven-plugin</artifactId> <groupId>org.jetbrains.kotlin</groupId> <version>1.1.4-3</version> <configuration> <compilerPlugins> <plugin>spring</plugin> </compilerPlugins> <jvmTarget>1.8</jvmTarget> </configuration> <executions> <execution> <id>compile</id> <phase>compile</phase> <goals> <goal>compile</goal> </goals> </execution> <execution> <id>test-compile</id> <phase>test-compile</phase> <goals> <goal>test-compile</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.jetbrains.kotlin</groupId> <artifactId>kotlin-maven-allopen</artifactId> <version>1.1.4-3</version> </dependency> </dependencies> </plugin> </plugins> </build>
3. Setup
Now let’s consider SimpleConfiguration.kt, a simple configuration class:
@Configuration class SimpleConfiguration { }
4. Without Kotlin-Allopen
If we build our project without the plugin, we’ll see get the following error message:
org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: @Configuration class 'SimpleConfiguration' may not be final. Remove the final modifier to continue.
The only way to solve it is to open it manually:
@Configuration open class SimpleConfiguration { }
5. Including Kotlin-Allopen
Opening all classes for Spring is not very handy. If we use the plugin, all necessary classes will be open.
We can clearly see that if we look at the compiled class:
@Configuration public open class SimpleConfiguration public constructor() { }
6. Conclusion
In this quick article, we’ve seen how to solve the “class may not be final” problem in Spring and Kotlin.
Source code for this article can be found over on GitHub.