aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes B&S 2.3.1 - Identifying clients uniquely in RMI Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "B&S 2.3.1 - Identifying clients uniquely in RMI" Watch "B&S 2.3.1 - Identifying clients uniquely in RMI" New topic
Author

B&S 2.3.1 - Identifying clients uniquely in RMI

Arun Subramanian
Ranch Hand

Joined: Oct 30, 2002
Posts: 47
Greetings all-
I have a single instance of Data being shared by all the networked clients. (I have a Proxy object that is unique to each client and exists on the client JVM and each proxy holds a reference to the same single RemoteObject which in turn has the Data instance). What would be a good way to identify the clients uniquely (client JVMs uniquely) on the RMI server JVM for my locking operations.

I could use java.rmi.server.RemoteServer.getClientHost() on the RMI server JVM but then I would have to specify in my choices.txt that 2 clients cannot be launched as network clients from the same machine.

Alternatively, I am thinking about callbacks but am a little stuck. I can quite easily send a generealized update to all the clients using callbacks by registering each client with the RMI server. But then using callbacks, how do I execute a method on a specific client to get the client's unique information if that client is executing the lock method.

Any help/advice would be appreciated.

Thanks,
Arun.


SCJP 1.4, SCBCD 1.3, SCWCD 5.0, SCJD B&S 2.3.1 (in progress)
Paul Bourdeaux
Ranch Hand

Joined: May 24, 2004
Posts: 783
Hi Arun,

What is the method signature of your lock and unlock methods in the interface provided by Sun? I ask because there are two different strategies, depending on whether or not your interface uses lock cookies...


“Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning.” - Rich Cook
Arun Subramanian
Ranch Hand

Joined: Oct 30, 2002
Posts: 47
What is the method signature of your lock and unlock methods in the interface provided by Sun? I ask because there are two different strategies, depending on whether or not your interface uses lock cookies...


Good question, Paul. Sorry, I should have mentioned that in my initial post itself. I have a single argument viz. "record number" and hence no place for a "client ID" in my lock methods.



Thanks,
Arun.
Kai Witte
Ranch Hand

Joined: Jul 17, 2004
Posts: 356
hello,

I assume that your methods don't use cookies, which would make an identification easy.

Use an additional layer. Don't make Data access the file directly. Rather use an other class for this which has similar method signatures, with one difference: Whereever identification is required add an argument to the method signature. This is of type DBMain. E. g. void lock(int recno) -> void lock(int recno, DBMain whoIsThis).
Now your clients don't share the same remote object. Each of them has its own remote object. Your Data class just delegates to this new class, passing itself as an argument, e. g.

Note that when an object returned by a Remote object implements Remote itself it is not serialized back to the client: It becomes a remote object on the server side. Use a remote factory that creates the remote objects to access the database.

To summarize: You have one remote object that is a factory, one instance of some file access class that is on the server side and which does not implement Remote, and for each client there is one other remote object obtained by the remote factory.

@Moderators feel free to delete parts of my post if I gave too many hints.

Conan


Kai Witte's business website Kai Witte's private homepage
Arun Subramanian
Ranch Hand

Joined: Oct 30, 2002
Posts: 47
To summarize: You have one remote object that is a factory, one instance of some file access class that is on the server side and which does not implement Remote, and for each client there is one other remote object obtained by the remote factory.


Thanks, Conan. So, if I understood you correctly, the above design entails each client having it's own RemoteObject and it's own DataAccessObject? Hmmm...that would be a reasonably big change in my design considering I would now have to think about how it affects my Data methods (which are currently synchronized), LockManager etc. In my current design, on the RMI Server JVM, I only have 1 instance of the RemoteObject thereby 1 instance of Data and thereby 1 instance of the LockManager (RemoteObject has Data as a private field and Data has LockManager as a private field). I would still be interested in knowing if anyone implemented a similar design as mine and were able to identify the clients uniquely given the lock methods w/ only 1 argument.


Note that when an object returned by a Remote object implements Remote itself it is not serialized back to the client: It becomes a remote object on the server side. Use a remote factory that creates the remote objects to access the database.


I think I understood this. The unique RemoteObject for each client returned by the RemoteFactory call that the client makes still sits very much on the RMI Server JVM but a stub to that RemoteObject is returned to the client JVM. Right?

Fyi, right now, I do have an RemoteFactory that's registered w/ the RMI Registry. But instead of returning the RemoteObject when the clients call the RemoteFactory method "getInterface()", I return a serializable Proxy object to the client. Each Proxy object has a reference to the one single instance of the RemoteObject. Each Proxy object also has a copy of the database file schema of the database file on the RMI Server and so a client doesn't have to do a network operation if it's interested in knowing the schema description. So, in my design, the clients invoke the methods on their Proxy objects which in turn invoke the methods on that 1 RemoteObject on the RMI Server.


Thanks,
Arun.
Frans Janssen
Ranch Hand

Joined: Dec 29, 2004
Posts: 357
Hi Arun,

I faced the same challenge (at first I had been assuming I could use the Thread ID to identify clients, but the friendly people here convinced me that was a bad idea) and eventually opted for the solution outlined above: create a new Data class instance for each client. I too thought that it would be a major redesign, but in the end I fixed it in a couple of hours.

Frans.


SCJP 1.4, SCJD
Kai Witte
Ranch Hand

Joined: Jul 17, 2004
Posts: 356
hello,

I don't think that you have to reimplement or redesign a lot. You just have to refactor a little.

Your current Data class (the one that accesses the file) just has to be RENAMED and the signatures of the methods have to be changed to accept a DBMain (to identify the client). Your new Data class is simple, because it just delegates to your old Data class.

Conan
[ March 26, 2005: Message edited by: Conan Elvitaro ]
Paul Truckle
Greenhorn

Joined: Feb 22, 2005
Posts: 24
Hi.... I'm in the same boat as Arun, and while I understand the factory concept at a more abstract level, I'm failing on a level of detail. When you say a RemoteObject and DataAccessObject for each client is that a newly registered and binded object for each client then? I'd would be really grateful if somebody could expand on this...obviously without giving away too much. I to have a single RemoteObject instance in my design at the moment, but have come across a lot of recent discussion on Factory's and a RemoteObject per client.

Many thanks,


Paul.
Arun Subramanian
Ranch Hand

Joined: Oct 30, 2002
Posts: 47
Hi Paul-
Based on the suggestions by Conan, Frans in this thread and also the observation from other threads in this forum that this indeed is a very popular design, I have changed my design to hand off each client their own RemoteObject. I specially need to do this because my locking methods don't have a provision for a "client ID" parameter in the parameter list.
When you say a RemoteObject and DataAccessObject for each client is that a newly registered and binded object for each client then?

No, you register and bind only 1 object or service w/ the RMI registry i.e. the RMIFactory object. The RMIFactory has a method that the clients call and which returns the RemoteObject (In this method, I create the RemoteObject and I return an interface to the client that the RemoteObject implements. Fyi, in my design, the LocalObject which is returned in the stand alone mode also implements the same interface so that client call to return the local/remote object is generic irrespective of the mode). So, the RemoteObject and the RMIFactory both extend UnicastRemoteObject and implement Remote but it's only the RMIFactory that's registered and bound.

Also, this is a good read...Link to thread w/ the RMI Factory link

Thanks,
Arun.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: B&S 2.3.1 - Identifying clients uniquely in RMI