my dog learned polymorphism*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes RMI Binding on localhost Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Android Security Essentials Live Lessons this week in the Android forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "RMI Binding on localhost" Watch "RMI Binding on localhost" New topic
Author

RMI Binding on localhost

Jim DiCesare
Greenhorn

Joined: Nov 23, 2003
Posts: 14
I am having trouble with my RMI binding and retrieving. Every time I start the server the logs show my cable modems IP address, and not the localhost 127.0.0.1. When I connect to the localhost the logs show "outbound call: [endpoint:[127.0.0.1:1099]".
//////heres the server startup code (straight from Max's book)
public static void register(String path)throws Exception {
RemoteDataAdapter rda = new RemoteDataAdapter(path);
java.rmi.registry.LocateRegistry.createRegistry(1099);
Naming.rebind("RemoteDataAdapter", rda);
System.out.println("RemoteDataAdapter Bound");
}
/////////////////////then my lookup from the client
try {
return (DBClient) Naming.lookup("//" + ip + "/RemoteDataAdapter");
}
catch (Exception e) {
System.out.println("exception in connector:" + e.getMessage());
throw new RemoteException(e.getMessage());
}
I start the server on the localhost, and when I try to connect using the client, the lookup call throws an exception "exception in connector: null". I'm assuming this means that my class was not bound, or that I'm trying to connect to the wrong IP. I don't get an exception when I call rebind, so I assume that my class is bound somewhere, and I just can't find it.
I've been stuck on this RemoteException for days now, can someone please help me before I go crazy.
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
It took me a while to get the registry stuff under control. I don't remember all the problems I had so your problem may be different. My suggestion however is general:
on the server side:
instantiate remote database accessor
createRegistry(port) and handle all the exceptions you can get from this method: RemoteException
if you catch a RemoteException then getRegistry("localhost", port) and handle all the exceptions you can get from this method: RemoteException
if you catch a RemoteException then -- it's hopeless
assuming you created or retrieved a registry:
registry.bind(REMOTE_OBJECT_NAME, database) and handle all the exceptions you can get from this method: AlreadyBoundException, AccessException, etc.
If you catch an AlreadyBoundException then try
registry.rebind(REMOTE_OBJECT_NAME, database) and handle all the exceptions you can
get from this method: AccessException, RemoteException, etc.
on the client side:
(DataAccess) Naming.lookup(url) and handle all the exceptions you can get
from this method: AccessException, MalformedURLException, etc
where the URL I'm using is:
"rmi://" + host + ":" + port + "/" + REMOTE_OBJECT_NAME
If nothing else, hopefully this will give you a better understanding of the error that your seeing.
- George


Regards, George
SCJP, SCJD, SCWCD, SCBCD
Jim DiCesare
Greenhorn

Joined: Nov 23, 2003
Posts: 14
Is there a difference in using Naming.rebind instead of java.rmi.registry.Registry.bind? Can I always just use rebind instead of trying to bind first?...I just read an interesting paragraph.."starting the RMI registry in the wrong directory (i.e., it needs to be started in the root directory above our package structure--...
I hope this is my problem.
Jim DiCesare
Greenhorn

Joined: Nov 23, 2003
Posts: 14
Is a security manager needed? The exam says you must not require installation of a security manager, but should I use one and not require it?
Bigwood Liu
Ranch Hand

Joined: Feb 26, 2003
Posts: 240
Did your server print "RemoteDataAdapter Bound"?
if not, it is the problem of server, or maybe you should connect to internet first.
Best,
Damu
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Originally posted by Jim DiCesare:
Is a security manager needed? The exam says you must not require installation of a security manager, but should I use one and not require it?

Hi Jim,
I don't use a security manager, Max doesn't use one in this book, and I believe my assignment instructions explicitly prohibit their use:
Restrictions on RMI
To avoid unnecessary complexity in the marking environment certain restrictions are placed on solutions that use RMI. Specifically:

You must not require the use of an HTTP server.
You must not require the installation of a security manager.
You must provide all classes pre-installed so that no dynamic class downloading occurs.
You must use RMI over JRMP (do not use IIOP)

To the extent that your instructions say the same thing, I think you're going down the wrong path using a security manager. I read "must not require" as essentially the same as "do not use." If you use a security manager to get your code to work (and I don't see how that would solve the problem, but let's accept for the moment that it would), upload your executable to the examiner, he decides not to use a security manager (as he's perfectly able to do given the instructions since you "must not require the installation of a security manager"), and then your executable no longer works because it depends on something that isn't being used (and then you're not if a very defensible position because you've been told that your submission can't require it).
Is there a difference in using Naming.rebind instead of java.rmi.registry.Registry.bind? Can I always just use rebind instead of trying to bind first?...I just read an interesting paragraph.."starting the RMI registry in the wrong directory (i.e., it needs to be started in the root directory above our package structure--...
I hope this is my problem.

Don't know the answer to your first question, my suggestion is to explicitly use a Registry object that's returned to you from the createRegistry or getRegistry methods, then you'll be doing a registry.bind() or registry.rebind(). Having my own registry object makes me feel better that I know what's going on.
The main difficulty I think I had was not knowing what the state of the registry was. Is the registry already created, or do I have to create it? Is the remote object already bound or do I need to rebind? That's why I do what I do in my earlier suggestion: try to create the registry, if that doesn't work then I try to get the registry, if that doesn' work I give up. Then I try to bind the remote object, if that doesn't work because of AlreadyBoundException then I rebind. Having all the possible exceptions handled after each method call made me feel like I was covering all the bases regardless of the state of the registry or the bound-ness of my remote object.
Regarding starting the RMI registry in the root directory above the package structure. I think this refers to manually starting the RMI registry, not doing it (as I think you should) programmatically from you code. So I don't think it's part of your problem here, and I wouldn't pursue it because I think it's the wrong path.
Another idea for you:
When your executable operating in server mode has finished registering and binding your remote database accessor why not try to retrieve it? After all, it should be there, right? I'm suggesting doing a (DataAccess)Naming.lookup(url). If this is going to cause an exception, don't you want to know about it when you're starting the server rather than when the first unwary client tries to get a remote database connection?
Damu's comment sounds right. If you're not seeing the "RemoteDataAdapter bound" message, then your server never did it's part and it's unfair to expect the client to work under these circumstances. I don't understand Damu's comment about starting the Internet first so I can't comment on it.
One other thing:
I don't think you're getting enough info about the exception you're seeing with an e.getMessage(). Add an e.printStackTrace() to your exception handling and you should be able to point to the line of code that's causing the problem; I'm not sure you're getting that just printing out the message.
I know the registry can be a little frustrating because it seems a little mysterious, but don't get frustrated. Get mad, and then get even! Revenge is a dish best served after a bunch of exception handlers and a few good printStackTraces.
Happy hunting,
George
[ December 21, 2003: Message edited by: George Marinkovich ]
Jim DiCesare
Greenhorn

Joined: Nov 23, 2003
Posts: 14
Thanks, using all the exception handling helped me correct my URL string, and find that the real problem is a ClassCastException when I cast my RemoteDataAdapter to the interface it implements (DBClient).
I'm psyched though because I believe that means I'm able to retrieve from my registry, and now I can move on.
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hi George, I got a couple of doubts while going through this. Can you please explain them?
Originally posted by George Marinkovich:

on the client side:
(DataAccess) Naming.lookup(url) and handle all the exceptions you can get
from this method: AccessException, MalformedURLException, etc
where the URL I'm using is:
"rmi://" + host + ":" + port + "/" + REMOTE_OBJECT_NAME
- George

Here is what I understood regarding this.

Now, we are doing two things here. One is creating a registry at xxxx port and let the server start listening at that port. And two, we registered the remote object RemoteDBHandle with the name DBHandleName in the registry.
In the client code we do something like this.

Here the port is the xxxx that we allowed the server to listen. What about the "host" string? I tried to read and understand for this, but could'nt fine, so resuurecting this thread. Is the "host" means the name with which the remote object "rebind" in the registry?
I got this doubt while doing the GUI part. Here's what doing.

As you can see, am confused of the purpose of "host". Can anyone please explain what exactly "host" meant? And do we need to use it to setup a server? My understanding is that we create a registry and rebinds the object at the server side and at the client side we lookup it using the url as stated by George. But I cannot understand what "host" stands for. Sometimes when IP is used as host, I think it tries connects to that particular IP machine and lookup. But what if a host name is provided?
Guys, any help in understanding is appreciated. Thanks.
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
George, Can you please explain the above problem? Am posting again so that the thread will come live and that you can see.
Thanks.
alzamabar
Ranch Hand

Joined: Jul 24, 2002
Posts: 379
Originally posted by Jim DiCesare:
Is there a difference in using Naming.rebind instead of java.rmi.registry.Registry.bind? Can I always just use rebind instead of trying to bind first?...I just read an interesting paragraph.."starting the RMI registry in the wrong directory (i.e., it needs to be started in the root directory above our package structure--...
I hope this is my problem.

Indeed.
bind() fails if the name we've used is already in use; rebind() is guaranteed to succeed.


Marco Tedone<br />SCJP1.4,SCJP5,SCBCD,SCWCD
alzamabar
Ranch Hand

Joined: Jul 24, 2002
Posts: 379
Hi Satish,



Ok, let's say that the examiner started your application in server mode on the following machine: suneduserver. Result: a naming service has started listening on the same machine (this is one of the limitations of the Naming Service shipped with JDK). This means that you will bind (or rebind) your server(s) on suneduserver.
The examiner then started your application in network mode on this machine: suneduclient
the hostName (and port) contained in the URL defines the registry, while the human-readable-name defines the server's name registered with the naming service.

As you can see, am confused of the purpose of "host". Can anyone please explain what exactly "host" meant? And do we need to use it to setup a server?

I would say that the server name must be configurable at startup (via a property or GUI this is up to you, provided that you defend your choices in the documentation).

Sometimes when IP is used as host, I think it tries connects to that particular IP machine and lookup. But what if a host name is provided?

An host name is a human-readable representation of an IP address. This is the mechanism that the Internet uses to map names to IP addresses. You don't have to worry about what happens behind the scenes, provided that your OS is configured for the mapping. Anyway, being configurable, the server user can choose either a name or an IP address depending on the underlying OS.
[ March 12, 2004: Message edited by: Marco Tedone ]
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hi Marco, appreciate your time in replying. I will try to explain what I understood from your reply. Please comment on it if am still wrong
Sample code for binding and lookup to discuss is as follows:

As far as my understanding, I think this is all we have to do for binding and looking up of service.
I do not completely understand of how to co-relate with the statement given by you "the hostName (and port) contained in the URL defines the registry, while the human-readable-name defines the server's name registered with the naming service." to above example.
Here server name is "Server_Machine", but what is hostName? Is it the same as server name? From what you said "An host name is a human-readable representation of an IP address.", can you please tell me how a machine's name is related to host name?

Sorry if my questions repeated, but I could'nt find enough material to understand. Maybe I found, I could not understand it Can you please give an example for host name too? I understood of what server name and ip are from your previous reply.
Appreciate your patience, thanks.
George Marinkovich
Ranch Hand

Joined: Apr 15, 2003
Posts: 619
Hi Satish,
Originally posted by Satish Avadhanam:

As you can see, am confused of the purpose of "host". Can anyone please explain what exactly "host" meant? And do we need to use it to setup a server? My understanding is that we create a registry and rebinds the object at the server side and at the client side we lookup it using the url as stated by George. But I cannot understand what "host" stands for. Sometimes when IP is used as host, I think it tries connects to that particular IP machine and lookup. But what if a host name is provided?

In a URL the host identifies the computer that hosts the resource, that is, on which machine the resource can be found. So you could call the host the host computer to make that more clear. Take a look at the URL class in the Java API. In my suncertify.properties file I called this property databaseServer. It identifies the computer that will serve as the database server. The network client uses this property to lookup the remote object on the computer that is acting as the database server.
[ March 12, 2004: Message edited by: George Marinkovich ]
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Thanks George. Am now working on the RMI server part. You have presented a very good way of creating registry or looking up. Will try to implement on those grounds. If I come up with any issues, will try to solve first, then search, and if anything does'nt work...I hope you will be here to clarify things
Thanks alot.
[ March 12, 2004: Message edited by: Satish Avadhanam ]
alzamabar
Ranch Hand

Joined: Jul 24, 2002
Posts: 379
Hi Satish,

[/qb]<hr></blockquote>
Ideally, the registry should be started as a separate Thread, that is like saying:"Ok, now I've got a naming service listening on port ...". Once the naming service is started and listening, your application can bind servers to the naming services, while clients can request a reference to the server's stub from the naming service . The steps involved in creating a RMI server consist of: 1) Creating the server code that actually performs client's requests; 2) Creating the launch code. The importance of the launch code is that it allows for a separation of concerns (the reason for revising and revisiting the launch code are different from those for revising and revisiting server code). Additionally, the launch code is the first step in managing the server lifecycle, that is important to answer questions like: when to start servers? When to shutdown servers? When to persist servers status? Therefore, the naming service and the servers should be managed through your launch code. Ideally, your application will have the launch code that will start the naming server and eventually will bind the servers to it on one side, and clients that will use remote servers on the other side. In the above code, the two things are mungled (this is just for clarity, although I suppose the above code wanted simply to show the concept).
The actual string you wrote:

actually should be written as:

What is important to realize here is that this string is equivalent, when running on a localhost, to the following:


As far as my understanding, I think this is all we have to do for binding and looking up of service.
I do not completely understand of how to co-relate with the statement given by you "the hostName (and port) contained in the URL defines the registry, while the human-readable-name defines the server's name registered with the naming service." to above example.

When you use the lookup method on the Naming class, you're querying the registry, not the server. Therefore, the hostName - port part of your url, identify the registry (i.e., the machine where the registry is running). When your client wants a reference to a server stub, it asks it to the registry, not directly to the server, and this is what the naming address wants to address. Instead of hardcoding all the remote locations into the clients' code, you register all the servers with one service (the naming) in one location. Now, because one of the limitations of the naming service is to run on the same machine where the remote server is running, it's clear that the remoteHost - port part of your url will also identify the machine where the server is running.

Here server name is "Server_Machine", but what is hostName? Is it the same as server name?

Here I think I'm beginning to understand that there is a little confusion about terminology: I'll try to explain myself as better as I can:
server ==> I mean the RMI server, i.e. the code that implements the remote interface, doing something useful;
hostName or Server_Machine ==> The machine where the RMI server and the naming service run.
Therefore in the url: //serverName : port/server
supposing that the server run on a machine named suneduserver and that the server is called BankTransferManager, you'll end up with:
//suneduserver:1099/BankTransferManager
Another thing to realize is that you can bind whichever name you want to the registry, although your class should be a RMI server implementation.

From what you said "An host name is a human-readable representation of an IP address.", can you please tell me how a machine's name is related to host name?

What I've said is:

human-readable-name defines the server's name registered with the naming service.

Where, server here identifies the code implementing your remote interface.
Hope this helps,
Marco
[ March 14, 2004: Message edited by: Marco Tedone ]
Satish Avadhanam
Ranch Hand

Joined: Aug 12, 2003
Posts: 697
Hi Marco. Thanks a million. You have explained in great detail and examples, the concept which was confusing me from quite sometime.
Once again, Thanks alot Marco
 
 
subject: RMI Binding on localhost
 
Similar Threads
Java RMI Client AccessControlException
RMI Server help please
Major problems with networking client.
RMI app behind NAT firewall
RMI implementation and Adapter Class