views:

42

answers:

2

Hi I'm starting a new web development project with my team using Hibernate and Spring MVC. We will be building with Maven2 and use the NetBeans IDE. Our past projects have used ant for the build system. We will be using Atlassian Bamboo for our CI server.

My question relates to the best practice for switching between dev/test/qa/production build environments which have different configurations.

More specifically our dev environments require two configurations, a shared server database and a local HSQL DB for offline development. Our test environment also requires the use of HSQL to ensure predictable tests.

I'm trying to find the best approach with Maven to select between these environments, with ant we just used to have <copy> targets which would copy our configuration files from predefined directories prior to the build and rewrite some .properties files.

So far I've found that we could possibly utilise maven profiles but not entirely sure what the best approach for this is, currently I've only found how to set certain properties using this approach but not found how to specify certain hibernate configurations.

I apologise for my sparse understanding of Maven, we are switching to maven as we've found the dependency resolution to remove a huge burden for us.

Thank you for your help and patience.

+1  A: 

Profiles are definitely the Maven way of supporting this kind of thing. There's a page on the Maven site that describes how to build for different environments that seems like it should meet your needs (essentially it uses the Maven AntRun plugin to duplicate what you were doing previously with Ant). I'd probably modify that approach to something like:

<profile>
 <id>test</id>
 <build>
   <plugins>
     <plugin>
       <artifactId>maven-antrun-plugin</artifactId>
       <executions>
         <execution>
           <phase>process-resources</phase>
           <goals>
             <goal>run</goal>
           </goals>
           <configuration>
             <tasks>
               <delete file="${project.build.outputDirectory}/environment.properties"/>
               <copy file="src/main/resources/environment.test.properties"
                     tofile="${project.build.outputDirectory}/environment.properties"/>
             </tasks>
           </configuration>
         </execution>
       </executions>
    </plugin>
   </plugins>
  </build>
 </profile>

Definitely not Maven at it's prettiest, though.

ig0774
A: 

If your goal is to build a different copy of your jar file for each environment, where the only difference is what is in the resources folder, then you can take advantage of the maven-resources-plugin, and have it copy your configuration files from the predefined directories.

To emulate your setup, I created a project which has these files:

  • src/main/resources/dev/app.properties
  • src/main/resources/qa/app.properties

My goal is to have, in the packaged jar:

  • src/main/resources/environment/app.properties

where the directory chosen is specified by a variable called environment. You could specify this in whatever way works best for your build system (ie: as a -D parameter, environment variable, or using profiles)

How I used the maven-resources-plugin to accomplish this was by adding this to the pom file:

<build>
    <resources>
        <resource>
            <directory>src/main/resources/${environment}</directory>
            <targetPath>src/main/reosurces/environment</targetPath>
        </resource>
    </resources>
</build>

Running this using the IDEA maven runner, setting -Denvironment=dev in the VM Parameters, I end up with the "dev" version of the file in the "environment" folder as intended.

I would highly recommend for further reading, taking a look at "Better Builds with Maven". It is a free e-book that you can find on Maven - External Resources. Dealing with classpath resources is covered in section 2.6 (note - the link on that page didn't work right when I tried it, but I ended up getting the e-book from a cached version from Google).

Michael D