Announcement Announcement Module
Collapse
No announcement yet.
Gracefully detecting missing configuration file Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Gracefully detecting missing configuration file

    Hello there,

    I most frequently use ClassPathXmlApplicationContext as a means to gain access to my bean factory, and was looking for a way of programatically providing a fallback configuration if the configuration I initially look for is missing. Ie, consider the following method:

    Is there are way to do this without relying on exception catching? One could argue that this is not an exceptional event.
    /**
    * Tries to load an environment specific version of the plugin configuration,
    * falling back to a non environmental version if this file was not found
    *
    * @param environment
    * @return context
    */

    private ApplicationContext loadContext(String environment)
    {
    ApplicationContext context = null;
    String environmentalContextDefinition = "plugin-config_"+environment+".xml";
    String fallbackContextDefinition = "plugin-config.xml";
    try{

    context = new ClassPathXmlApplicationContext(environmentalContex tDefinition);
    } catch(BeanDefinitionStoreException bdse){
    if (bdse.getCause() instanceof FileNotFoundException){
    logger.debug("No environmental context definition exists ["+environmentalContextDefinition+"], falling back to ["+fallbackContextDefinition+"]");
    context = new ClassPathXmlApplicationContext("plugin-config.xml");
    }
    else{
    //rethrow, as its only the FileNotFound that we can actually recover from
    throw bdse;
    }
    }
    return context;
    }
    Cheers,
    magic

  • #2
    I think it would be cleaner to check for the existence of the environment-specific file first, before trying to instantiate the bean factory. This way your code becomes as simple as

    Code:
    String configFile = "plugin-config" + env + ".xml";
    if( !(new File(configFile).exists()) ){
      configFile = "plugin-config.xml";
      if( !(new File(configFile).exists()) 
        throw new FileNotFoundException();
    }
    
    return new ClassPathXmlAppContext(configFile);

    Comment


    • #3
      A cooler way might be to extend org.springframework.core.io.Resource to create a DefaultableResource, where you could override getInputStream() to return one for a default file resource if the given resource wasnt found in the file system...

      You could then use GenericApplicationContext with an XmlBeanDefinitionReader, handing it your DefaultableResource object and it would blindly load from it, using either the environment-specific config or the default if it wasnt found.

      This just encapsulates the code I wrote above inside of DefaultableResource instead of in your loadAppContext() method.

      Comment


      • #4
        Originally posted by jstehler View Post
        I think it would be cleaner to check for the existence of the environment-specific file first, before trying to instantiate the bean factory. This way your code becomes as simple as

        Code:
        String configFile = "plugin-config" + env + ".xml";
        if( !(new File(configFile).exists()) ){
          configFile = "plugin-config.xml";
          if( !(new File(configFile).exists()) 
            throw new FileNotFoundException();
        }
        
        return new ClassPathXmlAppContext(configFile);
        Hi there,
        Thanks for your response.

        My only concern with this approach is that it is using the File API to locate a resource that is presumably located later by ClassPathXmlAppContext from the classpath. A similar solution checking manually for this resource from the class path would work successfully I think.

        Ideally, I was hoping that there was something in this class itself such as a static ClassPathXmlAppContext.exists(configFile) (returning boolean) method that would alert me if a later call to new ClassPathXmlAppContext(configFile) would fail. Under the covers Im sure it would do as above (the classpath variant) but would be hiding the implementation from me.

        From an OO point of view, (despite the obvious name) I shouldnt need to care that ClassPathXmlAppContext actually uses the classpath to locate the resource under the covers. I just want to know up front whether it will be able to locate the resource, if I were to ask.

        I like your second idea in priciple, but I was hoping somethign similar already existed, as I reckon Im not the first person to want to do this.

        Many thanks,
        magic

        Comment


        • #5
          I see your point; I believe the following is how ClasspathXmlAppContext retrieves resources:

          Code:
          new DefaultResourceLoader().getResource("classpath:myCtx.xml").exists();

          Comment

          Working...
          X