
Mastering Enterprise JavaBeans™ and the Java 2 Platform, Enterprise Edition - Roman E
..pdf
The Basics of Stateful Session Beans 127
/*
* Sleep for 1/2 second */
Thread.sleep(500);
}
/*
* Done with EJB Objects, so remove them */
for (int i=0; i < 3; i++) { count[i].remove();
}
} catch (Exception e) { e.printStackTrace();
}
}
}
Source 5.4 CountClient.java (continued).
Running the Client
To run the client, you need to know the parameters your JNDI service provider uses. This should also be part of your container’s documentation. With the BEA WebLogic server, we typed the following:
java -Djava.naming.factory.initial=
weblogic.jndi.TengahInitialContextFactory
-Djava.naming.provider.url=
t3://localhost:7001
com.wiley.compBooks.roman.session.count.CountClient
The Client-Side Output
After running the client, we see the following output:
Instantiating beans...
1
2
3
Calling count() on beans...
2
3
4
We first created three beans and then called count() on each. As expected, the beans incremented their values by one each during the second pass, so output
Go back to the first page for a quick link to buy this book online!

128 M A S T E R I N G E N T E R P R I S E J A V A B E A N S
is as expected. But were our beans really passivated and activated? Let’s check the server log.
The Server-Side Output
The container log yields the following results:
ejbCreate()
count()
ejbCreate()
count()
ejbCreate()
ejbPassivate()
count()
ejbPassivate()
ejbActivate()
count()
ejbPassivate()
ejbActivate()
count()
ejbPassivate()
ejbActivate()
count()
ejbPassivate()
ejbActivate()
ejbRemove()
ejbActivate()
ejbRemove()
ejbRemove()
As you can see from the passivation/activation messages in the log, the container is indeed passivating and activating beans to conserve system resources. Because the client-side output is correct, each of our beans’ conversational state was retained properly.
Stateful or Stateless?
Now that we’ve gone through a few examples, you may be wondering when stateful beans should be used and when stateless beans can get the job done. There are advantages and drawbacks to both stateless and stateful design.
Myths and Facts about Statelessness
Lately, there’s been a lot of fuss over statelessness. The limitations of statelessness are often exaggerated, as well as its benefits. Many statelessness proponents blindly declare that statelessness leads to increased scalability, while
Go back to the first page for a quick link to buy this book online!

The Basics of Stateful Session Beans 129
EJB Design Strategies
What If My Stateful Bean Dies?
Bean failure is an important factor to consider. Because a stateful session bean caches a client conversation in memory, a bean failure may entail losing your conversation. This was not a problem with statelessness—there was no conversation to be lost. Unless you are using an EJB product that routinely checkpoints (i.e., persists) your conversations, your conversations will be lost if an application server fails.
Losing a conversation has devastating impacts. If you have very large conversations that span over time, then you’ve lost important work. And the more stateful session beans that you use in tandem, the larger the existing network of interconnected objects that each rely on the other’s stability. This means that if your code is not prepared for a failure, you may have a very grim situation on your hands. Not an exciting prospect for mission-critical computing, is it?
When designing your stateful beans, you should use the following guidelines:
1.Make sure your problem lends itself to a stateful conversation.
2.Keep your conversations short.
3.If the performance is feasible, consider using an EJB product that checkpoints stateful conversations, to minimize the impacts of bean failure (unfortunately, if you’re selling beans, you may not have the luxury of choosing an EJB server).
4.Write “smart” client code that anticipates a bean failure and reestablishes the conversational state with a fresh stateful session bean.
stateful backers argue about having to rearchitect entire systems to accommodate statelessness. What’s the real story?
Designed right, statelessness has two virtues:
■■With stateless beans, the EJB container is able to easily pool and reuse beans, allowing a few beans to service many clients. While the same paradigm applies to stateful beans, the bean state must be passivated and activated between method calls, possibly resulting in I/O bottlenecks. So one practical virtue of statelessness is the ability to easily pool and reuse components at little or no overhead.
■■Because a stateful session bean caches a client conversation in memory, a bean failure may entail losing your conversation. This can have severe reprecussions if you don’t write your beans with this in mind or if you don’t use an EJB product that provides stateful recovery.
The largest drawback to statelessness is that you need to push client-specific data into the stateless bean for each method invocation. Most stateless session
Go back to the first page for a quick link to buy this book online!

130 M A S T E R I N G E N T E R P R I S E J A V A B E A N S
beans will need to receive some information that is specific to a certain client, such as a bank account number for a banking bean. This information must be resupplied to stateless beans each time a client request arrives because the bean cannot hold any state on behalf of a particular client.
One way to supply the bean with client-specific data is to pass the data as parameters into the bean’s methods. This can lead to performance degradation, however, especially if the data being passed is large. This also clogs the network, reducing available bandwidth for other processes.
Another way to get client-specific data to a stateless bean is for the bean to store data persistently on behalf of a client. The client then does not need to pass the entire state in a method invocation, but simply needs to supply an identifier to retrieve the data from persistent storage. The trade-off here is, again, perfor- mance—storing conversations persistently could lead to storage I/O bottlenecks, rather than network I/O bottlenecks.
Yet another way to work around the limitations of statelessness is for a bean to store client-specific data in a directory structure using JNDI. The client could later pass the bean an identifier for locating the data in the directory structure. This is quite similar to storing data in a database. The big difference is that a JNDI implementation could be an in-memory implementation (this would give a similar effect to a shared property manager, familiar to MTS/COM+ readers). If client data is stored in memory, there is no database hit.
When choosing between stateful and stateless, you should ask yourself what type of business process your session beans are attempting to emulate. Does the business process span multiple invocations, requiring a conversation? If so, the stateful model fits very nicely because client-specific conversations can be part of the bean state. On the other hand, if your business process lasts for a single method call, the stateless paradigm will better suit your needs.
In reality, most sophisticated deployments are likely to have a complex and interesting combination of stateless and stateful beans. The choice between stateful or stateless may also pale in comparison to other factors in your EJB deployment, such as proper use of transactions. We’ll find out how to appropriately use transactions in Chapter 10.
Summary
In this chapter, we learned how to program with stateful session beans. We began with a look at the concepts behind stateful session beans and how they are different from stateless session beans. We then coded up a simple counting program
Go back to the first page for a quick link to buy this book online!

The Basics of Stateful Session Beans 131
that illustrated stateful session bean programming. We wrapped up with a comparison of the stateful and stateless models.
In the next chapter, we’ll take our session bean knowledge and probe deeper. We’ll show how to use EJB session contexts, how properties files are used in EJB, and how beans can call other beans. We’ve just skimmed the surface of EJB programming—there are many interesting concepts ahead.
Go back to the first page for a quick link to buy this book online!

C H A P T E R6
Adding Functionality to Your Beans
n Chapters 3–5, we scratched the surface of EJB with an introduction to ses- Ision bean programming. Now that you’ve seen the bare-bones examples, let’s
put a bit more meat on our beans. In this chapter, you’ll see the following:
■■How to query the container with EJB contexts
■■How to use environment properties to customize your beans, and access those environment properties at runtime
■■How to use the EJB security model
■■How to use EJB object handles
■■How to call beans from other beans
■■A non-trivial example illustrating each of these concepts, using both stateless and stateful session beans
Let’s begin with a look at EJB contexts.
EJB Contexts: Your Gateway to the Container
As you’ll see once you begin your EJB development, non-trivial enterprise beans need to determine information about their current status at runtime. This can include the following:
■■Information about the bean’s home object or EJB object.
■■Information about any transaction the bean is currently involved in. For example, if the current transaction is going to fail, the bean can skip unnecessary computation steps.
133
Go back to the first page for a quick link to buy this book online!

134 M A S T E R I N G E N T E R P R I S E J A V A B E A N S
■■Security information for client authorization. A bean can query its environment to determine if a client has the required security access level to perform a desired operation.
■■Environment properties that the bean was deployed with.
The container houses all of this information in one object, called an EJB context object. An EJB context object is your gateway to the container. EJB contexts are physical parts containers, and can be accessed from within your beans. Thus, a context represents a way for beans to perform callbacks to the container. These callbacks help beans both ascertain their current status and modify their current status.
The motivation behind a context is to encapsulate the bean’s domain in one compact object. Note that a bean’s status may change over the bean’s life cycle, and thus this context object can dynamically change over time as well. At runtime, the container is responsible for changing the context to reflect any status changes, such as the bean becoming involved in a new transaction. Thus, you can think of the context as a middleman for storing status information about a bean—a middleman that is part of the container and is queried by the bean.
Here is what the EJB 1.0 javax.ejb.EJBContext interface looks like:
public interface javax.ejb.EJBContext
{
public javax.ejb.EJBHome getEJBHome(); public java.util.Properties getEnvironment();
public java.security.Identity getCallerIdentity(); public boolean isCallerInRole(java.security.Identity); public javax.jts.UserTransaction getUserTransaction(); public void setRollbackOnly();
public boolean getRollbackOnly();
}
We summarize the methods in javax.ejb.EJBContext in Table 6.1.
Session Bean Contexts
An EJB context contains callbacks useful for both session beans and entity beans. In comparison, a session context is a specific EJB context used only for session beans. Entity beans have their own EJB context, too, called an entity context. Both session and entity contexts define extra methods specific to the corresponding kind of bean.
Go back to the first page for a quick link to buy this book online!

|
Adding Functionality to Your Beans |
|
|
135 |
Table 6.1 javax.ejb.EJBContext |
|
|||
|
|
|
||
METHOD |
DESCRI PTION |
|
||
getHome() |
Your bean should call getHome() when it needs to access its own |
|||
|
home object. The bean can then use its home object to create, |
|
||
|
destroy, or find EJB objects. |
|
||
getEnivronment() |
Returns a list of environment properties that were deployed with |
|||
|
the bean. These properties can be used to set arbitrary information |
|||
|
that a bean may need, such as locations of files. |
|
||
getCallerIdentity() |
Returns the security identity of the client that is invoking methods |
|||
|
on the bean instance’s EJB object. You can use the client’s identity |
|||
|
for many things. For example, you can retrieve the caller’s |
|
||
|
distinguished name, and use it as a key to unlock secured |
|
||
|
information in a database. |
|
||
isCallerInRole() |
Returns whether the authenticated client is authorized to perform |
|||
|
an operation. The client must be in the correct security role, which |
|||
|
is a group authorized to perform certain operations. |
|
||
setRollbackOnly() |
Allows the instance to mark the current transaction such that the |
|||
|
only outcome of the transaction is a rollback. |
|
||
getRollbackOnly() |
Returns a boolean indicating whether the current transaction has |
|||
|
been marked for rollback. If it’s going to abort, you may be able to |
|||
|
bypass logic in your bean, saving valuable computation time. |
|
getUserTransaction()
Note: This method is only supported for beans that perform their own transactions. We’ll learn more about this method in Chapter 10.
Use this method if you want to write code in your bean to control transactions. Once you call this method, your bean can control transactions using the returned javax.transaction.UserTransaction object. You can then begin, commit, and rollback transactions explicitly.
Here is what the session context interface looks like:
public interface javax.ejb.SessionContext extends javax.ejb.EJBContext
{
public javax.ejb.EJBObject getEJBObject();
}
Go back to the first page for a quick link to buy this book online!

136 M A S T E R I N G E N T E R P R I S E J A V A B E A N S
Notice that the SessionContext interface extends the EJBContext interface, giving session beans access to all the methods that we defined above in EJBContext. The one extra method is getEJBObject().
As we saw in Chapter 3, all session beans (and entity beans) must expose a method that the container will call to associate the bean with a particular context. For session beans, this method is called setSessionContext(SessionContext ctx). This method is defined in the javax.ejb.SessionBean interface that we showed you in Chapter 3. As we will see in Chapter 7, entity beans have a similar method called setEntityContext(EntityContext ctx).
SessionContext.getEJBObject()
In EJB, beans can act as clients of other beans. The getEJBObject() method is useful if your bean needs to call another bean and if you want to pass a reference to your own bean. In Java, an object can obtain a reference to itself with the this keyword. In EJB, though, a bean cannot use the this keyword and pass it to other beans because all clients invoke methods on beans indirectly through beans’ EJB object. Thus, a bean can refer to itself by using a reference to its EJB object, rather than the this keyword.
Understanding EJB Security
The next topic we cover is adding security to your enterprise beans. Let’s get right down to the meat. There are two security measures that clients must pass when you add security to an EJB system:
First, the client must be authenticated. Authentication verifies that the client is who he claims to be. For instance, the client may enter a username/password in a Web browser, and those credentials are checked against a permanent client profile stored in a database or LDAP server. Once the client is authenticated, he is associated with a security identity for the remainder of his session.
Then, the client must be authorized. Once the client has been authenticated, he must have permission to perform desired operations. For example, in a procurement application, you’d want to ensure that while anyone can submit purchase orders, only supervisors can approve purchase orders.
There is a very important difference here—authentication verifies that the client is who he claims to be, whereas authorization checks to see if an already authenticated client is allowed to perform a task. Authentication must be performed sometime before an EJB method is called. If the client has an identity, then it has been authenticated. Authorization, on the other hand, occurs during an EJB method call.
Go back to the first page for a quick link to buy this book online!

Adding Functionality to Your Beans 137
Step 1: Authentication
EJB does not help you with authentication. The specific way your client code becomes associated with a security identity is left to the discretion of your application and your EJB container. This means each EJB container may handle authentication differently. For example, with BEA WebLogic your client code can specify its username and password when it uses JNDI to look up home objects, as shown in the following code:
Properties props = System.getProperties();
props.put(Context.SECURITY_PRINCIPAL, "EmployeeA"); props.put(Context.SECURITY_CREDENTIALS, "myPassword1");
Context ctx = new InitialContext(props);
// Use the initial context to lookup home objects...
Since the EJB specification does not specify how to perform authentication, this code is not portable to other application servers. Check your container’s documentation for authentication instructions.
When you run this code, the application server must map your username and password to a security identity. Again, this step is application server specific. Some application servers allow you to set up usernames and passwords in the application server’s properties file that the application server reads in at runtime. More advanced servers support complex integration with existing security systems, such as a list of usernames and passwords stored in an LDAP server.
As an academic example, here is how to specify usernames and passwords using BEA WebLogic’s weblogic.properties file. Note that this is insufficient for real deployments that need to map to real security systems, such as an IT shop’s existing list of employee usernames/passwords.
weblogic.password.EmployeeA=myPassword1
weblogic.password.EmployeeB=myPassword2
...
Step 2: Authorization
Once the client has been authenticated, it must then pass an authorization test to call methods on your beans. There are two ways to perform authorization with EJB: declaratively or programmatically.
With declarative authorization, the container performs all authorization checks for you. Effectively you are delegating authorization to the EJB container. This keeps your bean code lean and allows you to focus on your business logic, rather than focus on writing security checks.
Go back to the first page for a quick link to buy this book online!