I am trying to get started with java RMI but I keep running in to an error when my components try to bind (or even connect) to the rmiregistry. Whenever I try to bind anything to the rmiregisrty I get a java.rmi.ConnectIOException. I am honestly lost as to what I need to do to fix this.
Server
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {
HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry();
registry.bind("Hello", Obj);
System.out.println("Server is live");
}
}
Client
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry();
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}
Hello (interface)
import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}
HelloClass
import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello {
public HelloClass() throws Exception{
super();
}
public String Hello(){
return "Hello world!";
}
}
"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is:
**"C:\Program Files\Java\jdk1.8.0_144\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\lib\idea_rt.jar=57417:C:\Program Files\JetBrains\IntelliJ IDEA 2019.3.4\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_144\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_144\jre\lib\rt.jar;C:\Users\Roman\Desktop\RMI3\out\production\RMI3" Server
Exception in thread "main" java.rmi.ConnectIOException: Exception creating connection to: 192.168.2.21; nested exception is:
java.net.SocketException: Permission denied: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
**
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:631)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:216)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:202)
at sun.rmi.server.UnicastRef.newCall(UnicastRef.java:338)
at sun.rmi.registry.RegistryImpl_Stub.bind(RegistryImpl_Stub.java:60)
at Server.main(Server.java:15)
Caused by: java.net.SocketException: Permission denied: connect
at java.net.DualStackPlainSocketImpl.connect0(Native Method)
at java.net.DualStackPlainSocketImpl.socketConnect(DualStackPlainSocketImpl.java:79)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:172)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at java.net.Socket.connect(Socket.java:538)
at java.net.Socket.<init>(Socket.java:434)
at java.net.Socket.<init>(Socket.java:211)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:40)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:148)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:613)
... 5 more
In Server class you are retrieving remote object registry reference by calling LocateRegistry.getRegistry()
method.
As hostname and port not passed hence internally hostname will be derived using java.net.InetAddress.getLocalHost().getHostAddress()
api.
As per error message hostname is getting derived as 192.168.2.21, but on that IP attempt to create a socket in port 1099 is giving Permission denied error.
The host from where you are running Server class,
Is that node has IP_ADDRESS 192.168.2.21 ?
You may check using
ipconfig /all
You can check using java.net.InetAddress.getLocalHost().getHostAddress()
api.
I think better you may try to pass hostname and port to LocateRegistry.getRegistry("127.0.0.1",1099)
method. Changes are in Server and Client code.
Server.java
package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server {
public static void main(String[] args) throws Exception {
try {
HelloClass Obj = new HelloClass();
Registry registry = LocateRegistry.getRegistry("127.0.0.1", 1099);
System.out.println("registry=" + registry);
registry.bind("Hello", Obj);
System.out.println("Server is live");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Client.java
package rmi.learning;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Client {
public static void main(String[] args) throws Exception{
Registry registry = LocateRegistry.getRegistry("127.0.0.1",1099);
Hello hello = (Hello) registry.lookup("Hello");
String n = hello.Hello();
System.out.println(n);
}
}
I have put all classes in rmi.learning package.
Hello.java
package rmi.learning;
import java.rmi.*;
public interface Hello extends Remote {
public String Hello() throws RemoteException;
}
HelloClass.java
package rmi.learning;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
public class HelloClass extends UnicastRemoteObject implements Hello {
protected HelloClass() throws RemoteException {
super();
}
public String Hello() {
return "Hello world!";
}
}
Start rmi registry service
start d:\Java\jdk1.8.0_261\bin\rmiregistry
From a command prompt: Execute Server
cd d:\workspace_europa\StackOverflow\bin
start /B D:\Java\jdk1.8.0_261\bin\java.exe -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server
Output:
registry=RegistryImpl_Stub[UnicastRef [liveRef: [endpoint:[127.0.0.1:1099](remote),objID:[0:0:0, 0]]]]
Server is live
From a command prompt: Execute Client
D:\Java\jdk1.8.0_261\bin\java.exe -classpath . rmi.learning.Client
Output:
Hello world!
More investigation:
I was trying to reproduce this issue, I connect to internet via router. Once I connect to wifi then my router is assigning IP address 192.168.0.102.
java.net.InetAddress.getLocalHost().getHostAddress()
api return IP ADDRESS as 192.168.0.102
Wireless LAN adapter Wi-Fi:
Connection-specific DNS Suffix . :
Link-local IPv6 Address . . . . . : xxxx::xxxx:xxxx:xxxx:xxxx%18
IPv4 Address. . . . . . . . . . . : 192.168.0.102
Subnet Mask . . . . . . . . . . . : 255.255.255.0
Default Gateway . . . . . . . . . : 192.168.0.1
If I try to bind rmi service to 192.168.0.102 in port 1099 then it's working fine.
But if I connect to VPN then one new IP is assigned to my host. While connected to VPN, IP 192.168.0.102 is no more resolvable and my machine IP_ADDRESS is getting changed. This time if I try to bind rmi service to IP 192.168.0.102 then getting error java.net.SocketException: Permission denied: connect.
Hence the the error is coming if the IP ADDRESS is not no more applicable for current node.
In many places I have seen people are suggesting to use -Djava.net.preferIPv4Stack=true also. While running Server.class you may try similar
start /B D:\Java\jdk1.8.0_261\bin\java.exe -Djava.net.preferIPv4Stack=true -classpath .;rmi -Djava.rmi.server.codebase=file:rmi/ rmi.learning.Server
Even some places people are saying about disabling any Anti Virus running on the system, you may check that possibility also.