Tutorial: creating distributed applications in CORBA

Note: Only the Client/Server version of JBuilder ships with distributed applications features.

This tutorial helps you become acquainted with some of the JBuilder and VisiBroker for Java development tools, and describes how to develop a distributed, object-based application using JBuilder and VisiBroker for Java. A sample application is used to illustrate each step of the process. The Bank application explains how to build a sample client application that can query on the balance in a bank account. Extending the banking application to be an applet explains how to design a graphical user interface (GUI) for the applet, and how to write the necessary code to handle the GUI events.

For more information about Common Object Request Broker Architecture (CORBA), link to


The Bank application

In this tutorial, you will build a sample client application that can query on the balance in a bank account. To build this distributed application in JBuilder, you will need to

The code for this example is provided in the jbuilder\samples\visibroker\samples\bank directory where JBuilder was installed. The following files are provided:

When you develop distributed applications, you must first identify the objects required by the application.

The following figure illustrates the steps needed to develop the sample application.

Developing the sample Bank application.



Defining the interface for the CORBA object

The Bank.idl file defines the Bank module that contains two interfaces. The Account interface provides a method for obtaining the current balance. The AccountManager interface provides a method that opens an account with a specified name and returns an Account object reference. The Account object reference can then be used to obtain the balance in the account.

To create and enter the code for the IDL file,

  1. Select File|Close All from the JBuilder menu to close any existing projects.

  2. Select File|New Project to create a new project. Change the File Name to Bank.jpr and click Finish. The JBuilder AppBrowser appears.

  3. Create a new IDL file, Bank.IDL by selecting File|Open/Create. Enter Bank.IDL in the File Name field. Check the Add To Project button. Click Open. A new, empty IDL file is created and added to the project.

  4. Add the following IDL code to this file by selecting the file in the Navigation pane, and typing directly into the Source window to its right. For more information on writing IDL code, see http://www.omg.org/corba/cichpter.htm#idls&s for IDL syntax and semantics.

Bank.idl provides the Account and AccountManager interface definitions.
IDL:
module Bank {
    interface Account {
        float balance();
    };
    interface AccountManager {
        Account open(in string name);
    };
};

Compiling the CORBA interface definitions to generate Java code

The VisiBroker IDL compiler, named idl2java, generates Java code from a file containing IDL specifications. Since the Bank.idl file requires no special handling, you can compile it by

  1. Right-clicking on the IDL file in the Navigation pane.
  2. Selecting Rebuild.

Code Generation

Since Java allows only one public interface or class per file, compiling the Bank.idl file will generate several Java files. These files are stored in a sub-directory named Bank, which is the module name specified in the IDL file. IDL modules are mapped to Java packages, so all of the files listed below will be part of the Bank package.

For more information about the Helper, Holder, and Operations classes, see the "Generated Classes" chapter in the VisiBroker for Java Reference Manual, at http://www.visigenic.com/techpubs/htmlhelp/vbj30/ref/frames/vbj_4.htm.


Implement the CORBA interface

To implement the CORBA interface,

  1. Create a new file by selecting File|Open/Create. Name the file AccountImpl.java. Check Add To Project, and click Open.

  2. Add the following code by selecting the file in the Navigation pane and entering the code in the Source window.

    AccountImpl.java contains the implementation of the Account object.


    package visibroker.samples.bank;
    
    public class AccountImpl extends Bank_AccountImplBase {
      public AccountImpl(float balance) {
        _balance = balance;
      }
      public float balance() {
        return _balance;
      }
      private float _balance;
    }
    

  3. Create a new file by selecting File|Open/Create. Name the file AccountManagerImpl.java. Check Add To Project, and click Open.

  4. Add the following code by selecting the file in the Navigation pane and entering the code in the Source window.

    AccountManagerImpl.java contains the implementation of the Account Manager object.


    package visibroker.samples.bank;
    
    import java.util.*;
    
    public class AccountManagerImpl extends Bank._AccountManagerImplBase {
      public AccountManagerImpl(String name) {
        super(name);
      }
      public synchronized Bank.Account open(String name) {
        
        // Lookup the account in the account dictionary.
        Bank.Account account = (Bank.Account) _accounts.get(name);
    
        // If there was no account in the dictionary, create one.
        if(account == null) {
    
          // Make up the account's balance, between 0 and 1000 dollars.
          float balance = Math.abs(_random.nextInt()) % 100000 / 100f;
    
          // Create the account implementation, given the balance.
          account = new AccountImpl(balance);
    
          // Make the object available to the ORB.
          _boa().obj_is_ready(account);
    
          // Print out the new account.
          System.out.println("Created " + name + "'s account: " + account);
    
          // Save the account in the account dictionary.
          _accounts.put(name, account);
        }
    
        // Return the account.
        return account;
      }
      private Dictionary _accounts = new Hashtable();
      private Random _random = new Random();
    }
    

Create the client

Many of the files used in implementing the bank client are contained in the Bank package generated when the IDL file is compiled. However, you need to create the Client.java file.

Client.java

The client class implements the client application that obtains the current balance of a bank account.

  1. Create a new file with File|Open/Create. Name the file Client.java. Check Add To Project, and click Open.

  2. Enter the following code by selecting Client.java in the Navigation pane and typing this code into the Source window.

Client.java provides the client side program, written in Java.


CODE:
// Client.java

public class Client {

  public static void main(String[] args) {

      // Initialize the ORB.
      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);

      // Locate an account manager.
      Bank.AccountManager manager = 
        Bank.AccountManagerHelper.bind(orb,"BankManager");

      // use args[0] as the account name, or a default.
      String name = args.length > 0 ? args[0] : "Jack B. Quick";

      // Request the account manager to open a named account.
      Bank.Account account = manager.open(name);

      // Get the balance of the account.
      float balance = account.balance();

      // Print out the balance.
      System.out.println
        ("The balance in " + name + "'s account is $" + balance);
    }
  }

The program performs the following steps:

AccountManagerHelper.java

This file is located in the Bank package. It contains an AccountManagerHelper object and defines several methods for binding to the server that implements this object. The bind method transparently contacts a Smart Agent, described in The Smart Agent (see http://www.visigenic.com/techpubs/htmlhelp/vbj30/pg/frames/vbj_10.htm), to locate the object. Our example application uses the version of the bind method that accepts an object name, but the client may optionally specify a particular host and special bind options.

For information on these additional methods, see the "Specifying Bind Options", at http://www.visigenic.com/techpubs/htmlhelp/vbj30/pg/frames/vbj_4_8.htm. For more information about Helper classes, see the "Generated Classes" chapter in the VisiBroker for Java Reference Manual at http://www.visigenic.com/techpubs/htmlhelp/vbj30/ref/frames/vbj_4.htm.

The bind Method

When your application invokes the bind method, the ORB locates and establishes a connection with an appropriate server and returns a handle to the AccountManager object. If the ORB cannot locate or connect to the Bank.AccountManager server object, the bind method will raise a CORBA system exception.

Other Methods

Several other methods are provided that allow your client application to manipulate an AccountManager object reference. Most of these methods are not used in the example client application, but they are described in detail in the VisiBroker for Java Reference Manual at http://www.visigenic.com/techpubs/htmlhelp/vbj30/ref/startme.htm.

_st_AccountManager.java

This file is located in the Bank package. It contains the stub code for the AccountManager object on the client side. In the example, the client uses the AccountManager object open method to open an account.

The open method generated when the IDL file was compiled is really a stub method. When your client application calls the open method, a request is sent to the ORB with all the necessary parameters. The ORB ensures that the request is sent to the server that implements the AccountManager object. Once the method is executed on the server, the ORB returns the results to your client application.

Caution: Do not modify this generated file.

_st_Account.java

This file is located in the Bank package. It contains the stub code for the Account object on the client side. In the example, the client uses the Account object balance method to obtain an account balance.

The balance method generated when the IDL file was compiled is also a stub method. When your client application calls the balance method, a request is sent to the ORB with all the necessary parameters. The ORB ensures that the request is sent to the server that implements the Account object. Once the method is executed on the server, the ORB returns the results to your client application.

Caution: Do not modify this generated file.


Create the CORBA server

Just as with the client, many of the files used in implementing the bank server are contained in the Bank package generated when the IDL file was compiled. The Server.java file is a server implementation that you create. A simple server can be created with the Generate CORBA Server Wizard, accessed by selecting CORBA Server from the Visibroker tab of the File|New menu.

Server.java

This file implements the Server class for the server-side of our banking example.

To create Server.java,

  1. Create a new CORBA Server by selecting File|New. Select the VisiBroker tab.
  2. Double-click CORBA Server.
  3. Change the file name to Server.java. Click OK.
  4. Modify the as follows:

A portion of the Server.java file, showing the server implementation.


CODE:
// Server.java

public class Server {

  public static void main(String[] args) {

      // Initialize the ORB.
      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);

      // Initialize the BOA.
      org.omg.CORBA.BOA boa = orb.BOA_init();

      // Create the account manager object.
      Bank.AccountManager manager = 
      new AccountManagerImpl("BankManager");

      // Export the newly created object.
      boa.obj_is_ready(manager);
      System.out.println(manager + " is ready.");

      // Wait for incoming requests
      boa.impl_is_ready();
    }
}

The Server class does the following:

The AccountManagerImpl class in this file extends the Bank._AccountManagerImplBase class generated in the Bank package. This class provides the actual implementation of the open method used to obtain or create an Account. The manager uses a Dictionary to contain all the accounts. When a request to open an account is received, the open method does the following:

A portion of the AccountManagerImpl.java file, showing the AccountManager implementation.
CODE:
// AccountManagerImpl.java
import java.util.*;
public class AccountManagerImpl extends Bank.AccountManagerImplBase {

  public AccountManagerImpl(String name) {
    super(name);
  }
  public synchronized Bank.Account open(String name) {

    // Lookup the account in the account dictionary.
    Bank.Account account = (Bank.Account) _accounts.get(name);

    // If the account is not in the dictionary, create an account.
    if(account == null) {

      // Create a new account with between 0 and 1000 dollars.
      float balance = Math.abs(_random.nextInt()) % 100000 / 100f;
      account = new AccountImpl(balance);

      // Make the object available to the ORB.
      _boa().obj_is_ready(account);
      System.out.println("Created " + name + "'s account: " + account);

      // Save the account in the account dictionary.
      _accounts.put(name, account);
    }
    // Return the account.
    return account;
  }
  private Dictionary _accounts = new Hashtable();
  private Random _random = new Random();
}

The AccountManager Class Hierarchy

The AccountManagerImpl server class that you implement extends the Bank package's _AccountManagerImplBase class that was generated by the CORBA Settings Wizard. The skeleton class, _AccountManagerImpl, implements the AccountManager interface.


Building the example programs

To build the example program, select Build|Make Project Bank.jpr.

If you encounter errors during the build process, see the FAQ at ORB Central on the Visigenic Web site at http://www.visigenic.com.

Starting a Smart Agent (OsAgent)

The Smart Agent, or OsAgent, provides a fault-tolerant object location service. Ordinarily, you will want the OsAgent to be running on at least one machine in the LAN environment for you to run your applications. The Smart Agent is described in detail in The Smart Agent, at http://www.visigenic.com/techpubs/htmlhelp/vbj30/pg/frames/vbj_10.htm

Start Smart Agent by selecting Tools|VisiBroker Smart Agent from the JBuilder menu. This option is toggled on when there is a check mark to the left, and is toggled off when there is not a check mark to the left.

Running the Server

Now, you can start the server by running Server.java. Running Server.java invokes the virtual machine and offers other special features. For command-line options and more information, see "Commands" in the VisiBroker for Java Reference Manual, at http://www.visigenic.com/techpubs/htmlhelp/vbj30/ref/frames/vbj_p.htm.

To run Server.java, select the file in the Navigation pane, then select Run|Run from the JBuilder menu.

Running a Client

After starting the Smart Agent and the server, a client can be started in a different window, using either command-line options or by selecting Client.java in the Navigation pane and selecting Run|Run from the menu. If a command-line argument is provided to the client, that argument will be used as the name of the bank account to be opened:

Running the bank client application.
prompt> vbj Client
The balance in Jack B. Quick's account is $71.62

prompt> vbj Client "Jack Sprat"
The balance in Jack Sprat's account is $322.38

Since the account balance is computed randomly, the actual output you see will differ from that shown above. If you encounter problems running the client application, refer to The VisiBroker for Java GateKeeper Guide at http://www.visigenic.com/techpubs/#VBJLink.

Since the Server prints out a message every time it creates a new Account, you will see the following output on the server side:

Output from the bank server.
prompt> vbj Server
AccountManager[Server,oid=...] is ready.

Created Jack B. Quick's account: Account[Server,oid=...]

Created Jack Sprat's account: Account[Server,oid=...]

Deployment

VisiBroker is also used in the deployment phase. This phase occurs when a developer has created client programs or server applications that have been tested and are ready for production. At this point a system administrator is ready to deploy the client programs on end-users' desktops or server applications on server-class machines.

For deployment, the VisiBroker ORB supports client programs on the front end. You must install the ORB on each machine that runs the client program. Clients (that make use of the ORB) on the same host share the ORB. The VisiBroker ORB also supports server applications on the middle tier. You must install the full ORB on each machine that runs the server application. Server applications or objects (that make use of the ORB) on the same server machine share the ORB.

JBuilder includes a single DEVELOPMENT LICENSE of VisiBroker for Java 3.0 "Developer Version". This license must be used in conjunction with JBuilder. Additional licenses for multiple server machines on NT, UNIX, and MVS may be required during development.


Extending the banking application to be an applet

This section describes how to design Java applets that run VisiBroker applications, and how to use the GateKeeper which enables VisiBroker applets to communicate with object servers across large networks while still conforming to the security restrictions imposed by Web browsers.

Overview

In this topic, you will extend the banking client application to be an applet that can be run from any Java-enabled browser using these steps:

The GUI for this example will consist of four components that form a two-by-two grid:

Label(Account Name)

TextField(Account Name)

Button(Check Balance)

TextField(Account Balance)

To cause the Account Balance text field to be updated, the user will fill in the Account Name text field and then press the Check Balance button. If you are familiar with the JBuilder development environment, you can follow these steps to create the applet and accompanying HTML file. If not, create a new file called Applet1.java (be sure to add it to the project), and enter the following code:


CODE:
public boolean actionPerformed(Event ev, Object arg) {
     if(ev.target == _checkBalance) {
          // Request the account manager to open a named account.
          // Get the account name from the name text widget.
          Bank.Account account = _manager.open(_nameField.getText());
          // Set the balance text widget to the account's balance.
          _balanceField.setText(Float.toString(account.balance()));
          return true;
          }
     return false;
}

  1. Select File|New. Double-click the Applet icon to start the Applet Wizard. Click Next to move to page 2.

  2. Click Next to move to page 3.

    Click Finish.

  3. Select Applet1.java in the Navigation pane. Select the Design tab.

  4. From the JBCL tab, add components to the UI Designer as shown in the example above:

  5. With the ButtonControl still selected, click the Events tab of the Inspector. Double-click the actionPerformed event. Add this code to the actionPerformed method in the Source window at the location of the cursor:

You need to provide the code to an actual call to the bank manager and bank account. The code will get the account name from the first TextField, use it to open an account, and then fill in the second TextField with the account balance.

Bank.Account account = _manager.open(_nameField.getText());
_balanceField.setText(Float.toString(account.balance()));

The final step is to incorporate this new code into your existing client program. You will also need to write the exception handling code and the ORB initialization code again.

Note: The ORB is initialized by passing the Applet as an argument to the ORB_init(Applet) method.

The complete client program is shown below. For information about all of the available methods, see the VisiBroker for Java Reference Manual at http://www.visigenic.com/techpubs/.

The complete client applet.
CODE:
// Applet.java

import java.awt.*;

public class Applet extends java.applet.Applet {
    private TextField _nameField, _balanceField;
    private Button _checkBalance;
    private Bank.AccountManager _manager;
    public void init() {
      // This GUI uses a 2 by 2 grid of widgets.
      setLayout(new GridLayout(2, 2, 5, 5));
      // Add the four widgets.
      add(new Label("Account Name"));
      add(_nameField = new TextField());
      add(_checkBalance = new Button("Check Balance"));
      add(_balanceField = new TextField());
      // make the balance text field non-editable.
      _balanceField.setEditable(false);
      // Initialize the ORB (using the Applet).
      org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(this);
      // Locate an account manager.
      _manager = Bank.AccountManagerHelper.bind(orb, "BankManager");
    }
    public boolean action(Event ev, Object arg) {
      if(ev.target == _checkBalance) {
        // Request the account manager to open a named account.
        // Get the account name from the name text widget.
        Bank.Account account = _manager.open(_nameField.getText());
        // Set the balance text widget to the account's balance.
        _balanceField.setText(Float.toString(account.balance()));
        return true;
    }
    return false;
  }
}

Incorporating the applet into HTML

The following HTML is used to embed the Applet in a simple page. Click Applet1.html in the Navigation pane and click the Source tab to make any modifications to this file.

HTML used to embed Applet.
CODE:
<h1>VisiBroker Client Applet</h1>
<hr>
<center>
    <applet
      code=Applet.class
      width=200 height=80>
      <h2>You are probably not running a Java-enabled browser,
      Please use a Java-enabled browser (or enable your browser for
      Java)...</h2>
    </applet>
</center>
<hr>

This HTML does the following:

The Gatekeeper

The GateKeeper enables VisiBroker applets to communicate with object servers across large networks while still conforming to the security restrictions imposed by Web browsers. The GateKeeper may also be used as a Web server. For more information about the GateKeeper, refer to The VisiBroker for Java GateKeeper Guide, at http://www.visigenic.com/techpubs.

Using the appletviewer

Now you are ready to run the applet. It is usually best to run the example from the appletviewer before running it from your browser. The appletviewer can be started using the following command:

  1. Select Applet1.HTML in the Navigation pane.
  2. Select Run|Run from the menu.

If you have trouble running the client applet, you can refer to The VisiBroker for Java GateKeeper Guide, at http://www.visigenic.com/techpubs, or to the Building Applications with JBuilder topic Running applets.

Running the Example

After testing your applet with the appletviewer, you are now ready to run the applet from a Java-enabled browser. Be sure you are using a Web browser that supports Java 1.0 release or later. The URL for the applet has the following format:

http://<machine-name>[:<port-number>]/<file-name> 

The URL is composed of the following components:

ComponentDescription
<machine-name> The name of the host that is running the HTTP server.
<port-number> This should be 15000 if you are using the GateKeeper as the HTTP server. Otherwise, it should be set to the port number of your HTTP server. If the port number is not specified in the URL, a default port number of 80 is used.
<file-name> This should be Applet.html.

For example, if Applet.html resides in the directory pub/applets on machine foo.bar.com and the GateKeeper was started from that directory, the URL would be

http://foo.bar.com/pub/applets/Applet.html

If you were using the GateKeeper as your development Web server on the machine "foo.bar.com", the URL would be

http://foo.bar.com:15000/Applet.html 

If the Gatekeeper was started in a directory different than the directory where the server is running, the entire path must be specified and double slashes must be used.

http://foo.bar.com:15000//vbroker/java_examples/bank/Applet.html

Every time the browser requests a Java class, the IIOP GateKeeper will print a status message to stdout. If the Web server encounters errors in loading the file, it will also print error messages to stderr.


Other sample applications

Other examples using VisiBroker and JBuilder are located in the jbuilder\samples\visibroker\samples\ directory.