Tags

, , , , , ,

RMI – You heard this when you wanted to communicate between two different JVM’s. If you wanted to make it with plain Java, you need to do the below.

1. Write the service implementation class with methods that throw java.rmi.RemoteException.
2. Create the service interface to extend java.rmi.Remote.
3. Run the RMI compiler (rmic) to produce client stub and server skeleton classes.
4. Start an RMI registry to host the services.
5. Register the service in the RMI registry

After that you need to write you client to invoke the method from the remote application. Isn’t it hectic to do these many steps. Spring makes your life easy by reducing major portion of coding work. Spring provides an easier way to publish RMI services. Instead of writing RMI-specific classes with methods that throw RemoteException, you simply write a POJO that performs the functionality of your service. Spring handles the rest.

For that, you need RmiServiceExporter which exports any Spring-managed bean as an RMI service. RmiServiceExporter works by wrapping the bean in an adapter class. The adapter class is then bound to the RMI registry and proxies requests to the service class.
By default RmiServiceExporter attempts to bind to an RMI registry on port 1099 of the local machine. If no RMI registry is found at that port, RmiServiceExporter will start one. If you’d rather bind to an RMI registry at a different port or host, you can specify so with the registryPort and registryHost properties in spring configuration.

For a normal java application, in client side you make a call to your stub class and then the stub will communicate with remote and return the value. Spring reduces this task as well by providing a proxy bean to do that. We just need to invoke the bean like normal bean and spring will take the rest.

Below is the complete example for integrating RMI with spring. I am creating two separate projects one is RMISample which will be the RMI host (remote application). The other project will be the client application which make methods calls to the remote application.

Remote application:

In this example, we have the following files.
RMITest.java – Interface
RMITestImpl.java – Implementation for RMITest.
Host.java – Main application to start RMI service.
remoteapp-context.xml – Spring configuration file.

RMITest.java

 package com.test.rmi;
 public interface RMITest {
     int sum(int number);
 }
 

RMITestImpl.java

 package com.test.rmi;
 public class RMITestImpl implements RMITest {
     public int sum(int number) {
         return number + number;
     }
 }
 

Host.java

 package com.test.rmi;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.FileSystemXmlApplicationContext;
 public class Host {
     public static void main(String[] args) {
         String file = "C:\\Data\\RMISample\\remoteapp-context.xml";
         ApplicationContext context = new FileSystemXmlApplicationContext(file);
         System.out.println("waiting for requests...");
     }
 }
 

remoteapp-context.xml

 <beans:bean id="testBean" class="com.test.rmi.RMITestImpl">
 </beans:bean>

 <beans:bean class="org.springframework.remoting.rmi.RmiServiceExporter">
 <beans:property name="service" ref="testBean" />
 <beans:property name="serviceInterface" value="com.test.rmi.RMITest"/>
 <beans:property name="serviceName" value="RMITestService" />
 <beans:property name="replaceExistingBinding" value="true" />
 <beans:property name="registryPort" value="1099" />
 </beans:bean>

Now, the Host will register the spring context and will be waiting for RMI requests to serve. We have done with the remote application setup. Now we need to write client to make method calls to remote.

Client Application:

RMITest.java

 package com.test.rmi;
 public interface RMITest {
     int cube(int number);
 }
 

Client.java

 package com.test.rmi;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.support.FileSystemXmlApplicationContext;
 public class Client {
     public static void main(String[] args) {
         String file = "C:\\Data\\RMIClient\\client-context.xml";
         ApplicationContext context = new FileSystemXmlApplicationContext(file);
         RMITest test = (RMITest)context.getBean("proxyBean");
         System.out.println("Value: " +test.sum(3));
     }
 }

client-context.xml

 <beans:bean id="proxyBean" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
 <beans:property name="serviceUrl" value="rmi://localhost:1099/RMITestService" />
 <beans:property name="serviceInterface" value="com.test.rmi.RMITest" />
 </beans:bean>
 

As per this example, you will get “Value: 6″ as the output in your console.

About these ads