Search code examples
spring-bootkotlinspring-annotationsspring-webflux

Spring Boot + Kotlin annotation error(s)


I have a Spring Boot 2.0.0.M2 (with WebFlux) application written in Kotlin.

I'm used to define/declare "annotations" for test cases in order to avoid some boilerplate configuration; something like:

import java.lang.annotation.ElementType
import java.lang.annotation.Inherited
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
import java.lang.annotation.Target
...

@Inherited
@Target(ElementType.TYPE)
@AutoConfigureWebTestClient // TODO: FTW this really does?!
@Retention(RetentionPolicy.RUNTIME)
//@kotlin.annotation.Target(AnnotationTarget.TYPE)
//@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
@ActiveProfiles(profiles = arrayOf("default", "test"))
@ContextConfiguration(classes = arrayOf(Application::class))
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
annotation class SpringWebFluxTest

...then in my tests I use it like:

@SpringWebFluxTest
@RunWith(SpringRunner::class)
class PersonWorkflowTest {
  private lateinit var client: WebTestClient
  ...

The issue is that I can't achieve the same using the annotations provided by Kotlin:

@kotlin.annotation.Target(AnnotationTarget.TYPE)
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)

I'm getting a this annotation is not applicable to target 'class' inside PersonWorkflowTest. If I use the Java ones everything is fine, but on the other hand I get these warnings ― which what I'm really trying to get rid of :)

...
:compileTestKotlin
w: /home/gorre/Workshop/kotlin-spring-boot-reactive/src/test/kotlin/io/shido/annotations/SpringWebFluxTest.kt: (18, 1): This annotation is deprecated in Kotlin. Use '@kotlin.annotation.Target' instead
w: /home/gorre/Workshop/kotlin-spring-boot-reactive/src/test/kotlin/io/shido/annotations/SpringWebFluxTest.kt: (20, 1): This annotation is deprecated in Kotlin. Use '@kotlin.annotation.Retention' instead

Kotlin Annotation(s) error with Spring Boot


Solution

  • kotlin has it own @kotlin.annotation.Retention and @kotlin.annotation.Target annotations. take a while to look the kotlin annotation documentation please.

    Edit

    I have test it in springframework that no problem. Note that have a distinction in @Target between java and kotlin.

    the kotlin kotlin.annotation.@Target(AnnotationTarget.CLASS) is translated to:

    @java.lang.annotation.Target(ElementType.TYPE);
    

    and the kotlin kotlin.annotation.@Target(AnnotationTarget.TYPE) is translated to:

    @java.lang.annotation.Target;
    

    which means AnnotationTarget.TYPE don't supported for java. it just used in kotlin. so your own annotation should be like this:

    //spring-test annotations
    @ActiveProfiles(profiles = arrayOf("default", "test"))
    @ContextConfiguration(classes = arrayOf(Application::class))
    //spring-boot annotations
    @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
    @AutoConfigureWebTestClient
    //kotlin annotations
    @Target(AnnotationTarget.CLASS)
    @Retention(AnnotationRetention.RUNTIME)// can remove it default is RUNTIME
    annotation class SpringWebFluxTest;