PowerBuilder Authors: Chris Pollach, Yeshim Deniz, Jayaram Krishnaswamy, Kevin Benedict, Avi Rosenthal

Related Topics: PowerBuilder

PowerBuilder: Article

Developing EJBs and Servlets for EAServer

Developing EJBs and Servlets for EAServer

As many readers know, Sybase is one of the first licensees of the Java 2 Platform, Enterprise Edition from Sun Microsystems. J2EE promises to become the dominant industry model for quickly developing, enhancing and deploying mission-critical e-business applications.While portability is the most well-known of Java's attractions, the J2EE technology suite also provides a robust framework for reliable, scalable and secure applications.

As J2EE is largely targeted at mission-critical enterprise applications deployed to the middle tier, Sybase's powerful EAServer product is a natural staging platform for implementing these quickly emerging technologies. (Most readers are probably aware that EAServer also hosts PowerBuilder nonvisual user objects as middle-tier components.) This two-part article will provide getting-started examples of two of the J2EE technologies using Sybase's EAServer: Enterprise JavaBeans and servlets.

If you don't already own a copy of EAServer and PowerJ (Sybase's Java development tool), you can request a 30-day evaluation copy through Sybase's Web-based eShop. Go to www.sybase.com/products/easerver/ and click on "EAServer Eval CD".

Enterprise JavaBeans
The Enterprise JavaBean specification defines an execution-and-services framework for the deployment of server-side Java components. Servers that implement this specifcation provide support for portable business logic objects in an enterprise environment. Basic services such as transaction processing, security, persistence and resource pooling are transparently available to deployed components (EJBs) with little or no coding effort on the part of developers.

There are two broad types of EJBs: session beans and entity beans. Session beans are appropriate for coordinating and driving transient business processes, such as rating an insurance policy. Entity beans on the other hand aren't tied to processes but rather to persistent data stores, such as an RDBMS table. In fact, entity beans are usually mapped directly to individual rows within a database table.

Sybase's EAServer 3.5 supports the full EJB 1.0 specification, which requires EJB servers to fully support session beans. It also supports bean-managed entity beans, which is part of the EJB 1.1 specification. EAServer 3.6 (targeted for release in third-quarter 2000) will completely support the EJB 1.1 specification, including container-managed entity beans.

Servlets are another core piece of the overall J2EE suite of technologies. Servlets are intended to provide a far more scalable and portable method of dynamic Web site support than older methods that may use dynamic page servers (such as Microsoft's ActiveServer Pages), along with CGI (Common Gateway Interface) and related programs. We'll look at EAServer's excellent servlet support in Part 2 of this article.

Our Example: A Las Vegas Craps Game Simulator
In this article we go through the steps for developing a fun and instructive example of an EJB (Part 1) and a simple servlet (Part 2). The servlet will call business logic methods housed within the EJB. Both the servlet and EJB will be deployed to Sybase's EAServer 3.5. The better you know Java, the faster you'll move through this activity. However, it's not difficult for Java beginners and will hopefully be a useful learning tool for the reader. All of the code you'll need is supplied for you at the PBDJ Web site, PowerBuilderJournal.com.

The business logic we'll write is the fun part. In Part 1 we develop an EJB that will run a craps game for us. In particular, the EJB will implement the basic bet on a Las Vegas craps table - the "pass line" bet - whose "business" rules will be provided momentarily. Figure 1 is an example of the servlet output as seen from Internet Explorer once the EJB and servlet have been developed. It shows that this particular game consisted of seven rolls of the dice before a win occurred. It was the 28th game played by this particular browser session - the shooter has won 17 games and lost 11. Rules for craps aren't difficult. And the odds of winning are quite good too!

The servlet's job is merely to initiate a single craps game by calling our EJB and then passing back the EJB's results to the user's browser. One complete game consists of one or more rolls of the dice until either a win or loss occurs. If the user wishes to play additional times, she or he simply clicks on Another Game?.

Basic Craps Rules
How does one win or lose at craps? Every roll of the two dice used at a craps table is either a come-out roll or a point roll.

Come-out rolls initiate a new craps game. Shooters will immediately win or lose or they'll "establish a point." A 7 or 11 produces an immediate win. A 2, 3 or 12 yields an immediate loss. All other outcomes establish the point. The shooter continues to throw additional point rolls until the point turns up again (a win) or a 7 is rolled (a loss). See Table 1 for an easy summary of these rules.

A win gives you double your money. A loss loses your entire bet. Figure 2 shows the craps business rules as a simple flowchart.

Developing the Craps EJB Session Bean
Our first task in this article will be to develop the EJB session bean. The craps rules are a process or workflow; there's no need for data persistence over time as the application is now defined. Thus the session bean is the proper type of EJB to use. (If you wish to enhance the program scope to include some form of persistence, an entity bean may also be warranted.)

The Three Key Parts of a Session Bean
For our present purposes we'll use PowerJ 3.5 to define the needed session bean, which we'll call CrapsEJB. It'll assist us in developing the three required items we must write to properly code a session bean. These three pieces - the home interface, the remote interface and the implementation bean - must be deployed to any application server supporting the EJB specification, such as EAServer. Let's briefly discuss each of these three parts.

The implementation bean houses the particular business logic that supports a given application. This bean resides solely on the server and is accessed by client applications (e.g., servlets, applets, other EJBs) calling its exposed (public) methods. For client applications to issue legal method calls to this bean, they must use two client-side stub classes that declare these methods. One stub implements the home interface and the other the remote interface, defined next. The stubs are generated automatically by EAServer and are easily accessible through PowerJ's drag-and-drop interface.

The home interface exposes an EJB's life-cycle methods. It's implemented by the home stub, allowing a client to indirectly create, find and remove specific bean instances from EAServer. We use the term indirectly because at deployment time EAServer will also implement the home interface to build a server-side object called EJBHome. This object will act as a go-between for the client home stub and the server (i.e., container), functioning as a factory for new runtime EJB instances. The developer must implement key factory methods of the home interface, but PowerJ makes this job easy.

The remote interface exposes the business methods. It's implemented by the remote stub, allowing a client to indirectly call the corresponding methods residing on the server within a bound implementation bean. As with the home interface, there's a "go-between" or wrapper class between the remote stub and the implementation bean. This is called the EJBObject, which is defined by EAServer at deployment time and instantiated at runtime. EJBObject objects will wrap the implementation bean so that method calls to it can now transparently use EAServer-provided logic for common services such as networking, security and transaction management, instance pooling and more. In fact, the implementation bean is essentially unaware that it's even in a distributed environment - making the coding job a whole lot easier for the application developer. As with the home interface, the remote interface must also be coded by the developer before deployment - a task once again made easy by PowerJ, as you'll see firsthand.

Although the EJB architecture can seem confusing at first, the headache of understanding and writing API calls for important low-level services is considerably reduced when compared with other distributed component models, in addition to the important benefits of true portability and reusability. Do some additional outside reading or enroll in a class, as these few paragraphs can hardly do these topics justice.

PowerJ's EJB Wizard
As mentioned before, the reason PowerJ is helpful is that it automatically sets up these three important EJB parts and maintains them as a united set whenever the developer defines a new session or entity bean. Let's see how this works with our craps example.

There are six steps we'll walk through to create our CrapsEJB session bean.

Step 1: Create a new EJB component.

  • Start PowerJ and then Jaguar Server on your workstation. (Both should be at the 3.5 release or higher.)
  • To create a new workspace in PowerJ, select File—>New Workspace from the PowerJ menu and name it VegasCraps.wxj.
  • From the main PowerJ menu, select File—> New...and then select the EJB 1.0 (or 1.1 if using EAServer 3.6) component from the target tab. Select OK, which will initiate the EJB wizard for you.
  • Fill in the Jaguar Component wizard pages using Table 2 as a reference. If you're prompted for an option not shown, then accept the default value.

  • Save your workspace. You'll be brought automatically into the PowerJ code editor, viewing Casino.CrapsEJBBean. This is the implementation bean. Close the code editor for now, then click the Save Workspace icon to save the EJB target.
  • Select View—> Workspace on the PowerJ main menu. The window in Figure 3 should appear.

From the Workspace tab you can then see that all three critical EJB items were built for you by PowerJ. Casino.CrapsEJB is the remote interface discussed above; Casino.CrapsEJBBean is the implementation class; Casino.CrapsEJBHome is the home interface.

You'll also see what appears to be a blank square form. Although EJBs are nonvisual components, this design-time-only form allows the developer to use PowerJ's excellent drop-and-drag facilities during development time. You can close this form as it won't be needed here.

We're going to implement the craps business rules within the CrapsEJB bean using four business methods noted in Table 3.

Whether you use four or some other number of methods, the important task is to define some reasonable number of methods that encapsulate business process subtasks in a meaningful, maintainable and reusable way. As with Java in general, EJB development is strongly object-oriented.

Step 2: Define and code the session bean's three instance variables.
Our session bean will need three class variables. The first is an integer needed to store the game point. Another class variable is an integer array of the game's dice roll history for eventual user review. The third is a subscript variable to reference items within this array.

To code these variables, go to the Views window, Workspace tab, and open the Craps- EJB target's implementation bean, Casino. CrapsEJBBean. Then double-click on Data Members and PowerJ will launch the code editor and position the cursor right at the comment line "//add your data members here." You should type in:

// The history array of dice rolls:
private int[] crapsrolls;
// The array subscript:
private int arrayidx;
// The current point for use in //pointRoll() method:
private int point;
Step 3: Define and code the session bean's four business methods.
This step consists of four substeps - one for each method. When you define a new method from the Views window, Workspace tab, simply right-click on the remote interface (in the case of public methods) or on the implementation bean (in the case of private methods) within the CrapsEJB session bean's target. Select Insert—> Method. You'll get a popup window similar to the one in Figure 4. You must type in the case-sensitive method name in the first box (if present) and then the method signature (i.e., prototype) in the second box. For our example you'll need to do this four times as described below - once per method. For the public newCrapsGame() method you must right-click on the remote interface (Casino.CrapsEJB) since clients can access business methods only through an EJB's remote interface. However, the other methods are private (never invoked by clients) and thus you should right-click on the bean implementation class (Casino.CrapsEJBBean) itself. These private methods are part of the "black box" that hides the implementation details and can be enhanced with zero impact on client applications.

Let's define and code the four methods.

1. Define the newCrapsGame() method.
Right-click on the CrapsEJB (remote interface) object, insert a new method by selecting Insert—>Method and fill in this wizard with this signature (i.e., prototype):

Prototype:     public int[] newCraps
Game() throws java.rmi.RemoteException
Once you click Finish, PowerJ will open up the code editor automatically and position the cursor in the spot where you need to code the logic for this method, right after a comment labeled "//TO DO". Then, with the menu options Edit—> Insert from File, import Listing 1.

When the code import is completed, the PowerJ code editor should show your new method (see Figure 5).

Note from the window title that this is coded in the bean implementation package and class (Casino.CrapsEJBBean), which is exactly where it belongs. Even though you initially defined the method in the remote interface (CrapsEJB), PowerJ knew that the actual code for this method must go inside the bean implementation class. If you examine the remote interface, you'll see that PowerJ also put the prototype for the newCrapsGame there as well, which is also needed.

How Does newCrapsGame Method Work?
Let's review this code. The total for each roll of two dice during one complete craps game is stored in an array of primitive integers. Since there are two dice, the values in this array can vary from 2 through 12. Consistent with our business rules, the method will first call the comingOutRoll method to establish the game point. Then, if no immediate win or loss occurs, it'll repeatedly call the pointRoll method until a win or loss takes place. The crapsrolls integer array allows for 200 elements - more than sufficient for even the longest-running craps game. Each roll value gets stored in this array.

Since the values of 0 and 1 can never occur when rolling two dice, we'll use them instead as special flag values within the roll-history array. Both values indicate the game is over. However, note that a 0 means a loss occurred whereas a 1 flags a win. Thus, either a 0 or 1 will signal that the game ended with the preceding array element.

Close the code editor and return to the Views window of PowerJ. Insert the next three methods, since they're private, via a right-click on the bean implementation class (CrapsEJBBean) as opposed to the remote interface, for reasons discussed earlier.

2. Define the comingOutRoll() method.
Right-click on the CrapsEJBBean object, insert a new method and fill in the wizard as noted:

Method Name:    comingOutRoll()
Prototype: private void coming
OutRoll() throws java.rmi.RemoteException
Import filename:    CrapsEJBcomingOutRoll.txt
(See Listing 2 for filename.)

This method will roll two dice (via the rolldie() method). It is called by newCrapsGame(). The total is stored in the class variable "point" and in the first element of the array. Recall: if the value is a 2, 3 or 12, then a loss results and a 0 is placed in the next element of the roll history array. If the value is 7 or 11, we have a win, so a 1 is put there instead. If the roller neither wins or loses (i.e., a "point" is established), neither a 1 nor a 0 goes in the array. Hopefully, your imported code should implement this description. Take this chance to review it.

3. Define the pointRoll() method.
Right-click on the CrapsEJBBean object, insert a new method and fill in the wizard as noted:

Method Name:    pointRoll()
Prototype: private void pointRoll() throws java.rmi.RemoteException
Import filename:    CrapsEJBpointRoll.txt
(See Listing 3 )for filename.)

This method (also called by newCrapsGame()) will roll two dice and determine if the previously established point was rolled a second time (a win) or a 7 was rolled (a loss). This roll gets stored in the next available element in the dice-roll history array. The method then compares this latest roll to what was stored earlier in the comingOutRoll() method. If a win or loss occurred, a 1 or 0 is also added to the array in the next available slot. As before, double-check your imported code for a closer look at how it works.

4. Define the rolldie() method.
Right-click on the CrapsEJBBean object, insert a new method and fill in the wizard as noted:

Method Name:    rolldie()
Prototype: private int rolldie() throws java.rmi.RemoteException
Import filename: CrapsEJBrolldie.txt
(See Listing 4 for file name.)

This method generates a uniformly random number between 1 and 6, simulating a die roll. To get a proper simulation of two real dice, we'll need to call this method twice per craps roll.

At this point your Views window should show all four methods noted above. You can clearly see them all on the left pane of the Workspace tab in Figure 6. The other methods you see, such as ejbPassivate and ejbActivate, are life-cycle methods required by the specification but infrequently coded (as will be the case here). They allow the developer to code particular resource management tasks for server-triggered events.

Step 4: Build and deploy your EJB to EAServer.
First, be sure your EAServer 3.5 (or higher) engine is running, per Step 1.

Recall that the PowerJ EJB wizard built two targets for you. One is CrapsEJB, which houses the home interface, the remote interface and the implementation bean. The other is CrapsEJBAll, which consolidates all these (plus a deployment descriptor file) into a single Java JAR file. While we edit objects in the first target, we actually deploy the second target. This makes both the deployment process and the subsequent Jaguar repository management effort much easier. CrapsEJBAll is considered dependent on CrapsEJB.

We have three substeps to follow:

  1. Build the CrapsEJB target.
    Select the CrapsEJB target in the Views window, Workspace tab. Then right-mouse click and select the Build option. If all went well with the earlier steps, you should get no errors. Review the previous steps carefully if you do receive an error. Also, you may wish to be sure your NT System Variable "Classpath" is set to be consistent with PowerJ documentation.

  2. Set up your deployment options.
    Right-mouse click on the JAR target CrapsEJBAll and select the Deploy and Run options. Be sure the Deploy tab indicates to Deploy Components to Jaguar CTS as shown in Figure 7.

    This verifies that you'll be deploying to localhost port 9000 with the default Jaguar ID of "jagadmin" (and no password). It also confirms the name of your Jaguar package, bean implementation class and remote interface. Click on OK to close the window.

  3. Deploy the CrapsEJBAll JAR file.
    You can deploy quite effortlessly by right-clicking the CrapsEJBAll target and selecting the Deploy option.

    To view the deployment activity progress you'll see a popup window appear. It may take a minute or two to complete. Try watching the status text as it changes to see how many steps are being automated for you.

Step 5: Verify the deployment through Jaguar Manager.
To quickly check if the EJB was in fact deployed to EAServer, you can launch Jaguar Manager (also called Sybase Central - Java edition) and connect to your Jaguar Server using the menu options of Tools —> Connect —> Jaguar Manager. The window that pops up will ask for four parameters:

User Name:    jagadmin
Password:     <none>
Host Name:    localhost
Port Number:     9000

Click on the Servers folder and under that the Jaguar folder, and finally the Installed Packages folder. You should see a package Casino with our new component named CrapsEJB. You can click on Interfaces and then on the remote interface Casino::CrapsEJB to verify that the newCrapsGame method is now available.

Correspondingly, the home interface CrapsEJBHome has the create() method automatically set up for us by PowerJ. The client servlet will use this to instantiate a session bean. Figure 8 is a snapshot of the Jaguar Manager window with the Casino package exploded and the remote interface (CrapsEJB) highlighted.

You've now completed the first of our two overall tasks: you've built a working session bean EJB. It's now time to build our servlet. Bear in mind that although we'll use a servlet in Part 2, many types of clients can invoke EJBs hosted by EAServer. These include Java Applets, ActiveX, CORBA and PowerBuilder clients. This openness, coupled with a similar open standard for server-side component language support (in addition to EJB, that is), is one of EAServer's important and unique strengths within the application server marketplace.

Step 6: Test the EJB from an applet.
I've put together a simple applet that you may use if you wish to test your work thus far (prior to using the servlet in Part 2 of this article). You can unzip the CrapsAplt.Zip file found with the code for this article. The files it contains must be extracted into your %JAGUAR%\html\classes subdirectory. Generally, %JAGUAR% translates as C:\Program Files\Sybase\Jaguar CTS 3.5 for most users, but you can verify this by examining your Jaguar System Variable on the Control Panel's System icon. You may have installed Jaguar somewhere other than the default location.

The CrapsAplt.Zip file has three Java class files, their corresponding source Java files and a file called crapsindex.html. Once the files are extracted and your EJB is deployed, you can test the EJB by launching Internet Explorer and providing the following URL: http://localhost:8080/classes/indexcraps.html.

This should launch a simple applet that calls the session bean you wrote and deployed earlier. Stay tuned for Part 2 to learn about servlets and EAServer.

Part 1 of this article has discussed how to use EJB technology to implement the rules for the basic "Pass Line" bet at the craps table. We wrote a session bean EJB to house these business rules within Sybase's EAServer J2EE application server, making the EJB very reusable to a wide variety of clients. One such client can be an HTTP servlet (which in turn has its clients, namely browsers). We'll write such a servlet in Part 2 of this article, so drop back in for that discussion.

More Stories By Dan Weisberg

Dan can be contacted at:
[email protected]

Comments (0)

Share your thoughts on this story.

Add your comment
You must be signed in to add a comment. Sign-in | Register

In accordance with our Comment Policy, we encourage comments that are on topic, relevant and to-the-point. We will remove comments that include profanity, personal attacks, racial slurs, threats of violence, or other inappropriate material that violates our Terms and Conditions, and will block users who make repeated violations. We ask all readers to expect diversity of opinion and to treat one another with dignity and respect.