![]() |
![]() |
|
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
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.
$ java weblogic.rmic -clusterable -loadAlgorithm=weight-based
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.
|
Copyright © 2000 BEA Systems, Inc. All rights reserved.
|