[ Team LiB ] Previous Section Next Section

Writing RMI Code

To create a WebLogic RMI program, you must write a remote interface (client side), write the server-side implementation of the remote interface, compile (javac) the two classes, execute the weblogic.rmic compiler on the compiled implementation class, and write the RMI client that uses the remote interface. The code listings in later sections are samples for the remote interface, implementation class, and RMI client. Note: The remote interface, implementation class, and weblogic.rmic-generated classes must be available to the WebLogic classpath for execution.

Writing the Remote Interface

Two points to remember when writing a WebLogic RMI remote interface: You must extend the interface java.rm.Remote, and the remote interface must be public. For our distributed computing example, we'll code an RMI that retrieves the bid status (item number, current date, and bid end date) of an auction item. The interface and the RMI client are available to the client box, but the implementation class lives only on the WebLogic Server across a network. Implement the remote interface as shown in Listing 11.1.

Listing 11.1 Remote Interface
package your.package.structure;
/**
 * This interface is the remote interface.
 */
import java.rmi.*;
import javax.ejb.*;

public interface BidStatus extends java.rmi.Remote {
  public String getBidStatus(Integer itemId) throws javax.ejb.FinderException, java.rmi
graphics/ccc.gif.RemoteException;
}

Implementing Your Remote Interface

To implement your remote interface, extend the remote interface and define the methods. For your implementing class name, use the name of the remote interface with the string Impl appended, as shown in Listing 11.2.

The main() method implemented in the sample code allows WebLogic Server to initiate the RMI class as a startup class. The main() method contains the code that registers the RMI class within the WebLogic Registry.

NOTE

A WebLogic startup class initializes at server startup. Startup classes are normally used to create conditions required at server startup, such as application initialization that might include the retrieving and setting of initial data. For more information about WebLogic startup classes, refer to http://e-docs.bea.com/wls/docs81/ConsoleHelp/startup_shutdown.html.


Listing 11.2 Implementing Remote Interface
import javax.naming.*;
import java.util.*;
import weblogic.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import javax.ejb.*;
import com.gams.ejbs.item.*;

public class BidStatusImpl implements BidStatus
{

  private Item item;
  private String BidStatus;
  private int itemIN;
  private ItemHome home;

 /**
  * Constructor.
  *
  * @param itemId         item id
  */
 public BidStatusImpl(Integer itemId) throws FinderException, RemoteException {
  super();
  try {
    findItem(itemId);
    }
  catch (Exception e) {
        System.out.println("BidStatusImpl.constructor: an exception occurred:");
        e.printStackTrace();
  }
 }

 /**
  *Method Find Item, returns item matching item id.
  *
  *@return item    item matching itemId
  */
 public Item findItem(Integer itemId) throws FinderException, RemoteException {
  try {
        Context ctx = new InitialContext();
        home = (ItemHome)ctx.lookup("ItemHome");

         if (null != home)
           {item = (Item)home.findByPrimaryKey(itemId);}
         else {
            System.out.println("Item Matching ItemID Not Found");
             item=null;
         }
  }
  catch (Exception e) {
       System.out.println("BidStatusImpl.findItem: an exception occurred:");
       e.printStackTrace();
  }
  return item;
 }

 /**
  * Method Get Bid Status - Returns a string containing Bid status.
  *
  * @return         String Bid Status
  * @exception        java.rmi.RemoteException
  */
 public String getBidStatus(Integer inItemId) throws FinderException, RemoteException {
 try {
    item = findItem(inItemId);
    if (null != item) {
      BidStatus = "Title: " + item.getTitle() + " ItemID: " + item.getItemId() + " Curent
graphics/ccc.gif Bid: " + item.getCurrentBid() + " Bid End Date: " + item.getEndDate Time();
    }
    else {BidStatus = "No Bid Status Available For ItemID: " + inItemId;}
    }
  catch (Exception e) {
      System.out.println("BidStatusImpl.getBidStatus: an exception occurred:");
      e.printStackTrace();
  }
  return BidStatus;
 }

 /**
  * Allows the WebLogic Server to instantiate this implementation
  * and bind it in the registry. (allows rmi to run as a WebLogic startup class)
  */
 public static void main(String args[]) {

  try {
       BidStatusImpl bidStatus = new BidStatusImpl(new Integer(12345));
       Context ctx = new InitialContext();
       ctx.bind("BidStatus", bidStatus);
       System.out.println("BidStatusImpl created and bound in registry to the WebLogic
graphics/ccc.gif Server");
  }
  catch (Exception e) {
       System.out.println("BidStatusImpl.main: an exception occurred:");
       e.printStackTrace();
  }
 }

}

You can register startup classes manually by adding code to your config.xml as shown here:


<StartupClass ClassName="BidStatusImpl" Name="BidStatus" Targets="adminServer"/>

CAUTION

Take extra caution when manually editing the config.xml file. Ensure that you maintain a backup, even when making minor or routine modifications.


NOTE

An absolute pathname is not used for ClassName when registering a startup class within the config.xml file.


The formal method of registering a startup class is to use the WebLogic Administration Console. First ensure that the class is available to the server classpath. Enter the Administration Console at http://yourURL:port/console. Enter your username and password, and register the startup class using the sequence yourDomainDeploymentsStartup & ShutdownConfigure a New Startup Class as shown in Figure 11.6.

Figure 11.6. Configure the startup class.

graphics/11fig06.jpg

Compiling the Interface and Implementation

Compile the remote interface and the implementation class using the javac command as shown here:


$ javac BidStatus.java
$ javac BidStatusImpl.java

Running the weblogic.rmic Compiler

Run the weblogic.rmic complier on the implementing class as shown here:


$ java weblogic.rmic package.structure.BidStatusmpl

To produce stub and tie classes, run


$ java weblogic.rmic package.structure.BidStatusImpl -iiop

NOTE

An absolute pathname is required when submitting an implementation class to the RMI compiler.


Writing the RMI Client

Writing the client code is straightforward. You need only get a context, lookup the RMI name in the Registry, and execute the method as shown in Listing 11.3. If you're developing an IIOP client, you must narrow your object after lookup, as shown in lines 26–28 of Listing 11.3.

Listing 11.3 Writing RMI Client Code
1 import java.io.PrintStream;
2 import weblogic.utils.Debug;
3 import javax.naming.*;
4 import java.util.Hashtable;
5 import javax.rmi.*;
6
7
8 public class BidStatusClient {
9
10  public BidStatusClient() {}
11
12  public static void main(String[] argv) throws Exception {
13
14   try {
15
16       String host = argv[0];
17       String port = argv[1];
18       Integer itemId = new Integer(argv[2]);
19
20       InitialContext ctx = getInitialContext("t3://" + host + ":" + port);
21
22
23       BidStatus bStatus = (BidStatus)ctx.lookup("BidStatus");
24
25       //For IIOP Clients
26       //Context ctx = new InitialContext();
27       //Object home = ctx.lookup("BidStatus");
28       //BidStatus bStatus = (BidStatus)PortableRemoteObject.narrow(home, BidStatus.class);
29
30    System.out.println("BidStatus RMIClient Successfully connected to WebLogic Server:
graphics/ccc.gif\n" + bStatus.getBidStatus(itemId) );
31   }
32   catch (Exception e) {
33    e.printStackTrace();
34   }
35  }
36
37  private static InitialContext getInitialContext(String url)
38     throws NamingException
39  {
40   Hashtable env = new Hashtable();
41   env.put(Context.INITIAL_CONTEXT_FACTORY, "weblogic.jndi.WLInitialContextFactory");
42   env.put(Context.PROVIDER_URL, url);
43   return new InitialContext(env);
44  }
45
46 }

This Java client can be executed as shown here:


$ java BidStatusClient localhost 7001 3456 (parameters are WebLogic host, port, and item ID)
    [ Team LiB ] Previous Section Next Section