Results 1 to 9 of 9

Thread: Good Use for PropertyPlaceholderConfigurer

Hybrid View

  1. #1
    Join Date
    May 2005
    Posts
    29

    Default Good Use for PropertyPlaceholderConfigurer

    I'm not even sure if this is the right tool for the job... However, I have to externalize my environment specific properties in a properties file. I also have to deploy my application as an exploded directory structure (no WAR's here). I also have a third party tool that I have to use to deploy my files. I put items in to the 'drop zone' and push all files out to the review/preprod/prod environments.

    So, I can't just put a "review version" of my config.properties out on the review server, because that same file will then also get pushed to preprod and prod.

    So, what I would like to do is write a class that extends PropertyPlaceholderConfigurer. In that subclass, in addition to loading "config.properties", I would also figure out the server name, and then load either "review.properties" or "preprod.properties". What I would do is have config.properties have the prod values, but then I would like to have the values from "review.properties" override the default values.

    So, is there any way to load multiple .properties files and specify one of them as overriding the others? I suppose that I could just never have a "config.properties" and always have to load a "servername.properties" file. But, in production, I have multiple servers, and so I don't want to have to create "production1.properties" and "production2.properties" etc., if I could just let all the production servers use the "config.properties" and not have to worry about loading an environment specific version for that environment.

    Hope I explained this well. Thanks in advance for your help.

    Chris
    Chris

  2. #2
    Join Date
    May 2005
    Posts
    288

    Default

    We had a similar problem recently. We ended up putting the name of the properties file as a string into the JNDI tree of the server. The name was extracted by using a JndiObjectFactoryBean and subsequently injected into PropertyPlaceholderConfigurer.
    That way the properties files were all held in the application but which of them to use was "decided" by the server.

    HTH
    Fokko

  3. #3
    Join Date
    Oct 2007
    Posts
    4

    Default

    Could you use the preferences API? Not a particularly nice API but does support the concept of different values for different users/environments. Wasn't sure if you *had* to use properties. You can then load in the configuration from a database schema, where each environment points to a different database anyway.

  4. #4
    Join Date
    May 2005
    Location
    California, US
    Posts
    735

    Default

    Quote Originally Posted by F.Degenaar View Post
    We had a similar problem recently. We ended up putting the name of the properties file as a string into the JNDI tree of the server. The name was extracted by using a JndiObjectFactoryBean and subsequently injected into PropertyPlaceholderConfigurer.
    That way the properties files were all held in the application but which of them to use was "decided" by the server.

    HTH
    Fokko
    Fokko,
    Could you explain how you configured and set up your PropertyPlaceholderConfigurer bean? Mine is configured via my applicationContext.xml file so its locations are read from that file. I don't know how to set up a PropertyPlaceholderConfigurer from within my code and then have the Spring application context use it. I can guess how to set up the PropertyPlaceholderConfigurer; just instantiate one, and then call its setters. But how do you get the Spring application context to use it before it reads the application context xml file?

  5. #5
    Join Date
    May 2005
    Posts
    288

    Default

    @lumpynose:
    You don't have to set up the PropertyPlaceholderConfigurer programmatically.

    The recipe goes as follows:
    Define a name binding in your web server/app server. The value of the string is the position of the property file e.g. classpath:development.properties
    Define a resource environment reference in your web.xml/ejb-jar.xml
    Code:
    	<resource-env-ref>
    		<description></description>
    		<resource-env-ref-name>string/propertytest</resource-env-ref-name>
    		<resource-env-ref-type>java.lang.String</resource-env-ref-type>
    	</resource-env-ref>
    Define a string that comes from JNDI in the context.xml
    Code:
        <bean id="defaultJndiString" class="java.lang.String">
          <constructor-arg type="java.lang.String" value="error.string" />
        </bean>
    
        <bean id="jndiString" class="org.springframework.jndi.JndiObjectFactoryBean" abstract="true">
          <property name="defaultObject" ref="defaultJndiString"/>
        </bean>
    
        <bean id="propertytest" parent="jndiString">
          <property name="jndiName" value="java:comp/env/string/propertytest"/>
        </bean>
    Define the PropertyPlaceholderConfigurer with a ref to the JNDI string as location
    Code:
        <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" lazy-init="false">
          <property name="location" ref="propertytest"/>
        </bean>
    Now if you want to reference a different property file, say for acceptance tests, you go to the app server and change the value of the name binding to classpath:acceptance.properties.

    As I said earlier the deployment resource contains all configurations yet the app server decides which one to use by the value of the name binding.

    HTH
    Fokko

  6. #6

    Default

    You can use system property placeholders inside the location strings, e.g.
    Code:
    <bean id="propertyConfigurer" class="....PropertyPlaceholderConfigurer">
      <property name="location" value="/WEB-INF/${com.example.env}.properties"/>
    </bean>
    Nice and easy if there's a system property you can use to differentiate the environments.

  7. #7
    Join Date
    May 2005
    Location
    California, US
    Posts
    735

    Default

    Thanks to both of you. In my case this is a standalone program running via java -jar so the system property might well work for me. I have a shell script that runs the java -jar so I can have it look at the host name and set the system property appropriately.

  8. #8
    Join Date
    Sep 2006
    Location
    Work in New York City
    Posts
    127

    Default

    I have a similar but different problem. At the place I am consulting they have a rule that the EAR file in QA can never be modified once it is in QA. Furthermore, when the migration to PROD occurs, the rule is that the EAR file in QA is copied to PROD and has to work with no changes made to it. This of course biases my development choices towards keeping more options in the database than might otherwise be the case. The only other area of discretion I have is that DEV, QA, and PROD are each allowed to use a directory outside of the web context root named "/apps/app_name" that has nothing to do with the web server at all. For example, that's where the log4j log files always go. What I would like to do is put into "/aaps/app_name" the file property files that I currently define as follows:

    <!-- Configurer that replaces ${...} placeholders with values from properties files -->
    <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.Pr opertyPlaceholderConfigurer">
    <property name="locations">
    <list>
    <value>WEB-INF/mail.properties</value>
    <value>WEB-INF/jdbc.properties</value>
    </list>
    </property>
    </bean>
    That way I could modify the values in those property files while still not breaking the rule that I am not allowed to modify anything in the EAR file.

    Is there a way to do that which I don't know about? If not, wouldn't it be great if Spring could be enhanced to allow it.
    Java Developer with all the usual Sun Java certifications.

  9. #9
    Join Date
    May 2005
    Posts
    288

    Default

    @Robert:
    Have a look at http://static.springframework.org/sp...a.lang.String)
    The way the locations of the property files are resolved, it should be entirely legal and thus possible.
    Otherwise our JNDI-based solution should also work for you .

    Good luck!

    Fokko

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •