5.5. Tips and Tricks

Profiles can encourage build portability. If your build needs subtle customizations to work on different platforms or if you need your build to produce different results for different target platforms, project profiles increase build portability. Settings profiles generally decrease build portability by adding extra-project information that must be communicated from developer to developer. The following sections provide some guidelines and some ideas for applying Maven profiles to your project.

5.5.1. Common Environments

One of the core motivations for Maven project profiles was to provide for environment-specific configuration settings. In a development environment, you might want to produce bytecode with debug information and you might want to configure your system to use a development database instance. In a production environment you might want to produce a signed JAR and configure the system to use a production database. In this chapter, we defined a number of environments with identifiers like dev and prod. A simpler way to do this would be to define profiles that are activated by environment properties and to use these common environment properties across all of your projects. For example, if every project had a development profile activated by a property named environment.type having a value of dev, and if those same projects had a production profile activated by a property named environment.type having a value of prod, you could create a default profile in your settings.xml that always set environment.type to dev on your development machine. This way, each project defines a dev profile activated by the same environment variable. Let's see how this is done, the following settings.xml defines a profile in ~/.m2/settings.xml which sets the environment.type property to dev.

Example 5.6. ~/.m2/settings.xml defines a default profile setting environment.type

<settings>
  <profiles>
    <profile>
      <activation>
        <activeByDefault>true</activeByDefault>
      </activation>
      <properties>
        <environment.type>dev</environment.type>
      </properties>
    </profile>
  </profiles>
</settings>


This means that every time you run Maven on your machine, this profile will be activated and the property environment.type will have the value dev. You can then use this property to activate profiles defined in a project's pom.xml as follows. Let's take a look at how a project's pom.xml would define a profile activated by environment.type having the value dev.

Example 5.7. Project Profile Activated by setting environment.type to 'dev'

<project>
  ...
  <profiles>
    <profile>
      <id>development</id>
      <activation>
        <property>
          <name>environment.type</name>
          <value>dev</value>
        </property>
      </activation>
      <properties>
        <database.driverClassName>com.mysql.jdbc.Driver</database.driverClassName>
        <database.url>
          jdbc:mysql://localhost:3306/app_dev
        </database.url>
        <database.user>development_user</database.user>
        <database.password>development_password</database.password>
      </properties>
    </profile>
    <profile>
      <id>production</id>
      <activation>
        <property>
          <name>environment.type</name>
          <value>prod</value>
        </property>
      </activation>
      <properties>
        <database.driverClassName>com.mysql.jdbc.Driver</database.driverClassName>
        <database.url>jdbc:mysql://master01:3306,slave01:3306/app_prod</database.url>
        <database.user>prod_user</database.user>
      </properties>
    </profile>
  </profiles>
</project>


This project defines some properties like database.url and database.user which might be used to configure another Maven plugin configured in the pom.xml. There are plugins available that can manipulate the database, run SQL, and plugins like the Maven Hibernate3 plugin which can generate annotated model objects for use in persistence frameworks. A few of these plugins, can be configured in a pom.xml using these properties. These properties could also be used to filter resources. In this example, because we've defined a profile in ~/.m2/settings.xml which sets environment.type to dev, the development profile will always be activated when we run Maven on our development machine. Alternatively, if we wanted to override this default, we could set a property on the command-line. If we need to activate the production profile, we could always run Maven with:

~/examples/profiles $ mvn install -Denvironment.type=prod

Setting a property on the command-line would override the default property set in ~/.m2/settings.xml. We could have just defined a profile with an id of "dev" and invoked it directly with the -P command-line argument, but using this environment.type property allows us to code other project pom.xml files to this standard. Every project in your codebase could have a profile which is activated by the same environment.type property set in every user's ~/.m2/settings.xml. In this way, developers can share common configuration for development without defining this configuration in non-portable settings.xml files.