All topics
library
intermediate

Properties & Configuration Loading

Load configuration from .properties files, system properties, and environment variables in the right order.

Configuration lives outside the code, so one build can run in every environment.

Configuration loading = a stack of transparent sheets. Each sheet (source) has some settings filled in. You read from top to bottom — the first sheet with a value wins. Command-line is on top, defaults are on the bottom.

Key Concepts

1
    # app.properties
    db.url=jdbc:postgresql://localhost/shop
    db.pool.size=10
    feature.newCheckout=false
2
    Properties p = new Properties();
    try (var in = getClass().getResourceAsStream("/app.properties")) {
      p.load(in);
    }
    String url = p.getProperty("db.url");
    int size = Integer.parseInt(p.getProperty("db.pool.size", "5"));
3
The sources, highest precedence first.
    -Dkey=value          command line system property
    environment variable System.getenv("DATABASE_URL")
    a properties file    on the classpath or on disk
    a default in code    the last resort
4
That order is the point. The same artifact runs anywhere because anything can be overridden without rebuilding.
5
Properties is a Hashtable subclass, which is a historical wart — it is synchronized, and its keys and values are typed Object even though it stores strings. getProperty is the string-typed accessor to use.
PropertiesHashtableObjectgetProperty
6
The file format has details worth knowing.
    key=value       key:value       key value      all valid
    # comment       ! comment
    long=one \
         continued   a trailing backslash continues the line
7
Encoding is the trap. load(InputStream) reads ISO-8859-1, so a non-ASCII value arrives mangled. Use the reader overload:
load(InputStream)
8
    p.load(new InputStreamReader(in, StandardCharsets.UTF_8));
9
Never put secrets in a properties file. They end up committed. Pass them as environment variables, or read them from a secret manager at startup.
10
Validate at startup, not on first use.
    if (p.getProperty("db.url") == null)
      throw new IllegalStateException("db.url is required");
11
A missing setting that fails immediately costs minutes. One that fails on an uncommon code path three days later costs far more.
12
Spring Boot does all of this for you — application.yml, profiles like application-prod.yml, @Value and @ConfigurationProperties with validation. The precedence rules are the same idea, with more sources.
application.ymlapplication-prod.yml@Value@ConfigurationProperties
13
What the interviewer is probing.1. "Why does a non-ASCII value come out mangled from Properties.load?" Probing: the encoding default. Stalls: "The file is wrong." Moves up: load(InputStream) reads ISO-8859-1; use the Reader overload with UTF-8.
14
2. "Where should secrets live?" Probing: whether you draw the line. Stalls: "In the properties file, it is not in git." Moves up: never in the file — environment variables or a secret manager, because property files get committed sooner or later.
15
3. "What is a sensible precedence order?" Probing: externalised configuration. Stalls: "Whatever loads last." Moves up: command-line system properties, then environment, then file, then a default in code — so anything can be overridden without rebuilding.
16
4. "Why validate configuration at startup?" Probing: failure timing. Stalls: "It will fail when used." Moves up: a missing setting that fails immediately costs minutes; one that fails on an uncommon path three days later costs far more.