jinxed
jinxed

Reputation: 235

How do I read JVM arguments in the Spring applicationContext.xml

I have a JSF web application with Spring and I am trying to figure out a way to reference the JVM arguments from the applicationContext.xml. I am starting the JVM with an environment argument (-Denv=development, for example). I have found and tried a few different approaches including:

<bean id="myBean" class="com.foo.bar.myClass">
  <property name="environment">
    <value>${environment}</value>
  </property>
</bean>

But, when the setter method is invoked in MyClass, the string "${environment}" is passed, instead of "development". I have a work around in place to use System.getProperty(), but it would be nicer, and cleaner, to be able to set these values via Spring. Is there any way to do this?

Edit: What I should have mentioned before is that I am loading properties from my database using a JDBC connection. This seems to add complexity, because when I add a property placeholder to my configuration, the properties loaded from the database are overridden by the property placeholder. I'm not sure if it's order-dependent or something. It's like I can do one or the other, but not both.

Edit: I'm currently loading the properties using the following configuration:

<bean id="myDataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
    <property name="jndiName" value="jdbc.mydb.myschema"/> 
</bean>

<bean id="props" class="com.foo.bar.JdbcPropertiesFactoryBean">
    <property name="jdbcTemplate">
        <bean class="org.springframework.jdbc.core.JdbcTemplate">
            <constructor-arg ref="myDataSource" />
        </bean>
    </property>
</bean>

<context:property-placeholder properties-ref="props" />

Upvotes: 21

Views: 51151

Answers (6)

Amit M
Amit M

Reputation: 56

Use #{systemProperties['env']}. Basically pass the propertyName used in the Java command line as -DpropertyName=value. In this case it was -Denv=development so used env.

Upvotes: 1

disciolli
disciolli

Reputation: 1

Spring 3.0.7

<context:property-placeholder location="classpath:${env:config-prd.properties}" />

And at runtime set: -Denv=config-dev.properties

If not set "env" will use default "config-prd.properties".

Upvotes: 0

Chris J
Chris J

Reputation: 9262

Interestingly, Spring has evolved to handled this need more gracefully with PropertySources: http://spring.io/blog/2011/02/15/spring-3-1-m1-unified-property-management/

With a few configurations and perhaps a custom ApplicationInitializer if you are working on a Web app, you can have the property placeholder handle System, Environment, and custom properties. Spring provides PropertySourcesPlaceholderConfigurer which is used when you have in your Spring config. That one will look for properties in your properties files, then System, and then finally Environment.

Upvotes: 0

Ralph
Ralph

Reputation: 120851

You can use Spring EL expressions, then it is #{systemProperties.test} for -Dtest="hallo welt"

In your case it should be:

<bean id="myBean" class="com.foo.bar.myClass">
  <property name="environment">
    <value>#{systemProperties.environment}</value>
  </property>
</bean>

The # instead of $ is no mistake!

$ would refer to place holders, while # refers to beans, and systemProperties is a bean.


May it is only a spelling error, but may it is the cause for your problem: In the example for your command line statement you name the variable env

(-Denv=development, for example...

But in the spring configuration you name it environment. But both must be equals of course!

Upvotes: 27

anubhava
anubhava

Reputation: 785721

You can load a property file based on system property env like this:

   <bean id="applicationProperties"
      class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="ignoreResourceNotFound" value="false" />
      <property name="ignoreUnresolvablePlaceholders" value="true" />
      <property name="searchSystemEnvironment" value="false" />
      <property name="locations">
         <list>
            <value>classpath:myapp-${env:prod}.properties</value>
         </list>
      </property>
   </bean>

If env is not set default it to production otherwise development and testing teams can have their flavor of app by setting -Denv=development or -Denv=testing accordingly.

Upvotes: 4

sourcedelica
sourcedelica

Reputation: 24047

If you register a PropertyPlaceholderConfigurer it will use system properties as a fallback.

For example, add

<context:property-placeholder/>

to your configuration. Then you can use ${environment} in either your XML configuration or in @Value annotations.

Upvotes: 10

Related Questions