Home > Software design >  How to read Quarkus Config in dedicated Kotlin Class
How to read Quarkus Config in dedicated Kotlin Class

Time:10-14

Reading application properties in Kotlin/Quarkus works in a test class likes this correctly (the print will write the value which are defined in the application.properties file):

@QuarkusTest
class Test {

    @ConfigProperty(name = "test.env")
    val testEnv: String? = null

    @Test
    fun test(){
        println(testEnv)
    }
}

But when I create a dedicated configuration class and try to access the member from that class, the value is always null (and not as defined in the application.properties):

class Config{
    
    @ConfigProperty(name = "test.env")
    val foo: String? = null
}

Trying to access this value in the test class (but the value is always null):

@QuarkusTest
class Test {

    @Test
    fun test(){
        println(Config().foo)
    }
}

Quarkus version: 1.10.3.Final

What am I doing wrong?

CodePudding user response:

The @ConfigProperty annotation is in fact a CDI qualifier. In Quarkus, if a field is annotated with a qualifier, it doesn't have to be annotated @Inject -- but it is treated as if it was.

So your test class is equivalent to this:

@QuarkusTest
class Test {
    @Inject
    @ConfigProperty(name = "test.env")
    val testEnv: String? = null

    @Test
    fun test(){
        println(testEnv)
    }
}

Now, the other important thing is that if possible, the Quarkus test framework treats the test class as a CDI bean. That is, the test class is instantiated by the CDI container, which performs dependency injection. That is how testEnv is populated.

How do you achieve the same thing?

  1. Make your class a bean by adding a bean defining annotation.
@Singleton
class Config{ 
    @ConfigProperty(name = "test.env")
    val foo: String? = null
}

(Note that in standard CDI, @Singleton is not a bean defining annotation. In Quarkus, @Singleton is a bean defining annotation, but if you want to strictly adhere to the standard, you can use @ApplicationScoped instead.)

  1. Don't instantiate Config by calling the constructor. Instead, use dependency injection again:
@QuarkusTest
class Test {
    @Inject
    Config config;

    @Test
    fun test(){
        println(config.foo)
    }
}
  • Related