VisiBroker for Java Developer’s Guide : Developing an example application with VisiBroker

Developing an example application with VisiBroker
This section uses an example application to describe the development process for creating distributed, object-based applications for Java.
The code for the example application is provided in the bank_agent_java.html file. You can find this file in:
<install_dir>/examples/vbroker/basic/bank_agent/
Development process
When you develop distributed applications with VisiBroker, you must first identify the objects required by the application. The following figure illustrates the steps to develop a sample bank application. Here is a summary of the steps taken to develop the bank sample:
1
IDL is the language that an implementer uses to specify the operations that an object will provide and how they should be invoked. In this example, we define, in IDL, the Account interface with a balance() method and the AccountManager interface with an open() method.
2
With the interface specification described in step 1, use the idl2java or idl2cpp compilers to generate the client-side stubs and the server-side classes for the implementation of the remote objects.
3
To complete the implementation of the client program, initialize the VisiBroker ORB, bind to the Account and the AccountManager objects, invoke the methods on these objects, and print out the balance.
4
To complete the implementation of the server object code, we must derive from the AccountPOA and AccountManagerPOA classes, provide implementations of the interfaces' methods, and implement the server's main routine.
5
6
7
Figure 3
Step 1: Defining object interfaces
The first step to creating an application with VisiBroker is to specify all of your objects and their interfaces using the OMG's Interface Definition Language (IDL). The IDL can be mapped to a variety of programming languages.
You then use the idl2java compiler to generate stub routines and servant code compliant with the IDL specification. The stub routines are used by your client program to invoke operations on an object. You use the servant code, along with code you write, to create a server that implements the object.
Writing the account interface in IDL
IDL has a syntax similar to Java and can be used to define modules, interfaces, data structures, and more.
The sample below shows the contents of the Bank.idl file for the bank_agent example. The Account interface provides a single method for obtaining the current balance. The AccountManager interface creates an account for the user if one does not already exist.
module Bank{
interface
Account {
float balance();
};
interface AccountManager {
Account open(in string name);
};
};
Step 2: Generating client stubs and server servants
The interface specification you create in IDL is used by VisiBroker's idl2java compiler to generate Java classes for the client program, and skeleton code for the object implementation.
The client program uses the Java class for all method invocations.
You use the skeleton code, along with code you write, to create the server that implements the objects.
The code for the client program and server object, once completed, is used as input to your Java compiler to produce the client and server executables classes.
Because the Bank.idl file requires no special handling, you can compile the file with the following command.
prompt> idl2java Bank.idl
For more information on the command-line options for the idl2java compiler, see “Using IDL”.
Files produced by the idl compiler
Because Java allows only one public interface or class per file, compiling the IDL file will generate several .java files. These files are stored in a generated sub-directory called Bank, which is the module name specified in the IDL and is the package to which the generated files belong. The following is a list of .java files generated:
_AccountManagerStub.java: Stub code for the AccountManager object on the client side.
_AccountStub.java: Stub code for the Account object on the client side.
Account.java: The Account interface declaration.
AccountHelper.java: Declares the AccountHelper class, which defines helpful utility methods.
AccountHolder.java: Declares the AccountHolder class, which provides a holder for passing Account objects.
AccountManager.java: The AccountManager interface declaration.
AccountManagerHelper.java: Declares the AccountManagerHelper class, which defines helpful utility methods.
AccountManagerHolder.java: Declares the AccountManagerHolder class, which provides a holder for passing AccountManager objects.
AccountManagerOperation.java: This interface provides the method signatures defined in the AccountManager interface in Bank.idl.
AccountManagerPOA.java: POA servant code (implementation base code) for the AccountManager object implementation on the server side.
AccountManagerPOATie.java: Class used to implement the AccountManager object on the server side using the tie mechanism, described in “Using the tie mechanism”.
AccountOperations.java: This interface provides the method signatures defined in the Account interface in the Bank.idl file
AccountPOA.java: POA servant code (implementation base code) for the Account object implementation on the server side.
AccountPOATie.java: Class used to implement the Account object on the server side using the tie mechanism, described in “Using the tie mechanism”.
Step 3: Implementing the client
Client.java
Many of the classes used in implementing the bank client are contained in the Bank package generated by the idl2java compiler as shown in the previous example.
The Client.java file illustrates this example and is included in the bank_agent directory. Normally, you would create this file.
The Client class implements the client application which obtains the current balance of a bank account. The bank client program performs these steps:
1
2
Binds to an AccountManager object.
3
Obtains an Account object by invoking open on the AccountManager object.
4
Obtains the balance by invoking balance on the Account object.
public class Client {
public static void main(String[] args) {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// Get the manager Id
byte[] managerId = "BankManager".getBytes();
// Locate an account manager. Give the full POA name and servant ID.
Bank.AccountManager manager =
Bank.AccountManagerHelper.bind(orb, "/bank_agent_poa", managerId);
// 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);
}
}
Binding to the AccountManager object
Before your client program can invoke the open(String name) method, the client must use the bind() method to establish a connection to the server that implements the AccountManager object.
The implementation of the bind()method is generated automatically by the idl2java compiler. The bind() method requests the VisiBroker ORB to locate and establish a connection to the server.
If the server is successfully located and a connection is established, a proxy object is created to represent the server's AccountManagerPOA object. An object reference to the AccountManager object is returned to your client program.
Obtaining an Account object
Next, your client class needs to call the open() method on the AccountManager object to get an object reference to the Account object for the specified customer name.
Obtaining the balance
Once your client program has established a connection with an Account object, the balance() method can be used to obtain the balance. The balance() method on the client side is actually a stub generated by the idl2java compiler that gathers all the data required for the request and sends it to the server object.
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() class method contacts the specified POA manager to resolve 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 more information about Helper classes, see “Helper classes”.
package Bank;
public final class AccountManagerHelper {
...
public static Bank.AccountManager bind(org.omg.CORBA.ORB orb) {
return bind(orb, null, null, null);
...
}
}
Other methods
Several other methods are provided that allow your client program to manipulate an AccountManager object reference.
Many of these methods and member functions are not used in the example client application, but they are described in detail elsewhere in this Guide.
Step 4: Implementing the server
Just as with the client, many of the classes used in implementing the bank server are contained in the Bank package generated by the idl2java compiler. The Server.java file is a server implementation included for the purposes of illustrating this example. Normally you, the programmer, would create this file.
Server programs
This file implements the Server class for the server side of our banking example. The code sample below is an example of server side programming for Java. The server program does the following:
public class Server {
public static void main(String[] args) {
try {
// Initialize the ORB.
org.omg.CORBA.ORB orb = org.omg.CORBA.ORB.init(args,null);
// get a reference to the root POA
POA rootPoa =
POAHelper.narrow(orb.resolve_initial_references("RootPOA"));
// Create policies for our persistent POA
org.omg.CORBA.Policy[] policies = {
rootPoa.create_lifespan_policy(LifespanPolicyValue.PERSISTENT)
};
// Create myPOA with the right policies
POA myPOA = rootPoa.create_POA( "bank_agent_poa",
rootPoa.the_POAManager(),
policies );
// Create the servant
AccountManagerImpl managerServant = new AccountManagerImpl();
// Decide on the ID for the servant
byte[] managerId = "BankManager".getBytes();
// Activate the servant with the ID on myPOA
myPOA.activate_object_with_id(managerId, managerServant);
// Activate the POA manager
rootPoa.the_POAManager().activate();
System.out.println(myPOA.servant_to_reference(managerServant) +
" is ready.");
// Wait for incoming requests
orb.run();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Step 5: Building the example
The examples directory of your VisiBroker release contains a vbmake.bat for this example and other VisiBroker examples.
Compiling the example
Windows
Assuming VisiBroker is installed in C:\vbroker, type the following to compile the example:
prompt> vbmake
The command vbmake is a batch file which runs the idl2java compiler and then compiles each file.
If you encounter problems while running vbmake, check that your path environment variable points to the bin directory where you installed the VisiBroker software.
UNIX
Assuming VisiBroker is installed in /usr/local, type the following to compile the example:
prompt> make java
In this example, make is the standard UNIX facility. If you do not have it in your PATH, see your system administrator.
Step 6: Starting the server and running the example
Now that you have compiled your client program and server implementation, you are ready to run your first VisiBroker application.
Starting the Smart Agent
Before you attempt to run VisiBroker client programs or server implementations, you must start the Smart Agent on at least one host in your local network.
The basic command for starting the Smart Agent is:
prompt> osagent
The Smart Agent is described in detail in “Using the Smart Agent”.
Starting the server
Windows
Open a DOS prompt window and start your server by typing:
prompt> start vbj Server
UNIX
Start your Account server by typing:
prompt> vbj Server&
Running the client
Windows
Open a separate DOS prompt window and start your client by typing:
prompt> vbj Client
UNIX
To start your client program, type:
prompt> vbj Client
You should see output similar to that shown below (the account balance is computed randomly).
The balance in the account in $168.38.
Deploying applications with VisiBroker
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 VisiBroker ORB on each machine that runs the client program. Clients (that make use of the VisiBroker ORB) on the same host share the VisiBroker ORB. The VisiBroker ORB also supports server applications on the middle tier. You must install the full VisiBroker ORB on each machine that runs the server application. Server applications or objects (that make use of the VisiBroker ORB) on the same server machine share the VisiBroker ORB. Clients may be GUI front ends, applets, or client programs. Server implementations contain the business logic on the middle tier.
Figure 4
VisiBroker Applications
Deploying applications
In order to deploy applications developed with VisiBroker, you must first set up a runtime environment on the host where the application is to be executed and ensure that the necessary support services are available on the local network.
The run-time environment required for applications developed with the Java includes these components:
VisiBroker Java packages archived in the vbjorb.jar file, located in the lib subdirectory where you installed VisiBroker.
A Java Runtime Environment must be installed on the host where the deployed application is to execute, and the VisiBroker packages must be installed on the host where the deployed application is to execute.
Environment variables
When you use the vbj executable, the environmental variables are automatically set up for you.
If the deployed application is to use a Smart Agent (osagent) on a particular host, you must set the OSAGENT_ADDR environment variable before running the application. You can use the vbroker.agent.addr property as a command-line argument to specify a hostname or IP address. The table below lists the necessary command-line arguments.
If the deployed application is to use a particular UDP port when communicating with a Smart Agent, you must set the OSAGENT_PORT environment variable before running the application.
You can use vbroker.agent.port (Java) command-line argument to specify the UDP port number.
For more information about environment variables, see the VisiBroker Installation Guide.
Support service availability
A Smart Agent must be executing somewhere on the network where the deployed application is to be executed. Depending on the requirements of the application being deployed, you may need to ensure that other VisiBroker runtime support services are available, as well. These services include:
Using vbj
You can use the vbj command to start your application and enter command-line arguments that control the behavior of your application.
vbj -Dvbroker.agent.port=10000 <class>
Running the application
Before you attempt to run VisiBroker client programs or server implementations, you must start the Smart Agent on at least one host in your local network. The Smart Agent is described in detail in “Starting the Smart Agent”.
Executing client applications
A client application is one that uses VisiBroker ORB objects, but does not offer any VisiBroker ORB objects of its own to other client applications.
A client may be started with the vbj command, or from within a Java-enabled web browser.
The following table summarizes the command-line arguments that may be specified for a Java client application.
Specifies the size of the intermediate buffer used by VisiBroker for operation request processing. To improve performance, the VisiBroker ORB does more complex buffer management than in previous versions of VisiBroker. The default size of send and receive buffers is 4—4kb. If data sent or received is larger than the default, new buffers will be allocated for each request/reply. If your application frequently sends data larger than 4kb and you wish to take advantage of buffer management, you may use this system property to a specify a larger number of bytes for a default buffer size.
When set to true, all network connections will send data immediately. The default is false, which allows a network connection to send data in batches, as the buffer fills.
Specifies the maximum number of connections allowed for an object implementation when OAid TSession is selected. If you do not specify a value, the default is unlimited.
Specifies the number of milliseconds which a network connection can be idle before being shutdown by VisiBroker. By default, this is set to 360 which means that connections will never time-out. This option should be set for Internet applications.
Executing server applications in Java
A server application is one that offers one or more VisiBroker ORB objects to client applications. A server application may be started with the vbj command or it may be activated by the Object Activation Daemon (oad).
The following table summarizes the command-line arguments that may be specified for a Java server application.
-DOAport <port_number>
Specifies the maximum number of threads allowed when OAid TPool is selected. If you do not specify or you specify 0, this selects unlimited number of threads or, to be more precise, a number of threads limited only by your system resources.
Specifies the maximum number of connections allowed when OAid TSession is selected. If you do not specify, the default is unlimited.
Specifies the time which a connection can idle without any traffic. Connections that idle beyond this time can be shutdown by VisiBroker. By default, this is set to 0, meaning that connections will never automatically time-out. This option should be set for Internet applications.