6 Replies Latest reply on Sep 22, 2010 10:13 PM by mbrowne.wm.matthewhbrowne.com

    Best practice: external Configuration of Seam-Applications

    astein

      Hi there.


      I wrote a non-trivial application based on Seam packaged in an EAR-file that is deployed in a JBoss 4.2. Now there are for example different environments where I want to run this application (dev, qa, live) and I don't want to build a dedicated EAR for every environment, but use the same EAR everywhere. So what I finally want is to adopt some parameters for every single environment - so just external (not within the EAR) configuration. Currently I use the following two ways to do this:


      - I have hard-coded the path to a (XML)-configuration file in the file system within my application and read all needed parameters from there. This allows more complex and special structures (not just key-value-combinations) because I wrote my own parser for this config file.


      - It's possible to put a properties-file in $JBOSSHOME/server/default/conf directory and read configuration parameters from there using this:


      InputStream stream = Thread.currentThread().getContextClassLoader().getResourceAsStream("config.properties");
      Properties properties = new Properties();
      properties.load(stream);
      properties.getProperty("properties-key"));



      Another possibility would be to put a special XML file called foo-service.xml into $JBOSSHOME/server/default/deploy directory as described here. This would make the configured values available via JNDI. This basically what we want, but it's also pretty unsecure as everybody can access via JNDI for example passwords that were configured...


      So, as you see, I tried a lot of things, but I haven't found the silver bullet right now. Does anybody else have ideas how to configure web-applications without modifying the EAR? Any other approaches? Is there a Seam-way to do this that I overlooked until now? Thanks!


      Greetings,


      --


      André

        • 1. Re: Best practice: external Configuration of Seam-Applications
          fernando_jmt

          I am using the properties service MBean JBoss has embedded and it is working pretty well for my application.


          1. Open JBOSSHOME/server/default/deploy/properties-service.xml


          2. Here an example how I added myapp-configuration.properties



          <mbean code="org.jboss.varia.property.SystemPropertiesService" 
                name="jboss:type=Service,name=SystemProperties">
             <attribute name="URLList">
                ./conf/myapp-configuration.properties
              </attribute>
          </mbean>




          3. Just put myapp-configuration.properties into JBOSSHOME/server/default/conf (or wherever you want, just update the url)


          4. Now, when JBoss will start you will be able to get the properties you have defined in myapp-configuration.properties just using


          System.getProperty("myproperty");


          That's all.


          HTH.


          • 2. Re: Best practice: external Configuration of Seam-Applications
            astein

            Hi Fernando,


            thanks for your reply. Your way is very similar to the things I currently do (the second way I described) - just with the difference that you configure the path to your properties-file in properties-service.xml and it's a bit easier to access the properties. All in all your way seems to be a bit smoother than mine, but finally we both access the same properties-files but just in slightly different ways.
            I just thought Seam had a better (more automatic/convention over coding/less tedious fussing around) way to handle external configurations and I just haven't found it until now. Currently, it's a lot of manual work and I thought some other people were as unsatisfied with their proprietary solutions as I am... First I liked the third alternative (JNDI-bindings) because you just deploy the configuration like the application itself. But the fact that everybody can simply access these values is a bit frightening regarding security aspects.
            Anybody else here who wants to contribute and tell about his way of doing it? ;-)


            --


            André

            • 3. Re: Best practice: external Configuration of Seam-Applications
              thejosh

              I do it the way you describe with a properties file in server/default/conf. No problems so far. I wrap the code in a seam component called Environment.



              @Name("environment")
              @Scope(ScopeType.APPLICATION)
              @AutoCreate
              public class Environment
              {
                  private Properties properties;
              
                  @Create
                  public void setup() {
                      ClassLoader loader = Thread.currentThread().getContextClassLoader();
                      properties = new Properties();
              
                      try {
                          properties.load(loader.getResourceAsStream("environment.properties"));
                      }catch(IOException e) {
                          throw new EnvironmentException("unable to load environment.properties", e);
                      }
                  }
              
                  public String getProperty(String name) {
                      return properties.getProperty(name);
                  }
              }
              



              Another way I did this pre-Seam was to embed property files for each environment inside the ear.




              • dev.properties

              • qa.properties

              • production.properties



              etc...


              And then pass the environment name to the server in the startup script. -Denvironment=dev


              Josh


              • 4. Re: Best practice: external Configuration of Seam-Applications
                joblini

                We use a table in our database with two columns (name, value), in conjunction with a very simple Seam component named property.  We put this in application scope, and load it from the database at Seam startup.  BTW, We also keep resource bundles in the database.


                We access the properties from Java code using Property.get(name), or from EL, using property.get(name).


                Planned improvements are to allow dynamic reloading (without restarting the app), and to allow user properties as well as system properties.


                Has anyone looked at the Java Preferences Framework?


                • 5. Re: Best practice: external Configuration of Seam-Applications
                  astein

                  Hey Guys,


                  some weeks after my first posting, I found another way how to configure Seam applications externally pretty easy. Today I use the JBoss-Properties-Service. You just put a file called whatever-service.xml into your JBoss-Deploy-Directory. The content of this file looks like this:


                  <mbean code="org.jboss.varia.property.SystemPropertiesService" name="jboss.util:type=Service,name=something">
                    <attribute name="Properties">
                      key=<value
                    </attribute>
                  </mbean>



                  You can even have more than one of these files if you need, just the name = something has to differ. Now you can access the properties within you application via:
                  System.getProperty(key);


                  The fine thing abou this way is that you can deploy your configuration just like you do it with your application (EAR/WAR) and it's always next to the application itself. And IIRC even changes on properties-files are applied immediately, so you always have the newest configuations values without needing to restart your application (if it supports changing properties).
                  So, that's my current way to configure web applications. I think it's much less painful than my three options descibed in the first post... ;-)
                  If anybody has even better approaches, please let us all know about it! :-)


                  Greetings,


                  --


                  André

                  • 6. Re: Best practice: external Configuration of Seam-Applications
                    mbrowne.wm.matthewhbrowne.com

                    I just wanted to add that jFig (http://jfig.sourceforge.net/) seems to offer a promising solution for this (and seemingly less complicated than the Java Preferences framework).


                    I'm planning to assign a Seam component name to the JFig class (in components.properties) so I can inject the needed configuration properties into my components that need them when they're loaded.


                    It seems like the best solution to me...configuration per environment, substitution, inheritance, and all with an easy syntax in either XML or INI format. I haven't used jFig before so I'll post back if I have any trouble like this; it seems fairly straightforward though.