JBoss.org Community Documentation
EJB3 beans may reference EJB2.1 and vice versa. This tutorial demonstrates mechanisms for such references.
To start, take a look at the EJB3 SLSB org.jboss.tutorial.reference21_30.bean.Stateless3Bean
,
the EJB2.1 SLSB org.jboss.tutorial.reference21_30.bean.Stateless2Bean
and the deployment descriptors for the EJB2.1 SLSB ejb21_app/src/main/resources/META-INF/ejb-jar.xml
and
ejb21_app/src/main/resources/META-INF/jboss.xml
:
<session> <ejb-name>ejb/Stateless2</ejb-name> <home>org.jboss.tutorial.reference21_30.bean.Stateless2Home</home> <remote>org.jboss.tutorial.reference21_30.bean.Stateless2</remote> <ejb-class>org.jboss.tutorial.reference21_30.bean.Stateless2Bean</ejb-class> <session-type>Stateless</session-type> <transaction-type>Container</transaction-type> <ejb-ref> <ejb-ref-name>ejb/Stateless3</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> <home>org.jboss.tutorial.reference21_30.bean.Stateless3Home</home> <remote>org.jboss.tutorial.reference21_30.bean.Stateless3</remote> </ejb-ref> </session>
Notice, the ejb-jar.xml use a 2.x dtd for this EJB2.x application:
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
The ejb-ref
element references the 3.0 EJB. This mapping will make available the Stateless3
bean
in the ENC (java:comp/env) namespace of the Stateless2
EJB.
Observe carefully, the use of <home>
and <remote>
in the ejb-ref
.
Remember that we can provide a EJB2.1 view for an EJB3 bean. See the "ejb21_client_adaptors" for more details. We have intentionally
exposed the home and remote view for the EJB3 Stateless3Bean so that it can be referenced by a EJB2.1 bean, without which the EJB2.1
bean would not have been able to reference this bean through its local ENC (because the home/remote are mandatory for a ejb-ref for EJB2.1 app)
@Stateless @RemoteHome(Stateless3Home.class) public class Stateless3Bean { ...
public interface Stateless3Home extends EJBHome { public Stateless3Remote create() throws java.rmi.RemoteException, javax.ejb.CreateException; ...
Two mechanisms for referencing EJB2.1 from a EJB3 are demonstrated. The first mechanism uses annotations exclusively.
Note the @EJBs
annotation on org.jboss.tutorial.reference21_30.bean.Stateless3Bean
.
The name
parameter for the @EJB
specifies the name with which the 2.1 EJB will be bound
in the ENC (java:comp/env) namespace of the Stateless3Bean
. The mapped-name
parameter
specifies the global JNDI binding of the 2.1 EJB.
@EJBs( {@EJB(name = "injected/Stateless2", mappedName = "Stateless2")}) public class Stateless3Bean { ...
The testAccess
method in the Stateless3Bean
looks up this EJB2.1 using the
ENC jndi-name:
Stateless2Home home = (Stateless2Home) jndiContext.lookup(Container.ENC_CTX_NAME + "/env/injected/Stateless2"); Stateless2 test2 = home.create();
Also note that since the bean being looked up is a EJB2.1 bean, the lookup will return the home interface of the bean.
The second mechanism of referencing a EJB2.1 bean in a EJB3 bean is through the deployment descriptors. Take a look at the
ejb3_app/src/main/resources/META-INF/ejb-jar.xml
and ejb3_app/src/main/resources/META-INF/jboss.xml
<session> <ejb-name>Stateless3Bean</ejb-name> <ejb-ref> <ejb-ref-name>ejb/Stateless2</ejb-ref-name> <ejb-ref-type>Session</ejb-ref-type> </ejb-ref> </session>
The ejb-jar.xml should use the ejb-jar 3.0 xsd:
<ejb-jar xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/ejb-jar_3_0.xsd" version="3.0">
This binds the Stateless2 bean to the ENC (java:comp/env) namespace of the Stateless3Bean. Also take a look at the
ejb3_app/src/main/resources/META-INF/jboss.xml
which maps the global jndi name of the Stateless2
bean with the ejb-ref-name.
<session> <ejb-name>Stateless3Bean</ejb-name> <ejb-ref> <ejb-ref-name>ejb/Stateless2</ejb-ref-name> <jndi-name>Stateless2</jndi-name> </ejb-ref> </session>
This reference is then used to inject the Stateless2 bean in the Stateless3Bean using @EJB
annotation:
@EJB (name="ejb/Stateless2") private Stateless2Home stateless2Home;
org.jboss.tutorial.reference21_30.bean.Stateless3Bean
also exposes a business-remote interface, so
that the org.jboss.tutorial.reference21_30.servlet.EJBReferenceServlet
can use the business-remote interface.
@Stateless @Remote(Stateless3.class) @RemoteBinding(jndiBinding = "Stateless3") public class Stateless3Bean { ...
There's a very important difference between the remote
and a business-remote
interface. The EJB2.x remote interfaces, which extend from EJBObject, are referred through the <remote>
tag in the ejb-jar.xml. On the other hand, the EJB3 style Plain Old Java Interface which is implemented by your EJB3 style
POJO bean is known as the business-remote interface and is represented by the @Remote
and it's
corresponding <business-remote>
tag in ejb-jar.xml.
Similar is the case with <local>
and the <business-local>
tags in ejb-jar.xml.
To build and run the example, make sure you have installed JBoss 5.x. See the Section 1.1, “JBoss Application Server 5.x” for details.
From the command prompt, move to the "reference21_30" folder under the Section 1.3, “Set the EJB3_TUTORIAL_HOME”
Make sure your JBossAS-5.x is running
$ ant
This will deploy the ear into the JBossAS-5.x server ("default" configuration).
Test
button to check that the EJB2.1 and EJB3 beans are referencing
each other.
$ mvn clean install -PRunSingleTutorial
This will create the EAR in the target
folder of the tutorial. Copy this EAR to the deploy folder of JBossAS-5.x
and start the server (if it's already not started). Then follow the steps mentioned above, to access the servlet from the web browser.