How insert Maven profile properties in Spring context
Asked Answered
P

2

6

i created two maven profile cause i want to deploy my app to heroku, so i have one profile dev with db properties that located on my PC, and prod with properties for heroku db. POM.xml below

<modelVersion>4.0.0</modelVersion>
<groupId>com.phone-book</groupId>
<artifactId>phone-book</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
    <module>controller</module>
    <module>dao</module>
    <module>model</module>
    <module>service</module>
</modules>
<name>Phonebook web app</name>
<build>
    <filters>
        <filter>profiles/${build.profile.id}/config.properties </filter>
    </filters>
    <resources>
        <resource>
            <filtering>true</filtering>
            <directory>controller/src/main/webapp/WEB-INF/spring</directory>
        </resource>
    </resources>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>2.19.1</version>
            <configuration>
                <skipTests>true</skipTests>
            </configuration>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-dependency-plugin</artifactId>
            <version>2.3</version>
            <executions>
                <execution>
                    <phase>package</phase>
                    <goals><goal>copy</goal></goals>
                    <configuration>
                        <artifactItems>
                            <artifactItem>
                                <groupId>com.github.jsimone</groupId>
                                <artifactId>webapp-runner</artifactId>
                                <version>8.0.30.2</version>
                                <destFileName>webapp-runner.jar</destFileName>
                            </artifactItem>
                        </artifactItems>
                    </configuration>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>
<profiles>
    <profile>
        <id>prod</id>
        <properties>
            <build.profile.id>prod</build.profile.id>
        </properties>
    </profile>
    <profile>
        <id>dev</id>
        <activation>
            <activeByDefault>true</activeByDefault>
        </activation>
        <properties>
            <build.profile.id>dev</build.profile.id>
        </properties>
    </profile>
</profiles>

i created folder in each maven module profile that contains folders dev and prod and wrote my prop like in this tutorials https://www.petrikainulainen.net/programming/tips-and-tricks/creating-profile-specific-configuration-files-with-maven/ Finaly create spring context with this param, see below

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="org.postgresql.Driver" />
    <property name="url" value="${url.property}" />
    <property name="username" value="${user.property}" />
    <property name="password" value="${password.property}" />
    <property name="initialSize" value="20" />
    <property name="maxActive" value="100"/>
</bean>

but when i make my app, properties does not replace and i get something like that Cannot create JDBC driver of class 'org.postgresql.Driver' for connect URL '${url.property}'

Puncheon answered 11/8, 2016 at 9:42 Comment(2)
Have you tried to add <beans profile="dev/prod"> in your beans xml files definition?Barbecue
@Barbecue yes, when i wrote this i got spring exeptionPuncheon
A
4

I don't see where you load the concrete properties file in your application context.

I think that you need something similar in your app context:

<context:property-placeholder location="classpath:profiles/${build.profile.id}/config.properties" />

The filtering for the controller module should be in its pom file so that it is applied during its build lifecycle. That way the filtering is applied when the root is build and not when the controller module is build.

The modules should have the root pom set as their parent so that they can inherit the profiles and the properties.

Aquarium answered 11/8, 2016 at 11:8 Comment(9)
but i have <filter>profiles/${build.profile.id}/config.properties </filter> i dont sure that i need this <context:property-placeholder location="classpath:/path/${profile.name}/config.properties" />Puncheon
the variable name is ${build.profile.id} in your caseAquarium
<context:property-placeholder /> tells spring to load and parse this property file. I am not sure what was the default behaviour but I think that nothing gets loaded by default.Aquarium
you have to use it in the property-placeholder declaration, i have edited the answerAquarium
and when i add this string ${build.profile.id} doesn't replacePuncheon
Doesn't replace where ? The application context xml file should also be processed from maven. Make sure that this context file is filtered with maven.Aquarium
I think that context file isn't filtered, i set filterd param in root pom.xml, but context located in another module, i set this param in controller module but in dont helped too,Puncheon
You have messed your setup :)Aquarium
What does it mean?Puncheon
G
2

Seems your profile properties are inconsistent along with where you copy the properties to

prod : profile should be

<profile>
  <id>prod</id>
  <properties>
    <build.profile.id>prod</build.profile.id>
  </properties>
</profile>

copy location properties to a location in classpath, it should be something usually like(unless you have specified a different location in your maven)

 <resources>
        <resource>
            <filtering>true</filtering>
            <directory>src/main/resources</directory>
        </resource>
  </resources>

and you should be having properties files such as,

config.properties

user.property=xxxxx
..

in prod/dev folders

and when you run, you should clearly invoke your mvn profiles something like this

mvn -P dev clean install

or

mvn -P prod clean install

and as @vbhlev suggested you need to have this in beans xml

<context:property-placeholder location="classpath:/config.properties" />
Gothicize answered 11/8, 2016 at 10:11 Comment(6)
sorry i had mistake i just copy not valid POM.xml, now question is correctPuncheon
check if you are copying the properties file to a correct class path locationGothicize
yes all os correct, when i write incorrect path app just dont makePuncheon
I think the problem lies elsewherePuncheon
clean install -DskipTestsPuncheon
you need to provide the profile mvn -P dev clean install -DskipTests and before that make sure you have added <context:property-placeholder location="classpath:/config.properties" /> in your beans xmlGothicize

© 2022 - 2024 — McMap. All rights reserved.