Using enterprise JavaBeans with remote interfaces on Liberty
You can remotely access Enterprise Java™ Bean (EJB) methods with remote interfaces when
the EJB is hosted by another Java virtual machine (JVM) or another application within the same JVM.
WebSphere® Application Server implements remote EJB interfaces by using RMI-IIOP technologies. You
can enable remote EJB support with the
About this task
To configure a Liberty server to run an
application with remote EJB support enabled, you must set the
When you use remote EJB interfaces, review the following considerations:
- Using the
The EJB specification requires that remote interfaces are bound to the
java:namespace, which is available to the application server and the application client container, as shown in the following example:
java:global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface java:app/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface java:module/ExampleBean!com.ibm.example.ExampleRemoteInterface
In version 220.127.116.11 and later, EJB components are bound to both the default and the
ejblocal:Java Naming and Directory Interface (JNDI) namespaces, as in WebSphere® Application Server traditional. In these versions, for EJB components that are hosted within the same server,
@EJBlookups and bindings in
ibm-*-bnd.xml/xmifiles can use either the
java:namespace or the heritage namespaces from WebSphere Application Server traditional. For EJB components that are hosted in another server, lookups and bindings can use
corbanameURLs. Before version 18.104.22.168, EJB components are not bound to the default JNDI namespace and must use the
java:names for EJB components that are hosted within the same server.
Interfaces are also bound to the ORB CosNaming name service in similar contexts to those interfaces used in the
java:globalnamespace. These interfaces can be accessed through JNDI by using
corbanameURLs; for example:
On the server, the
rir:form of the URL uses the local name service. On the client, it uses the default or configured remote name service.
According to the Object Management Group (OMG) Naming Service specification, some characters in
corbanameURLs must be escaped. Liberty tries to determine whether a
corbanameURL that is derived from the
java:globalnamespace needs to be escaped, and then escapes it automatically. It is not possible to do the escape in all cases. For example, if a name contains a single dot (.), and has no invalid characters, it cannot be escaped automatically. To force a name to be interpreted in a particular way, it is necessary to escape the URL manually as described in the OMG Naming Service specification.Consider the following
java:globalname for an enterprise bean:
The simple form of the
corbanameURL cannot be escaped automatically because it represents a different, but valid location. Therefore, the following URL does not work as expected:
Instead, this URL must be manually escaped as follows:
corbaname:rir:#ejb/global/TestApp/TestModule/TestBean!test%5c.TestRemoteInterfaceNot all client and application server implementations support the use of
%5cin a JNDI name to represent an escape character. For these implementations, including WebSphere Application Server traditional, the backslash (
\) character can be used directly. Because a backslash must be escaped in a Java String, the URL can be manually escaped as shown in the following example:
The syntax for escaping
corbanameURLs is described fully in OMG Naming Service specification.
- Using JNDI names programmatically
All of the URLs and JNDI names in these examples can be looked up programmatically from an
InitialContext. When you look up a
java:name, the resulting object can be cast directly to the expected type; for example:
However, when you retrieve objects by using
Object found = new InitialContext().lookup("java:global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface"); ExampleRemoteInterface bean = (ExampleRemoteInterface) found;
corbanameURLs, the RMI style of casting, called narrowing, must be used; for example:
Object found = new InitialContext().lookup("corbaname:rir:#ejb/global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface"); ExampleRemoteInterface bean = (ExampleRemoteInterface)PortableRemoteObject.narrow(found, ExampleRemoteInterface.class);If the same context is used to look up multiple enterprise beans from the same remote server, then the
corbalocvalue can be used when you create the
InitialContextclass, as shown in the following example:
Properties p = new Properties(); p.put(Context.PROVIDER_URL, "corbaloc::test.ibm.com:2809"); InitialContext c = new InitialContext(p); Object found = c.lookup("ejb/global/ExampleApp/ExampleModule/ExampleBean!com.ibm.example.ExampleRemoteInterface"); ExampleRemoteInterface bean = (ExampleRemoteInterface)PortableRemoteObject.narrow(found, ExampleRemoteInterface.class);
- Using the
- Any product that supports the IIOP protocol can call enterprise beans that use the EJB 2.x
remote programming model with
EJBObjectwhen it is packaged in an EJB JAR module with a version 2.0 deployment descriptor. The WLP_INSTALL_DIR/clients/ejbRemotePortable.jar file must be included on the class path of the remote client. This file contains system value classes that are required for communication with a Liberty server. This file is not required when you remotely access EJB components from the WebSphere Application Server Liberty or WebSphere Application Server traditional. EJB components that use the EJB 3 remote programming model on Liberty can be remotely accessed by WebSphere Application Server processes. Liberty does not provide a thin client to start EJB components from a stand-alone Java process. Liberty does not provide workload management or failover capabilities for remote EJB components, including when you start EJB components that are hosted from WebSphere Application Server traditional.
- Stub classes
- A client must include stub classes when you start a remote EJB that is hosted on an WebSphere
Application Server. In some cases, if the client is WebSphere Application Server, the product
automatically generates the correct stub classes:
- If a client application starts a remote EJB that is contained within the same application, Liberty automatically generates stub classes.
- If the target EJB is running in a separate application and is using the EJB 2.x remote
programming model with
EJBObject, then the client must include stub classes on its classpath. If the EJB is hosted on WebSphere Application Server traditional, you can copy the EJB client JAR from the application from the EAR after it is processed by the ejbdeploy command. If the EJB is hosted on Liberty, you must use the rmic program that is included with your Java SDK to generate the stub classes for the target EJB, and then you must include the stub classes with the client.
- If the target EJB is running in a separate application and is using the EJB 3 remote programming model, then the client Liberty or WebSphere Application Server traditional process automatically generates stub classes. EJB components that use the EJB 3 remote programming model on Liberty can be remotely accessed by WebSphere Application Server or WebSphere Application Client processes only.
- Transaction propagation
- Liberty does not support outbound or
inbound transaction propagation. Additionally, the EJB specification requires that, even if a
product supports outbound transaction propagation, it must still send a null transaction context.
This context must be rejected by EJB components that use the
Supportstransaction attributes. A client with an active global transaction cannot start an EJB with default transaction attributes if either the client or server is in Liberty. The client can start the EJB if the EJB is changed to use the
NotSupportedtransaction attributes. However, the transactional work that is done by the EJB is not committed as part of the transactions of the client.
- Asynchronous methods
- An EJB remote interface can have an asynchronous method with a return value of type
Future. The server will return a Future object to the client, which is used to retrieve the value. Remote asynchronous methods are not recommended because accumulation of unclaimed results can exhaust memory. To mitigate this problem, the server results expire if the client does not retrieve the result within 24 hours or if the maximum number of unclaimed results exceeds 1000. These values can be adjusted in the server.xml file; for example:
<ejbContainer> <async maxUnclaimedRemoteResults="10"unclaimedRemoteResultTimeout="10m"/> </ejbContainer>
To enable this feature, update the server.xml file to add the
ejbRemote-3.2feature; for example:
<featureManager> <feature>ejbRemote-3.2</feature> </featureManager>
Configure your application binding files, ibm-*-bnd.xml files, for remote
EJB references that have been defined either in the deployment descriptor
<ejb-ref>or with source code annotations,
@EJB.A binding is not required for EJB references that provide a lookup name, either on the annotation or in the deployment descriptor. In the binding file, the EJB reference can be bound using one of the
java:names for an EJB or with one of the
corbaname:names; for example:For an EJB reference:
The binding is defined:
@EJB(name="TestBean") TestRemoteInterface testBean;
<ejb-ref name="TestBean" binding-name="corbaname:rir:#ejb/global/TestApp/TestModule/TestBean!test\\.TestRemoteInterface"/>
- Configure your application client to include stub classes.
- (Optional) Configure interoperability for applications that support the IIOP protocol to use EJB remote interfaces by adding the WLP_INSTALL_DIR/clients/ejbRemotePortable.jar file on the class path of the remote client.