Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Mastering Enterprise JavaBeans™ and the Java 2 Platform, Enterprise Edition - Roman E

..pdf
Скачиваний:
41
Добавлен:
24.05.2014
Размер:
6.28 Mб
Скачать

300 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

horrible performance for concurrent threads of execution. If the transaction cannot eventually be made to succeed, you should consider aborting your business process.

For a stateless session bean, aborting a business process is a simple task—simply throw an exception back to the client. But for a stateful session bean, things are a bit trickier. Stateful session beans represent business processes that span multiple method calls and hence have in-memory conversational state. Tossing away that conversation and throwing an exception to the client could entail a significant amount of lost work.

Fortunately, a well-designed stateful session bean can salvage its conversations in the case of failed transactions. The key is to design your beans to be aware of changes to conversational state and to be smart enough to undo any of those changes in case of a transactional abort.

Because this process is highly application-specific, your application server cannot automate this task for you. Your application server can aid you in determining when a transaction failed, enabling you to take application-specific steps. If your session bean needs to be alerted to transaction status (such as failed transactions), your enterprise bean class can implement an optional interface called javax.ejb.SessionSynchronization, shown in the following code:

public interface javax.ejb.SessionSynchronization

{

public void afterBegin(); public void beforeCompletion();

public void afterCompletion(boolean);

}

You should implement this interface in your enterprise bean class and define your own implementations of each of these methods. The container will call your methods automatically at the appropriate times during transactions, alerting you to important transactional events. This adds to the existing arsenal of alerts that your session beans receive already—life-cycle alerts via ejbCreate() and ejbRemove(), passivation alerts via ejbActivate() and ejbPassivate(), and now transactional alerts via afterBegin(), beforeCompletion(), and afterCompletion().

Here’s what each of the SessionSynchronization methods do:

afterBegin() is called by the container directly after a transaction begins.

beforeCompletion() is called by the container right before a transaction completes.

afterCompletion() is called by the container directly after a transaction completes.

The key method that is most important for rolling back conversations is afterCompletion(). The container calls your afterCompletion() method when a transaction completes either in a commit or an abort. You can figure out

Go back to the first page for a quick link to buy this book online!

Transactions 301

whether a commit or an abort happened by the Boolean parameter that gets passed to you in afterCompletion()—true indicates a successful commit, false indicates an abort. If an abort happened, you should roll back your conversational state to preserve your session bean’s conversation.

Here’s an example of afterCompletion() in action:

public class CountBean implements SessionBean, SessionSynchronization {

private SessionContext ctx; public int val;

public void ejbCreate(int val) throws CreateException { this.val = val;

}

 

 

 

public

int count() {

 

return ++val;

 

}

 

 

 

public void

afterCompletion(boolean b) {

if

(b == false) --val;

 

}

 

 

 

public

void

afterBegin() {}

 

public

void

beforeCompletion() {}

public

void

ejbRemove() {}

 

public

void

ejbActivate() {

}

public

void

ejbPassivate() {}

 

public

void

setSessionContext(SessionContext ctx) {}

}

This is a new version of our Count bean from Chapter 5. The conversational state is val, an integer that gets incremented whenever count() is called. The key method to notice is afterCompletion()—it rolls back our conversational state in case of a transactional abort. Note that we must make count() transactional in the deployment descriptor.

The other two methods in SessionSynchronization—both afterBegin() and beforeCompletion()—are useful for when your stateful session bean caches database data in memory during a transaction. You should use these methods as follows:

When the container calls afterBegin(), the transaction has just started. Thus, you should read in any database data you want to cache in your stateful session bean.

When the container calls beforeCompletion(), the transaction has ended. Write out any database data you’ve cached.

Go back to the first page for a quick link to buy this book online!

302 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

You can implement SessionSynchronization only if you’re using a stateful session bean with declarative (container-managed) transactions. If your bean is using programmatic (bean-managed) transactions, you are already in control of the transaction because you issue the begin(), commit(), and abort() statements. Stateless session beans do not hold conversations and hence do not need these callbacks.

Summary

Whew! That’s a lot of data to digest. You may want to come back and reread this chapter later to make sure you’ve grasped all the concepts. You should definitely return to this chapter frequently when you’re creating transactional beans or when you’re just wondering about transactions in general.

In this chapter, we learned about transactions and how they can make a serverside deployment robust. We saw the virtues of transactions, which are called the ACID properties. We then looked at different transactional models, including flat and nested transactions.

We then applied this transactional knowledge to EJB. We saw how both declarative and programmatic transactions were useful in EJB and when to use each. We saw the different transaction attributes that you can place on your beans. We then looked at transaction isolation levels and understood the problems that each level solves.

Finally, we learned about distributed transactions and the two-phase commit protocol. We wrapped up with explaining how programmatic transactions were performed in EJB, with an example of how a bean method could be written with either methodology, and ended with a look at writing transactional conversations.

Your efforts reading this chapter were well worth it because now you have a solid foundation in the importance and usefulness of transactions in EJB. You’ll see some real-world examples using transactions in Part IV, when we perform a sophisticated e-commerce deployment using EJB.

Go back to the first page for a quick link to buy this book online!

C H A P T E R11

CORBA and RMI-IIOP

JB would not be complete without a way to integrate legacy systems. By itself, EEJB gives you portable, enterprise-class server-side applications. These applications can be developed rapidly without the management overhead of having to construct a scalable, secure environment. Combining this with CORBA allows EJB customers to leverage legacy CORBA applications, as well as integrate with existing investments written in non-Java languages such as C++ and COBOL. Indeed, CORBA and EJB are very related—many of the concepts in Java 2 Plat-

form, Enterprise Edition came from CORBA.

In this chapter, we’ll learn the high-level concepts behind CORBA. We’ll then see how Java RMI and CORBA can be combined via RMI-IIOP. Finally, we’ll look at how to use RMI-IIOP and CORBA clients to access EJB systems.

To understand this chapter, you must first understand Java RMI. If you are unfamiliar with this technology, please read Appendix A before reading this chapter.

What Is CORBA?

The Common Object Request Broker Architecture (CORBA) is a unifying standard for writing distributed object systems. The standard is completely neutral with respect to platform, language, and vendor. CORBA incorporates a host of technologies and is very broad in scope.

CORBA was invented by the Object Management Group (OMG), a consortium of companies that began in 1989. CORBA itself is simply a standard, just like

303

Go back to the first page for a quick link to buy this book online!

304 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

EJB. The CORBA specification is implemented by CORBA-compliant products, such as Inprise’s VisiBroker for Java, Iona’s OrbixWeb, and Sun Microsystem’s Java IDL, just as the EJB specification is implemented by EJB-compliant products, such as BEA’s WebLogic, IBM’s WebSphere, and Oracle’s Oracle 8i products.

CORBA as the Basis for EJB

Many of the concepts in EJB came out of CORBA. In a sense, you can think of EJB as CORBA with a new hat on. EJB and the Java 2 Platform, Enterprise Edition (J2EE) bring a Java-centric, component-based approach to traditional middleware programming—an architecture suitable for rapid application development. CORBA, on the other hand, offers a much broader suite of middleware features with which to work. This includes a time service, a distributed locking service, a relationship service, and more. To use CORBA’s services, you need to program to complex middleware APIs, which increase the learning curve for CORBA programming. This is why EJB and J2EE are much more suitable for rapid application development than CORBA. And because EJB is officially being supported by the industry (there are 25+ vendors writing EJB products at this time), EJB will give you a much wider variety of tools to work with in the long run.

Regardless of this, CORBA is a very important technology and is quite useful for advanced middleware development, cross-language support, and legacy integration. In fact, most serious EJB products on the market are based on CORBA and use CORBA concepts behind the scenes.

Why Should I Care about CORBA?

To you, as an EJB application assembler or bean provider, CORBA is important for three reasons:

You can use CORBA for legacy integration. If you have an existing investment (such as a legacy banking application) you can leverage that investment today using CORBA. For example, let’s say you have a banking application written in C++. CORBA gives you the ability to preserve and reuse it. You can wrap your existing investment as a CORBA object, allowing it to be called from any application. As we’ll find out, CORBA is a language-neutral standard and allows code written in several languages to communicate. Thus CORBA is an ideal platform for code written in different languages to cooperate.

CORBA allows for advanced middleware development. Remember that EJB is not supposed to be an end-all to every problem. But if there is a middleware service that can be generalized, you’re likely to find it standardized as a CORBA service. For those who need it, CORBA gives great functionality.

Go back to the first page for a quick link to buy this book online!

CORBA and RMI-IIOP 305

CORBA and EJB have hooks connecting them. Some EJB products will allow your enterprise beans to be called from two different kinds of clients: clients written to use the J2EE suite of APIs and clients written to use CORBA APIs. This means that code written in C++ or Smalltalk can call your enterprise beans.

Benefits of Using CORBA

Why would you want to use CORBA? There are many reasons:

CORBA is not controlled by one company. Because CORBA has been invented by a consortium of companies, there are many parties invested in CORBA’s success. This also means that any changes to the CORBA specification are voted on jointly. This prevents CORBA from becoming a standard that’s specific to one product or architecture (in the way that COM+, for example, is specific to MS Windows). And in reality, Enterprise JavaBeans is also the product of a consortium of companies, including IBM, Oracle, Sun, and others, which means that EJB is also not strictly controlled by one company.

CORBA is language-independent. When you use CORBA, you can invoke methods on objects written in other languages without programming in those languages. This allows for very easy legacy integration with languages such as COBOL. If you’re writing your programs in Java, you can use CORBA as an alternative to the Java Native Interface for invoking objects written in native code such as C++.

CORBA provides optional value-added services. Vendors of CORBA products can add optional functionality to enhance deployments—common services that many objects will need, such as persistence, security, transactions, and events. Developers who use CORBA don’t need to reinvent the wheel— they can leverage services written to a common standard by another vendor.

Drawbacks of CORBA

As usual, the world isn’t perfect. Using CORBA has disadvantages as well as advantages:

CORBA is slow-moving. All standards committees are bureaucratic and slow to make decisions. This is because the standards committee itself is not driven by revenues, but rather by individual interests from participating companies. CORBA experiences benefits from not being owned by one company, but its openness is also a drawback. The cycle time for the OMG to adopt a new CORBA feature is on the order of years.

CORBA has a steep learning curve. As CORBA has evolved over the years, it’s undergone “feature creep.” More and more features have been added, which makes CORBA a robust standard but also increases the learning curve.

Go back to the first page for a quick link to buy this book online!

306 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

Indeed, the specifications that define the whole of CORBA are thousands of pages long and are quite challenging to master. The nice thing about CORBA is that you don’t have to learn it all to use it—there are optional CORBA services that you can learn as you need them.

Products developed under CORBA may have incompatible features. It’s great that CORBA is a unifying standard. Because no one company controls the standard, it levels the playing field for companies competing to build CORBA products. But there remain the problems of multivendor solutions. As with EJB products, if you mix and match CORBA products, you will inevitably run into assumptions that vendors have made but that are specific to their own products. This is the trade-off between a one-vendor solution, such as Microsoft, and an open standard, such as CORBA or EJB. The price of freedom is eternal vigilance.

Understanding How CORBA Works

Before we delve into CORBA/EJB interoperability, we’ll cover the core CORBA fundamental concepts. This will lay the groundwork for us to discuss how CORBA and EJB are compatible.

Object Request Brokers

An Object Request Broker or ORB is a facilitator for objects on the network to communicate. ORBs are intermediaries between distributed objects. They enable disparate applications to communicate without being aware of the underlying communications mechanism. ORBs allow objects to call methods on each other, dynamically discover each other, and more. ORBs are responsible for finding objects to service method calls, handling parameter passing, and returning results. Whenever you have multiple objects interacting in a CORBA environment, ORBs facilitate the communications. This is shown in Figure 11.1.

There are numerous CORBA ORBs on the market. Some examples are Iona’s

OrbixWeb, Inprise’s VisiBroker, and IBM’s ComponentBroker. Each vendor offers various qualities of service that differentiate that vendor’s product from those of other vendors in the marketplace.

The concept of an ORB is absolutely not specific to CORBA. Both Java RMI and Microsoft COM+ contain ORB functionality as well because both RMI and COM+ facilitate network communications and hence serve as object request brokers. For the rest of this chapter, however, we’ll assume we’re dealing with CORBA ORBs.

Go back to the first page for a quick link to buy this book online!

CORBA and RMI-IIOP 307

Machine 1

Application

Code

ORB

 

 

Machine 2

 

IIOP

 

IIOP

ORB

Application

 

Code

 

 

Machine 3

IIOP

 

ORB

Application

Code

Figure 11.1 The ORB facilitates your networking needs.

What Is IIOP?

Throughout this book, we’ve seen EJB applications that communicate via the Java RMI API. Java RMI is a communications package for performing distributed computing in Java. Behind the scenes, Java RMI uses the Java Remote Method Protocol (JRMP) as the default protocol layer for communications.

The CORBA world, however, does not use JRMP. Rather, CORBA products use a different protocol called IIOP (Internet Inter-ORB Protocol). IIOP is the standard Internet protocol for CORBA. IIOP, just like JRMP, is used behind the scenes for distributed object communications. CORBA ORBs use IIOP to communicate with each other, as shown in Figure 11.1.

Go back to the first page for a quick link to buy this book online!

308 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

Object Implementations and Object References

CORBA provides a clean separation between an object’s interface and its implementation. When you write a CORBA object implementation, that object is callable over the network by remote clients. Those clients deal with your CORBA object implementation’s interface only—clients do not deal directly with your object implementation. This separation of interface from implementation is quite analogous to how distributed computing is performed in Java RMI. With both CORBA and Java RMI, clients are unaware of object implementation details— clients are concerned only with the interfaces to the object implementations that they are using.

In addition to interface/implementation separation, one of CORBA’s goals is location transparency of distributed objects. Location transparency means that client code is unaware of where a real object implementation resides—perhaps it is local, perhaps remote. CORBA achieves location transparency with object references. An object reference is an identifier for a particular object implementation in CORBA. It uniquely identifies the object implementation across the network. An object reference automatically tracks the object implementation it represents behind-the-scenes.

Note that in theory, you should not need to worry yourself with the details of object references—you should just know that the ORB vendors use them internally in their ORBs to identify objects. In reality, each vendor’s CORBA implementation deals with references in a slightly different way, and you have to know how to get an object reference from each type of ORB.

Object Adapters

A CORBA object adapter is a pluggable entity that assists in the following tasks:

■■When an object is accessed, the object adapter is responsible for mapping an object reference onto an object implementation behind the scenes. When a client performs an invocation, the ORB, the object adapter, and the implementation object coordinate to figure out which implementation object should be called.

■■If a client calls a method on an object implementation that is not in memory, the object adapter activates the object (or initializes it into memory) so it can service the client request. The converse is also true—object adapters also deactivate objects. Activation is a great help because it gives clients the illusion that server-side objects are always up and running, even though they are lazy-loaded (activated) into memory on the fly.

CORBA was designed to be flexible with object adapters. They are truly pluggable entities. You can have many different kinds of object adapters running in your system, with different kinds of behavior.

Go back to the first page for a quick link to buy this book online!

CORBA and RMI-IIOP 309

The first object adapter that the OMG introduced was the Basic Object Adapter or BOA. Very quickly, ORB vendors began to realize that the BOA was poorly defined and ambiguous in many cases (for example, the BOA did not define properly the mechanisms for activation and deactivation of objects). So what happened? ORB vendors began to write their own proprietary versions of the BOA, which are totally incompatible with each other. This severely hindered CORBA’s portability.

The OMG realized this and decided to give up on the BOA (fixing it would be too difficult). Instead, a new Portable Object Adapter or POA was born. The POA is very flexible and defines a set of common services from which other object adapters can be derived. Hence, the POA is somewhat like a parent that defines rules for its children, so that each child adheres to the same rules, yielding portability.

Having the POA adds flexibility to CORBA. Object adapters can now be defined that are not only portable but have very different kinds of behavior. For example, different POA subobjects can have different policies for activating and deactivating objects. Each object adapter derived from the POA can have a policy that’s applicable to certain objects in your system.

The POA makes a clear distinction between two kinds of object references in CORBA. A transient object reference is an object reference that is useful only for the lifetime of the client. While the client is still alive, the transient object reference is used to call the object implementation.

But what if the client wants to store an object reference persistently? It might be nice for clients to be able to get a reference to a CORBA object implementation, shut down, then start up and start calling methods again. The POA allows for this. The idea is to stringify the object reference (that is, convert the object reference into a human-readable string). Strings are easily sent around and saved to disk. You can later read the string back in and pass it to your object adapter to reconstruct the transient object reference. You can then start calling methods again. This is very handy because strings are human-readable, easily stored in a variety of media, and easily sent between parties.

Repositories

A repository is a service that stores information and can be queried for that information. Repositories are somewhat like databases (and, in fact, their implementation may indeed use a database).

In CORBA, there are two important repositories: an Interface Repository and an Implementation Repository. Let’s take a look at these repositories and how they’re used.

Go back to the first page for a quick link to buy this book online!