I'm working on a project using Java RMI and with a client-server implementation.
On the server side, this is how I initialize my server:
final String url = "localhost";
final int port = 8090;
LocateRegistry.createRegistry(port);
IServerGame serverGame = new ServerGame();
Naming.rebind("//"+url+":"+port+"/undercover", serverGame);
System.out.println("Server running at //" + url + ":" + port + "/undercover")
Undercover is the name of my application. We chose to use the port 8090
arbitrarily.
Now, here is how I initialize the connection client-side:
try {
server = (IServerGame) Naming.lookup("//"+address+":8090/undercover");
System.out.println("Connected to server " + address + ".");
} catch (Exception e) {
System.out.println("Connection failed.");
e.printStackTrace();
}
address is a string in the parameter of the method which initializes the connection and is the IP of the server. We ask the client to enter this IP to allow us to connect to different servers if we want.
When I run my application in local, whether I use localhost or my private IP 192.168.x.x as address, everything works fine. The client connects to the server and I can use the application. The problem is that when I want to use the application via WAN, sending the client to a friend and starting the server on my local machine, it doesn't work anymore. I get this error:
java.rmi.ConnectException: Connection refused to host: (private IP of host machine); nested exception is:
java.net.ConnectException: Connection timed out: connect
I've already checked a lot of posts in StackOverflow with the exact same problem and the usual answer is to either set the SystemProperty(java.rmi.server.hostname,"192.168.x.x") or do it via the -Djava.rmi.server.hostname in command line. I'm using Gradle to compile. I run the application via the run task. The client is a basic fx application too. None of this works unfortunately. I've also tried to open the port 8090 in my firewall but it doesn't solve the problem either.
Now maybe I'm doing this wrong. I've also tried to replace my private IP 192.168.x.x, which is IPv4 that I found via ipconfig in the command shell, with my public IP 79.95.x.x. But, again, it doesn't work.
I tried adding the SystemProperty(java.rmi.server.hostname,"192.168.x.x") like the first line of code that appears in the server code I showed you above.
I'm connected to internet via 4G. I don't have a box connection, so I can't really go to the box settings to allow certain ports, if that's ever a thing that could fix the issue.
EDIT :
So i've tried to switch from naming implementation in server-side to Registry implementation as it was suggested bellow but it didn't make any difference. As i thought it could be just a connection problem, i asked a friend to ping the server with telnet on the port 8090 and in fact it didn't work. He ran telnet [domain name or ip] [port] and the error was :
Unable to connect to remote host: Connection timed out
So the problem is that the external clients cannot reach my server or connect to the port. As i'm using 4G as internet connection as i mentioned above, any idea on how i could make the port reachable ?
Try using class java.rmi.registry.Registry rather than class java.rmi.Naming.
On the server side:
final int port = 8090;
Registry registry = LocateRegistry.createRegistry(port);
ServerGame serverGame = new ServerGame();
IServerGame stub = (IServerGame) UnicastRemoteObject.exportObject(serverGame, 0);
registry.bind("undercover", stub);
On the client side:
Registry registry = LocateRegistry.getRegistry("server host name or IP", 8090);
IServerGame serverGame = (IServerGame) registry.lookup("undercover");
I have a java rmi application i simply do:
Client:
Registry registry = LocateRegistry.getRegistry("localhost");
costApi = (CostApi) registry.lookup("server.CostApi");
Everything works fine when I host the server at localhost. When I start the same program at another machine withing the local network, at 192.168.x.x and change to:
Client:
Registry registry = LocateRegistry.getRegistry("192.168.x.x");
costApi = (CostApi) registry.lookup("server.CostApi");
it does not work anymore and it fails with a very strange error:
java.rmi.ConnectException: Connection refused to host: 127.0.1.1; nested exception is:
java.net.ConnectException: Connection refused
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:619)
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.invoke(UnicastRef.java:129)
at java.rmi.server.RemoteObjectInvocationHandler.invokeRemoteMethod(RemoteObjectInvocationHandler.java:194)
at java.rmi.server.RemoteObjectInvocationHandler.invoke(RemoteObjectInvocationHandler.java:148)
at com.sun.proxy.$Proxy0.dataCost(Unknown Source)
at billing.data.DataBiller.performBilling(DataBiller.java:57)
at billing.data.DataBiller.consumeMessage(DataBiller.java:46)
at general.templates.RabbitWorker.run(RabbitWorker.java:124)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.net.ConnectException: Connection refused
at java.net.PlainSocketImpl.socketConnect(Native Method)
I'm not even trying to connect to 127.0.1.1 but to 192.168.x.x, how do I solve this? I prefer to use java code only and not modify my machine with config files. I'm using linux
This is usually caused by a misconfiguration. Check your /etc/hosts file to ensure that:
localhost maps to 127.0.0.1
your real hostname maps to your real host address
Some Linux distributions are known to have this back to front.
If the problem persists, try setting java.rmi.server.hostname at the server to the IP address the client should use when executing remote method calls. It needs to be set before you export any remote objects, including the Registry.
The problem is caused by the IP address embedded in the stub, which ultimately comes from something like InetAddress.getLocalAddress(), which is fallible as above. It is overridden by java.rmi.server.hostname.
This is item A.1 in the FMI FAQ, but note that the item is mistitled. It doesn't happen during lookup(), it happens when you call a remote method on the resulting stub.
I just ran into the same issue. I'm doing something very similar to what you are doing. What I noticed was that the first time I ran the client program, and it failed ( by design of the firewall test ) - that it failed with an error message showing the actual ip address of the host that I originally specified ( the 192.168.x.x address ), but all subsequent failures show that it is failing to make a connection to 127.0.0.1. Currently I'm suspecting some kind of caching on the client - has the JVM marked that ip address as never accessible again and it's refusing to ever try to connect to it again?
UPDATE: In my case, the JVM on the RMI Server side was not able to properly set the java.rmi.server.hostname property at JVM startup. This property was being left as null. When clients connect to a specific RMI Registry and ask for a stub to a particular named object, they receive a stub containing the ip address of the remote machine where the actual object can be found. The RMI server copies the contents of the java.rmi.server.hostname property into the stubs it returns to clients, so if the java.rmi.server.hostname property is "" and it copies that to each stub it creates, each stub contains a reference to remote server with an IP address of "". By default the client jvm reacts to this by attempting to connect to the server object on the localhost, 127.0.0.1. To work around the problem, try this line of code before exporting any remote objects on the server side:
System.setProperty( "java.rmi.server.hostname", "192.168.RMIServer.IP" ) ;
This property will be automatically copied to all remote stubs exported on that server, and clients who receive that stub should then be able to reach the remote server ( assuming any firewalls are configured correctly ).
I have a JMX enabled application which creates RMI Registry by doing:
rmiRegistry = LocateRegistry.createRegistry(registryPort);
and then later on it creates JMXConnectorServer by doing:
JMXServiceURL url = new JMXServiceURL(
"service:jmx:rmi://localhost:" + serverPort
+ "/jndi/rmi://:" + registryPort + "/jmxrmi");
connector = JMXConnectorServerFactory.newJMXConnectorServer(
url,
null,
ManagementFactory.getPlatformMBeanServer());
connector.start();
My problem is that I cannot connect to this JMX Server from a remote host using JConsole. I've followed the instructions for debugging/tracing JConsole and I can see that the problem is that JConsole tries to connect to a bogus IP address that it must have gotten from the Registry. Ok, it isn't exactly bogus because it happens to correspond to a virtual network interface I have on the JMX Server host machine. How on earth does JMX pick that up?
A netstat on my application reveals that both the serverPort and the registryPort are bound on the wildcard interface (on both IP4 and IP6) which is as expected since I haven't supplied socket factories. Basic connectivity works from the remote host, i.e. I can get the telnet test to pass on both ports.
I would have assumed that I would have to change 'localhost' in the JMXServiceURL to the name of my host (as other hosts sees it, not how it sees itself) but that doesn't help.
What do do ?
UPDATE1
After some more investigation I'm pretty sure this 'bogus IP address' comes because RMI just picks the first IP it finds on its own host and then uses that as its 'call-me-back' address. It then happens to find that virtual NIC that exists on this host. That's really not want I want. I want to be able to control explicitly the RMI 'call-me-back' address.
Welcome to RMI hell.
The end point resolve himself and send back to jconsole the ip to use.
If you can try to use JMXMP : http://meteatamel.wordpress.com/2012/02/13/jmx-rmi-vs-jmxmp/.
You can also try java.rmi.server.hostname :
http://docs.oracle.com/javase/7/docs/platform/rmi/spec/rmi-properties2.html
I want to write a JMX server and client and while writing the client i encountered this problem
I can register my MBean properly but when I am trying to run the server I get the following exception:
cannot bind URL [rmi://localhost:9999/server]
I configured the server as follows :
JMXServiceURL url = new JMXServiceURL("service:jmx:rmi:///jndi/rmi://localhost:9999/server");
JMXConnectorServer cs =JMXConnectorServerFactory.newJMXConnectorServer(url,null,mbs);
cs.start;
Check nothing running on the port (netstat)
Try 127.0.0.1 instead of localhost
What are the steps I should take to solve the error:
java.net.UnknownHostException: Invalid hostname for server: local
I added the new virtual host name at Android emulator but the result returns to
java.net.UnknownHostException virtualhostname at
java.net.InetAddress.lookUpHostByName(InetAddress.java:506)
When I type my virtualhost URL on my PC, it works on display. Then again, when I ran on Emulator and check on Logcat, I couldn't be able to read or check the HTTP status if 200, 202, or an error code number. It simply returned to UnknownHostException
I was having the same issue on my mac. I found the issue when I pinged my $HOSTNAME from terminal and it returned ping: cannot resolve myHostName: Unknown host.
To resolve:
Do echo $HOSTNAME on your terminal.
Whatever hostname it shows (lets say myHostName), try to ping it : ping myHostName. If it returns ping: cannot resolve myHostName: Unknown host then add an entry into your /etc/hosts file.
For that edit /etc/hosts file and add following:
127.0.0.1 myHostName
What the exception is really saying is that there is no known server with the name "local". My guess is that you're trying to connect to your local computer. Try with the hostname "localhost" instead, or perhaps 127.0.0.1 or ::1 (the last one is IPv6).
From the javadocs:
Thrown to indicate that the IP address
of a host could not be determined.
127.0.0.1or ::1 or "localhost" should always be the loopback interface, so if that doesn't work I'd be really surprised.
If there really is a server called "local" on your network - examine your DNS settings or add it to your hosts file.
java.net.UnknownHostException: Host is unresolved:
Thrown to indicate that the IP address of a host could not be determined.
This exception is also raised when you are connected to a valid wifi but router does not receive the internet. Its very easy to reproduce this:
Connect to a valid wifi
Now remove the cable from the router while router is pluged-in
You will observe this error!!
You can't really solve this, You can only notify the user gracefully. (something like - "Unable to make a connection")
This is not specific to the question, but this question showed up when I was Googling for the mentioned UnknownHostException, and the fix is not found anywhere else so I thought I'd add an answer here.
The exception that was continuously received was:
java.net.UnknownHostException: google.com
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:184)
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)
...
No matter how I tried to connect to any valid host, printing it in the terminal would not help either. Everything was right.
The Solution
Not calling trim() for the host string which contained whitespace. In writing a proxy server the host was obtained from HTTP headers with the use of split(":") by semicolons for the HOST header. This left whitespace, and causes the UnknownHostException as a host with whitespace is not a valid host. Doing a host = host.trim() on the String host solved the ambiguous issue.
Your hostname is missing. JBoss uses this environment variable ($HOSTNAME) when it connects to the server.
[root#xyz ~]# echo $HOSTNAME
xyz
[root#xyz ~]# ping $HOSTNAME
ping: unknown host xyz
[root#xyz ~]# hostname -f
hostname: Unknown host
There are dozens of things that can cause this. Please comment if you discover a new reason.
For a hack until you can permanently resolve this issue on your server, you can add a line to the end of your /etc/hosts file:
127.0.0.1 xyz.xxx.xxx.edu xyz
This might happen due to various reasons
1) Check if you have VPN connected, you might get this error sometimes if yes
"Your hostname, localhost resolves to a loopback address: 127.0.0.1; using 10.xxx.1.193 instead (on interface cscotun0)"
2) Check your $HOSTNAME
3) try to ping $HOSTNAME on commandline and if it doesnt work, tweak the system settings to make your local host respond to pings
Try the following :
String url = "http://www.google.com/search?q=java";
URL urlObj = (URL)new URL(url.trim());
HttpURLConnection httpConn =
(HttpURLConnection)urlObj.openConnection();
httpConn.setRequestMethod("GET");
Integer rescode = httpConn.getResponseCode();
System.out.println(rescode);
Trim() the URL
Trying to connect to your local computer.try with the hostname "localhost" instead or perhaps ::/ - the last one is ipv6
Please try to set SPARK_LOCAL_IP environment variable to the ip address(can be localhost i.e. your own ip address) you want to connect. E.g.
$ export SPARK_LOCAL_IP=182.95.208.152
This way you will not be required to alter existing linux settings.
Worked for me, hope helps you too.
Connect your mobile with different wifi connection with different service provider.
I don't know the exact issue but i could not connect to server with a specific service provider but it work when i connected to other service provider. So try it!
I had this issue in my android app when grabbing an xml file the format of my link was not valid, I reformatted with the full url and it worked.
If you are here because your emulator gives you that Exception, Go to Tools > AVD Manager in your android emulator and Cold boot your Emulator.
I had the same issue.
Restart docker was the fix for me. For some reason it needed a restart, I donĀ“t know why, but it worked.
If your /etc/localhosts file has entry as below:
Add hostname entry as below:
127.0.0.1 local host (add your hostname here)
::1 (add hostname here) (the last one is IPv6).
This should resolve the issue.