BEA Logo BEA WebLogic Server Release 6.1

  Corporate Info  |  News  |  Solutions  |  Products  |  Partners  |  Services  |  Events  |  Download  |  How To Buy

   Programming WebLogic RMI:   Previous Topic   |   Next Topic   |   Contents   

 

WebLogic RMI API

 

The following sections describe the WebLogic RMI API.

Overview of the WebLogic RMI API

There are several packages shipped as part of WebLogic RMI. The public API includes the WebLogic implementation of the RMI base classes, the registry, and the server packages. It also includes the WebLogic RMI compiler and supporting classes that are not part of the public API.

If you have written RMI classes, you can drop them in WebLogic RMI by changing the import statement on a remote interface and the classes that extend it. To add remote invocation to your client applications, look up the object by name in the registry.

The basic building block for all Remote objects is the interface weblogic.rmi.Remote, which contains no methods. You extend this "tagging" interface -- that is, it functions as a tag to identify remote classes -- to create your own remote interface, with method stubs that create a structure for your remote object. Then you implement your own remote interface with a remote class. This implementation is bound to a name in the registry, from whence a client or server may look up the object and use it remotely.

As in the JavaSoft reference implementation of RMI, the weblogic.rmi.Naming class is an important one. It includes methods for binding, unbinding, and rebinding names to remote objects in the registry. It also includes a lookup() method to give a client access to a named remote object in the registry.

In addition, WebLogic JNDI provides naming and lookup services. WebLogic RMI supports naming and lookup in JNDI.

WebLogic RMI Exceptions are identical to and extend java.rmi exceptions so that existing interfaces and implementations do not have to changeexception handling.

Implementing with WebLogic RMI

There are two parts to using WebLogic RMI. First you create the interfaces and classes that you will invoke remotely. Then you add code to your client application that carries out the remote invocations. The following sections detail these implementation phases.

Creating classes that can be invoked remotely
Step 1. Write a Remote interface
Step 2. Implement the Remote interface
Step 3. Compile the java class
Step 4. Compile the implementation class with RMI compiler
Step 5. Write a client that invokes on remote objects
Full code examples

Setting up WebLogic Server for RMI

WebLogic RMI for clustered services
Cluster-specific RMI compiler options
Non-replicated stubs

Creating classes that can be invoked remotely

You can write your own WebLogic RMI classes in just a few steps. Here is a simple example.

Step 1. Write a Remote interface

Every class that can be remotely invoked implements a remote interface. A remote interface must extend the interface weblogic.rmi.Remote, which contains no method signatures.

The interface that you write should include method signatures that will be implemented in every remote class that implements it. Interfaces in Java are a powerful concept, and allow great flexibility at both design time and runtime. If you need more information on how to write an interface, see the JavaSoft tutorial Creating Interfaces.

Your Remote interface should follow guidelines similar to those followed if you are using JavaSoft's RMI:

With JavaSoft's RMI, every class that implements a remote interface must have accompanying, precompiled stubs and skeletons. WebLogic RMI supports more flexible runtime code generation; WebLogic RMI supports stubs and skeletons that are type-correct but are otherwise independent of the class that implements the interface. If a class implements a single remote interface, the stub and skeleton that is generated by the compiler will have the same name as the remote interface. If a class implements more than one remote interface, the name of the stub and skeleton that result from compilation will depend on the name mangling used by the compiler.

Your Remote interface may not contain much code. All you need are the method signatures for methods you want to implement in Remote classes.

Here is an example of a Remote interface. It has only one method signature.

package examples.rmi.multihello;

import weblogic.rmi.*;

public interface Hello extends weblogic.rmi.Remote {

  String sayHello() throws RemoteException;

}

Step 2. Implement the Remote interface

Now write the class that will be invoked remotely. The class should implement the Remote interface that you wrote in Step 1, which means that you implement the method signatures that are contained in the interface. Currently, all the code generation that takes place in WebLogic RMI is dependent on this class file, but this will change in future releases.

With WebLogic's RMI, there is no need for your class to extend UnicastRemoteObject, which is required by JavaSoft's RMI. (If you extend UnicastRemoteObject, WebLogic RMI will not care, but it isn't necessary.) This allows you to retain a class hierarchy that makes sense for your application.

Your class may implement more than one Remote interface. Your class may also define methods that are not in the Remote interface, but you will not be able to invoke those methods remotely. You should also define at least a default constructor.

In this example, we implement a class that creates multiple HelloImpls and binds each to a unique name in the Registry. The method sayHello() greets the user and identifies the object which was remotely invoked.

package examples.rmi.multihello;

import weblogic.rmi.*;

public class HelloImpl implements Hello {

  private String name;

  public HelloImpl(String s) throws RemoteException {

    name = s;

  }

  public String sayHello() throws RemoteException {

    return "Hello! From " + name;

  }

Finally, write a main that creates an instance of the remote object and registers it in the WebLogic RMI registry, by binding it to a name (a URL that points to the implementation of the object). A client that wants to obtain a stub to use the object remotely will be able to look up the object by name.

Here is an example of a main() for the HelloImpl class. This registers the HelloImpl object under the name HelloRemoteWorld in a WebLogic Server registry.

  public static void main(String[] argv) {

    // Not needed with WebLogic RMI

    // System.setSecurityManager(new RmiSecurityManager());

    // But if you include this line of code, you should make

    // it conditional, as shown here:

    // if (System.getSecurityManager() == null)

    //   System.setSecurityManager(new RmiSecurityManager());

    int i = 0;

    try {

      for (i = 0; i < 10; i++) {

        HelloImpl obj = new HelloImpl("MultiHelloServer" + i);

        Naming.rebind("//localhost/MultiHelloServer" + i, obj);

  System.out.println("MultiHelloServer" + i + " created.");

      }

      System.out.println("Created and registered " + i +

                         " MultiHelloImpls.");

    }

    catch (Exception e) {

      System.out.println("HelloImpl error: " + e.getMessage());

      e.printStackTrace();

    }

  }

WebLogic RMI does not require that you set a SecurityManager in order to integrate security into your application. Security is handled by WebLogic Server support for SSL and ACLs. If you must, you may use your own security manager, but do not install it in the WebLogic Server.

Step 3. Compile the java class

First compile the .java files with javac or some other Java compiler to produce .class files for the Remote interface and the class that implements it.

Step 4. Compile the implementation class with RMI compiler

Run the WebLogic RMI compiler against the remote class to generate the stub and skeleton. A stub is the client-side proxy for a remote object that forwards each WebLogic RMI call to its matching serverside skeleton, which in turn forwards the call to the actual remote object implementation. To run the WebLogic RM compiler, use the command pattern:

  $ java weblogic.rmic nameOfRemoteClass

where nameOfRemoteClass is the full package name of the class that implements your Remote interface. With the examples we have used previously, the command would be:

  $ java weblogic.rmic examples.rmi.hello.HelloImpl

You should set the flag -keepgenerated when you run the WebLogic RMI compiler if you want to keep the generated stub and skeleton files. For a listing of the available WebLogic RMI compiler options, see WebLogic RMI Compiler..

Running the WebLogic RMI compiler creates two new classes, a stub and a skeleton. These appear as nameOfInterface_Stub.class and nameOfInterface_Skel.class. The four files created -- the remote interface, the class that implements it, and the stub and skeleton created by the WebLogic RMI compiler -- should be placed in the appropriate directory in the CLASSPATH of the WebLogic Server whose URL you used in the naming scheme of the object's main().

Invoking methods on remote objects in your client code

Once you compile and install the remote class, the interface it implements, and its stub and skeleton on the WebLogic Server, you can add code to a WebLogic client application to invoke methods in the remote class.

In general, it takes just a single line of code: you need to get a reference to the remote object. Do this with the Naming.lookup() method. Here is a short WebLogic client application that uses an object created in a previous example.

package mypackage.myclient;

import weblogic.rmi.*;

import weblogic.common.*;

public class HelloWorld throws Exception {

  // Look up the remote object in the

  // WebLogic's registry

  Hello hi = (Hello)Naming.lookup("HelloRemoteWorld");

  // Invoke a method remotely

  String message = hi.sayHello();

  System.out.println(message);

}

This example demonstrates using a Java application as the client.

Full Code Examples

Here is the full code for the Hello interface.

package examples.rmi.hello;

import weblogic.rmi.*;

public interface Hello extends weblogic.rmi.Remote {

  String sayHello() throws RemoteException;

}

Here is the full code for the HelloImpl class that implements it.

package examples.rmi.hello;

import weblogic.rmi.*;

public class HelloImpl

    // Don't need this in WebLogic RMI:

    // extends UnicastRemoteObject

    implements Hello {

  public HelloImpl() throws RemoteException {

    super();

  }

  public String sayHello() throws RemoteException {

    return "Hello Remote World!!";

  }

  public static void main(String[] argv) {

    try {

      HelloImpl obj = new HelloImpl();

      Naming.bind("HelloRemoteWorld", obj);

    }

    catch (Exception e) {

      System.out.println("HelloImpl error: " + e.getMessage());

      e.printStackTrace();

    }

  }

}

Using the WebLogic RMI Compiler for Clustered Services

The following sections identifies the cluster-specific RMI options used with WebLogic's implementation of RMI and describes the non-replicated stubs.

Cluster-specific RMI compiler options

The RMI compiler (RMIC) has several flags that relate to clusters. These argument tags are not case sensitive; inner caps are used in these descriptions for ease of reading.

-clusterable
Generates a stub that can failover and load balance. By default, the generated stub will be capable of failover and will load balance between replicas using a round-robin scheduling algorithm.

-methodsAreIdempotent
May only be used in conjunction with "-clusterable". Indicates to the stub that it can attempt retries after failover even if it might result in executing the same method multiple times. If this flag isn't present, methods for this stub are not considered idempotent. The exceptions that are handled by this are described in Exceptions used for failover.

-loadAlgorithm load algorithm name
May only be used in conjunction with "-clusterable". Specifies a service-specific algorithm that will be used by the stub to handle failover and load balancing. If this argument is unspecified, the default load balancing algorithm specified in the Administration Console. For example, to specify weight-based load balancing:

 $ java weblogic.rmic -clusterable -loadAlgorithm=weight-based

-stickToFirstServer
May only be used in conjunction with "-clusterable". Enables 'sticky' load balancing. The server chosen for servicing the first request will be used for all subsequent requests.

-replicaListRefreshInterval seconds
May only be used in conjunction with "-clusterable". Specifies the minimum time to wait between attempts to refresh the replica list from the Cluster. Default is 180 seconds (3 minutes).

-callRouter callRouterClass
May only be used in conjunction with "-clusterable". Specifies the class to be used for routing method calls. This class must implement weblogic.rmi.extensions.CallRouter. If specified, an instance of this class will be called before each method call and be given the opportunity to choose the server given the method parameters. It either returns a server name or null indicating that the current load algorithm should be used to pick the server.

Non-Replicated Stubs

You can also generate stubs that are not replicated; these are known as "pinned" services, because after they are registered they will be available only from the host with which they are registered and will not provide transparent failover or load balancing. Pinned services are available cluster-wide, since they are bound into the replicated cluster-wide JNDI tree; but if the individual server that hosts them fails, the client cannot failover to another server.

Client-side RMI objects can only be reached through a single WebLogic Server, even in a cluster. If a client-side RMI object is bound into the JNDI naming service, it will only be reachable as long as the Server that carried out the bind is reachable.

 

Back to Top