8

I have a properties file which I would like loaded in to System Properties so that I can access it via System.getProperty("myProp"). Currently, I'm trying to use the Spring <context:propert-placeholder/> like so:

<context:property-placeholder location="/WEB-INF/properties/webServerProperties.properties" />

However, when I try to access my properties via System.getProperty("myProp") I'm getting null. My properties file looks like this:

myProp=hello world

How could I achieve this? I'm pretty sure I could set a runtime argument, however I'd like to avoid this.

Thanks!

DigitalZebra
  • 39,494
  • 39
  • 114
  • 146
  • Perhaps [this related question](http://stackoverflow.com/questions/1311360/property-placeholder-location-from-another-property) gives some direction? – Raghuram Nov 07 '10 at 06:12

4 Answers4

18

In Spring 3 you can load system properties this way:

  <bean id="systemPropertiesLoader"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" value="#{@systemProperties}" />
    <property name="targetMethod" value="putAll" />
    <property name="arguments">
        <util:properties location="file:///${user.home}/mySystemEnv.properties" />
    </property>
</bean>
Florin
  • 181
  • 1
  • 2
10

The point is to do this the other way around - i.e. use system properties in spring, rather than spring properties in the system.

With PropertyPlaceholderConfigurer you get your properties + the system properties accessible via the ${property.key} syntax. In spring 3.0 you can inject these using the @Value annotation.

The idea is not to rely on calls to System.getProperty(..), but to instead inject your property values. So:

@Value("${foo.property}")
private String foo;

public void someMethod {
    String path = getPath(foo);
    //.. etc
}

rather than

public void someMethod {
    String path = getPath(System.getProperty("your.property"));
    //.. etc
}

Imagine you want to unit test your class - you'd have to prepopulate the System object with properties. With the spring-way you'd just have to set some fields of the object.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
Bozho
  • 588,226
  • 146
  • 1,060
  • 1,140
  • Is there also a way to grab the property programatically instead of using the annotation with Spring Expression syntax? for example: `someSpringApi.getProperty("${foo.property}")` – DigitalZebra Nov 07 '10 at 15:57
  • Yes - http://static.springsource.org/spring/docs/3.0.0.M3/spring-framework-reference/html/ch07.html – Bozho Nov 07 '10 at 16:27
10

While I subscribe to the Spirit of Bozho's answer, I recently also had a situation where I needed to set System Properties from Spring. Here's the class I came up with:

Java Code:

public class SystemPropertiesReader{

    private Collection<Resource> resources;

    public void setResources(final Collection<Resource> resources){
        this.resources = resources;
    }

    public void setResource(final Resource resource){
        resources = Collections.singleton(resource);
    }

    @PostConstruct
    public void applyProperties() throws Exception{
        final Properties systemProperties = System.getProperties();
        for(final Resource resource : resources){
            final InputStream inputStream = resource.getInputStream();
            try{
                systemProperties.load(inputStream);
            } finally{
                // Guava
                Closeables.closeQuietly(inputStream);
            }
        }
    }

}

Spring Config:

<bean class="x.y.SystemPropertiesReader">

    <!-- either a single .properties file -->
    <property name="resource" value="classpath:dummy.properties" />

    <!-- or a collection of .properties file -->
    <property name="resources" value="classpath*:many.properties" />

    <!-- but not both -->

</bean>
Community
  • 1
  • 1
Sean Patrick Floyd
  • 292,901
  • 67
  • 465
  • 588
0
@Configuration
Public class YourAppConfig {

    @Value("${your.system.property}") String prop
    @Autowired
    Public void LoadProperties() {
        System.setProperty(PROPERTY_NAME, prop) ;
    }

    @Bean
    ...
theRiley
  • 1,077
  • 13
  • 16