Spring Framework
  1. Spring Framework
  2. SPR-4902

Allow locations value in PropertyPlaceholderConfigurer be resolved

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Complete
    • Affects Version/s: None
    • Fix Version/s: 3.1 GA
    • Component/s: Core
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      When configuring PropertyPlaceholderConfigurer bean, the "locations" value can use property resolvable variable, but only if it defined in System properties ONLY. If not defined, it errors out. It would be very useful to have it also lookup an defined Map in another bean within the context that provide default values.

      I notice that we can do this on other bean definitions after a PropertyPlaceholderConfigurer has been setup, but the "locations" properties of PropertyPlaceholderConfigurer bean itself is not configurable, which is a shame.

      Can we add this improvement?

      Thanks.

      There is a also a forum topic created, but no one replied
      http://forum.springframework.org/showthread.php?p=185477

        Activity

        Zemian Deng created issue -
        Hide
        Jon Osborn added a comment -

        Not an issue. You need two configurers...one that is loaded first and will configure your second configurer...

        Show
        Jon Osborn added a comment - Not an issue. You need two configurers...one that is loaded first and will configure your second configurer...
        Hide
        Zemian Deng added a comment -

        Hum.. I just recently get couple replies to the post, but still I don't have an answer that works. You guys made it so simple in the answer and yet I can't seem to get it to work.

        Would you please please take my example in the post and give me example of config on how you do it?

        Much appreciated and Thanks,
        -Zemian

        Show
        Zemian Deng added a comment - Hum.. I just recently get couple replies to the post, but still I don't have an answer that works. You guys made it so simple in the answer and yet I can't seem to get it to work. Would you please please take my example in the post and give me example of config on how you do it? Much appreciated and Thanks, -Zemian
        Hide
        Juergen Hoeller added a comment -

        Actually, this isn't possible between multiple PropertyPlaceholderConfigurers at present, since all such PropertyPlaceholderConfigurer instances will be created at the same time and then executed in the order that those instances specify themselves. For that reason, one such PropertyPlaceholderConfigurer cannot resolve values from another such PropertyPlaceholderConfigurer.

        Note that we will generally revise this in Spring 3.0 through the introduction of expression language support. We'll also revisit PropertyPlaceholderConfigurer locations resolution at that point.

        Juergen

        Show
        Juergen Hoeller added a comment - Actually, this isn't possible between multiple PropertyPlaceholderConfigurers at present, since all such PropertyPlaceholderConfigurer instances will be created at the same time and then executed in the order that those instances specify themselves. For that reason, one such PropertyPlaceholderConfigurer cannot resolve values from another such PropertyPlaceholderConfigurer. Note that we will generally revise this in Spring 3.0 through the introduction of expression language support. We'll also revisit PropertyPlaceholderConfigurer locations resolution at that point. Juergen
        Juergen Hoeller made changes -
        Field Original Value New Value
        Fix Version/s 3.0 M2 [ 10540 ]
        Assignee Juergen Hoeller [ juergen.hoeller ]
        Hide
        Zemian Deng added a comment -

        Thank you for the confirm and updates Juergen. This seems to be very valuable feature to me. Not sure how other practice deployment, but for me, I would really like default everything in a config properties that can be search in the following order:

        System properties like -Dmyconfig.dir=/data/myapp/conf/config.properties

        if missing then in system env MYCONFIG_DIR=/data/myapp/conf/config.properties

        and if that is missing then search classpath:/com/myapp/config.properties

        This gives me change to provide a default set of parameters in classpath if user choose not to specify, but allow admin to supply their own during production environment. This style allow me to repackage and upgrade war (SpringMVC) file much faster and still keeping config externalize!

        Current spring doesn't allow me to do this. I asked this question almost 8 months ago in forum and got no right responses. This is little disappointing.

        Show
        Zemian Deng added a comment - Thank you for the confirm and updates Juergen. This seems to be very valuable feature to me. Not sure how other practice deployment, but for me, I would really like default everything in a config properties that can be search in the following order: System properties like -Dmyconfig.dir=/data/myapp/conf/config.properties if missing then in system env MYCONFIG_DIR=/data/myapp/conf/config.properties and if that is missing then search classpath:/com/myapp/config.properties This gives me change to provide a default set of parameters in classpath if user choose not to specify, but allow admin to supply their own during production environment. This style allow me to repackage and upgrade war (SpringMVC) file much faster and still keeping config externalize! Current spring doesn't allow me to do this. I asked this question almost 8 months ago in forum and got no right responses. This is little disappointing.
        Hide
        Zemian Deng added a comment -

        Well, let me add that I can do this by forcing deploying to MUST supply a system properties, which is working fine, becuase if it's missing the webapp will failed to startup. It's just that I can't smoothly fall back to a default set in classpath is annoying.

        Show
        Zemian Deng added a comment - Well, let me add that I can do this by forcing deploying to MUST supply a system properties, which is working fine, becuase if it's missing the webapp will failed to startup. It's just that I can't smoothly fall back to a default set in classpath is annoying.
        Juergen Hoeller made changes -
        Fix Version/s 3.0 M1 [ 10552 ]
        Fix Version/s 3.0 M2 [ 10540 ]
        Juergen Hoeller made changes -
        Fix Version/s 3.0 M2 [ 10540 ]
        Fix Version/s 3.0 M1 [ 10552 ]
        Juergen Hoeller made changes -
        Fix Version/s 3.0 M3 [ 11136 ]
        Fix Version/s 3.0 M2 [ 10540 ]
        Juergen Hoeller made changes -
        Fix Version/s 3.0 RC1 [ 10956 ]
        Fix Version/s 3.0 M3 [ 11136 ]
        Hide
        Marvin S. Addison added a comment -

        I do hope a fix for this improvement will make it into the Spring 3.0 release. I need this feature to support the following use case, which I believe would be generally beneficial.

        I would like to use a ServletContextPropertyPlaceholderConfigurer to configure the filesystem paths to properties files that need to be provided by deployers to customize application behavior. A PropertyPlaceholderConfigurer loaded subsequently would use the locations provided by the servlet context to load the properties for bean values. Of course one could put all properties directly in the servlet context, but I believe it would be much easier for deployers to edit well-documented properties files rather than XML needed to customize servlet context.

        Hopefully the following bean definitions will clarify the use case above:

        <bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer"
        p:order="1"
        p:placeholderPrefix="#["
        p:placeholderSuffix="]"
        p:ignoreUnresolvablePlaceholders="false">
        <property name="properties">
        <!-- Define defaults -->
        <props>
        <prop key="runtimePropertiesLocation">classpath:runtime.properties</prop>
        </props>
        </property>
        </bean>

        <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"
        p:order="2"
        p:location="#[runtimePropertiesLocation]"
        p:ignoreResourceNotFound="false"
        p:ignoreUnresolvablePlaceholders="false"
        />

        Show
        Marvin S. Addison added a comment - I do hope a fix for this improvement will make it into the Spring 3.0 release. I need this feature to support the following use case, which I believe would be generally beneficial. I would like to use a ServletContextPropertyPlaceholderConfigurer to configure the filesystem paths to properties files that need to be provided by deployers to customize application behavior. A PropertyPlaceholderConfigurer loaded subsequently would use the locations provided by the servlet context to load the properties for bean values. Of course one could put all properties directly in the servlet context, but I believe it would be much easier for deployers to edit well-documented properties files rather than XML needed to customize servlet context. Hopefully the following bean definitions will clarify the use case above: <bean class="org.springframework.web.context.support.ServletContextPropertyPlaceholderConfigurer" p:order="1" p:placeholderPrefix="#[" p:placeholderSuffix="]" p:ignoreUnresolvablePlaceholders="false"> <property name="properties"> <!-- Define defaults --> <props> <prop key="runtimePropertiesLocation">classpath:runtime.properties</prop> </props> </property> </bean> <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" p:order="2" p:location="# [runtimePropertiesLocation] " p:ignoreResourceNotFound="false" p:ignoreUnresolvablePlaceholders="false" />
        Juergen Hoeller made changes -
        Fix Version/s 3.0 RC1 [ 11289 ]
        Fix Version/s 3.0 M4 [ 10956 ]
        Juergen Hoeller made changes -
        Fix Version/s 3.0 RC1 [ 11289 ]
        Fix Version/s 3.1 RC1 [ 11107 ]
        Juergen Hoeller made changes -
        Fix Version/s 3.1 M2 [ 11379 ]
        Fix Version/s 3.1 RC1 [ 11107 ]
        Hide
        Connor Barry added a comment -

        Juergen said: "Note that we will generally revise this in Spring 3.0 through the introduction of expression language support". Spring 3.0 is out now; does anyone know how to accomplish this two-level indirection using expressions?

        ---------------------

        My particular situation -
        I want to use a String stored in JNDI (configured in Tomcat's GlobalNamingResources section as an <Environment> entry) to define the environment name: "dev", "sqa", or "prod". Then I want to load the appropriate properties file in the format $

        {envname}

        .properties to be used in a PropertiesPlaceholderConfigurer so the environment-specific values can be externalized to a file. My workaround currently is to set a system property instead of the JNDI value, but it would be nice to push this into JNDI so I don't have to mess with the Tomcat startup scripts.

        Show
        Connor Barry added a comment - Juergen said: "Note that we will generally revise this in Spring 3.0 through the introduction of expression language support". Spring 3.0 is out now; does anyone know how to accomplish this two-level indirection using expressions? --------------------- My particular situation - I want to use a String stored in JNDI (configured in Tomcat's GlobalNamingResources section as an <Environment> entry) to define the environment name: "dev", "sqa", or "prod". Then I want to load the appropriate properties file in the format $ {envname} .properties to be used in a PropertiesPlaceholderConfigurer so the environment-specific values can be externalized to a file. My workaround currently is to set a system property instead of the JNDI value, but it would be nice to push this into JNDI so I don't have to mess with the Tomcat startup scripts.
        Hide
        Jeff Johnston added a comment -

        I accidentally posted this to the web flow project...I think Configleon solves this problem perfectly so I am re-posting this here.

        I am wondering if the Spring framework would be interested in including something like Configleon in with Spring? The reason I thought I would write to you guys is because we have found Configleon to be invaluable and cannot imagine using Spring without it. It seems like such a missing feature in Spring and I think a lot of people would find it to be as useful as we do.

        The reason we use Configleon is because Spring out of the box provides little support for loading property attributes based on environments and/or server contexts. Many projects work around this by creating custom ant builds. With Configleon you can build one war file that can be deployed to every location.

        Configleon really shines is in it's ability to cascade the property attributes. This allows the common attributes to be defined in a global file and then overridden at the environment and server context.

        Here is a link to the site in case you are interested in checking it out more. The code has been road tested for a couple years and works really well.

        http://code.google.com/p/configleon/

        -Jeff Johnston

        Show
        Jeff Johnston added a comment - I accidentally posted this to the web flow project...I think Configleon solves this problem perfectly so I am re-posting this here. I am wondering if the Spring framework would be interested in including something like Configleon in with Spring? The reason I thought I would write to you guys is because we have found Configleon to be invaluable and cannot imagine using Spring without it. It seems like such a missing feature in Spring and I think a lot of people would find it to be as useful as we do. The reason we use Configleon is because Spring out of the box provides little support for loading property attributes based on environments and/or server contexts. Many projects work around this by creating custom ant builds. With Configleon you can build one war file that can be deployed to every location. Configleon really shines is in it's ability to cascade the property attributes. This allows the common attributes to be defined in a global file and then overridden at the environment and server context. Here is a link to the site in case you are interested in checking it out more. The code has been road tested for a couple years and works really well. http://code.google.com/p/configleon/ -Jeff Johnston
        Juergen Hoeller made changes -
        Fix Version/s 3.2 RC1 [ 11128 ]
        Fix Version/s 3.1 M2 [ 11379 ]
        Dave Syer made changes -
        Assignee Juergen Hoeller [ juergen.hoeller ] Dave Syer [ david_syer ]
        Hide
        Dave Syer added a comment -

        See also SPR-7481 for a feature that contains this one as a special case.

        P.S. Configleon solves a different problem (see my comments on SPR-1876).

        Show
        Dave Syer added a comment - See also SPR-7481 for a feature that contains this one as a special case. P.S. Configleon solves a different problem (see my comments on SPR-1876 ).
        Trevor Marshall made changes -
        Workflow jira [ 22835 ] SPR Workflow [ 40896 ]
        Chris Beams made changes -
        Assignee Dave Syer [ david_syer ] Chris Beams [ cbeams ]
        Hide
        Chris Beams added a comment -

        It's been quite some time since this issue was last addressed, but in the meantime we've come a long way with Spring 3.1's Environment and PropertySource mechanisms.

        You should be able to achieve the desired results here, probably with the combination of a SpEL expression taking advantage of the new environment object, e.g.:

        #{environment['some.prop']}
        

        This results in a call to Environment#getProperty, which in turn iterates through any registered PropertySource objects in order to resolve the value of 'some.prop'. Property sources are an open extension point, and by default in Spring's StandardEnvironment, system properties and environment variable property sources are registered. In StandardWebEnvironment, servlet context-params, init-params, and JNDI are added into the mix. See Javadoc for the mentioned classes for details.

        Show
        Chris Beams added a comment - It's been quite some time since this issue was last addressed, but in the meantime we've come a long way with Spring 3.1's Environment and PropertySource mechanisms. You should be able to achieve the desired results here, probably with the combination of a SpEL expression taking advantage of the new environment object, e.g.: #{environment['some.prop']} This results in a call to Environment#getProperty , which in turn iterates through any registered PropertySource objects in order to resolve the value of 'some.prop'. Property sources are an open extension point, and by default in Spring's StandardEnvironment , system properties and environment variable property sources are registered. In StandardWebEnvironment , servlet context-params, init-params, and JNDI are added into the mix. See Javadoc for the mentioned classes for details.
        Chris Beams made changes -
        Fix Version/s 3.2 Backlog [ 11128 ]
        Status Open [ 1 ] Resolved [ 5 ]
        Resolution Complete [ 8 ]
        Fix Version/s 3.1 GA [ 12697 ]
        Chris Beams made changes -
        Status Resolved [ 5 ] Closed [ 6 ]
        Trevor Marshall made changes -
        Workflow SPR Workflow [ 40896 ] New SPR Workflow [ 57339 ]
        Trevor Marshall made changes -
        Workflow New SPR Workflow [ 57339 ] SPR Workflow [ 66395 ]
        Transition Time In Source Status Execution Times Last Executer Last Execution Date
        Open Open Resolved Resolved
        1281d 15h 39m 1 Chris Beams 12/Dec/11 7:35 PM
        Resolved Resolved Closed Closed
        189d 7h 12m 1 Chris Beams 19/Jun/12 3:47 AM

          People

          • Assignee:
            Chris Beams
            Reporter:
            Zemian Deng
            Last updater:
            Trevor Marshall
          • Votes:
            10 Vote for this issue
            Watchers:
            15 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              2 years, 18 weeks, 4 days ago