Search code examples
javaspringspring-annotations

Using both PropertyPlaceholderConfigurer and PropertySource


I am having a bit of a difficulty here. I am designing a utility for which I require the ability for my Spring context to treat command-line arguments as properties. This was easily done:

if (args != null && args.length > 0) {
    PropertySource<?> ps = new SimpleCommandLinePropertySource(args);
    ctx.getEnvironment().getPropertySources().addFirst(ps);
}

What I have a problem with is the next step: to be compliant with my enterprise framework, I must set a PropertyPlaceholderConfigurer they provide1. Easily done too.

@Bean
public PropertyPlaceholderConfigurer propertyPlaceholderConfigurer() {
    return new MyPropertyPlaceholderConfigurer();
}

The thing is, once the latter is set, what was previously working with the command-line is not, and I have errors:

java.lang.IllegalArgumentException: Could not resolve placeholder 'input.file' in string value "${input.file}"

Now, I am aware using both is far from ideal (and that ideally, I should not even be using PropertyPlaceholderConfigurer but rather PropertySourcesPlaceholderConfigurer). Yet, I have no choice as to the configurer.

As a consequence, I think I must change something with my PropertySource, but I am at a loss as to how I can do it in an elegant way. Should I extend the PropertyPlaceholderConfigurer to add the PropertySource? Is that even possible?

What is the best solution to go for in this case? Even vague leads are welcome, since I don't know in which way to go.

(Spring version: 4.1.6)


1. This PropertyPlaceholderConfigurer loads some properties files and apply some additional processing (e.g. to allow encrypted values in the properties files).


Solution

  • With the

     ctx.getEnvironment().getPropertySources().addFirst(ps);
    

    you go right way.

    I think your MyPropertyPlaceholderConfigurer (from that Enterprise Framework) isn't just compatible with the PropertySourcesPlaceholderConfigurer.

    You should take a look to their code and override it to extend PropertySourcesPlaceholderConfigurer.

    From other side PlaceholderConfigurerSupport is a BeanFactoryPostProcessor and these guys must be configured as a static @Beans.

    HTH