Can I define System Properties within Spring Boot configuration files?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Spring Boot configuration properties (application.properties / application.yml) are not Java system properties by default. They live in Spring's Environment abstraction and are accessible via @Value and @ConfigurationProperties, but System.getProperty() does not see them. To set actual JVM system properties, pass them as -D flags on the command line, use a @PostConstruct method to call System.setProperty(), or use SpringApplication.setDefaultProperties(). Some libraries read only from System.getProperty(), requiring you to bridge Spring properties into system properties.
Spring Properties vs System Properties
Spring properties are not JVM system properties. @Value reads from Spring's Environment. System.getProperty() reads from the JVM's system properties map — a different store.
Setting System Properties via Command Line
JVM system properties set with -D are in both the JVM properties map and Spring's Environment (Spring reads system properties as a property source).
Bridging Spring Properties to System Properties
This pattern is useful when third-party libraries (like JDBC drivers or SSL subsystems) read configuration from System.getProperty() rather than Spring's Environment.
Using EnvironmentPostProcessor
For properties that must be set as system properties before any beans are created:
Using SpringApplication.setDefaultProperties
Default properties have the lowest precedence — command-line arguments and application.properties override them.
Property Source Precedence
Common Pitfalls
- Expecting
application.propertiesvalues to appear inSystem.getProperty(): Spring properties and JVM system properties are different stores. Properties defined inapplication.propertiesare only in Spring's Environment. Use@ValueorEnvironment.getProperty()for Spring properties, or bridge them withSystem.setProperty()if a library requires JVM system properties. - Setting system properties too late for SSL/JNDI initialization: Some JVM subsystems (SSL, JNDI, security managers) read system properties during class loading, before Spring beans are created. A
@PostConstructbridge may be too late. Use anEnvironmentPostProcessoror set the properties inmain()before callingSpringApplication.run(). - Overriding system properties with
application.propertiesunintentionally: If you set-Dserver.port=8080on the command line and also haveserver.port=9090inapplication.properties, the command-line value wins (higher precedence). But if you callSystem.setProperty()in@PostConstruct, it overwrites the JVM property regardless of precedence. - Relaxed binding not working with
System.getProperty(): Spring's relaxed binding convertsapp-nametoappNameandAPP_NAME.System.getProperty()does exact string matching —System.getProperty("app-name")returns null if the property was set asappName. Use the exact key string when reading from system properties. - Secrets appearing in
/actuator/env: Spring Boot Actuator's/envendpoint displays all properties including those set viaSystem.setProperty(). Sensitive values (passwords, API keys) are exposed unless you configuremanagement.endpoint.env.keys-to-sanitizeto mask them. Add patterns like.*password.*,.*secret.*,.*key.*to the sanitization list.
Summary
application.propertiesvalues are Spring Environment properties, not JVM system properties- Use
-Dflags for properties that must be both Spring and JVM system properties - Bridge Spring properties to system properties with
System.setProperty()in@PostConstructorEnvironmentPostProcessor - Use
EnvironmentPostProcessorfor properties needed before bean creation (SSL, JNDI) - Remember the property source precedence: command line > system properties > env vars > application.properties

