Tuesday, October 9, 2012

Simple RMI and RMI with Spring

RMI (=Remote Method Invocation)

The basic structure of an RMI-based method call involves a client, a server and a registry. To make a call to a remote object, the client first looks up the object it wishes to invoke a method on in the registry. The registry returns a reference to the object (assuming it exists) on the server, which the client can use to invoke any methods that the remote object implements.

Step1 : HelloInterface.java

 
import java.rmi.Remote;
import java.rmi.RemoteException;

public interface HelloInterface extends Remote {
  public String say() throws RemoteException;
}


Step 2: Hello.java

import java.rmi.*;
import java.rmi.server.*;

public class Hello extends UnicastRemoteObject
 implements HelloInterface {
  private String message;
  public Hello (String msg) throws RemoteException {
  message = msg;
  }
  public String say() throws RemoteException {
  return message;
  }
}


Step3.Compile the above two Source file named HelloInterface.java and Hello.java.

Step4.After compiling the above two classes type the following command i.e-  "rmic Hello" in console
> rmic Hello


By running the "rmic Hello" command a new class will be created i.e "Hello_Stub.class" in the directory.

Step5.Create Server application named HelloServer.java

HelloServer.java
import java.rmi.Naming;

public class HelloServer
{
  public static void main (String[] argv)
  {
  try {
  Naming.rebind("Hello", new Hello ("Hello,From Roseindia.net pvt ltd!"));
  System.out.println ("Server is connected and ready for operation.");
  }
  catch (Exception e) {
  System.out.println ("Server not connected: " + e);
  }
  }
}


Step6.Create Client application named HelloClient.java

HelloClient.java

import java.rmi.Naming;

public class HelloClient
{
  public static void main (String[] argv) {
  try {
HelloInterface hello =(HelloInterface)
 Naming.lookup ("//192.168.10.201/Hello");
  System.out.println (hello.say());
  }
  catch (Exception e){
  System.out.println ("HelloClient exception: " + e);}
  }
}

Step6.Compile both of the files.

Step7.Type "rmicregistry" on commandprompt and press ENTER.


Step8.Type java HelloServer in commandprompt and press ENTER.The following message will be displayed on console.

Console output will come
Server is connected and ready for operation.

Step9.Now,open another separate command terminal,and run the client application like shown in the figure given below:-

javac HelloClient.java
java  HelloClient

Hello, From RoseIndia.net pvt ltd.

Step10. If the message similar to the above appears in figure comes means that you have implemented your RMI application.


In short:
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.


RMI using SPRING:

Fortunately, 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 a typical Spring Application we need the following files:

1. An interface that defines the functions.
2. An Implementation that contains properties, its setter and getter methods, functions etc.
3. A XML file called Spring configuration file.
4. Client program that uses the function

Instead of generating a server skeleton and client stub using rmic and manually adding it to the RMI registry (as you would in conventional RMI), we’ll use Spring’s RmiServiceExporter.

RmiServiceExporter 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.

<bean class="org.springframework.remoting.rmi.RmiServiceExporter">
        <property name="serviceName" value="employee-service"/>
        <property name="service" ref="employeeService"/>
        <property name="serviceInterface" value="rmi.common.EmployeeI"/>
        <property name="registryPort" value="1234"/>
</bean>

<bean id="employeeService" class="rmi.server.EmployeeImpl">
</bean>

public class Employee implements Serializable {
 private String name;
 private String address;

 public Employee(String name,String address){
  this.name = name;
  this.address = address;
 }

 // getters and setters
}


public interface EmployeeI {

 public void addEmployee(Employee employee);
 public void removeEmployee(Employee employee);
 public List<Employee> getEmployees();
  
}

public class EmployeeImpl implements EmployeeI{

    private List<Employee> employees = new ArrayList<Employee>();

    public void addEmployee(Employee employee) {
     employees.add(employee);
    }
  
    public void removeEmployee(Employee employee){
     employees.remove(employee);
    }

    public List<Employee> getEmployees() {
        return employees;
    }
}


Now to run the server side service you need Spring context initialization.


public class EmpServerDemo {
 public static void main(String[] args) {
  ApplicationContext ctx = new ClassPathXmlApplicationContext("rmi/server/rmi-server-context.xml");
 }
}

CLIENT SIDE

Now let us have a look at client side.

To link in the service on the client, we'll create a separate Spring container, containing the simple object and the service
linking configuration bits:


<beans>
    <bean id="employeeService" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
        <property name="serviceUrl" value="rmi://localhost:1234/employee-service"/>
        <property name="serviceInterface" value="rmi.common.EmployeeI"/>
    </bean>
</beans>

You can make client calls through the below code...

public class EmpClientDemo {
 public static void main(String[] args) {
  ApplicationContext ctx = new ClassPathXmlApplicationContext("rmi/client/rmi-client-context.xml");
  EmployeeI employee = (EmployeeI) ctx.getBean("employeeService");
  employee.addEmployee(new Employee("Prashant", "address1"));
  employee.addEmployee(new Employee("Sneha", "address2"));
  List<Employee> employees = employee.getEmployees();
  System.out.println("Total number of employees: " + employees.size());
  Iterator<Employee> it = employees.iterator();
  while (it.hasNext()) {
   Employee emp = (Employee) it.next();
   System.out.println(" " + emp);
  }
 }
}

 UnicastRemoteObject : This is the simplest way to ensure that objects of a class can be used as remote objects.

0 comments:

Post a Comment