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?
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;
}
}