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

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

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

158 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

required by JNDI (see Appendix B for a full review of JNDI). We use those environment properties to form a JNDI initial context, and then use that to retrieve our home object.

The JNDI initialization parameters are part of the application-specific properties deployed with our MachineBean, which we’ll see later. Thus, our MachineBean, as well as our client, needs to have JNDI initialization parameters, such as the location of the directory structure (e.g., ldap://louvre:389/o=Airius.com).

There are several alternatives to this approach:

■■Have the client pass in the JNDI initialization properties to the MachineBean’s makeComponent() method.

■■Have the client retrieve the component home object, and pass in the home object as a parameter to our MachineBean’s makeComponent().

Both of these alternative approaches would rid us of the need to duplicate-code JNDI initialization parameters in both the client and the bean, reducing maintenance. In a production environment, however, you may want to keep the approach we’ve shown. When your beans look up other beans, the beans you look up may be hosted in a different application server, which may have a different directory protocol.

The Machine Home Interface

Next, we have the home interface for our MachineBean’s EJB object— MachineHome.java. It’s shown in Source 6.7.

Our home interface has a simple, blank create() method, which corresponds to our MachineBean’s empty ejbCreate() method.

The Machine Custom Exception Class

Our last MachineBean Java file is our custom Exception class, shown in Source 6.8. This exception is virtually identical to our ComponentException shown earlier.

The Machine Deployment Descriptor

Finally, we have the MachineBean deployment descriptor (DD). It’s shown in Table 6.4.

The only difference between this and the component’s DD is that the machine is a stateless session bean, rather than stateful. We also have a number of environment properties, shown in Table 6.5.

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

Adding Functionality to Your Beans 159

package com.wiley.compBooks.session.Fazuul;

import javax.ejb.*;

import java.rmi.RemoteException;

/**

*This is the home interface for MachineBean. This interface is implemented

*by the EJB Server's glue-code tools - the implemented object is called

*the Home Object and serves as a factory for EJB objects.

*

*One create() method is in this Home Interface, which corresponds to the

*ejbCreate() method in the MachineBean file.

*/

public interface MachineHome extends EJBHome {

/*

*This method creates the EJB object.

*@return The newly created EJB object. */

public Machine create() throws RemoteException, CreateException;

}

Source 6.7 MachineHome.java.

package com.wiley.compBooks.session.Fazuul;

/**

* Exceptions thrown by Machine */

public class MachineException extends Exception {

public MachineException() { super();

}

public MachineException(Exception e) { super(e.toString());

}

public MachineException(String s) { super(s);

}

}

Source 6.8 MachineException.java

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

160

 

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

Table 6.4 Deployment Descriptor Settings for MachineBean

 

 

DEPLOYMENT

 

DESCRIPTOR SETTING

VALUE

Bean home name

MachineHome

Enterprise bean class name

com.wiley.compBooks.roman.session.fazuul.MachineBean

Home interface class name

com.wiley.compBooks.roman.session.fazuul.MachineHome

Remote interface class name

com.wiley.compBooks.roman.session.fazuul.Machine

Environment properties

See Table 6.5

Re-entrant

false

Stateful or stateless

STATELESS_SESSION

Session timeout

10 seconds

Declarative security on

none

methods

 

runAsMode

SPECIFIED_IDENTITY

runAsIdentity

creator

Table 6.5 Environment Properties for MachineBean

ENVIRONMENT

PROPERTY SETTING

VALUE

java.naming.factory.initial

“weblogic.jndi.TengahInitialContextFactory”

java.naming.provider.url

“t3://localhost:7001”

COMPONENT_LIST

“Snarf,Vrommell,Rector”

 

 

The java.naming.factory.initial and java.naming.provider.url settings are used for JNDI initialization. The ones shown in the table are for the BEA WebLogic JNDI implementation. The EJB container you use should have documentation detailing which settings to use here.

Our machine bean can query the COMPONENT_LIST setting to see which components it can create.

Client.java

The final piece of code we have is the client application that calls our beans. This is shown in Source 6.9.

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

Adding Functionality to Your Beans 161

package com.wiley.compBooks.roman.session.fazuul;

import javax.ejb.*; import javax.naming.*; import java.rmi.*; import java.util.*; import java.io.*;

/**

* Client for Fazuul Game. */

public class Client {

public static void main(String[] args) {

new Client().start();

}

//Current list of Component EJB Objects I own private Vector components = new Vector();

//A Machine which dispenses Component EJB Objects private Machine machine;

/**

* Starts the game. The main game loop is here. */

public void start() {

try { /*

* Get System properties for JNDI initialization */

Properties props = System.getProperties();

/*

*Get a reference to the MachineHome Object - the

*factory for Machine EJB Objects

*/

Context ctx = new InitialContext(props);

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

/*

* Use the factory to create the Machine EJB Object */

machine = home.create();

}

catch (Exception e) { e.printStackTrace();

Source 6.9 Client.java (continues).

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

162 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

System.exit(-1);

}

/*

* Start reading input from standard input */

String line = null, command = null, args = null;

StringTokenizer tokens = null;

BufferedReader reader = new BufferedReader(new

InputStreamReader (System.in));

while (true) {

/*

* Print prompt, read next input line, and get command */

try { System.out.println(); System.out.print("> ");

line = reader.readLine(); System.out.println();

tokens = new StringTokenizer(line, " ", false);

//Get command. e.g. "attach" or "inv" command = tokens.nextToken();

//Get arguments to command.

args = null;

if (tokens.hasMoreElements()) {

args = line.substring( command.length()+1, line.length());

}

}

catch (Exception e) { continue;

}

/*

* Do case analysis based upon command. */

try { /*

* If the user wants to examine a component */

if (command.equals("examine")) { examine(args);

}

/*

* If user wants to attach 2 components,

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 163

*then extract the 2 component names from

*the argument string, and call attach()

*/

else if (command.equals("attach")) { String item1 = null, item2 = null; try {

StringTokenizer argtokens = new StringTokenizer(args, " ");

item1 = argtokens.nextToken(); argtokens.nextToken();

item2 = argtokens.nextToken();

}

catch (Exception e) {

throw new Exception("Syntax: attach <item1> to <item2>");

}

attach(item1, item2);

}

/*

* If the user wants to discard an object */

else if (command.equals("drop")) { drop(args);

}

/*

* If the user needs more components */

else if (command.equals("gimme")) { gimme();

}

/*

*If the user wants to list the components

*he has.

*/

else if (command.equals("inv")) { inv();

}

/*

* If the user wants to end the game */

else if (command.equals("quit")) { quit();

}

/*

* If the user wants to suspend the game */

else if (command.equals("suspend")) { if (args == null) {

Source 6.9 Client.java (continues).

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

164 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

System.out.println("Please specify a filename.");

}

else { suspend(args);

}

}

/*

*If the user wants to resume a suspended

*game.

*/

else if (command.equals("resume")) { if (args == null) {

System.out.println("Please specify a filename.");

}

else { resume(args);

}

}

else {

System.out.println("Syntax: [attach <item1> to <item2> | examine <item> | inv | gimme | drop <item> | suspend <filename> | resume <filename> | quit]");

}

}

catch (Exception e) { e.printStackTrace();

}

}

}

/**

*Suspends the game. Writes the current game state to disk

*via EJB object handles.

*/

private void suspend(String filename) {

ObjectOutputStream stream = null;

try {

stream = new ObjectOutputStream( new FileOutputStream(filename));

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

Component comp = (Component) components.elementAt(i); Handle handle = comp.getHandle(); stream.writeObject(handle);

}

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 165

stream.flush();

System.out.println("Game saved.");

}

catch (Exception e) { e.printStackTrace();

}

finally {

if (stream != null) {

try { stream.close(); } catch (Exception e) {}

}

}

System.exit(0);

}

/**

* Resumes a suspended game via EJB object handles. */

private void resume(String filename) {

clearComps();

ObjectInputStream stream = null;

try {

stream = new ObjectInputStream(

new FileInputStream(filename));

while (true) {

Handle handle = (Handle) stream.readObject();

components.addElement(

(Component) handle.getEJBObject());

}

}

catch (EOFException e) { System.out.println("Game loaded.");

}

catch (Exception e) { e.printStackTrace();

}

finally {

if (stream != null) {

try { stream.close(); } catch (Exception e) {}

}

}

}

Source 6.9 Client.java (continues).

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

166 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

/*

* Removes all components the user has. */

private void clearComps() {

System.out.println("Clearing game state...");

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

Component comp =

(Component) components.elementAt(i);

comp.remove();

}

catch (Exception e) { e.printStackTrace();

}

}

components = new Vector();

}

/**

* Quits the game, cleaning up all EJB Objects. */

private void quit() {

/*

* 1: Remove all components */

clearComps();

/*

* 2: Remove machine */

try { machine.remove();

}

catch (Exception e) { e.printStackTrace();

}

System.exit(0);

}

/**

* Gets more components from the machine */

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 167

private void gimme() throws Exception { for (int i=0; i < 3; i++) {

Component comp = machine.makeComponent(); components.addElement(comp);

System.out.println("The machine pops out a " + comp.getName());

}

}

/**

* Drops a component. */

private void drop(String componentName) throws Exception { for (int i=0; i < components.size(); i++) {

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

// Call remove() on EJB Object comp.remove();

components.removeElement(comp);

System.out.println("You dropped your " + componentName); return;

}

}

}

/**

* Lists the inventory of components I currently have. */

private void inv() throws Exception {

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

Component comp = (Component) components.elementAt(i);

System.out.println(comp.getName());

}

}

/**

* Prints out the description of component with name componentName. */

private void examine(String componentName) throws Exception { /*

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

*component. If the name matches, then print out that

*component's description.

*/

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

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

System.out.println(comp.getDescription());

Source 6.9 Client.java (continues).

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