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.