RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


Keep Your Maven Projects Portable Throughout the Build Cycle

How portable is your Java project? How many modifications must be made to a build environment in order to produce a successful artifact? Determine your project's portability and learn how Maven can improve it.

f your software development lifecycle is anything like mine, it has several phases that each requires its own project configurations—which can make moving a project through all the different phases a challenge. For instance, your development phase may require you to connect to a local database, but your integration test environment database won't be local. And your test database will certainly differ from your production database (for your sake, I hope it does.).

Apache Maven 2 can help. It enables you to create a single portable Project Object Model (POM), which will relieve the integration tester and the deployment team from making changes to the project. In addition to providing enforcement of project structure, project dependency management, project encapsulation, built-in site generation, and simple integration with tools such as Subversion and Continuum, Maven aims to make portability as simple as possible while maintaining flexibility. To that end, Maven has two main tools to deal with build portability issues: properties and profiles. (See "Sidebar 1. From Make to Maven" for a closer look at the history of Java-build portability.)

Properties and Profiles

Maven properties are exactly like properties in Ant. They are placeholders for values, some of which are pre-populated. Four different styles of properties are available:
  1. env.X—Prefixing a variable with "env." will return the shell's environment variable. For example, ${env.PATH} contains the $path environment variable (%PATH% in Windows).
  2. project.x—A dot (.) notated path in the POM will contain the corresponding element's value. For example, <project><version>1.0</version></project> is accessible via ${project.version}.
  3. System Properties—All properties accessible via java.lang.System.getProperties() are available as POM properties, such as ${java.home}. (See "Sidebar 2. Viewing Property Values" for a shortcut to debugging your POM.)
  4. x—Set within a <properties /> element or an external file, the value may be used as ${someVar}.

Along with properties, Maven has added the concept of build profiles as a solution for making sweeping changes to the POM based on environmental factors. The common practice in Ant-based builds is to use properties that dictate how a project will build across environments. Maven simplifies this by removing such procedural approaches with a declaration: "If some profile is active, then use these settings." You can activate profiles via:

  • Activations: For example, "this profile will be activated if compiling with JDK1.4."
  • Command line: Using the argument -P <profileID>
  • Active profiles: An element in the "settings.xml" file containing an <activeProfile>profileID</activeProfile> element

For more details on profiles, I highly recommend you read the Maven site's guide.

Levels of Portability

Now that you have the basic tools under your belt, you can determine precisely on which level of portability your Java project falls. Maven can help you deal with the four common levels of Java portability and their corresponding concerns:
  • Wide
  • In-house
  • Environmental
  • Non-portable

In the Maven world, anyone may download a wide portability project's source, and then compile and install it (sans modification) to the POM or requirements beyond standard Maven. This is the highest level of portability; anything less requires extra work for those who wish to build your project. This level of portability is especially important for open source projects, which thrive on the ability for would-be contributors to easily download and install.

As you may imagine, being the highest level of portability makes it generally the most difficult to attain. It restricts your dependencies to those projects and tools that may be widely distributed according to their licenses (such as most commercial software packages). It also restricts dependencies to those pieces of software that may be distributed as Maven artifacts. For example, if you depend upon MySQL, your users will have to download and install it; this is not widely portable (only MySQL users can use your project without changing their systems). Using HSQLDB, on the other hand, is available from Maven Central repository, and thus is widely portable.

For most non-trivial software efforts, in-house portability is the best you can hope for. The majority of software projects fall under this listing, either for an open source development team or a closed-source production company. The center of this level of portability is your project's requirement that only a select few may access an internal (in-house) remote repository. In-house does not necessarily mean a specific company. A widely dispersed open-source project may require specific tools or connection access; this would be classified as in-house. (See "Sidebar 3. More About In-House Portability" for an expanded discussion of this level.)

Maven created profiles for the environmental portability level, which largely concerns code and resource generation. As an example, consider a test environment that points to a separate database from that of production. When built on a test box, therefore, at least one resource file (or code—hopefully not) must be manipulated. If a file must be altered to successfully build and run on a specific environment, then the project is at best environmentally portable. A project that contains a reference to a test database in a test environment, for example, and a production database in a production environment, is environmentally portable. When you move to a different environment, one that is not defined and has no profile created for it, the project will not work. Hence, it is only portable between defined environments.

The example project is environmentally portable.

A non-portable project is buildable only under a specific set of circumstances and criteria (e.g., your local machine). Unless you have no plans on porting your project to any other machines—ever, it is best to avoid non-portability entirely. Non-portable is similar to environmental portability with a single definition; the project may be built in only one environment setting.

See "Sidebar 4. Where to Draw the Line?" for help on deciding on which level your project should fall.

Close Icon
Thanks for your registration, follow us on our social networks to keep up-to-date