Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Maven settings.xml properties inside Spring context

Tags:

spring

maven

I've got a Maven settings.xml file in my ~/.m2 directory; it looks like this:

<settings>
    <profiles>
        <profile>
            <id>mike</id>
            <properties>
                <db.driver>org.postgresql.Driver</db.driver>
                <db.type>postgresql</db.type>
                <db.host>localhost</db.host>
                <db.port>5432</db.port>
                <db.url>jdbc:${db.type}://${db.host}:${db.port}/dbname</db.url>
            </properties>
        </profile>
    </profiles>
    <activeProfiles>
        <activeProfile>mike</activeProfile>
    </activeProfiles>
    <servers>
        <server>
            <id>server_id</id>
            <username>mike</username>
            <password>{some_encrypted_password}</password>
        </server>
    </servers>
</settings>

I'd like to use these properties twice

  • Once inside Maven's integration-test phase to set up and tear down my database. Using Maven filtering, this is working perfectly.
  • A second time when running my Spring application, which means I need to substitute these properties into my servlet-context.xml file during Maven's resources:resources phase. For properties in the upper section of settings.xml, such as ${db.url}, this works fine. I cannot figure out how to substitute my database username and (decrypted) password into the Spring servlet-context.xml file.

The pertinent part of my servlet-context.xml file looks like:

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName"><value>${db.driver}</value></property>
    <property name="url"><value>${db.url}</value></property>
    <property name="username"><value>${username}</value></property>
    <property name="password"><value>${password}</value></property>
</bean>

The end goal here is for each developer to have their own Maven settings (and database on their own machine for integration testing)...And a similar setup on the Jenkins server. We do not want to share a common username/password/etc.

like image 748
Mike Avatar asked May 24 '12 03:05

Mike


2 Answers

There is a way of filtering web resources by configuration of Maven War Plugin. Look at this for a snippet from official plugin's docs.

And by the way, I strongly recommend reconsidering this filtering-based way for providing de facto run-time configuration at build-time. Just notice that you have to rebuild the same code to just prepare package for another environment (or alternatively edit package contents). You can use application server's specific stuff for this (at least JBoss has one) or use Spring that AFAIR also can be configured like this.

like image 194
Michał Kalinowski Avatar answered Nov 15 '22 14:11

Michał Kalinowski


I recommend you to use a property file in the middle. I mean: Spring application would load properties values form the property file using context:property-placeholder and Maven would be the one who replace ${...} variables using values from settings.xml using filtering.

Your property file:

db.driver=${db.driver}
db.url=${db.url}
username=${username}
password=${password}

Your servlet-context.xml file

<context:property-placeholder location="classpath:your-property-file.properties" />

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName"><value>${db.driver}</value></property>
    <property name="url"><value>${db.url}</value></property>
    <property name="username"><value>${username}</value></property>
    <property name="password"><value>${password}</value></property>
</bean>

In your pom.xml

<resources>
    ...
    <resource>
        <directory>src/main/resources</directory>
        <filtering>true</filtering>
    </resource>
    ...
</resources>
like image 43
jddsantaella Avatar answered Nov 15 '22 13:11

jddsantaella