I've created an RMI service that includes some method calls from another computer. Server and client have valid IP addresses and when I try to run the program in the client I get a connection refused exception.
When I change the IP address to localhost it will solve my problem, but when I try remote to another IP address the same error occurs.
There are three cases of 'connection refused' in RMI:
When calling bind()/rebind()/unbind(). The Registry isn't started at the host:port or URL you're using.
When calling lookup(). If (1) succeeded, you're trying to lookup the wrong Registry. The Registry normally runs at the same host as the server.
When calling a remote method. This means that you need to set java.rmi.server.hostname at the server JVM before exporting any remote objects. See the RMI FAQ item A.1 for why. A better fix is to fix the DNS or hosts file.
Try use this before register rmi
System.setProperty("java.rmi.server.hostname", REGISTRY_HOST);
here REGISTRY_HOST is the ip address.
Related
I know this is something repetead but couldn't find the solution to my problem...
I am trying to implement a simulated distributed system and I struggling a lot with the connectivity through RMI.
I have three different components, grid schedulers, resources managers and clients. The three of them interact among themselves. The behaviour is the following: the user looks up resource manager reference on the registry and then invokes a remote method which will invoke another one in the grid scheduler and eventually one method in the user will be invoked delivering the results. If I execute the whole system in local everything works as expected.
Now the thing is, I am trying to move one of the resource mananger nodes to a EC2 Amazon instance with public address A.A.A.A, the rest of the system will run locally on my laptop with public address B.B.B.B. I allowed TCP traffic on the port 1099 TCP/UDP on the security group policy, also set the java.security.policy to grant all permision in both machines. To create the registry in every component I do:
LocateRegistry.createRegistry(1099);
Then the components will discover themselves by
Naming.lookup(url)
Now, user will look up for ip address A.A.A.A/component the public address of the Amazon instance. I can check that sometimes it gets the reference, sometimes it doesn't (NotBoundException). However, when it does gets the reference and tries to call the method I get:
java.rmi.ConnectException: Connection refused to host: INTERNAL IP OF AMAZON INSTANCE nested exception is: java.net.ConnectException: Connection timed out: connec.
Am I doing something wrong? I tried to set the property
java.rmi.server.hostname
To the public ip A.A.A.A in the Amazon instance and I got same results. I also tried doing the same on my laptop to the public address B.B.B.B and I got "connection refused IP B.B.B.B is not a localhost address"
I also opened the port in the router of my houe just in case that's the problem but it doesn't seem to be...
Am I missing something?
Thanks in advance.
Okay apparently, the issue was that even if the server listens on port 1099 then the port you use to connect the stub is random so I had to open all TCP ports in the security group of AWS. In that way it's working, however even if I turned off my windows firewall and open all the ports in the router it wasn't working my laptop - AWS, just different instances in AWS. But well, I can live with that...
Regarding the hostname you have to set it to the private address returned by
hostname -i
If you're going to deploy it inside AWS or to the public IP if you're connecting different instances such as your laptop and one EC2.
I hope this helps people on the same situation (have seen couple of questions with the same issue but no response).
Have a nice day!
I'm trying to write a program for Client/Server communication using RMI and this subject is new to me. I've looked at ton of examples to see if I can try to understand it and they all seem to be designed using local host. My program won't be run on localhost, it will be connecting to Server which is a whole different machine.
If anyone can show me just a simple example of how to establish a connection between two different machines using RMI that would be awesome. I don't need to see how its done for localhost, I've seen like million of those.
Thanks
You only have to change the client.
Change its Naming.lookup() string, from "localhost" to the server's hostname or IP address. The server's Naming string in the bind() or rebind() call does not change from "localhost", because the server and its Registry are always on the same host.
If you are using Registry instead of Naming, again you only have to change the client's LocateRegistry.getRegistry() call.
Let us assume we are connecting two Systems , A(server) with IP address 192.168.1.2 and B (client) with IP address 192.168.1.3 .
You should start the registry on server,i.e., system A then the Server Program should bind the Object like
Naming.rebind("rmi://192.168.1.2/myObject",obj);
Then compile the Client Program on system B which has the lookup function as
myInterface objHandle = (myInterface)Naming.lookup("rmi://192.168.1.2/myObject");
The main catch is that the two systems have to be on the same network for communicating, you might have to create your own network.
I am testing a web application using Java Remote Method Invocation (RMI). When I am connected to internet through dongle, broadband; it takes very long time for the RMI to respond to the request. It takes around 10 seconds in completing the method call. I can also see the data transfer rate rising in the internet connection as soon as I make a method call. So definitely it seems to be making an RMI connection between two internal processes through the external network.
While disconnected from internet it responds vary fast, like in few milliseconds. My /etc/hosts file have entry for 127.0.0.1 localhost. I always use 127.0.0.1 in the method invocation url for naming.lookup. But can't figure out how to make machine respond quickly to RMI calls while I am connected to the internet. Any suggestions?
You problem is not the the address that you use for the lookup call to the RMI Registry, but rather it's the address in the URL that is the result of the call to lookup. This defaults to the IP address of the first interface on the system so my guess is that when you're connected to the Internet it's your external connection.
What I think is happening is that you make a call to the RMI Registry on 127.0.0.1 and this returns your Internet address the location of the service you want, and so your RMI call gets routed out over the dongle interface.
You need to set the java.rmi.server.hostname property to tell the RMI Registry which hostname or IP Adress to return in its RMI URLs.
So you'll need something like:
String ipAddress = "10.1.2.3"; //Local IP address
System.setProperty("java.rmi.server.hostname",ipAddress);
or
String hostname = "myserver"; //hostname that resolves for a local address
System.setProperty("java.rmi.server.hostname",hostname);
I am trying to tcp connect to a server machine in java, by using its public i.p. but when i run the client application i constantly getting a connection refused error. if i used localhost instead of the public ip, it works perfectly.
i search the internet for several causes of the issue but i couldnt fix it.
i forwarded the port to my machines' local i.p address(192.168.1.3) in routers settings. then i checked if port is listening when i ran the server application using netstat -an. i saw lines like,
0.0.0.0:19999 or []:19999 .
19999 is the port number i am trying to listen to. Then i changed my ServerSocket constructor to the 3 parameter one, which also binds the local address.
InetAddress miad = InetAddress.getByAddress(addr);
ServerSocket socket1 = new ServerSocket(port,10,miad);
addr is the InetAddress of my machines local i.p. After these modifications, when i start the server application, i run netstat and it shows:
TCP 192.168.1.3:19999 0.0.0.0 LISTENING
Here i think that my server is listening on the port specified properly.
I have also disabled my firewall and antivirus software.
I have seen several threads and discussions on the net about the issue, and tried most of the things mentioned there, but i keep getting the connection refused error.
What can i be doing wrong? It runs without any errors when i test with localhost.
This is because of the router (not very sure, but almost). Try to see if a webservice like www.canyouseeme.org can connect to your server.
The main idea is that an internal machine (inside the LAN) cannot connect to a machine inside the same LAN by using the external (public) IP address.
I'm pretty sure that it will work, using you internal ip (192.168.1.3).
And if you are sure that you forwarded ports correctly, CanYouSeeMe will say your server is reachable. If it doesn't, make sure you ISP isn't blocking the ports for some kind of "safety reasons".
To figure out if your problem relates to Java and programming please do
telnet 192.168.1.3 19999
If it can't connect then superuser.com would be a better place to discuss this issue.
When I packed my RMI applications and moved to Linux system and ran it.
The log shows that RMI services are running on server 127.0.0.1(Which was printed by method of InetAddress.getLocalhost()).
The configuration in Host file is "127.0.0.1 localhost.localdomain localhost", so I think RMI server was defalutly got the Localhost as servering IP.
After that, my RMI client try to invoke the RMI server method with its real IP(172.16.7.155) which caused a exception "Refused to connect 127.0.0.1".
There're two ways to reslove this problem. The one is modify Host file and reflect the localhost to real IP(172.16.7.155), but I can not modify it because other applications are using localhost domain.
Another way is to reset the method of fecthing IP address at RMI Server, i.e. instead the InetAddress.getLocalhost(), is there any configuration for this method?
You can probably fix this by starting your java rmi server process with the system property "-Djava.rmi.server.hostname=172.16.7.155" (or whatever the public ip of the box is). (details here)