bea.com | products | dev2dev | support | askBEA

Download Docs | Site Map | Glossary
Search

Programming WebLogic RMI

Implementing WebLogic RMI

The following sections describe the WebLogic RMI API:

- Overview of the WebLogic RMI API

- Procedures for Implementing WebLogic RMI

Overview of the WebLogic RMI API

Several packages are shipped with WebLogic Server as part of WebLogic RMI. The API includes:

- WebLogic implementation of the RMI base classes

- WebLogic RMI compiler

- 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 java.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, where a client or server can look up the object and use it remotely.

As in the JavaSoft reference implementation of RMI, the java.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 change exception handling.

Procedures for Implementing WebLogic RMI

The following sections describe how to implement WebLogic Server RMI:

- 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 Code That Invokes Remote Methods

- Full Code Examples

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. Using a Java code text editor, write the remote interface in adherence with the following guidelines.

- A remote interface must extend the interface java.rmi.Remote, which contains no method signatures. Include method signatures that will be implemented in every remote class that implements the interface. For detailed information on how to write an interface, see the Sun Microsystems JavaSoft tutorial Creating Interfaces.

- The remote interface must be public. Otherwise a client gets an error when attempting to load a remote object that implements it.

- Unlike the JavaSoft RMI, it is not necessary for each method in the interface to declare java.rmi.RemoteException in its throws block. The exceptions that your application throws can be specific to your application, and can extend RuntimeException. WebLogic RMI subclasses java.rmi.RemoteException, so if you already have existing RMI classes, you will not have to change your exception handling.

- 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 with the method signature sayHello().

  package examples.rmi.multihello;

  import java.rmi.*;

  public interface Hello extends java.rmi.Remote {

  String sayHello() throws RemoteException;

  }

With JavaSoft's RMI, every class that implements a remote interface must have accompanying, precompiled proxies. WebLogic RMI supports more flexible runtime code generation; WebLogic RMI supports dynamic proxies and dynamically created bytecode that are type-correct but are otherwise independent of the class that implements the interface. If a class implements a single remote interface, the proxy and bytecode 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 proxy and bytecode that result from the compilation depend on the name mangling used by the compiler.

Step 2. Implement the Remote Interface

Still using a Java code text editor, write the class 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.

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

Note: With Weblogic server, you can use both Weblogic RMI and standard JDK RMI. If you use Weblogic RMI, then you must use "java weblogic.rmic ..." as the rmic compiler and you must not create your RMI implementation as a subclass of "java.rmi.server.UnicastRemoteObject". If you use standard JDK RMI, then you must use "%JAVA_HOME%\bin\rmic" as the rmic compiler and you must create your RMI implementation class as a subclass of "java.rmi.server.UnicastRemoteObject".

Your class can implement more than one remote interface. Your class can also define methods that are not in the remote interface, but you cannot invoke those methods remotely.

This example implements 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 java.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;

>       }

Next, write a main() method 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 needs to obtain a proxy to use the object remotely will be able to look up the object by name.

Below is an example of a main() method 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);

>             Context.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 Security Manager 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 WebLogic Server.

Step 3. Compile the Java Class

Use javac or some other Java compiler to compile the .java files 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 (weblogic.rmic) against the remote class to generate the dynamic proxy and bytecode, on the fly. A proxy is the client-side proxy for a remote object that forwards each WebLogic RMI call to its matching server-side bytecode, which in turn forwards the call to the actual remote object implementation. To run the weblogic.rmic, 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

Set the flag -keepgenerated when you run weblogic.rmic if you want to keep the source when generating stub and skeleton classes. For a listing of the available command-line options, see WebLogic RMI Compiler Options.

Step 5: Write Code That Invokes Remote Methods

Using a Java code text editor, once you compile and install the remote class, the interface it implements, and its proxy and the bytecode 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: 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 java.rmi.*;

>     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 java.rmi.*;

>     public interface Hello extends java.rmi.Remote {

>       String sayHello() throws RemoteException;

>     }

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

>     package examples.rmi.hello;

>     import java.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();

>         }

>       }

>     }