unit-testingmavenejb-3.1glassfish-embedded

How to filter (substitute) env-entry values in ebj-jar.xml for unit tests with embedded enterprise bean container (GlassFish)?


I need several profiles for deployment. In the Maven POM I have defined a profile "dev" and a property "theHost" (as localhost):

<profiles>
  <profile>
    <id>dev</id>
    <activation>
      <activeByDefault>true</activeByDefault> <!-- use dev profile by default -->
    </activation>
    <build>
    </build>
    <properties>
      <theHost>localhost</theHost>
    </properties>
  </profile>
...

I have activated filterDeploymentDescriptor on the maven-ejb-plugin in order to tell it to filter (substitute) values in ejb-jar.xml:

<plugins>
  <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-ejb-plugin</artifactId>
    <version>2.3</version>
    <configuration>
      <ejbVersion>3.1</ejbVersion>
-->   <filterDeploymentDescriptor>true</filterDeploymentDescriptor>
    </configuration>
</plugin

Finally, in ejb-jar.xml I refer to ${theHost} to obtain the desired profile-specific value for the @Resource attribute "host":

<session>
  <ejb-name>MongoDao</ejb-name>
  <ejb-class>com.coolcorp.MongoDao</ejb-class>
  <session-type>Stateless</session-type>
  <env-entry>
    <env-entry-name>host</env-entry-name>
    <env-entry-type>java.lang.String</env-entry-type>
    <env-entry-value>${theHost}</env-entry-value>
  </env-entry>
...

This all works great with a regular Maven build. But when I run an EJB unit test using the Embedded Enterprise Bean Container of GlassFish [EJBContainer.createEJBContainer()], the maven-ejb-plugin seems to ignore filterDeploymentDescriptor=true. The EJB sees "${theHost}" instead of "localhost" although I run maven with the same "dev" profile.

mvn.bat -Pdev test

Does anybody have an idea why the substitution does not work when running a unit test? Is there something more I have to define especially for the unit test so that filtering of ejb-jar.xml occurs? Or a better approach to unit testing EJBs if different profiles exist?


Solution

  • Ideally, you would be able to specify an external "binding" for the env-entry. I know that's possible to do with WebSphere Application Server (via EnvEntry.Value properties), but I don't know if it's possible with Glassfish.

    As a workaround, you could declare the env-entry for injection, and then check in PostConstruct whether any value was injected by the container (i.e., don't specify env-entry-value until you're deploying into the server). If you're using JNDI only, you can do the same thing with try/catch(NameNotFoundException).

    @Resource(name="host")
    private String host;
    
    @PostConstruct
    public void postConstruct() {
      if (host == null) {
        // Not configured at deployment time.
        host = System.getProperty("test.host");
      }
    }