1

Hello I am new to Maven in general so I'd like to apologise in advance if I get things wrong.

I have a Maven project with spring in which I also access a MySQL database.
often the MySQL database is not accessible so I use a local database for testing, I swap between the two by changing the active profile.

I set up the profiles by putting this in my POM.xml:

<profiles>
        <profile>
            <id>Local</id>
            <dependencies>
                <dependency>
                    <groupId>org.hsqldb</groupId>
                    <artifactId>hsqldb</artifactId>
                    <version>2.3.3</version>
                    <classifier>jdk5</classifier>
                </dependency>
            </dependencies>
            <properties>
                <jdbc.url>jdbc:hsqldb:file:databaseName</jdbc.url>
                <jdbc.username>a</jdbc.username>
                <jdbc.password></jdbc.password>
                <jdbc.driver>org.hsqldb.jdbcDriver</jdbc.driver>
            </properties>
        </profile>
        <profile>
            <id>MySQL</id>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-java</artifactId>
                    <version>5.1.38</version>
                </dependency>
            </dependencies>
            <properties>
                <jdbc.url>jdbc:mysql://mysql.website.ac.uk:3306</jdbc.url>
                <jdbc.username>user</jdbc.username>
                <jdbc.password>1234</jdbc.password>
                <jdbc.driver>com.mysql.jdbc.Driver</jdbc.driver>
            </properties>
        </profile>
    </profiles>

When I try to access the properties variables through for example ${jdbc.url} they are not converted to the actual values as defined in the profile and I get errors. I suspect it might have something to do with Spring Boot.

Aritz
  • 30,971
  • 16
  • 136
  • 217
sf298
  • 33
  • 1
  • 6
  • Did you try to enable the debug and verbose logging to see what is happening? – randominstanceOfLivingThing Apr 24 '16 at 16:48
  • Not related to your question, but it's bad idea to set your database properties in pom.xml. Do you store your code in some external VCS like Github, bitbucket, etc? – Everv0id Apr 24 '16 at 16:59
  • make sure to update the project after making changes in POM – Priyamal Apr 24 '16 at 16:59
  • Be sure that you understand what you are trying to do. Maven properties work at project build time, the value is determined when project is packaged. You need to enable maven filtering in order to get your maven properties writen in the files you want. On the other hand, Spring Boot uses run time values, and there are multiple ways to pass them to the application. You can define your defaults in `application.properties` file and then decide to override them when running the project. See this answer: http://stackoverflow.com/a/36703638/1199132 – Aritz Apr 24 '16 at 17:03

3 Answers3

2

Apart from the specific sprint-boot problem I think you are missing the maven resource filtering configuration.

Maven properties are not automatically propagated to Spring unless you put them into a separate properties files which must then be managed by spring (Usually via PropertyPlaceholderConfigurer).

But without maven filtering turned on properties are not automatically resolved, usually if you do not have many items under tour src/resources folder you can just enable filtering globally with

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

And your properties file should replace placeholders with maven values.

If, on the other hand in you have several resources in src/main/resources, you should check documentation more deeply to avoid binary files corruption

I think that spring boot is simply wrapping up all the process automatically in your application properties files.

0

You specified properties in profile, so there is a workaround. Annotations such as @Value("${name}") are referencing to externalized configuration, e.g. from application.yml. You should use this file to load properties you want. @property_name@ loads property from your maven profile.

jdbc:
  url: @jdbc.url@
  username: @jdbc.username@
and so on...

Then these properties will be accessible in your code.

Mateusz Stefaniak
  • 856
  • 1
  • 9
  • 20
  • I'm really sorry, but I really am new to all of this. I don't quite understand your answer. did you mean to just replace all the $([name]) with @[name]@ ? – sf298 Apr 24 '16 at 17:24
  • 1
    No. In this case, you should provide a file 'application.yml' in your resources. Then maven inserts values from your profile to this file and by this file they're accessible in your code. Please see: [Spring Boot Externalized Configuration](https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-external-config.html) – Mateusz Stefaniak Apr 24 '16 at 18:13
  • Glad to hear it :) So, if m answer was a solution to you problem, please mark it as an answer. I don't have much points on Stack Overflow, so it will help me a bit :) – Mateusz Stefaniak Apr 24 '16 at 23:06
0

Maven properties are not put into environment variables or JVM variables that you can access by Spring.
However you can usually instruct maven plugin to do it for you.
For example configuration of maven-failsafe-plugin I use to set up test db:

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-failsafe-plugin</artifactId>
                <configuration>
                    <includes>**/*Integration.java</includes>
                    <environmentVariables>
                        <mysql.version>${mysql.version}</mysql.version>
                        <test.mysql.username>${test.mysql.username}</test.mysql.username>
                        <test.mysql.password>${test.mysql.password}</test.mysql.password>
                        <test.mysql.port>${test.mysql.port}</test.mysql.port>
                        <test.mysql.db>${test.mysql.db}</test.mysql.db>
                    </environmentVariables>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
oneat
  • 10,778
  • 16
  • 52
  • 70