Thursday 31 March 2011

Portable Global JNDI Names and Maven

With the advent of the EJB 3.1 specification, the JNDI names for session beans have become portable via the java:global namespace.

As described on the Glassfish EJB FAQ page (http://glassfish.java.net/javaee5/ejb/EJB_FAQ.html#What_is_the_syntax_for_portable_global_) the syntax for the global namespace is:

java:global[/<app-name>]/<module-name>/<bean-name>

where the app-name is the ear name (if the app is deployed as an ear), the module-name the ejb jar or war name and the bean-name the session bean name. Note that names are unqualified and minus the extension.

Given the syntax an example of using the portable JNDI name using the @EJB annotation would be:

@EJB(lookup=
    "java:global/customer-ear/customer-1-0-0/CustomerServiceBean")

The JNDI name may now be portable but the above code would not be reusable if the customer jar name changed. It is quite often the case that jars will have versions in their name eg customer-1-0-0.jar and you would not want to change your code everytime there was a new release of the customer jar so you need to change the module name in the lookup.

One option would be to rename the jar when building the ear file so the module name defaults to the jar name. To do this in Maven would be to explicitly add the ejbModule to the ear plugin as shown below. The name of the jar is what is specified in the bundleFileName tag.

    <plugin>
        <artifactId>maven-ear-plugin</artifactId>
        <version>2.4</version>
        <configuration>
            <generateApplicationXml>true</generateApplicationXml>
            <archive>
                <manifest>
                    <addClasspath>true</addClasspath>
                </manifest>
            </archive>
            <version>6</version>
            <defaultLibBundleDir>lib</defaultLibBundleDir>
            <earSourceDirectory>resources</earSourceDirectory>
            <modules>
                <ejbModule>
                    <groupId>com.mybank.customer</groupId>
                    <artifactId>customer-server</artifactId>
                    <bundleFileName>customer.jar</bundleFileName>
                </ejbModule>
            </modules>
        </configuration>
    </plugin>


The lookup would then be as below:

@EJB(lookup=
    "java:global/customer-ear/customer/CustomerServiceBean")

This means the code containing the injection point doesn't have to change with the names of the jars.

No comments:

Post a Comment

Note: only a member of this blog may post a comment.