Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Set System Property With Spring Configuration File

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.

like image 958
Steve Avatar asked Jul 26 '10 23:07

Steve


People also ask

Does spring set system properties?

Spring Boot does that itself in its LoggingSystem where various logging. * properties are mapped to System properties. Note that you'll probably want to set the system properties as early as possible, probably as soon as the Environment is prepared.

How do I set environment specific properties in spring boot?

Environment-Specific Properties File. If we need to target different environments, there's a built-in mechanism for that in Boot. We can simply define an application-environment. properties file in the src/main/resources directory, and then set a Spring profile with the same environment name.


2 Answers

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> 
like image 134
Patrick Avatar answered Sep 17 '22 14:09

Patrick


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 overwriting existing properties     System.out.println("java.io.tmpdir: "+System.getProperty("java.io.tmpdir")); } 

And here's the output:

my.key: myvalue my.key2: myvalue2 my.key3: myvalue3 java.io.tmpdir: C:\DOKUME~1\SEANFL~1\LOKALE~1\Temp\ 
like image 29
Sean Patrick Floyd Avatar answered Sep 20 '22 14:09

Sean Patrick Floyd