4
votes

I have a Java EE 6 app that I build with Maven, code in NetBeans 7 and deploy on GlassFish 3.1.2. As I near completion, I find myself deploying demo builds.

The problem is that I don't have any dead easy way to build for different environment such as dev, QA, demo, prod, etc. For some stuff, I've been using a Java class with a bunch of static getters that return values based on the value of an environment constant. But this doesn't help me with conditionally setting

  • javax.faces.PROJECT_STAGE (web.xml)
  • database credentials (glassfish-resources.xml)
  • mail servers (glassfish-resources.xml)
  • JPA logging level (persistence.xml)

and probably a number of other things I can't think about now that are scattered across XML files.

Is there any way to define multiple versions of these configuration files and just set a flag at build time to select the environment, while defaulting to dev when no environment is specified? Is there a way I could make Maven work for me in this instance?

3

3 Answers

11
votes

You can use maven to achieve that. Especially using resource filtering.

First, you can define list of profiles:

  <profiles>
    <profile>
      <id>dev</id>
      <properties>
        <env>development</env>
      </properties>
      <activation>
        <activeByDefault>true</activeByDefault> <!-- use dev profile by default -->
      </activation>
    </profile>
    <profile>
      <id>prod</id>
      <properties>
        <env>production</env>
      </properties>
    </profile>
  </profiles>

Then the resources that you need to filter:

  <build>
    <outputDirectory>${basedir}/src/main/webapp/WEB-INF/classes</outputDirectory>
    <filters>
      <filter>src/main/filters/filter-${env}.properties</filter> <!-- ${env} default to "development" -->
    </filters>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
        <filtering>true</filtering>
      </resource>
    </resources>
  </build>

And then your custom properties based on profiles in src/main/filters directory:

filter-development.properties

# profile for developer
db.driver=org.hsqldb.jdbcDriver
db.url=jdbc:hsqldb:mem:web

and

filter-production.properties

# profile for production
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/web?createDatabaseIfNotExist=true

to use production profile, you can package war using mvn clean package -Pprod command.

Here you can see the sample project that use profile in maven.

0
votes

This is not direct response to question. This explain diff strategy to manage env properties One other way to manage properties for diff env is using the database to store the properties. This way you have only need to manage the config of the DB. Based on which DB you are pointing you can load the properties from that DB. If you are using spring than spring provides PropertyPlaceholderConfigurer which can initialize the properties from DB. This approach allows you to change the property value without doing a build.

This approach is useful if you want to promote the artifact tested by QA\Testing team. In this case DB configuration will not be part of artifact generated by build process.

0
votes

If you need to configure web.xml check this how-to: https://community.jboss.org/docs/DOC-19076

It uses same method (resource filtering) as described in another answers.