0

I have a property configuration bean looking like:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="false"/>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="localOverride" value="false"/>
    <property name="locations">
        <list>
            <value>file://${emulator.config}</value>
            <value>classpath:emulator.properties</value>
            <value>file://${db.config}</value>
            <value>classpath:db.properties</value>
        </list>
    </property>
</bean>

The values from the first emulator config are taken in the code with @Value like:

@Value("${emulator.database.template.create}")
private String createDBPath;

All they are correctly taken in the desired order:

  1. If I supply the external file path to the jvm options like that

      java \
     -Dlog4j.configurationFile=/correctfullpath/log4j2.xml \
     -Dspring.config.location=/correctfullpath/application.properties \
     -Demulator.config=/correctfullpath/emulator.properties \
     -Ddb.config=/correctfullpath/db.properties -jar target/registrator-emulator.war
    

I got the values loaded to @Value-decorated variables taken from the supplied /correctfullpath/emulator.properties ;

  1. If the jvm options are ommited, the values are taken from the classpath properties file within the jar

and something goes absolutelly different if I'm obtaining property values to the xml-configurated bean:

<bean id="manageDataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="${database.driver}"/>
    <property name="url" value="${database.url}"/>
    <property name="username" value="${database.user}"/>
    <property name="password" value="${database.password}"/>
</bean>

Here ${database.url} use to be taken from db.properties are ignoring values supplied with -Ddb.config=/correctfullpath/db.properties option; they are always taken from classpath property file from the jar. The only workaround (not very suitable for me) is to comment out the classpath property from the properties placeholder bean:

<bean class="org.springframework.context.support.PropertySourcesPlaceholderConfigurer">
    <property name="ignoreUnresolvablePlaceholders" value="false"/>
    <property name="ignoreResourceNotFound" value="true"/>
    <property name="localOverride" value="false"/>
    <property name="locations">
        <list>
            <value>file://${emulator.config}</value>
            <value>classpath:emulator.properties</value>
            <value>file://${db.config}</value>
            <!--<value>classpath:db.properties</value>-->
        </list>
    </property>
</bean>

So is there any option to force classpath properties be ignored in xml configuration when the file properties are supplied?

UPD. According to advice of M. Deinum I tried toscwitch to Spring boot annotated configurration.

But I'm still have to comment out the classpath db.properties:

@Configuration
@PropertySources({@PropertySource("file://${emulator.config}"),
        @PropertySource("classpath:emulator.properties"),
        @PropertySource(value = "file://${statsd.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:statsd.properties"),
        @PropertySource(value = "file://${pools.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:pools.properties"),
        @PropertySource(value= "file://${db.config}"),
        //@PropertySource("classpath:db.properties")
        })

and here how I create the bean:

@Value("${database.driver}") private String dataBaseDriver;

@Value("${database.url}")
private String dataBaseUrl;

@Value("${database.user}")
private String dataBaseUser;

@Value("${database.password}")
private String dataBasePassword;




@Bean
@Primary
public DataSource manageDataSource() {
    return DataSourceBuilder
            .create()
            .username(dataBaseUser)
            .password(dataBasePassword)
            .url(dataBaseUrl)
            .driverClassName(dataBaseDriver)
            .build();
}
Eljah
  • 4,188
  • 4
  • 41
  • 85
  • 1
    You are using Spring Boot why are you configuring your own `PropertySourcesPlaceholderConfigurer`? Don't as that will interfere with the one already added by Spring Boot. Instead add 1 or more `@PropertySource` annotations to your `@Configuration` or, preferable `@SpringBootApplication` class to load the additional files. – M. Deinum Oct 06 '17 at 07:39
  • Seems to be some kind of magic, but nothing has changed with switching to Springboot annootated configuration: I still have to comment out property to the classpaht: – Eljah Oct 06 '17 at 08:30
  • @PropertySources({@PropertySource("file://${emulator.config}"), @PropertySource("classpath:emulator.properties"), @PropertySource(value = "file://${statsd.config}",ignoreResourceNotFound = true), @PropertySource("classpath:statsd.properties"), @PropertySource(value = "file://${pools.config}",ignoreResourceNotFound = true), @PropertySource("classpath:pools.properties"), @PropertySource(value= "file://${db.config}"), //@PropertySource("classpath:db.properties") }) – Eljah Oct 06 '17 at 08:30

1 Answers1

0

The root of the problem was in properties order!

Since the file properties override the classpath properties, they should be placed after the classpath ones:

@PropertySources({
        @PropertySource("classpath:emulator.properties"),
        @PropertySource(value = "file://${emulator.config}", ignoreResourceNotFound = true),
        @PropertySource("classpath:statsd.properties"),
        @PropertySource(value = "file://${statsd.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:pools.properties"),
        @PropertySource(value = "file://${pools.config}",ignoreResourceNotFound = true),
        @PropertySource("classpath:db.properties"),
        @PropertySource(value= "file://${db.config}",ignoreResourceNotFound = true)
        })
Eljah
  • 4,188
  • 4
  • 41
  • 85