Login

Language :
TitleJava RMI
Java RMI
Writer이지섭Write DateJan 18 2018Modify DateAug 9 2024View Count6635

Java Remote Method Invocation (RMI) provides communication between servers and clients through remote objects in a distributed environment.

 

The RMI service communicates between the server and the client on two ports.

 

One is the port that the RMI Registry communicates.

One port that the Remote Object communicates with.

 

The RMI Registry has a default port of 1099.

Remote Object connects to any port, if not specified.

 

So it's easy to communicate between the same servers (PCs).

When communicating between different servers (PCs),

it is almost impossible to service because the ports are not open.

 

You must specify a port and open both ports of TCP on the server.

 

 

Remote Object is created as a Java Interface that inherits the java.rmi.Remote object.

The server and clients will find and communicate this interface through the RMI Registry.

 

Implementing interfaces for this remote object is a server program.

 

RMI Registry runs the program in the background, which allows you to specify the port.

 

The server specifies the port when it deploys remote objects.

Bind this object in the RMI Registry.

 

The server and client specify the port when they find the RMI Registry (getRegistry).

 

[Program Source]

Remote Object Interface

 : Hello.java

  - inherits the java.rmi.Remote Class.

package example.hello;

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

public interface Hello extends Remote {
    String sayHello() throws RemoteException;
}

 

Server Program

 : Server.java

  - Remote Object communicates to the 2002 port.

  - RMI Registry has been found on port 2000. (My port confuguration, you can change it.)

package example.hello;

import java.rmi.registry.Registry;
import java.rmi.registry.LocateRegistry;
import java.rmi.server.UnicastRemoteObject;
        
public class Server implements Hello {

    public Server() {}

    public String sayHello() {
        return "Hello, world!";
    }
        
    public static void main(String args[]) {

        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
        
        try {
            Server obj = new Server();
            Hello stub = (Hello) UnicastRemoteObject.exportObject(obj, 2002);

            // Bind the remote object's stub in the registry
            Registry registry = LocateRegistry.getRegistry(2000);
            registry.bind("Hello", stub);

            System.err.println("Server ready");
        } catch (Exception e) {
            System.err.println("Server exception: " + e.toString());
            e.printStackTrace();
        }
    }
}

 

Client Program

 : Client.java

  - Assumed server IP as 100.100.100.100. Must be changed to actual IP.

  - Communicate with the RMI Registry on port 2000.

package example.hello;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Client {

    public Client() {}

    public static void main(String[] args) {

        String host = (args.length < 1) ? "100.100.100.100" : args[0];

        if (System.getSecurityManager() == null) {
            System.setSecurityManager(new SecurityManager());
        }
        
        try {
            Registry registry = LocateRegistry.getRegistry(host, 2000);
            Hello stub = (Hello) registry.lookup("Hello");
            String response = stub.sayHello();
            System.out.println("response: " + response);
        } catch (Exception e) {
            System.err.println("Client exception: " + e.toString());
            e.printStackTrace();
        }
    }
}


Server server.policy file

Location : /home/user/rmi/bin

grant codeBase "file:/home/user/rmi/bin/*" {
    permission java.security.AllPermission;
};

 

Client client.policy file

Location : D:/eclipse-workspace/RMI/bin

grant codeBase "file:D:/eclipse-workspace/RMI/bin/*" {
    permission java.security.AllPermission;
};

 

[Running Program]

1) Run RMI Registry

  - If the class is not found, use the -J-Djava.class.path= option to specify the class path.

  - RMI Registry port is 2000

  - Run in the background.

rmiregistry 
  -J-Djava.class.path=/home/user/rmi/bin 
  2000 
  &

 

2) Run Server Program

  - Java.rmi when running server-side programs.

   You must set the java.rmi.server.hostname environment value.

    If the IP of the host matches the IP of the server,

   you can write the host name, otherwise type the IP.

  - Run in the background.

java 
  -classpath /home/user/rmi/bin 
  -Djava.security.policy=server.policy 
  -Djava.rmi.server.codebase=file:/home/user/rmi/bin/ 
  -Djava.rmi.server.hostname=100.100.100.100 
  example.hello.Server 
  &

 

3) Check Server Port LISTEN

  - In this program, the RMI Registry port is 2000 on the server side

  and the Remote Object port is 2002.

   You must open both TCP ports as inbound on the server.

netstat -anp | grep LISTEN | grep 2000
tcp6 0 0 :::2000 :::* LISTEN 27187/rmiregistry

netstat -anp | grep LISTEN | grep 2002
tcp6 0 0 :::2002 :::* LISTEN 27200/java

 

4) Run Client Program

  - Works with the Java policy client.policy file.

java 
  -classpath D:\eclipse-workspace\RMI\bin;. 
  -Djava.security.policy=client.policy 
  -Djava.rmi.server.codebase=file:/D:/eclipse-workspace/RMI/bin/ 
  example.hello.Client

 

5) Program execution results

response: Hello, world!

 

 

On the server (Linux), the program's class location is /home/user/rmi/bin

In client (Windows), the class location of the program is D:/eclipse-workspace/RMI/bin

(My configuration, you can change it.)

 


In Windows, when you run a server program,

you can do the following: start rmerieistry ..., start java ...

start rmiregistry -J-Djava.class.path=D:/eclipse-workspace/RMI/bin 2000

start java
    -classpath D:/eclipse-workspace/RMI/bin 
    -Djava.security.policy=server.policy 
    -Djava.rmi.server.codebase=file:D:/eclipse-workspace/RMI/bin/ 
    -Djava.rmi.server.hostname=100.100.100.100
    example.hello.Server

 

 

In some cases, you may need to do so within the Java source code to specify the policy file associated with the security policy.

Here's what you can do.

 
1) First of all, apply the below
System.setProperty("java.security.policy","file:/C:/Documents/rmi.policy");
 
2) Then apply the following
if (System.getSecurityManager() == null) {
    System.setSecurityManager(new SecurityManager());
}

 

 

[Web page referenced]

  https://docs.oracle.com/javase/tutorial/rmi/overview.html

  https://docs.oracle.com/javase/8/docs/technotes/guides/rmi/hello/hello-world.html

  https://stackoverflow.com/questions/15685686/java-rmi-connectexception-connection-refused-to-host-127-0-1-1

  https://docs.oracle.com/javase/7/docs/technotes/guides/rmi/faq.html#domain

  https://stackoverflow.com/questions/3071376/what-port-is-used-by-java-rmi-connection

  https://docs.oracle.com/javase/7/docs/technotes/tools/windows/rmic.html

  https://stackoverflow.com/questions/9440619/how-do-i-set-the-classpath-that-rmiregistry-uses

  https://www.linuxquestions.org/questions/programming-9/java-rmi-on-linux-connection-problems-875214/

  https://zetawiki.com/wiki/리눅스_포트_사용하는_프로세스_확인

  https://www.linuxquestions.org/questions/programming-9/java-rmi-on-linux-connection-problems-875214/

 

Comment

Name               Password 
Content
Check Password.

Please enter your password when registering your comment.