Question

In machine1/folder1, I placed HelloClient.java & HelloInterface.java and ran java1.5 compilation:

javac HelloClient.java HelloInterface.java

In machine2/folder2, I placed HelloInterface.java / Hello.java / HelloServer.java files and ran java 1.5 compilation:

 javac *.java` //here `HelloInterface` definition is required by Hello Class only for compilation.

stub/skeleton classes also get generated here in machine2.

I copied Hello_stub.class in to machine1/folder1

Next, i ran object registry

rmiregistry &

and started the server which binds the object to that registry.

java -Djava.security.policy=policy HelloServer &

where the policy file has

grant{
     permission  java.security.AllPermission;
}     

and then ran the client:

java HelloClient testing abc

My question is:

1) HelloClient.class on machine1 is using Hello_stub.class when we invoke hello.say() from client program to communicate with machine2, But am not clear at which instance Hello_skel.class on machine 2 is invoked by HelloServer.class ? Can you please help me understand this?

2) Coming from socket programming background in C, How do i visualise socket()/connect() part of client program and socket()/bind()/listen()/accept() pasrt of server program in this RMI framework?

I wrote the below interface(HelloInterface.java)

import java.rmi.*;
public interface HelloInterface extends Remote{
          public String say(String msg) throws RemoteException;
    }

and i wrote the below class(Hello.java) whose object's method will be accessed from remote.

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(String m) throws RemoteException{
               return new StringBuffer(m).reverse().toString();
        } 
}

I wrote the Server program(HelloServer.java), which registers the 'Hello' Object with rmiregistry program.

import java.rmi.*;
import java.rmi.server.*;
public class HelloServer{
       public static void main(String argv[]){
           if(System.getSecurityManager() == null)
                   System.setSecurityManager(new RMISecurityManager());
           try{
                   Naming.rebind("Hello", new Hello("Hello, world!"));
                   System.out.println("Server is running");
              }catch(Exception e){
                    System.out.println("Hello server failed: " + e);
              }
       }
}   

I wrote the client program(HelloClient.java) that invokes remote method 'say'

import java.rmi.*;
public class HelloClient {
     public static void main(String argv[]){
           try{
                 if(args.length < 0){
                     System.err.println("usage: java HelloCient string..");
                     System.exit(1);
                  }
                  HelloInterface hello =
                      (HelloInterface)Naming.lookup("//machine2:1099/Hello");
                  for(int i=0; i < args.length; i++)
                         System.out.println(hello.say(argv[i]); 
              }catch(Exception e){
                   System.out.println("HelloClient exception: " + e);
              }
      }
}
Was it helpful?

Solution

// here HelloInterface definition is required by Hello Class only for compilation

No. It is also required by HelloServer and HelloClient for compilation, and it is required at runtime as well, by both the server and the client, and also by the RMI Registry.

stub/skeleton classes also get generated here in machine2.

No. RMI skeletons have been obsolete since 1998. You didn't generate one at all, unless you used the rmic option -v1.1 or -vcompat, and you don't need to use either. You don't even need to use rmic itself at all since Java 1.5, if you just add super(0) to your Hello constructor.

I copied Hello_stub.class in to machine1/folder1

You also need HelloInterface.class here.

HelloClient.class on machine1 is using Hello_stub.class when we invoke hello.say() from client program to communicate with machine2

Correct.

[I] am not clear at which instance Hello_skel.class on machine 2 is invoked by HelloServer.class

It isn't invoked at all, unless you used rmic -v1.1, in which case it is invoked by RMI to mediate between the RMI runtime system and the Hello object. It doesn't have anything to do with the HelloServer class at all.

Coming from socket programming background in C, How do i visualise socket()/connect() part of client program

RMI creates connections as needed, pools them, and closes them when they've been idle. There is a connection required to call Naming.lookup(), and another one to call the remote method.

and socket()/bind()/listen()/accept() pasrt of server program in this RMI framework?

Exporting a remote object creates a listening socket, or shares one that has already been created by RMI. The RMI runtime system calls accept(), works out from the request header which remote object it's for, and calls that remote object via reflection (or the old skeleton) with the arguments in the request, and sends the result or exception if any back to the client.

NB:

  1. You don't need a SecurityManager or a .policy file or the -Djava.security.policy argument unless you're using the RMI codebase feature, and you aren't.

  2. I don't see what the msg parameter and instance member is for in Hello. You aren't using it.

  3. You don't really need HelloServer. You could put that main() method into Hello.

  4. Your client doesn't call any remote methods on the object it looks up. Presumably you want to add that?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top