Sunday, 26 September 2010

References to EJBs Outside Your Application With Oracle WebLogic

Table of Contents


In the previous posts we made an overview of the EJB v. 3.0 and of the portable mechanisms it provides you to build your Java EE application. Since Java EE specifications are all about portability, at the risk of repeating ourselves we've often stressed the most important portability limit still present on the EJB v. 3.0 specifications: there is no portable way to declare and link a reference to an EJB outside your application.

Although there exist other standards (such as Web Services) that let you loosely couple components of your applications, remote EJBs are still an ideal mean to accomplish this task because of their simplicity, their standardization, the good development support of many IDEs and the good performance they provide.

In this blog post we'll make an overview of the mechanisms provided by one of the leading Java EE application servers, Oracle WebLogic, to give support to references to EJBs outside the scope of your application.

mappedName in Oracle WebLogic

Java EE compliant application servers provide additional non-portable API, tools and mechanisms used to enhance the standard Java EE features they implement. One of the features we've mentioned in the first part of this series was the mappedName @EJB element.

Although the EJB v. 3.0 Specification is willingly unclear about this element (that was sort of replaced by the lookup element introduced by the EJB v. 3.1 Specification), many application server vendors have implemented it with the intuitive behavior suggested by its own name: mapping an EJB to a global JNDI name.

If you want to trade portability for simplicity, many application servers (such as Oracle WebLogic or GlassFish) will let you define a bean's global JNDI name with the value of the mappedName element (or its corresponding deployment descriptor element.) As already stated, beware that Oracle WebLogic will assign global JNDI names to remote business interfaces only. This isn't really a limitation since local business interfaces can always be referenced using the APIs described in the previous parts of this series.

Oracle WebLogic Naming Conventions for EJB Remote Business Interfaces

With such a mechanism in place, linking a reference to a bean outside your application is straightforward. JDeveloper's EJB wizard, indeed, will put a default mappedName for you with an intuitive naming scheme that resembles somehow the new portable global JNDI names introduced by the EJB v. 3.1 specification, as shown in the following screenshot:


The naming scheme suggested by JDeveloper is the following:

mappedName = [application-name]-[module-name]-[bean-name]

If adopted, this naming scheme provides an easy way to assign every bean an unique name throughout your applications. I recognize that such names are a bit awkward but, being non-portable, is a naming scheme as good as any other.

Global JNDI Names for Remote EJB Interfaces in Oracle WebLogic

The global JNDI names of the remote business interfaces of an EJB with a mappedName in Oracle WebLogic Application Server will be:

mappedName#[interface-FQN]

Using this naming scheme will allow you to build loosely coupled Java EE application that reuse each other EJBs. If you want to inspect your server JNDI tree and check the actual names of your deployed EJB, you can use WebLogic's JNDI Tree inspector, which can be launched opening the WebLogic console, navigating to the Environment/Servers/[your-server] page and using the View JNDI Tree link. In the following screenshot you can examine the global JNDI entry for a bean defined as follows:

package es.reacts;

import ...;

@Stateless(name = "EJBByMappedName", mappedName = "Application1-EjbTest0-EJBByMappedName")
@Remote
public class EJBByMappedNameBean implements RemoteByMappedName {
  [...]
}


In the screenshot you can appreciate the entry corresponding to the es.reacts.RemoteByMappedName business interface.

Customizing the JNDI Name of an EJB Remote Interface

Oracle WebLogic provides you the necessary tools to customize and override its default naming conventions for EJB remote interfaces. To assign or override the global JNDI name of an EJB remote interface you can use the WebLogic specific deployment descriptors. In the case of an EJB module, for example, you can use JDeveloper to quickly add a default weblogic-ejb-jar.xml or, if using another IDE such as NetBeans, you can create a new XML file named weblogic-ejb-jar.xml in the META-INF directory of your module. An empty weblogic-ejb-jar.xml file looks like this (as of Oracle WebLogic 10.3):

<?xml version = '1.0' encoding = 'UTF-8'?>
<weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd"
  xmlns="http://www.bea.com/ns/weblogic/weblogic-ejb-jar">
</weblogic-ejb-jar>

To assign or override a global JNDI name for a given EJB remote interface you can use the following elements:

<?xml version = '1.0' encoding = 'UTF-8'?>
<weblogic-ejb-jar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-ejb-jar http://www.bea.com/ns/weblogic/weblogic-ejb-jar/1.0/weblogic-ejb-jar.xsd"
  xmlns="http://www.bea.com/ns/weblogic/weblogic-ejb-jar">
  <weblogic-enterprise-bean>
    <ejb-name>SessionTest0</ejb-name>
    <stateless-session-descriptor>
      <business-interface-jndi-name-map>
        <business-remote>es.reacts.SessionTest0</business-remote>
        <jndi-name>global-jndi-name</jndi-name>
      </business-interface-jndi-name-map>
    </stateless-session-descriptor>
  </weblogic-enterprise-bean>
</weblogic-ejb-jar>

If you're using JDeveloper, it provides you an easy GUI to edit the weblogic-ejb-jar.xml file:


The JDeveloper GUI will let you easily customize the WebLogic deployment descriptor and configure other non-portable features of the WebLogic Application Server such as EJB clustering.

Linking an EJB Reference to a Global JNDI Name

In the previous section we made an overview of the tools that Oracle WebLogic Application Server provides to customize the execution environment and establish a global JNDI name for a remote interface of an EJB. In the same way, Oracle WebLogic provides you other tools to link an EJB reference to a specific target EJB using a global JNDI name.

In the examples seen so far, we've always linked an EJB reference to a target using the portable mechanisms provided by the EJB v. 3.0 Specification. If you need to establish a target to a remote EJB outside the scope of your application, you can use the WebLogic-specific deployment descriptor of the module that acts as the EJB client. In the case of the Java EE module we've used so far, you can use JDeveloper to add the WebLogic-specific deployment descriptor called weblogic.xml. If you're using other IDEs, the skeleton of this file is the following (as of Oracle WebLogic 10.3):

<?xml version = '1.0' encoding = 'UTF-8'?>
<weblogic-web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.bea.com/ns/weblogic/weblogic-web-app http://www.bea.com/ns/weblogic/weblogic-web-app/1.0/weblogic-web-app.xsd"
  xmlns="http://www.bea.com/ns/weblogic/weblogic-web-app">
  <ejb-reference-description>
    <ejb-ref-name>ejb/myGlobalRef</ejb-ref-name>
    <jndi-name>global-jndi-name</jndi-name>
  </ejb-reference-description>
</weblogic-web-app>

This weblogic.xml deployment descriptor links the EJB reference ejb/myGlobalRef with the object stored with the global JNDI name global-jndi-name, that is the name we've specified in the weblogic-ejb-jar.xml file described in the previous section. This reference will be declared as usual with a @EJB annotation or in the standard deployment descriptor (in this case, the web.xml file).

If you're using JDeveloper, a GUI will help you build the WebLogic-specific deployment descriptor. The GUI is well done and is also able to scan you module's EJB references and let them choose from a list when customizing them.

Next Steps

In this part we've learnt how to use WebLogic-specific tools in the case we had to link an EJB reference to an EJB that lives outsides our application using a global JNDI name. In the following part (coming soon) we'll see how the EJB v. 3.1 Specification has (finally) filled this gap defining portable JNDI names. With EJB v. 3.1 you'll be able to build modular Java EE application that reuse components of one another without the need to rely on non-portable mechanisms any longer.







No comments:

Post a Comment