Search code examples
kotlinreflectionserver

Get annotation value via reflection


I am trying to get all the "Keys" of annotations for use later, I am initializing the value like this:

private val wgKeys = SpecialRequestContext::class.members.associate { m ->
    m.name to run {
        val headerAnnotation = m.annotations.find { a -> a is Header } as? Header
        headerAnnotation?.key
    }
}

Unfortunately, the result is a Map with name for keys (correct), but all the values are null. While debugging I see that m.annotations has no values.

Are annotations not available at this step?

Update: The minimum code to demonstrate this is here, unfortunately Kotlin playground cannot do reflection though:

@Target(AnnotationTarget.VALUE_PARAMETER)
annotation class Header(val key: String)

data class SpecialRequestContext(
    @Header("BK-Correlation-Id") val correlationId: String? = null,
    @Header("BK-Origin") val origin: String? = null,
    @Header("BK-Origin-City") val originCity: String? = null,
)

fun main() {
    println(wgKeys.count())
    println(wgKeys["origin"])
}

private val wgKeys = SpecialRequestContext::class.members.associate { m ->
        m.name to run {
            val headerAnnotation = m.annotations.find { a -> a is Header } as? Header
            headerAnnotation?.key
        }
    }

Solution

  • Notice:

    @Target(AnnotationTarget.VALUE_PARAMETER)
    

    This means that the annotation is applied to the constructor parameters, not the properties. You won't find them on the properties.

    To find them on the properties, you can change it to:

    @Target(AnnotationTarget.PROPERTY)
    

    If you need them applied to the parameters for some reason, you can find them like this:

    private val wgKeys = SpecialRequestContext::class.primaryConstructor!!.parameters.associate { p ->
        p.name to p.findAnnotation<Header>()?.key
    }