8 Replies Latest reply on Feb 23, 2009 9:12 PM by Devon Hillard

    Configuration properties outside application

    Aede van der Weij Newbie

      I like an application to be deployable on any environment (development, test, production etc.) without building a specific war/ear. In case of JBoss I used to put an property file in the conf directory. This file would contain all the environment specific properties such as urls for endpoints, time-outs and all imaginable properties that might be subject to change per environment.


      Of course I could create a component that will load a similar file from the application's classpath (conf is on your classpath). I would however prefer a seam.properties solution.... (might work coming to think of it to just put a seam.property file in there).


      Is there anyone that came across a similar situation? I would like to now the solution. Any advise is appreciated.


      In the mean time I'll try to put the seam.property file in the conf directory and see if I can inject values in components that are in archives with their own property file. I post the results of course...

        • 1. Re: Configuration properties outside application
          Eric H Novice

          I ran into exactly this question / problem and I did find a good solution.  Use MBeans.  I set it up so that I can access a configuration MBean through the JMXConsole of JBoss and set values which a) are persistent in the container (JBoss) and b) visible to the application. 


          I can post the code for how I did this.  It's not too complex but it did involve some figuring out.  Once you have the code in place it's very easy to use.


          You are right, an EAR file should be an application file which isn't modified.


          It would be handy if this were in the Seam examples because it's something that every application needs.

          • 2. Re: Configuration properties outside application
            Aede van der Weij Newbie

            I would like to see the code of the MBean solution. Could you please post it.

            • 3. Re: Configuration properties outside application
              Aede van der Weij Newbie

              Putting the seam.properties file in the conf directory did not do the trick...

              • 4. Re: Configuration properties outside application
                Emily Price Newbie

                I would also like to see this code. I'm trying to solve the same problem but so far most of the solutions I've seen have been for Spring or Struts. Thanks in advance for sharing your solution.

                • 5. Re: Configuration properties outside application
                  Rodney Moore Newbie

                  Try integrating commons-configuration ..  the solution below will give you a flexible way to manage configuration in/out from any component (seam,ejb3 or pojo).  Configuration files are externalized for environment portability, but can also be packaged with the application.





                  In the application ear/META-INF, create a file named config.xml


                  <?xml version="1.0" encoding="ISO-8859-1" ?>
                  
                  <configuration>
                       <xml fileName="config-file1.xml" optional="true" />
                       <xml fileName="config-file2.xml" />
                       <xml fileName="config-file3.xml" />
                  </configuration>




                  Add this line to the jboss-service.xml file located int the ${jboss.server.home}/conf directory


                  <classpath codebase="${jboss.server.lib.url:lib/config}" archives="*.xml"/>



                  Create a directory named config under ${jboss.server.home}/lib/


                  Create a configuration file named config-file1.xml in the ${jboss.server.home}/lib/ directory


                  example config-file1.xml


                  <configuration>
                   <prop1>prop1value</prop1>
                   <prop2>prop2value</prop2>                    
                  </configuration> 
                  



                  Properties can always be accessed from any class using a configuration factory. This is an old-school singleton for older libraries and unit tests.  A more modern approach would use the @Resource annotation combined with a Seam component that initialized the configuration factory.



                  public class Config {
                  
                       private static Config instance;
                       private static Configuration configuration;
                  
                       public static Config getInstance() {
                  
                            if (instance == null) {
                                 try {
                                      instance = new Config();
                                      ConfigurationFactory factory = new ConfigurationFactory();
                                      URL configURL = Config.class
                                                .getResource("/META-INF/config.xml");
                                      factory.setConfigurationURL(configURL);
                  
                                      configuration = factory.getConfiguration();
                  
                                 } catch (ConfigurationException e) {
                                      // TODO Auto-generated catch block
                                      e.printStackTrace();
                                 }
                  
                            }
                            return instance;
                       }
                  
                  
                  }



                  One nice feature of commons-config is the jndiConfiguration factory,


                  Adding the jndi prefix directive to a config file will bind all properties in the naming directory.


                  <configuration>
                  <jndi prefix="java:comp/env"/>
                   <prop1>prop1value</prop1>
                   <prop2>prop2value</prop2>                    
                  </configuration>



                  You can use the @Resource annotation to inject configuration values:



                  @Resource(name="java:comp/env/prop1")
                  private String prop1;
                  




                  It would be nice to have a seam component that initialized the commons configuration factory at start-up.  I belive this would be trivial using the @Startup annotation.  I will try to post a component later this week.





                  • 6. Re: Configuration properties outside application
                    Vladimir Kovalyuk Apprentice

                    Aede van der Weij,


                    did you try putting components.xml into conf/META-INF folder?


                    Since conf is in classpath META-INF/components.xml should be loaded by Seam and processed successfully. Moreover, settings in META-INF/components.xml would override settings in .ear.

                    • 7. Re: Configuration properties outside application
                      Vladimir Kovalyuk Apprentice

                      Hmm ... one disadvantage of all those - setttings taken from classpath would affect all the applications deployed into the app server.

                      • 8. Re: Configuration properties outside application
                        Devon Hillard Novice

                        For what it's worth, this works perfectly.  Thanks!