NewUser
NewUser

Reputation: 3819

Classes annotated with @Configuration could be implicitly subclassed and must not be final

I created a new project on Kotlin to generate a report. Knowing Kotlin can reduce number of lines of code and is safer than Java, I used Spring-jpa and Kotlin to get this done. All my @Configuration classes had an error:

Classes annotated with @Configuration could be implicitly subclassed and must not be final

FYI, I am using a maven project with Kotlin 1.3.50. From my knowledge, I knew that spring does subclass for injecting values.

How do I make spring happy but not keep writing open in each of my class where spring complains?

Upvotes: 8

Views: 11251

Answers (2)

Grigory Kislin
Grigory Kislin

Reputation: 18020

When project generated by Spring initializr, plugin kotlin-spring automatically added and open all Spring beans: https://github.com/spring-guides/tut-spring-boot-kotlin#plugins

Upvotes: 1

NewUser
NewUser

Reputation: 3819

As you might already know, by default kotlin classes cannot be extended. In order to support inheritance, you got to add open keyword. Also, we know for a fact that spring annotation processing needs classes marked as @Configuration can be subclassed.

The alternative of writing open in each of the classes is to add a plugin : kotlin-allopen

ex :

<plugin>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-maven-plugin</artifactId>
    <version>${kotlin.version}</version>
    <configuration>
        <compilerPlugins>
            <plugin>spring</plugin>
        </compilerPlugins>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.jetbrains.kotlin</groupId>
            <artifactId>kotlin-maven-allopen</artifactId>
            <version>${kotlin.version}</version>
        </dependency>
    </dependencies>
    <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>
</plugin>




<compilerPlugins>
    <plugin>spring</plugin>
</compilerPlugins>

The above does the trick of adding open to the following annotations: @Component, @Async, @Transactional, @Cacheable and @SpringBootTest. Thanks to meta-annotations support classes annotated with @Configuration, @Controller, @RestController, @Service or @Repository are automatically opened since these annotations are meta-annotated with @Component.

You can find the documentation here: https://kotlinlang.org/docs/reference/compiler-plugins.html

Upvotes: 12

Related Questions