Announcement Announcement Module
Collapse
No announcement yet.
System configuration per environment Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • System configuration per environment

    My current client has 4 different application environments. When promoting to another environment, they do not allow rebuilds of the archive. They simply just take the war, in my case, and place it in the next environment. The issue here is that certain environmental properties must change without a rebuild. For example, the application sends out emails to the user's inviting them with a link to the web site. Unfortunately this link is different per environment.

    I have considered having an environment system property with possible values of dev, qa, or prod and reading in the appropriate properties file based on it's value. This approach will work but is there a better, more standard solution to this issue? Thanks.

  • #2
    You can configure the environment properties using JNDI. This should allow to deploy the war unchanged.
    HTH

    Comment


    • #3
      You can also you the BeanFactoryPostProcessor to set the values of Spring managed JavaBeans based on system properties. If the JVM has standard properties set, then you can grab those and use them in this manner. Or you could have 4 different beans, and using property name to in setup:
      Code:
      <bean id="devEmailBean" .../>
      <bean id="qaEmailBean" .../>
      
      <bean id="emailManager" class="...">
          <property name="emailBean"><ref bean="$&#123;system.envType&#125;EmailBean"/></property>
      </bean>
      (where system.envType is the name of the system property).


      Also, as I understand it there are a solutions for scripting a Spring configuration (so you could turn on/off beans using this). Spring also has JNDI wiring support to assist you if you choose to go that route.

      Comment


      • #4
        I like the simplicity of setting the values of beans based on system properties. I am wondering what other scripting variables are available when using an XML application context? Is there some documentation out there on using these variables?

        I have to admit, I am somewhat confused on how JNDI can allow me to change settings based on my environment. In my mind I would still need some kind of env system property to pivot on. Am I missing something?

        Thanks for your help.

        -karl

        Comment


        • #5
          Lookup: org.springframework.beans.factory.config.PropertyP laceholderConfigurer. For the most part you have to set the properties your self.

          At some point you'll need to get a property from somewhere - a properties file, a database, JNDI... With JNDI (which I am by no means an expert on) I think the simplest thing would be to use it to store a propety name/value pair, which your code would then lookup by name. While there are all sorts of 'different' options at some point they do boil down reading in a configuration property from somewhere; which is best depends on lots of things, but mainly how your code is structured, and on what server environment you will be deploying to; you obviously want to work with the tools and within the constraints of both.

          Comment


          • #6
            I use the JNDI approach. I bound a java.util.Properties object into our app server's JNDI tree, configuring it from a properties file located outside of the war file. The specifics on how to do this depend on your application server.

            For different environments, you'd just use a different properties file. The JNDI object is configured and bound at app-server startup.

            This properties JNDI object can be accessed by your app directly via JNDI, or given to a PropertyPlaceHolderConfigurer like so:
            Code:
              <bean id="propertyResourceConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                <property name="properties"><ref local="config" /></property>
              </bean>
              <bean id="config" class="org.springframework.jndi.JndiObjectFactoryBean">
                <property name="jndiName"><value>config/Properties</value></property>
                <property name="resourceRef"><value>true</value></property>
              </bean>
            where "config/Properties" is the JNDI name defined in web.xml and mapped in the appserver-specific web xml file.

            Then you can configure your beans by using ${property} throughout your application context as mentioned by other posters.


            Tim

            Comment


            • #7
              I read somewhere that there are issues with JNDI in a cluster. If memory serves, the issue is that if a server puts something into JNDI and that server fails, the jndi entry is removed. Which would put a crimp on using JNDI for property storage.

              If I have this incorrect please correct me.

              Comment


              • #8
                JNDI and Properties

                Here's how I configured our server settings... it's combination of JNDI and property files. I preferred to put all variables in a property file to have a single location where we can change all variables... the JNDI is used to simply indicate which property file to use.

                http://www.ideyatech.com/resources/?p=52

                The sample didn't use Spring, but I've had similar implementation using Spring.

                Comment


                • #9
                  Hello ,

                  this solution sounds very interesting. I am at the same point but have some problems to configure JNDI on Bea weblogic to access properties files outside the war file? Is there any simple way to do it?

                  Thanks for any help!

                  Originally posted by timmorrow View Post
                  I use the JNDI approach. I bound a java.util.Properties object into our app server's JNDI tree, configuring it from a properties file located outside of the war file. The specifics on how to do this depend on your application server.

                  For different environments, you'd just use a different properties file. The JNDI object is configured and bound at app-server startup.

                  This properties JNDI object can be accessed by your app directly via JNDI, or given to a PropertyPlaceHolderConfigurer like so:
                  Code:
                    <bean id="propertyResourceConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                      <property name="properties"><ref local="config" /></property>
                    </bean>
                    <bean id="config" class="org.springframework.jndi.JndiObjectFactoryBean">
                      <property name="jndiName"><value>config/Properties</value></property>
                      <property name="resourceRef"><value>true</value></property>
                    </bean>
                  where "config/Properties" is the JNDI name defined in web.xml and mapped in the appserver-specific web xml file.

                  Then you can configure your beans by using ${property} throughout your application context as mentioned by other posters.


                  Tim

                  Comment


                  • #10
                    There is a solution for that here: "Using Spring Framework to enable multi-environment deployment without rebuilding or repackaging."

                    Comment


                    • #11
                      @Kristina:
                      Just put the properties files for all stages into your archive. There will probably be items your admins don't want you to know like production passwords. For those items you can still define resource environment entries in your web.xml or ejb-jar.xml. Your admins can configure them in the app server's JNDI tree.

                      HTH
                      Fokko

                      Comment


                      • #12
                        Hello Chris,

                        thanks, this works great!
                        But the properties files are still in the war archive.
                        I am wondering if it's possible to place the properties files somewhere on the server file system and access them there?
                        That would be even better...

                        Comment


                        • #13
                          Since the code use a Resource object, you can inject the location using the classpath: or file: prefixes.

                          For example, to have the properties files in '/opt/app/conf':

                          <property name=""propertyLocation" value="file:/opt/app/conf/"/>

                          ...note that the trailing slash is required to denote this as a directory so the properties files can be found relative to the directory.

                          Comment


                          • #14
                            Originally posted by timmorrow View Post
                            I use the JNDI approach. I bound a java.util.Properties object into our app server's JNDI tree, configuring it from a properties file located outside of the war file. The specifics on how to do this depend on your application server.

                            For different environments, you'd just use a different properties file. The JNDI object is configured and bound at app-server startup.

                            This properties JNDI object can be accessed by your app directly via JNDI, or given to a PropertyPlaceHolderConfigurer like so:
                            Code:
                              <bean id="propertyResourceConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
                                <property name="properties"><ref local="config" /></property>
                              </bean>
                              <bean id="config" class="org.springframework.jndi.JndiObjectFactoryBean">
                                <property name="jndiName"><value>config/Properties</value></property>
                                <property name="resourceRef"><value>true</value></property>
                              </bean>
                            where "config/Properties" is the JNDI name defined in web.xml and mapped in the appserver-specific web xml file.

                            Then you can configure your beans by using ${property} throughout your application context as mentioned by other posters.


                            Tim

                            I like this idea, and you could take it one step further, by defining a local properties object as the 'defaultObject' property of the JndiObjectFactoryBean. This way, if the JNDI environment is unavailable as it would be in a unit test or local non-server environment, it will fall back to localized settings.

                            Comment


                            • #15
                              For loading the properties file is the solution with RuntimeEnvironmentPropertiesConfigurer more fliexible than with JNDI.
                              you can put your file anywhere and don't need to configure the JNDI on the appserver.

                              thanks!

                              Comment

                              Working...
                              X