Swapping configuration between development and production (and often other environments) is usually a custom solution but often follows a general pattern. Personally, I usually leave this up to properties files. For instance, let’s say we have a specific URL for an adding service and let’s say the URL changes between the development and production environments. Obviously we would want to automate this.It is quite simple to define a component to invoke the service using Seam:

package com.solutionsfit.example.service;

@Scope(ScopeType.STATELESS)
public class AddingServiceFacade {
  private location;
  private port;

  public int add(int num1, int num2) {
    // invoke service at location and port
    // ... ...
  }

  // getters and setters
  // ... ...
}

Once defined, we can simply create a namespace for this component (as shown in this previous posting) and our configuration in components.xml becomes simple:

<components xmlns="http://jboss.com/products/seam/components"
    xmlns:service="http://solutionsfit.com/example/service"
  ... ...
  <service:adding-service-facade name="addingService"
    location="@addingServiceIpAddress@" port="@addingServicePort@" />
  ... ...

The wildcard attributes above are replaced by our components.properties definition:

addingServiceIpAddress=192.168.0.1
addingServicePort=9999

The properties are set into our component at create time and invocation is now as simple as injecting the component:

@Name("addingAction")
public class AddingAction {
  @In
  private AddingServiceFacade addingService;

  // ... ...

  public void addNumbers() {
    result = addingService.addNumbers(num1, num2);
  }
}

Since this definition changes between development and production we simply maintain properties files specific to each environment aptly named: components-dev.properties and components-prod.properties. A simple ant target (or Maven profile) resolves the appropriate properties file based on environment when creating the archive that is being deployed.

This becomes even more useful when creating integration tests. An additional properties file can be defined that specifically defines the integration testing properties for your automated tests (e.g. components-test.properties). The integration test target can then use this properties file for running automated tests, avoiding any additional setup in the tests, and allowing a full integration test to be run.

So my question, how are you managing your environment-specific configuration with Seam?

UPDATE: This approach will be supported in Seam 2.1 as a feature of seam-gen’d projects as part the profiling functionality. See JBSEAM-3157 to patch your existing seam-gen’d project.