6

I'm trying to read an environment variable in my Quarkus application using @ConfigProperty, but didn't manage to do that. I thought that just specifying variable name should be enough, but it isn't working:

@ConfigProperty(name = "MY_ENV_VAR")
String envVar;

I've also tried to specify a property in application.properties

my.var=${MY_ENV_VAR:defaultValue}

and read it like

@ConfigProperty(name = "my.var")
String myVar;

but the variable is always null.

Did I miss something? What is the correct way to read an environment variable in Quarkus?
I'm using Quarkus 1.2.0.Final

Kukeltje
  • 12,223
  • 4
  • 24
  • 47
Denis.Kipchakbaev
  • 970
  • 15
  • 24
  • 1
    What you have is correct. Can you show the full class? It must be a CDI bean, e.g. `@ApplicationScoped`. – Ladicek Jan 31 '20 at 14:27

1 Answers1

9

Me and my colleagues have found the source of the problem. I was trying to read a field annotated with @ConfigProperty in the constructor, but the properties are being injected only after calling a constructor.

I provide a working example:

package org.acme.config;

import org.eclipse.microprofile.config.inject.ConfigProperty;

import javax.enterprise.context.ApplicationScoped;

@ApplicationScoped
public class EnvGreetingService {

    private final String varA;

    @ConfigProperty(name = "ENV_VAR_B")
    String varB;

    public EnvGreetingService(@ConfigProperty(name = "ENV_VAR_A") String varA) {
        System.out.println("constructor varA=" + varA);
        System.out.println("constructor varB=" + varB);
        this.varA = varA;
    }

    public void greetWithEnvVar() {
        System.out.println("method varA=" + varA);
        System.out.println("method varB=" + varB);
    }
}

Note: it is not required map environment variables in application.properties

And console output would be:

constructor varA=a
constructor varB=null
method varA=a
method varB=b

So, if you want to use application properties or environment variables in the constructor, you should inject it in constructor arguments.

Denis.Kipchakbaev
  • 970
  • 15
  • 24
  • In case of CDI Bean injection. It is preferable to use @Inject on a void & no params method. This method will be called after a bean is active in CDI lifecycle so it can understand and read your annotated field variables. constructors are not recommended in your case. – iabughosh Jan 31 '20 at 18:06
  • I like field injection, constructor injections creates a huge mess once you have too many fields – Marian Klühspies Jan 31 '20 at 23:49