Search code examples
spring-bootdockerenvironment-variables

Unable to read external properties in spring boot 3


I have a spring boot 3.1.0 project on a Windows machine with JDK 17 and an Alpine JDK 17 docker container It has a controller which is something as below:

@RestController
@RequestMapping("/api")
public class ApiController {

    @Value("${app_sql_db_user}")
    String user;

    public ApiController() {
        log.info("user = {}", user);
    }
}

This property is not defined in application.properties so I expect it to be able to get it from my environment variables where I have added it. In Windows, I have tried adding it to both User and System variables. In Docker, I have used the -e flag.

Neither of the above worked and it prints user as null. At which point, I added a new property in my application.properties as:

app.sql.db.user=${app_sql_db_user}

This doesn't solve the problem either. I attempted to pass them as JVM arguments

java -Dapp_sql_db_user=springapp -jar target/app.war

This also sends it as null. It seems it is dead set on ignoring any external property and I couldn't find any valid threads online which worked. Does anyone have any idea why this might be happening?


Solution

  • The constructor is evaluated before the value is acutally injected in the variable.

    Declare a controller and you can see the value is correctly set:

        @GetMapping("/")
        String all() {
            return "user: " + user;
        }
    

    If you want your variable to be available in the constructor you need to declare it as an argument to the constructor:

    @RestController
    @RequestMapping("/api")
    public class ApiController {
    
        
        String user;
    
        public ApiController(@Value("${app_sql_db_user}") final String usr) {
            user = usr;
            log.info("user = {}", user);
        }
    
        @GetMapping("/")
        String all() {
            return "user: " + user;
        }
    }