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!
Related
In my project I need to find the public ip address of a machine.
I have implemented that using method mentioned in Finding public ip address using java
I have an api url like 'http://182.14.10.5:8080/test/addVendor' (not exact url) in my project and has been deployed in external tomcat server which has public ip address as 187.15.161.90.
The issue am facing is:
When i tried loading this api url from other devices like mobile or computers belong to some other network, am getting the same ip 182.14.161.90 for every URL hit.
This is where i got confused. Whether the program is written according to that or am i getting wrong output.
According to the search results what I understood is, when I load the particular api url, I should get different ip address based on different machine connected with different network.
But am getting the same public ip (182.14.161.90) of the server where my project is deployed.
Can anyone pls clarify it and help me to fix the issue.
Any suggestions would be appreciated.
Thanks
It sounds to me like you have a Java Web Application deployed via tomcat and want to get a user's IP address.
The question you've linked in your question Finding public ip address using java is specifically for getting the IP address of the machine where the Java Code is running (for example, if you have a desktop application and want to get the IP of the machine that app is running on for some reason)
If you want to get the user's remote IP, it depends on your server configuration
If Tomcat is the ONLY webserver in your environment, and there is nothing in front of it, you can access the Request's remote ip using HttpServletRequest#getRomoteAddr, which will give you the IP address of the socket connection that initiated the Request.
This will work great unless you have a proxy server, like Apache HTTPD or Nginx in front of Tomcat, in which case you'll need to configure your server to send the
X-Forwarded-For header, and get the user's remote IP using HttpServletRequest#getHeader for example, request.getHeader("X-Forwarded-For")
If I've misunderstood your question, please clarify and let me know with a comment.
I am developing a Java application which will listen a local port to communicate with another program. Normally it will listen to, say 127.0.0.1:8808.
One of my client reports that they are using Citrix environment, it is like MS remote desktop environment, multiple users can log in the same machine in the same time.
As you may know, such terminal server users share one loopback address, that means, only the first user run my application can successfully bind to 127.0.0.1:8808, the others will receive resource conflict error.
My client try to fix this by enable "virtual loopback", this setting can automatically assign different loopback address to different users, every user will get 127.0.0.2-127.0.0.255 as the loopback address instead of all 127.0.0.1, that sound like a perfect solution for this situation.
A test shows virtual loopback works well for other programs like chrome and IE, TCPView tool shows any connection to localhost are redirect to 127.0.0.2, except my program.
I am thinking the problem may be because I am using the fixed address 127.0.0.1 in the code, but I don't have an environment to confirm. So my question here is: Is there any Java method I can use to get the REAL loopback address in such situation, so I can bind to the the right address?
Thanks in advance!
I'm wondering if there is a way to setup connection between a client and a server over the internet and have both of them programmatic setup all needed router/firewall configuration changes to open needed external ports to communicate.
Assuming both server and client have known ip addresses and a DNS is not needed in this example to find the IP addresses. How might one have a server that when started configures access past the firewall and tells the router how to route proper communication to the server. I would assume the client may not need anything like this as it should only need to know the external IP address and port number of the server. If i'm wrong about my assumption please let me know.
Example if I have two houses house (A) has a server and house (B) has a client and both sites know what the other house external IP address is and know what port they will be using how may a Java application do all the configuration or at least do as much as possible on say windows,mac,ubuntu. The idea is the user of the server and client should not have to do a bunch of firewall/router configurations to get the application running. It would also be nice if in the example it shows how to release the connections when the server is terminated. Example when the java server is turned off it should close up port settings on the firewall and router. security and clean house.
There is no easy way of doing that as it will depend on the OS and on the many possible firewall application running on the machine. Plus, if your app crash, you will never set back the original parameters, which can be problematic when talking about security. Instead of trying to set up custom configuration, you should try to use standard communication template/protocol like http. This will gives you a high probability of your app running without additional configuration almost anywhere (since there is almost no point of having an internet connection if you don't allow http port).
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.
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)