Alex Rivera | Logout

Set System Property With Spring Configuration File

Asked 2010-07-26T23:33:46.550
60

Configuration:
Spring 2.5, Junit 4, Log4j
The log4j file location is specified from a system property

${log.location}

At runtime, system property set with -D java option. All is well.

Problem / What I Need:
At unit test time, system property not set, and file location not resolved.
App uses Spring, would like to simply configure Spring to set the system property.

More Info:
Requirement is for configuration only. Can't introduce new Java code, or entries into IDE. Ideally, one of Spring's property configuration implementations could handle this--I just haven't been able to find the right combination.

This idea is close, but needs to add Java code:
Spring SystemPropertyInitializingBean

Any help out there? Any ideas are appreciated.

Edit
Report

2 Answers

96

There was a request in the comments for a Spring 3 example on how to do this.

<bean id="systemPrereqs"
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject" value="#{@systemProperties}" />
    <property name="targetMethod" value="putAll" />
    <property name="arguments">
        <!-- The new Properties -->
        <util:properties>
            <prop key="java.security.auth.login.config">/super/secret/jaas.conf</prop>
        </util:properties>
    </property>
</bean>
answered 2011-09-12T16:36:37.463
57

You can achieve that with the combination of two MethodInvokingFactoryBeans

Create an inner bean that accesses System.getProperties and an outer bean that invokes putAll on the properties acquired by the inner bean:

<bean
    class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property
        name="targetObject">
        <!-- System.getProperties() -->
        <bean
            class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
            <property name="targetClass" value="java.lang.System" />
            <property name="targetMethod" value="getProperties" />
        </bean>
    </property>
    <property
        name="targetMethod"
        value="putAll" />
    <property
        name="arguments">
        <!-- The new Properties -->
        <util:properties>
            <prop
                key="my.key">myvalue</prop>
            <prop
                key="my.key2">myvalue2</prop>
            <prop
                key="my.key3">myvalue3</prop>

        </util:properties>
    </property>
</bean>

(You could of course use just one bean and target System.setProperties(), but then you'd be replacing existing properties which is not a good idea.

Anyway, here's my little test method:

public static void main(final String[] args) {

    new ClassPathXmlApplicationContext("classpath:beans.xml");

    System.out.println("my.key: "+System.getProperty("my.key"));
    System.out.println("my.key2: "+System.getProperty("my.key2"));
    System.out.println("my.key3: "+System.getProperty("my.key3"));

    // to test that we're not overwri
answered 2010-07-27T05:26:17.923

Your Answer