Resin supports the use of RMI with the resource class class com.caucho.resources.rmi.RmiRegistry .
The goal of RMI is to provideto remote clients. A remote client obtains and uses a that implements an . The interface is the contract for the service, it is the definition of the methods that the service provides.
Because the client is using a proxy object, the actual execution of code occurs on the server. A proxy object is placeholder that the client uses to cause execution of code on a server.
The RMI registry is used to store a list of available services. A client uses the registry to make it's proxy object, and the Registry is responsible for giving appropriate information to the client so that it can hook up with the server that implements the service.
In many scenarios, the Registry and the server for the services are in the same JVM. It is possible, however, for the Registry to run in a different JVM or even on a different machine than the server or servers that implement the services.
A registry has a TCP port that it uses to listen to incoming requests, typically this is port 1099. The RMI registry is a global resource, each JVM can have only one Registry on a particular port. This has important ramifications for the naming of services.
If you are considering RMI as a mechanism for publishing services, you may want to consider using Hessian instead. Hessian offers the following advantages:
The JDK requires that a security manager be in place for the use of RMI. This is true for both clients and servers. A security manager is enabled in Resin using the <security-manager> configuration:
For clients that are applets, the developer does not need to enable the security manager; the browser provides the security manager.
More information is available in the Security section of the documentation.
Resin provides the resource class class com.caucho.resources.rmi.RmiRegistry to define an RMI Registry and register services with it. If the Registry is on the `localhost' server, then Resin will also start the RMI Registry if needed.
RmiRegistry is used to define the location of an RMI Registry to use. If server is `localhost', then the Registry will be started on the specified port, if it has not already been started.
If server is something other than `localhost', then it is assumed that the Registry has been started by some other JVM , and is treated as remote Registry to register any services defined with rmi-server.
child of: com.caucho.resources.rmi.RmiRegistry
Each RmiRegistry can have rmi-service children, which causes the service to be instantiated and registered with the RMI Registry defined by the containing RmiRegistry.
An RMI service requires the developer to create two classes - an interface and an implementation. The interface defines the contract for the service, it is given to the client and it is the client view of the service. The implementation class implements the functionality; it implements the interface and is used on on the server.
The following is a simple hello world example.
When the client uses a service, it uses a. The proxy object is a placeholder, it implements the interface defined for the service, and call's through to the server so that the code is executed on the server.
RMI calls proxy objects Stubs, and the stubs must be manually generated. The generation of stubs is done using the rmic tool.
This call to rmic will use the file WEB-INF/classes/example/HelloWorldImpl.class to generate the class file WEB-INF/classes/example/HelloWorldImpl_Stub.class.
It is tedious to perform this step manually, an ant build script (as shown in a later section) can be used to expediate the process.
Once the work of making an interface, an implementation, and generating a stub is complete, it is a simple process to deploy the service in Resin.
More than once service is easily deployed with the use of multiple rmi-service tags:
By convention, the name chosen for the service often matches the name of the interface class. For example, if the interface name is "example.HelloWorld" then service-name is "HelloWorld" or even "example.HelloWorld" to match.
The RMI Registry has a global namespace. If two different web-app's try to publish the same service, with the same name, there will be conflicts.
An ant build file is useful for completing the rmic step, and for preparing a jar for use by the client. The client jar contains the interfaces and the stubs.
The following build file, placed in /WEB-INF/build, creates the jar file /rmiclient.jar.
The client is usually on a different machine, or at least in a different JVM, than the server. That is the point of RMI, it enables the execution of code on a remote machine.
In order to use the RMI service, the client needs the interface classes and the Stubs. The easiest way to provide these to the client is to provide a jar; the ant build file above provides an example of using ant to automate the creation of the jar file for the client.
Once the jar file is available to the client, using the RMI service id fairly simple.
In the most common scenario, the Resin server provides both the RMI Registry and the RMI services. When the registry server is defined as `localhost', Resin will start the rmi registry if has not been started already.
This provides a simple method of using RMI, you don't have to worry about the (somewhat tricky) process of starting the rmi registry yourself.
When the Resin server starts, it will start the rmi registry on port 1099 and register the `HelloWorld' service with it.
In this scenario, the rmi registry is located on the machine services.hogwarts.com. The registry is started with a custom (not Resin) server implemented by Hogwarts.
The requirement is for the HelloWorld service, implemented within a Resin server, to be registered with the remote Registry.
In this scenario, the Resin resource RmiRegistry is used to attach to the existing RMI registry running on services.hogwarts.com.
When the Resin server starts, it will register the `HelloWorld' service with the RMI Registry on services.hogwarts.com. Since the server is on a remote machine, Resin will not create a registry on the local machine. When the REsin server shuts down, or is restarted, the `HelloWorld' service will be removed from the remote registry.
In this scenario, the rmi registry is located on the same machine as the Resin server, but is started with a custom (not Resin) server implemented by Hogwarts.
This is essentially the same scenario as having a Registry on a different szerver. The server name cannot be provided as `localhost', however, because Resin will try to create the RMI registry.
The solution is to use an IP address of `127.0.0.1' as the address of the server. Because the server name is not `localhost', the RMI registry will not be created.
When the Resin server starts, it will register the `HelloWorld' service with the RMI Registry on the local machine. Since the server is not `localhost', Resin will not create a registry on the local machine. When the Resin server shuts down, or is restarted, the `HelloWorld' service will be removed from the remote registry.