About the Spring RMI running in Linux system - java

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)

Related

Connection refused error in java RMI

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.

Strange RMI connection exception with Amazon EC2

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!

How to get listening server port in Java?

My application is deployed in websphere server and from java code, I need to get listening port of the server.
NOTE:
I am using below line for getting internal host name of the system.
InetAddress.getLocalHost().getHostName();
EDIT:
Our server is running on local port 30036 and a local host name. We cannot connect this server using these host and port from out side. We have separate public host/port for outside connection. But in our scenario, we want to access a service running on the same server from the java code. Any way to get this internal port dynamically?
You should be able to access request.getLocalPort() in your service methods (get, post, service, etc). That will tell you what port the request came in on. It's possible it got changed during routing somewhere, and that the port the server is listening on isn't exactly what the client knows about, but if that's the case there's absolutely no where for the server to be able to know that.

JVisualVM remote working when destination is behind NAT?

I am in developer network and the JBoss to be monitored using JVisualVM is behind client firewall in separate network. JBoss is exposed to us through a NAT. The exposed JMX port works when using telnet from our developer network, but JVisualVM still doesn't find the remote JMX. Apparently this can be due to two things: 1) one or several dynamic RMI sockets need to be accessed, or 2) the "java.rmi.server.hostname" is not defined. My problem may be both points 1 and 2, but apparently since we have SSH access this can be tackled according to this site:
http://rafaelsteil.com/setting-up-jmx-for-jconsole-visualvm-on-ec2-plus-jetty-configuration/
“java.rmi.server.hostname” is the public hostname (like example.com) of your server, without HTTP or anything else. You cannot use an internal address, otherwise you won’t be able to remotely access the service.
However I have one question about the "java.rmi.server.hostname", should the defined IP address be the server internal IP or NAT IP which is publicly expoed to our developer network?
I have actually just tackled this problem myself and figured it out.
I would wager that the problem is the RMI connections - you can't predict which ports it will use and so you can't get it to work with a firewall.
The workaround is to use an SSH proxy:
SSH to the box where your application is running but use the -D option like this:
ssh user#remoteHost -D 9999
This will start a socks proxy on your local machine on port 9999.
Open JVisualVM and in the preferences, under 'network' configure it to use a socks proxy at localhost, on port 9999.
If you do the above, you should then be able to connect to the remote machine as normal and since all the RMI traffic is now going over the SSH proxy, it is punched through the firewall and works nicely.
Good luck :-)

Java RMI - Implementing Local to Implementing Remote

I understand and have coded up some RMI code and it works. I can create a RMIServer object and a RMIClient object and the client can send messages to the server and the server receives it perfectly.
My question is how do I communicate between two different computers in different parts of the world?
When you connect to the RMI server you provide an IP or name of the machine hosting the server. You will simply provide the IP/name of the RMI server in place of the one you're currently using.
To get your ip, if you have windows go to start ->run-> write cmd. now in the console write ipconfig your ip is ADDRESS IP.
Remember, if you have dynamic ip (unless your supplier get you a static ip) this change when restart your pc

Categories

Resources