http://www.developer.com/java/ent/article.php/1436981/Introduction-to-EJBs-Part-3.htm
This is the third of four installments that make up Chapter 4: Introduction to EJBs from the book Sams Teach Yourself J2EE in 21 Days (ISBN:0-672-32384-2) written by Martin Bond, Dan Haywood, Debbie Law, Andy Longshaw, and Peter Roxburgh, published by Sams Publishing. You will create specific types of EJB as you progress through the book.
However, the creation of EJBs follows the same steps and principals for all
types of EJB. As you may have gathered from the previous discussion on EJB contents, the
EJB developer must go through the following cycle: Design and define the business interface. This may involve mapping from a
UML model of the solution into Java. Decide on a bean type appropriate to the task in hand. Entity, Session,
and Message-driven beans all have their own pros and cons. If you choose to use
a Session bean, another question is whether to use a stateful Session bean or a
stateless Session bean. Choice of the appropriate type is discussed in more
detail on Days 5, 6, 7, and 10. Decide which home interface methods are appropriate for the bean type and
define the home interface for the EJB. Create (or generate) a "boilerplate" bean with correct
lifecycle methods. Create your business logic by filling out the business
methods. Fill out lifecycle methods to control creation,
destruction and to manage state (if applicable). If your EJB classes are written correctly, all that remains is to wrap them
up as a deployable unit. However, there are certain caveats you should bear in
mind while creating your bean. Due to the managed nature of the bean lifecycle, the EJB container imposes
certain restrictions on the bean including: EJBs cannot perform file I/O. If you need to log messages or access
files, you must find an alternative mechanism. EJBs are not allowed to start threads. All threading is controlled by the
container. EJBs cannot call native methods. EJBs cannot use static member variables. There is no GUI available to an EJB, so it must not attempt to use AWT or
JFC components. An EJB cannot act as a network server, listening for inbound
connections. An EJB should not attempt to create classloaders or change factories for
artifacts, such as sockets. An EJB should not return this from a method. Although not
strictly a restriction (the container will not prevent you from doing it), it is
identified as being a very bad practice. This relates to the earlier discussion
that a bean should not implement its associated remote interface. This would
potentially give a client a direct remote reference to the bean rather than the
EJBObject. Instead, the bean should query its EJB context for a reference to its
associated EJBObject and return that to the caller. For a full list of restrictions, see section 24.1.2 of the EJB 2.0
specification (available online at
http://java.sun.com/products/ejb/docs.html). One alternative definition of a component is "a unit of
deployment." Following this theme, a component should Contain all the information required to deploy it, above and beyond the
classes. This is the metadata discussed earlier. Be bound up in such a way that it can easily be transported and deployed
without losing any parts along the way. Consequently, after the classes and interfaces for an EJB have been created,
the following steps must be performed: Capture the EJB's metadata in a universally understood format. This
takes the form of an XML-based deployment descriptor (DD). Bundle
the classes and deployment descriptor up in a deployable format, namely a JAR
file. The EJB specification defines a standard format of an XML deployment
descriptor document that can house EJB metadata. The exact format of a
deployment descriptor is usually hidden behind tools that manipulate them on
your behalf. However, it is worth examining some of the contents of a deployment
descriptor to see how the EJB fits together and how extra information and
metadata is provided. Listing 4.5 shows the deployment descriptor for the example Agency EJB. The essential parts of the deployment descriptor in Listing 4.5 are The <session> tag delimits the definition of the
Agency EJB and indicates that it is a Session EJB (lines 8 and
31). The <ejb-name> tag defines the name of the EJB, in this
case Agency (line 10). The home and remote interface types (as defined by their fully-qualified
class filenames) are specified by the <home> and
<remote> tags, respectively (lines 1112). The type of the
bean itself is defined by the <ejb-class> tag (line 13). In addition, two other parts are of particular note at this point in
time: An environment entry is defined between lines 16 and 20 by using the
<env-entry> tag. This indicates that a String property
called AgencyName should be made available to the bean. The value of
the property is J2EE in 21 Days Job Agency. The environment defined in
the deployment descriptor is made available through JNDI under the name
java:comp/env. In this case, the agency name can be retrieved by
looking up the name java:comp/env/AgencyName. This lookup can be seen
in the ejbCreate() method of Listing 4.3. An external resource is defined in lines 2530 using the
<resource-ref> tag. This defines that a DataSource
should be made available to this EJB under the name jdbc/Agency. As
with the environment entry for the agency name, this resource is made available
through JNDI under java:comp/env, so the EJB can retrieve the
DataSource by looking up the name java:comp/env/jdbc/Agency.
Again, this lookup can be seen in the ejbCreate() method of Listing
4.3. Note It is important to realize that the name used for a
<resource-ref> is only a logical name. In other words, it is just
a text string used by a component to reference an external resource. In theory,
the resource name used by the EJB to refer to the data source could be anything
(foo, for example) as long as it ties in with the information in the
deployment descriptor. However, by convention, such names are kept in line with
the name you would expect to use under JNDI. As a result, in this example, the
data source resource is referred to by the bean as jdbc/Agency and will
be registered under JNDI with the same name. All of the EJB classes and the deployment descriptor should then be bundled
up in a JAR file. The deployment descriptor should be named
ejb-jar.xml. If there are multiple EJBs packaged in the same JAR file,
the deployment descriptor will have multiple EJB definitions in it. This JAR
file is then termed an EJB-JAR file to denote its payload. The JAR file itself
can be called anything (within reason) and has a .jar file
extension. The EJB-JAR file can also contain any extra resources required by the EJB,
such as application-specific configuration information that does not fit in a
deployment descriptor environment entry. Although the EJB-JAR file is now complete, it must form part of an
application to serve a useful purpose. J2EE defines that enterprise applications
can be built from components (Web, EJB, and application components). The key is
how to define the relationships between the different parts of the
applicationthere must be some way of plugging things together. The answer is that there must be a description of the application itself,
which components it uses, how those components relate to each other, and which
specific resources they use. This is the information provided by the Application
Assembler and Deployer roles. To provide this information to the target J2EE platform, another level of
deployment descriptor is used the J2EE deployment descriptor. The J2EE
deployment descriptor provides the following: A list of the components in the application Security role information Web root information for Web components This information is stored in an XML file called application.xml.
All of the constituent component JAR files (such as EJB-JARs) and the J2EE
deployment descriptor are then bundled up in another JAR file, this time called
an Enterprise Archive (EAR) file, which has a .ear extension. The
contents of the J2EE deployment descriptor will be covered in more detail as you
examine the different parts of the example enterprise application. Is the application now ready to deploy? Unfortunately, the answer is
"Not quite yet." The J2EE deployment descriptor does not cover
information about how to map the application onto a specific J2EE application
server, specifically The JNDI name under which the application server will make the EJB
available. In the case of the Agency bean, this would mean that an
entry was required to map the bean name of Agency to the JNDI name
under which the EJB is registered, for example, ejb/Agency. Information about how the security roles defined map to underlying
security principals (this is covered on Day 15). So, yet another XML-based deployment descriptor is required to contain this
information, this time an application server-specific one. This file contains
extra mapping information, as previously described, and also any other
container-specific information required for a smooth deployment in that
environment. This extra deployment descriptor is also stored in the EAR file,
ready to be accessed when the application is deployed. Note The specific deployment descriptor for the J2EE Reference
Implementation (RI) server is called sun-j2ee-ri.xml. After an EJB is packaged, it can be deployed in an appropriate J2EE server.
There is no limit to the number of times an EJB can be deployed as a part of
different applications. Remember that J2EE defines a separate role for the application deployer. It
may be that for particular installations, databases, or other resource names
need to be changed to match the local environment. When configuring the
application, the deployer can alter this EJB or enterprise application
metadata. When an EJB is deployed into a particular EJB container, the EJB must be
plugged into that container. To do this, an EJBObject must be generated based on
the EJB's remote interface. This EJBObject will be specific to that EJB
container and will contain code that allows it to interface with that container
to access security and transaction information. The container will examine the
metadata supplied with the EJB to determine what type of security and
transaction code is required in the EJBObject. The container will also generate the home interface implementation so that
calls to create, find, and destroy EJB instances are delegated to
container-defined methods. The container will examine the EJB and enterprise application metadata and
hook up resource references. It will also provide an environment for the
application components. Finally, the container will register the home interface of the EJB with JNDI.
This allows other application components to create and find EJBs of this
type. As mentioned previously, when deploying an EJB or enterprise application, the
application developer taking on the J2EE role of deployer can choose to alter
certain of the metadata relating to the configuration of the application.
Although this can be done manually, it is usually done through a GUI tool to
make things easier and to keep things consistent. After the EJB has been deployed, any subsequent changes to its functionality
will mean that the EJB must be re-deployed. If the enterprise application or EJB
is no longer needed, it should be undeployed from the container. Given that EJBs are middle-tier business components, they are of little use
without a client to drive them. As mentioned earlier, those clients can be Web
components, standalone Java clients, or other EJBs. Regardless of the type of client, using an EJB requires the same set of
stepsnamely, discovery, retrieval, use, and disposal. These steps are
covered in the next three sections. To create or find an EJB, the client must call the appropriate method on the
EJB's home interface. Consequently, the first step for the client is to get
hold of a remote reference to the home interface. On Day 3, you looked at naming
services and how these can be used to register information in a distributed
environment. In a J2EE environment, such a naming service is accessible through
JNDI and can be used to store references to EJB home interfaces. The EJB container will have registered the home interface using the JNDI name
specified during deployment (as part of the deployment descriptor). This is the
name that the client should use to look up the home interface. Recall from the
EJB deployment descriptor shown in Listing 4.5 that the EJB name specified was
Agency. When deploying the EJB, the deployer has a chance to set the
JNDI name by which clients will find this EJB. In this case, you would expect
the deployer to simply set a JNDI name of ejb/Agency so that the client
could find the home interface by looking up java:comp/env/ejb/Agency.
The following code shows the initial lookup required: As you can see, because the reference returned from JNDI is just an object,
you must narrow it to the home interface type you expectin this case,
AgencyHome. If there are any problems with the JNDI access or if the
wrong object type is returned, a NamingException or
ClassCastException will be thrown. There is no magic here. The object returned by the JNDI is simply an RMI remote
object stub. This stub represents the home interface remote object created by
the container when the EJB was deployed. This can be seen in Figure 4.2. Now that you have a reference to the home interface, you can create the EJB
you want to use. You can now call the create() method you saw defined on the
AgencyHome interface in Listing 4.4 as follows: The create() method returns a remote reference to the newly-created
EJB. If there are any problems with the EJB creation or the remote connection, a
CreateException or RemoteException will be thrown.
CreateException is defined in the javax.ejb package, and
RemoteException is defined in the java.rmi package, so
remember to import these packages at the top of your client class. Now that you have a reference to an EJB, you can call its methods. The
previous code sample shows the getAgencyName() method being called on
the returned Agency reference. Again, whenever you call a remote method
that is defined in an EJB remote interface, you must be prepared to handle
RemoteExceptions. Note You will see later that some types of EJB are found rather than
created. In this case, all steps are the same except that the create()
method is replaced by the appropriate finder method and find-related exceptions
must be handled. You still end up with a remote reference to an EJB. All of this
is covered later when Entity EJBs are discussed on Day 6. You have now created and used an EJB. What happens now? Well, if you no
longer need the EJB, you can get rid of it in exactly the same way that you
would get rid of a local Java object or a remote Java object defined using
RMIby setting its reference to null as follows: When the local RMI runtime detects that the remote object no longer has any
local references, it will trigger remote garbage collection for that object,
which means that its remote reference will time out. This will result in the
object being de-referenced at the server-side. In the case of the simple
Agency bean (a stateless Session bean), this will cause the bean to be
destroyed. Although it is possible to use the remove() method to get rid of the
EJB, you would not normally use this for such a simple bean. Use of this method
is discussed in more detail on Days 5 and 6. You are now in a position to write a simple application client for the
Agency EJB. After you have written it, you will want to compile and run
it. Before compiling your client, you should ensure that you have
j2ee.jar on your classpath. This JAR file lives in the lib
directory under J2EE_HOME. If you are using an enterprise IDE, you may
find that all the relevant classes are already in your classpath. To compile and run the client, you will need the following: The J2EE classes. These must be accessible through the
classpath. Access to the EJB's home and remote interface class files via the
classpath. RMI stubs for the home and remote interfaces. These can either be
installed on the local classpath or downloaded dynamically from the EJB
server. If the client does not have the JNDI name of the EJB compiled in, you may
want to provide this on the command line or through a system property. When you deploy the EJB, you should be able to ask the container for a client
JAR file. This client JAR file will contain all of the classes and interfaces
needed to compile the client (as defined in the previous bulleted list). You
should add this client JAR file to your classpath when compiling your
client. In theory, this should be it. However, you will find that any form of
security definition on the server will require you to authenticate yourself
before you can run the application. In this case, you must explicitly use the
client container to provide the required security mechanism. Note The client container is called runclient under the J2EE
RI. Andy Longshaw is a consultant, writer and educator specializing in J2EE, XML, Web-based technologies and components, particularly the design and architecture decisions required to use these technologies successfully. Andy has been explaining technology for most of the last decade as a trainer and in conference sessions. A wild rumor suggests that some people have managed to stay awake in these sessions. Despite being well educated and otherwise fairly normal, Andy still subjects himself, and his family, to "trial by unpredictability" by watching Manchester City FC far more often than is healthy. Andy and the other authors work for Content Master Ltd., a technical authoring company in the United Kingdom specializing in the production of training and educational materials. For more information on Content Master, please see their web site at www.contentmaster.com To access the full Table of Contents for the book
Introduction to EJBs: Part 3
July 31, 2002
How Do I Create an EJB?
The Creation Mechanism
Caveats on Code Creation
Create the Deployable Component
The Deployment Descriptor
Listing 4.5 Agency Bean EJB Deployment Descriptor
1: <?xml version="1.0" encoding="UTF-8"?>
2:
3: <!DOCTYPE ejb-jar PUBLIC
'-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN'
'http://java.sun.com/dtd/ejb-jar_2_0.dtd'>
4:
5: <ejb-jar>
6: <display-name>Simple</display-name>
7: <enterprise-beans>
8: <session>
9: <display-name>Agency</display-name>
10: <ejb-name>Agency</ejb-name>
11: <home>agency.AgencyHome</home>
12: <remote>agency.Agency</remote>
13: <ejb-class>agency.AgencyBean</ejb-class>
14: <session-type>Stateless</session-type>
15: <transaction-type>Bean</transaction-type>
16: <env-entry>
17: <env-entry-name>AgencyName</env-entry-name>
18: <env-entry-type>java.lang.String</env-entry-type>
19: <env-entry-value>J2EE in 21 Days Job Agency</env-entry-value>
20: </env-entry>
21: <security-identity>
22: <description></description>
23: <use-caller-identity></use-caller-identity>
24: </security-identity>
25: <resource-ref>
26: <res-ref-name>jdbc/Agency</res-ref-name>
27: <res-type>javax.sql.DataSource</res-type>
28: <res-auth>Container</res-auth>
29: <res-sharing-scope>Shareable</res-sharing-scope>
30: </resource-ref>
31: </session>
32: </enterprise-beans>
33: </ejb-jar>
Enterprise Applications
How Do I Deploy an EJB?
Plugging into the Container
Performing the Deployment
How Do I Use an EJB?
Discovery
try
{
InitialContext ic = new InitialContext();
Object lookup = ic.lookup("java:comp/env/ejb/Agency");
AgencyHome home =
(AgencyHome)PortableRemoteObject.narrow(lookup, AgencyHome.class);
...
}
catch (NamingException ex) { /* Handle it */ }
catch (ClassCastException ex) { /* Handle it */ }
Retrieval and Use
try
{
...
Agency agency = home.create();
System.out.println("Welcome to: " + agency.getAgencyName());
...
}
catch (RemoteException ex) { /* Handle it */ }
catch (CreateException ex) { /* Handle it */ }
Disposing of the EJB
// No longer need the agency EJB instance
agency = null;
Running the Client
Monday's installment: What is an EJB and why use them?
Tuesday's installment: What's in an EJB and how do I create one?
Thursday's installment: Deploying and Using an EJB in the J2EE Reference Implementation
About the Author
Source of this material

This is the first of four installments that make up Chapter 4: Introduction to EJBs from the book Sams Teach Yourself J2EE in 21 Days (ISBN:0-672-32384-2) written by Martin Bond, Dan Haywood, Debbie Law, Andy Longshaw, and Peter Roxburgh, published by Sams Publishing.