aspose file tools*
The moose likes Java in General and the fly likes RMI Call Works on Same Host, Fails Over Network Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Java » Java in General
Bookmark "RMI Call Works on Same Host, Fails Over Network" Watch "RMI Call Works on Same Host, Fails Over Network" New topic
Author

RMI Call Works on Same Host, Fails Over Network

Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

I swear I have Googled this, and done my best to apply the advice I found (almost all of which was, in essence, "turn off your firewalls," which I have).

I have a pair of classes (one client, one server), and an interface, in an attempt to create an RMI server that will respond to method invocations from my client machine. Everything works fine when all of the code is on one machine. That includes all .class files on my Windows 7/64 machine, and all .class files on my on Linux machine. When I run the server on the Linux machine and the client on the Windows machine, I get a run-time error that is quite baffling to me, partly because it seems to be complaining about an inability of the client to establish a socket connection on its own host, not the server host. I know the client machine does make contact with the server because, if I don't start the server running, the client gives me a different error (a javax.naming.ServiceUnavailableException, which makes sense).

Here's my interface:


Here's the server:


And here's the client:


I try to run it by first running rmiregistry in a command window, then running java RMIserver in a diffferent window. That always yields this output:

Then if I run java RMIclient localhost, I get this:

But, when I run java RMIclient DFL0015, I get this:


I am particularly puzzled by the fact that it seems to succeed when calling context.lookup, but fails at the call to iface.RMImethod, with, apparently, an attempt to connect to the client host, not the server host.

Can anyone shed light on this one for me?
Thanks.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19719
    
  20

Until you've made sure it's not a network issue, don't even look at your code. So the first question is, can you open a telnet session to the RMI registry on the machine? Does telnet DFL0015 1099 work?


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Rob Spoor wrote:Until you've made sure it's not a network issue, don't even look at your code. So the first question is, can you open a telnet session to the RMI registry on the machine? Does telnet DFL0015 1099 work?

Yes, that connects successfully.
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Ah, cracked it, I believe. According to this posting, one must specify the host name for the server, or else it exports its localhost IP address. I did this for the RMI registry and the server both. It probably only needs one of those. I'll test further and post what I learn.
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

This fixes it:



Line 18 solves the problem. When the code registers the server (at Line 23), the registry (maintained by the rmiregistry process) associates that server with an IP address, which it (the rmiregistry process) will hand out to clients that want to use the server. Note that this means the server can reside on a third machine (with rmiregistry running on another one, and the client running on yet one other). So long as all servers register with the central rmiregistry process, and all clients query that process for servers, the clients will all get the IP address of the host the server is actually on.

Why, then, is Line 18 necessary? The answer appears to be that *nix systems use a default IP address they get from somewhere (maybe the localhost entry in /etc/hosts, maybe not; not sure about that yet), and that tends to be the loopback address of 127.0.0.1. This is a really nasty little bug, because, when your client queries the registry for a server, the registry responds that the server exists and can be found at address 127.0.0.1. Your client then attempts to make a remote method call to the server at that address. Well, 127.0.0.1 is, for each machine, itself. Thus, the exception makes it look like the client has attempted to run a method provided by the server on the client's own machine, because that is actually what the client has done. It has done this because it has acted in reliance on the IP address given to it by the registry which, earlier, stored that address in reliance upon what it got told by the server object when the server object was registered. So, the server starts up and thinks its IP is 127.0.0.1. It gives that to the rmiregistry process. That process then gives that address to any clients who ask about that server. Those clients then try to access 127.0.0.1, which always exists, but, in all probability, isn't the server machine (unless the client and the server are on the same machine, which--nasty, nasty--might well mask this entire problem if one is developing both on the same computer).

One can cure this at run-time with the -Djava.rmi.server.hostname=192.168.2.145 trick, but Line 18 moves the same effect into the code. Of course, one need not hard-code the IP address like I've done here. No doubt, one could query the platform for its IP address (its "real" address, not its loopback address) at run-time, and use that. Regardless, this appears to get the job done.

If anyone with better RMI or networking knowledge would like to comment, I'd be grateful for your wisdom.

Stevens
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2315
    
  49
Hi Stevens,

I used RMI a long time ago so the recommended way of doing things may well have changed (or maybe I never did it correctly in the first place) but as far as I remember I never had to set the java.rmi.server.hostname property.

I've looked back through some old code and the way I wrote it involved using LocateRegistry.createRegistry() rather than the InitialContext class and then using bind()/unbind()/rebind() on the returned Registry object to register/unregister objects. The name specified when binding an object through Registry was in the format of: [EDIT: this should have said:] on the Naming class. The name specified when binding an object through Naming was in the format of:
rmi://[host][:port][/[object]]
and if the host was omitted localhost was used instead and if port was omitted 1099 was used. I don't if this applies to the InitialContext bind() method as well and even if it does I'm not sure it actually helps you as you would still need to specify the host name but it may explain what is happening.
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Tony Docherty wrote:Hi Stevens,

I used RMI a long time ago so the recommended way of doing things may well have changed (or maybe I never did it correctly in the first place) but as far as I remember I never had to set the java.rmi.server.hostname property.

I've looked back through some old code and the way I wrote it involved using LocateRegistry.createRegistry() rather than the InitialContext class and then using bind()/unbind()/rebind() on the returned Registry object to register/unregister objects. The name specified when binding an object through Registry was in the format of:
rmi://[host][:port][/[object]]
and if the host was omitted localhost was used instead and if port was omitted 1099 was used. I don't if this applies to the InitialContext bind() method as well and even if it does I'm not sure it actually helps you as you would still need to specify the host name but it may explain what is happening.


You are correct! This code works equally well:



Now, in that old code of yours , would you happen to have a fragment or line that shows how to register a server object when the rmiregistry process is running on a machine other than the server's own platform?

(Weren't you away for a bit? Nice to have you back.)
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2315
    
  49
Now, in that old code of yours , would you happen to have a fragment or line that shows how to register a server object when the rmiregistry process is running on a machine other than the server's own platform?

It is/was as simple as:

Just noticed my previous post contained an error in that I said you used the Registry object to bind objects, that is wrong you use the Naming class.

(Weren't you away for a bit? Nice to have you back.)

Just for a 10 day holiday, and thanks although I can't say being back in the cold and wet weather here is nicer than being in Thailand
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39395
    
  28
At least today’s weather is better than yesterday’s!
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2315
    
  49
Very true, but still not 35C and sunshine.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39395
    
  28
Sunshine (well, setting now) and at least 35F
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Hey, just where are you guys? I know Winston is in exotic Belgium, and I think Tony is somewhere in England, but I'm not really sure. I'm in Loudoun county, Virginia, which is about 25 miles west of Washington DC (and where it is 45F/7C at 2:30pm).

Tony: That snippet you've posted has me in a spin. It appears that InitialContext and Naming both have bind methods, but neither is an "is-a" of the other. Further, my reading on remotely registering a server object with rmiregistry is telling me you can't do it (or, at least, you could not do it as of 2008; a lot about RMI seems to have changed since then, including the elimination of rmic from the process).

Once again, I can see I've got a lot of work to do. Will post here what I can.

Hey, do we have a place here at coderanch to post "how to" or "white paper" documents? Every time I figure out how to do a new thing in Java, I tend to write one. It would be great to share them with others who do the same thing.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18654
    
    8

Stevens Miller wrote:Hey, do we have a place here at coderanch to post "how to" or "white paper" documents? Every time I figure out how to do a new thing in Java, I tend to write one. It would be great to share them with others who do the same thing.


Have a look at our (fairly) new Blog Around the Campfile forum.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39395
    
  28
North Yorkshire, about 2 miles from the nearest salt water. We had about 45°F at 2.30pm, too, but our 2.30pm is different from your 2.30pm
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Paul Clapham wrote:
Stevens Miller wrote:Hey, do we have a place here at coderanch to post "how to" or "white paper" documents? Every time I figure out how to do a new thing in Java, I tend to write one. It would be great to share them with others who do the same thing.


Have a look at our (fairly) new Blog Around the Campfile forum.


That's useful, but I had something more in the way of a knowledge-bank, maybe with volunteer vetting. Perhaps that's too much to ask, but what I have in mind would (usually) be rather small documents. On my machine, I have a directory called "How to." It is filled with files with names like, Add a jar File to a NetBeans Project with Source and Javadoc.txt. That one contains this:

You must have at least the .jar file with the compiled class files in it. You may also have the .jar files with the source and with the javadoc in them. You may put these anywhere, though it allows you to move things easily if they are in the same subtree as your project (they can be in an ancestor or a sibling; the latter makes the most sense if you created them all yourself in tne NetBeansProjects subtree).

Right-click the "Libraries" folder under your project's root node in the "Projects" explorer and pick "Add JAR/Folder..."

In the window, navigate to the folder with your .jar files in it.

Select the class file .jar and open it.

Right-click that .jar file under "Libraries" in your project's tree in the "Projects" explorer and pick "Edit..."

Browse to your javadoc and source files. This is where you can set a relative or absolute path to them.

Open both.

Javadoc and source are now available from the IDE.


Now, that's a bit terse, but it does get me going whenever I forget how to do what the filename describes. Do we (or might we) have a place for stuff like that?
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Campbell Ritchie wrote:North Yorkshire, about 2 miles from the nearest salt water. We had about 45°F at 2.30pm, too, but our 2.30pm is different from your 2.30pm

Ah, the North Sea! I visited Aberdeen, about ten years ago. Wonderful place, and looking out over that water was kind of awesome. Also awesome was seeing light in the sky at 10:30pm.
Paul Clapham
Bartender

Joined: Oct 14, 2005
Posts: 18654
    
    8

Stevens Miller wrote:Do we (or might we) have a place for stuff like that?


There's our Java FAQ (you should have a link for it at the top of the page you're looking at now). It's a wiki so anybody can edit it. However it seems to me that how to configure RMI is more of an IAQ than an FAQ.
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Paul Clapham wrote:
Stevens Miller wrote:Do we (or might we) have a place for stuff like that?


There's our Java FAQ (you should have a link for it at the top of the page you're looking at now). It's a wiki so anybody can edit it. However it seems to me that how to configure RMI is more of an IAQ than an FAQ.


Heh. Well, perhaps the way to look at it is that some of the discussion here addresses Qs that are not Java FAQs, but they are RMI FAQs. That list of FAQs looks like the ideal place for some of the more editorially acceptable HowTo files I've got to share. How does one add a new FAQ file?
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Tony Docherty wrote:
Now, in that old code of yours , would you happen to have a fragment or line that shows how to register a server object when the rmiregistry process is running on a machine other than the server's own platform?

It is/was as simple as:

Tony, are you sure that will register a server on another platform? "Core Java" says that only an application running on the same host as the rmiregistry process can register a server with that process. This, it says, is a security measure that "prevents hostile clients from changing the registry information." (p.849, 8th ed.) Now, that wording would also appear to allow for an application to register a remote server, so long as the application doing the registration were on the same host as the registry, but I have no idea if that's possible or, if it is, how do it.

To be as clear as I can: I am thinking of a scenario with three distinct computers. Computer One runs the rmiregistry process. Computer Two runs the server object. Computer Three runs the client. If "Core Java" is correct, only an application running on Computer One can register a server with the rmiregistry process. If so, is it possible for that application to register the server object that will run on Computer Two?
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2315
    
  49
Hey, just where are you guys? I know Winston is in exotic Belgium, and I think Tony is somewhere in England, but I'm not really sure.

Unlike lucky old Campbell I'm just about as far from the sea as it's possible to get in England - a small town near to Birmingham.

Tony: That snippet you've posted has me in a spin. It appears that InitialContext and Naming both have bind methods, but neither is an "is-a" of the other. Further, my reading on remotely registering a server object with rmiregistry is telling me you can't do it (or, at least, you could not do it as of 2008; a lot about RMI seems to have changed since then, including the elimination of rmic from the process).

As I said earlier it is old code and I thought I had setup the registry on a remote machine in the test environment but either my memory is playing tricks on me or we weren't using the standard rmi registry. Here's an article showing how it possibly can be done by writing your own rmi registry implementation. http://www.drdobbs.com/jvm/a-remote-java-rmi-registry/212001090?pgno=1
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Tony Docherty wrote:
Hey, just where are you guys? I know Winston is in exotic Belgium, and I think Tony is somewhere in England, but I'm not really sure.

Unlike lucky old Campbell I'm just about as far from the sea as it's possible to get in England - a small town near to Birmingham.

Still looks like a nice place to visit. Isn't it amazing that people in Europe save their money to visit the United States, while Americans save our money so we can visit Europe? Lesson in that, somwhere.
Regardless, for all of us, there are worse places we could live.

Tony: That snippet you've posted has me in a spin. It appears that InitialContext and Naming both have bind methods, but neither is an "is-a" of the other. Further, my reading on remotely registering a server object with rmiregistry is telling me you can't do it (or, at least, you could not do it as of 2008; a lot about RMI seems to have changed since then, including the elimination of rmic from the process).

As I said earlier it is old code and I thought I had setup the registry on a remote machine in the test environment but either my memory is playing tricks on me or we weren't using the standard rmi registry. Here's an article showing how it possibly can be done by writing your own rmi registry implementation. http://www.drdobbs.com/jvm/a-remote-java-rmi-registry/212001090?pgno=1

Ah, thanks. I feel better already. I found that same article, but didn't want to rely on it as it seems to have been written before some of the recent, significant changes to RMI appeared.
Apologies, btw, for posting this item in the wrong forum. I just found out there is a "Distributed Java" forum, where I'll take my RMI questions from now on.
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2315
    
  49
Still looks like a nice place to visit.

It is, there are lots of things to do and see around here and we are only a few hours drive from virtually everywhere else in the country.

Isn't it amazing that people in Europe save their money to visit the United States, while Americans save our money so we can visit Europe? Lesson in that, somwhere.

Even more amazing is people here spend loads of money to go to places like Thailand with the sole intention of lying on a beach and getting a good tan, whereas the locals do whatever they can to stay out of the sun because they all want to be as light coloured as possible. It seems that it is human nature to want to be somewhere else and look more like someone else.

Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Tony Docherty wrote: It seems that it is human nature to want to be somewhere else and look more like someone else.

Unless, of course, somewhere else is where they program in C++.
Campbell Ritchie
Sheriff

Joined: Oct 13, 2005
Posts: 39395
    
  28
Stevens Miller wrote: . . . Also awesome was seeing light in the sky at 10:30pm.
I can read small print by daylight at 10.30pm in June. Of course, it cuts both ways; it is pitch‑black by 4.00pm in December.
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Guess we all take the good with the bad, wherever we live. Got this on the good side, just now:

Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2315
    
  49
Nice.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42276
    
  64
Stevens Miller wrote:Well, perhaps the way to look at it is that some of the discussion here addresses Qs that are not Java FAQs, but they are RMI FAQs. That list of FAQs looks like the ideal place for some of the more editorially acceptable HowTo files I've got to share. How does one add a new FAQ file?

I wouldn't worry that the wiki bills itself as an FAQ - there's plenty of stuff in there that falls in the IAQ category, and a bunch of stuff that is neither because it's more blog-like in nature. Rest assured, we welcome all contributions.

The easiest way to add a new page is to add the WikiWord title that you want to use to an existing page, and upon saving it will turn into a link that you can use to open and edit the new page. Since we don't have an RMI or networking FAQ, maybe http://www.coderanch.com/how-to/java/JavaIoFaq would be a good place to put such a link.

The login credentials are the same that you'd use for the forums here.


Ping & DNS - my free Android networking tools app
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Ulf Dittmer wrote:Since we don't have an RMI or networking FAQ, maybe http://www.coderanch.com/how-to/java/JavaIoFaq would be a good place to put such a link.

Great idea, Ulf. Thanks. Although I have done IPC stuff for decades, I'm new to RMI. Would it be best to post a draft first FAQ in the Distributed Objects forum, or just put it up in the wiki and mark it as a draft? I wouldn't be shocked if my first attempt has a mistake or two, and would indeed be shocked if it couldn't be improved in at least some way or another.
Ulf Dittmer
Marshal

Joined: Mar 22, 2005
Posts: 42276
    
  64
I think it's fine to just put it up there. Wikis are perpetual works in progress anyway, so change is normal. You could also post a notice in the Ranch Office forum to let people know that it's there.
Stevens Miller
Ranch Hand

Joined: Jul 26, 2012
Posts: 531
    
    3

Ulf Dittmer wrote:I think it's fine to just put it up there. Wikis are perpetual works in progress anyway, so change is normal. You could also post a notice in the Ranch Office forum to let people know that it's there.

Will do! Thanks for the encouragement.
 
It is sorta covered in the JavaRanch Style Guide.
 
subject: RMI Call Works on Same Host, Fails Over Network