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

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

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

168 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

return;

}

}

}

/**

* Attempts to attach components with names A and B together. */

private void attach(String componentNameA, String componentNameB) throws Exception {

Component componentA = null, componentB = null;

/*

*Loop through all the components. Get the Names of each

*component. If the name matches, then that's our Component A.

*/

for (int i=0; i < components.size(); i++) {

Component comp = (Component) components.elementAt(i); if (comp.getName().equals(componentNameA)) {

componentA = comp;

}

}

/*

* Print out some error codes if we didn't find any matches */

if (componentA == null) {

System.out.println("You don't have a " + componentNameA); return;

}

/*

*Loop through all the components. Get the Names of each

*component. If the name matches, AND it's not the same

*as the Component A above, then that's our Component B.

*/

for (int i=0; i < components.size(); i++) {

Component comp = (Component) components.elementAt(i); if (comp.getName().equals(componentNameB)

&& (!comp.equals(componentA))) { componentB = comp;

}

}

/*

* Print out some error codes if we didn't find any matches */

if (componentB == null) {

System.out.println("You don't have a " + componentNameB);

Source 6.9 Client.java (continues).

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

Adding Functionality to Your Beans 169

return;

}

/*

*Try to attach the two components. If they attach,

*1) Remove the old Component EJB Objects

*2) Remove the old Components from our list of components

*3) Add the new, combined component to our list

*/ try {

Component newComp = componentA.attachTo(componentB);

// Remove the two old Components' EJB Object componentA.remove();

componentB.remove();

components.removeElement(componentA);

components.removeElement(componentB);

components.addElement(newComp);

System.out.println("Fitting the " + componentNameA + " into the " + componentNameB + ", out pops a " + newComp.getName() + "!");

}

/*

*If an application-level exception occurs (i.e. if

*the two components won't attach) then handle it.

*Let the main loop handle system-level exceptions.

*/

catch (ComponentException e) { System.out.println(e.toString());

}

}

}

Source 6.9 Client.java (continued).

The client app illustrates looking up a bean via JNDI, calling business methods on beans, removing beans, and using EJB object handles.

The program itself consists of a main game loop in its start() method. Depending on what the user inputs, the main game loop calls one of the following methods:

gimme(). Asks the machine EJB object for three more components.

inv(). Lists the current components EJB objects I have in my inventory.

attach(). Tries to attach two components together.

examine(). Prints out the long description of a component.

drop(). Removes a component (if my inventory gets too big).

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

170 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

suspend(). Suspends the game, allowing the user to quit to the command prompt. The user’s game state is saved using EJB object handles.

resume(). Resumes a suspended game.

quit(). Quits the game.

The Manifest

The final piece of our deployment equation is the manifest file. Because we have two beans, we need to list two serialized deployment descriptors, as shown in the following code snippet. Note that the actual names of your serialized deployment descriptors may vary depending on which EJB tool you use to generate your deployment descriptors.

Name: com/wiley/compBooks/roman/session/fazuul/deployment/

ComponentBeanDD.ser

Enterprise-Bean: True

Name: com/wiley/compBooks/roman/session/fazuul/deployment/

MachineBeanDD.ser

Enterprise-Bean: True

Running the Client

Let’s try the game out. To run the game (assuming the BEA WebLogic server), type:

java

-Djava.naming.factory.initial=

weblogic.jndi.TengahInitialContextFactory

-Djava.naming.provider.url=

t3://localhost:7001

com.wiley.compBooks.roman.session.fazuul.Client

Note that your machine’s network must be properly set up for the localhost:7001 to resolve properly. If you can’t get the client to connect with the EJB server, try using your IP address instead.

The following is a typical game interaction. The commands the user types are in bold:

> help

Syntax: [attach <item1> to <item2> | examine <item> | inv | gimme | drop <item> | suspend <filename> | resume <filename> | quit]

> inv

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

Adding Functionality to Your Beans 171

> gimme

The machine pops out a Snarf

The machine pops out a Rector

The machine pops out a Snarf

> gimme

The machine pops out a Rector

The machine pops out a Snarf

The machine pops out a Vrommell

> inv

Snarf

Rector

Snarf

Rector

Snarf

Vrommell

> drop Rector

You dropped your Rector

> inv

Snarf

Snarf

Rector

Snarf

Vrommell

> examine Snarf

This is a snarf. It came all the way from snarfland. It looks like a large peanut, with a hole in the side of it. The hole looks big enough to fit a Vrommell inside.

> examine Vrommell

This Vrommell is a funny banana-shaped thing. It looks like it will fit snugly into a Snarf.

> attach Snarf to Vrommell

Fitting the Snarf into the Vrommell, out pops a Subbert!

> inv

Snarf

Rector

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

172 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

Snarf

Rector

Subbert

> examine Subbert

Subberts are small discs and smell funny. There's a small, bananashaped hole in this Subbert.

> gimme

The machine pops out a Rector

The machine pops out a Vrommell

The machine pops out a Rector

> attach Vrommell to Subbert

Fitting the Vrommell into the Subbert, out pops a Fwiffo!

> examine Fwiffo

It's a Fwiffo! Fwiffos are cute, furry little creatures. This Fwiffo has lost some fur on his head, though, and needs something to cover it up.

> examine Rector

Oh no, it's Rector! Rectors are dangerous, disease-spreading devices. You don't want to hold on to this one for very long. Perhaps if you fed the Rector a peanut or disc, it would be pacified.

> attach Snarf to Rector

Fitting the Snarf into the Rector, out pops a Lucia!

> examine Lucia

Lucias are peaceful, harmless components. This Lucia is brown. Lucia wants something furry to play with or someone to sing to her.

> attach Lucia to Fwiffo

Fitting the Lucia into the Fwiffo, out pops a Simpthat!

> quit

As you can see, typing “gimme” gets three components from the machine. Dropping a component removes it from our inventory, and combining components replaces two components in our inventory with a new merged component.

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

Adding Functionality to Your Beans 173

We examine each component as we get it, and we look for clues as to what the components should attach. For example, the Snarf has a hole inside that can fit a Vrommell, so we attach the Vrommell to the Snarf to generate a Subbert. The Subbert has a banana-shaped hole in it. What should we attach it to? Well, its long description indicates that our Vrommell looks like a banana, so the two naturally fit together. And so we continue. At the end of our interaction, we notice that the Rector can be pacified by feeding it peanuts. The Snarf is pea- nut-shaped, so we “feed” it to the Rector by attaching the two, and magically a Lucia is born.

Try the game out yourself—you may become addicted. You can modify the game parameters (or cheat!) by modifying the deployment descriptor.

Experimenting with Handles

Let’s check out how EJB object handles work in our game.

> inv

Vrommell

Rector

Vrommell

> suspend myGame

Game saved.

//At this point, the game exits to the command line

//and the client JVM quits.

//

//Later, when we're ready to start playing again, we

//re-run the client..

>inv

>resume myGame

Clearing game state...

Game loaded.

> inv

Vrommell

Rector

Vrommell

As you can see, the EJB object handles served as persistent component references across the client JVM lifecycle.

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

174 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

Experimenting with Security

Just for fun, let’s see what happens when we try to create a component directly from the client:

ComponentHome home = (ComponentHome) ctx.lookup("ComponentHome");

Component comp = home.create("Snarf");

Running this code yields the following output:

java.rmi.RemoteException:

java.lang.SecurityException:

User 'guest' not allowed access to method ejbCreate_S in EJB class

'com.wiley.compBooks.roman.session.fazuul.ComponentBean'

As you can see, the container is enforcing the correct security policies we outlined in the deployment descriptor. Client code is not allowed to directly instantiate our component bean.

Summary

In this chapter, we stepped up and learned how to make our beans more robust. We learned how to use EJB contexts, how to access environment properties, how to use EJB security, how to use EJB object handles, and how to call beans from other beans. You also saw a non-trivial example illustrating these concepts in action.

In the following chapters, you will gain insight into the sister of the session bean—the persistent entity bean.

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

C H A P T E R7

Introduction to Entity Beans

n Chapters 3–6, you learned how to code session beans—distributed components Ithat represent business processes. But session beans are only half of what Enterprise JavaBeans has to offer. One of the key benefits of EJB is the power to create entity beans. Entity beans are persistent objects that can be stored in permanent storage. This means you can model your business’s fundamental, underlying data as entity beans. We’ll see exactly what this means in the pages to come.

In this chapter, we’ll cover these topics:

■■The basic concepts of persistence

■■A definition of entity beans, from a programmer’s perspective

■■The features that entity beans have to offer

■■How entity beans compare with session beans

■■Entity bean programming concepts

Entity beans are an optional part of Enterprise JavaBeans 1.0. Even if your EJB container is compliant with EJB 1.0, the EJB container may not be able to handle entity beans. If you need entity beans, make sure you choose a container capable of deploying them. EJB 1.1, which is part of Java 2 Platform, Enterprise Edition (J2EE), mandates entity bean support.

This chapter is relatively theoretical, and it is meant to give you a deep foundation in entity bean programming concepts. For those of you with a traditional procedural programming background, entity beans can be a very tough topic to grasp. You may need to reread this chapter a few times to really understand how things work. Make sure you’ve read and understood the previous chapters in this

175

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

176 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

book; our discussion of entity beans will build on the knowledge you’ve acquired so far. We’ll use these concepts with hands-on code in Chapters 8 and 9.

Persistence Concepts

Because entity beans are persistent objects, our discussion begins with a quick look at popular ways to persist objects.

Java Object Serialization

When you work with Java objects, in many cases you would like to capture the state of the object you’re currently working with and save it to a permanent storage. One way to do this, as covered in Appendix A, is to use object serialization. Object serialization is an easy way to marshal an object graph into a compact representation. When you serialize an object graph, you convert the graph into a byte stream. You can then do anything you want to with that stream, such as push the data over the network (which is how Java RMI passes parameters over the network), or you can save the stream to a storage, such as a file system, database or JNDI tree. For sophisticated persistence, however, object serialization falls short in many areas.

For example, let’s say we store a million serializable bank account objects onto a file system. We do this by converting the objects to their bit-blob representation and then storing the bytes on disk. Let’s say we then want to retrieve all bank accounts that have balances over $1000. To do this with serialization, we’d have to load each and every bank account serialized bit-blob from the disk, construct the corresponding object, and then execute a method query on the object to determine if the balance is over $1000. We might want to perform more advanced queries as well, such as retrieving all checking accounts that have been inactive for six months. There is no efficient way to do this with object serialization.

In general, querying objects stored using object serialization is very expensive and cumbersome. Submitting queries against business data is an absolute necessity for large-scale applications, which makes simple object serialization unsuitable for persistent storage. While object serialization has its purpose, it is best used in restricted domains, such as for network communications and simple persistence. For EJB, we’ll need a more robust persistence mechanism to address more complex querying operations.

Object-Relational Mapping

Another popular way to store Java objects is to use a traditional relational database, such as Oracle or Microsoft SQL Server. Rather than serialize each object,

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

Introduction to Entity Beans 177

we could decompose each object into its constituent parts and store each part separately. For example, for a bank account object, the bank account number could be stored in one relational database row, while the bank account balance could be stored in another row. When you save your Java objects, you would use JDBC or SQL/J to map the object data into a relational database. You could also store the name of the Java class that this data corresponds to, so that you know which class to instantiate when reading the object back from the database. When you want to load your objects from the database, you’d first instantiate an object from that class, read the data in from the database, and then populate that object instance’s fields with the relational data read in. This is shown in Figure 7.1.

Bank Account

Database API such as JDBC or SQLJ

Bank Account

Table

Relational Database

Figure 7.1 Object-relational mapping.

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