Search code examples
springspring-bootkotlinspring-el

Kotlin compiler complains about using a SPeL expression in a property definition. WHY?


When I try to use a SPeL expression to inject a value it works from in Java but NOT in Kotlin. The compiler says

Error:(13, 25) Kotlin: An annotation parameter must be a compile-time constant

Code:

@SpringBootApplication
open class DeDup(@Value("#{new java.io.File('${roots}')}") val roots: Set<File>,
                 @Value("algo") val hashAlgo: String,
                 @Value("types")val fileTypes: List<String>) {

}

fun main(args: Array<String>) {
 SpringApplication.run(DeDup::class.java, *args)
}

Mmm... news flash Kotlin compiler: It IS a constant! The compiler clearly knows it's a SPeL expression and doesn't like it.

My questions:

  1. Why doesn't Kotlin like SPeL? This is a construction injection (or is it) and doesn't violate immutability.

  2. Is this a compiler bug? The message is irrefutably wrong.


Solution

  • ${roots} inside a String in Kotlin is a string template, therefore that String is not a constant.

    If you want the String to contain those actual characters and not be interpreted as a template, you'll have to escape the $:

    @Value("#{new java.io.File('\${roots}')}")