This week's book giveaway is in the Mac OS forum.
We're giving away four copies of a choice of "Take Control of Upgrading to Yosemite" or "Take Control of Automating Your Mac" and have Joe Kissell on-line!
See this thread for details.
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes URLyBird's [Version 1.2.3] and network side 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 "URLyBird Watch "URLyBird New topic
Author

URLyBird's [Version 1.2.3] and network side

Payal Shah
Ranch Hand

Joined: Jul 10, 2006
Posts: 67
I am working on network side of this project. I have no experience with it.

I read chapter on RMI from Andrew's book. It seems like in the book example the value object is DVDdatabase which gets send back and forth to server and client.

In URLyBird's, i have something call lockCookie.
So am I sending lockCookie back and forth or both [Cookie and database object]

I try to search a post about RMI or network side but could not find anything.

Can someone please help?

Thank you.
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2265
    
    3

Can someone please help?


Surely, partner!

First, take a look here. This is how I developed my server. What you have to do is make available the functionalities of the interface that was provided to you via network. I used RMI, since it is easier. Here's what I did: I created an interface that extends java.rmi.Remote with the same methods of the interface that was provided to me, but all of them throw java.rmi.RemoteException. In the implementation of this interface, I use the Data class (which is a singleton). For instance, here's the create method of my RMI server:



Where dataManager is the instance of the Data class.

In my case, I also have a method called startServer, which is called to start the server. This method also has a shutdown hook, so when you press Ctrl + C in the command line, it stops.

The cookie of your lock method is used to identify the client that locked a record (it is a value that you'll have to generate on the server side, for instance System.currentTimeMillis()), so when you call this method on the client side, you generate it in your Data class and return it to the client. Then use it to update/delete the locked record, and unlock it.

Take a look at the link I sent you. If you have further questions, please let us know. And by the way, if you are using Java 5 or a later version, there's no need to generate stubs.


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
Payal Shah
Ranch Hand

Joined: Jul 10, 2006
Posts: 67
Thank you so much Roberto. I will read all you posted and will try to digest it today.

Will let you know if i have question. I am sure,, i will :roll:

Payal
Payal Shah
Ranch Hand

Joined: Jul 10, 2006
Posts: 67
hi Roberto,

I did read the RMI document that you had linked. It was very good and it helped a lot too. Thank you so much. I do have few questions..

1)In the linked documents they start the registery by calling "start rmiregistry". I have also looking at Andrew's book and in that i do not see he is calling start registery and I can still run his app.. How does that work?

2)time out: in the lock function, do you do time out. My specification does not say anything about time out. But then, i wounder, how long should someone wait for the record to get unlock..or should they just wait for till someone unlock the record [could be forever]..

thank you
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2265
    
    3

In the linked documents they start the registery by calling "start rmiregistry". I have also looking at Andrew's book and in that i do not see he is calling start registery and I can still run his app.. How does that work?

Indeed, there's no need to use rmiregistry. In fact, there's no need to use any external command. This is how I start my RMI server:

This is a small piece of code of my RMI server. This is in the startServer that I created for it. The portNumber is the number that identifies the port where the server will be started, and Server is an interface I created to offer the Data class functionalities via RMI. The SERVER_NAME constant is a String that is used to identify the Server object in the RMI Registry.
time out: in the lock function, do you do time out. My specification does not say anything about time out. But then, i wounder, how long should someone wait for the record to get unlock..or should they just wait for till someone unlock the record [could be forever]..

In my locking mechanism, I did not worry about that, since this was not specified. Honestly, I don't really think we should worry about this. I just wait until the record is available.
[ January 02, 2009: Message edited by: Roberto Perillo ]
Payal Shah
Ranch Hand

Joined: Jul 10, 2006
Posts: 67
hey,

Thank you so much for quick reply..

It seems like you are not doing factory pattern for your rmi logic.. I know in Andrew's book he is doing that. Also he is extending UnicastRemoteObject rather than calling exportObject method.
He had mentioned in the book that if you are not extending UnicastRemoteObject , you have to implement hastcode, toString and equals method. Did you do that? or what are your thoughts on that..why I need to implement that?

Sorry for bothering you on this. But since i read the chapter on Rmi and also read the link you send me, I have started comparing little bit. I am just trying to understand the both ways.

Thank you
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2265
    
    3

Hey, partner!

It seems like you are not doing factory pattern for your rmi logic..

Exactly. I did not use that book a lot, but I believe he does that so he can identify the remote client, isn't it? I'm not sure, though...
Also he is extending UnicastRemoteObject rather than calling exportObject method.
He had mentioned in the book that if you are not extending UnicastRemoteObject , you have to implement hastcode, toString and equals method. Did you do that? or what are your thoughts on that..why I need to implement that?

I did not do that. I don't really think that's necessary. In the link I sent you, you can see that when the remote interface is implemented, they do not override hashCode, toString or equals. I think that what you have to do if you implement your server the way the tutorial I sent you shows is easier than when you extend UnicastRemoteObject (but this is just my opinion), but that's also an option.
Payal Shah
Ranch Hand

Joined: Jul 10, 2006
Posts: 67
hi,
you are right. Following the tutorial seem easy to me and it makes more sense too.
Factory method does not make sense to me. I just do not get factory pattern.

I do have more questions:
hi,
you are right. Following the tutorial seem easy to me and it makes more sense too.
Factory method does not make sense to me. I just do not get factory pattern.

I do have more questions:
1)final Server server = (Server) UnicastRemoteObject.exportObject(this, 0);
final Registry registry = LocateRegistry.createRegistry(portNumber);
registry.bind(ApplicationConstants.SERVER_NAME, server);


I see you are passing 0 as the port number here. I did not understand this in the tutorial either. Why 0 and not port number[which was enter by the gui- port where server will start]

2)I am stuck at the remote interface section now

We are not allow to change the DBAccess interface.

I have
public interface DataRemote extends Remote, DBAccess {
// I need to throw RemoteException for all the methods of DBAccess in order for them to work for RMI
}

This is what I have:
public interface DataRemote extends Remote, DBAccess {}

public class DataRemoteImpl implements DataRemote
{
private DBAccess db = null;
public String [] readRecord(long recNo)
throws RecordNotFoundException {
return db.readRecord(recNo);

GuiController:
private DBAccess dbAccess;
try
{
if(connectionType == ApplicationMode.STANDALONE_CLIENT)
{
dbAccess = suncertify.direct.RoomConnector.getLocal(dbLocation);
}
else
{
dbAccess = suncertify.remote.RoomConnector.getRemote(dbLocation, port);
}
}

How can i add RemoteException and still use DbAccess interface?

Thanks
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2265
    
    3

Hey, partner. Sorry for the late response!

I was looking at the UnicastRemoteObject class API, and saw that the exportObject method that I used returns a Remote object. The exportObject method that takes only a Remote object returns a RemoteStub object, and exports the remote object to make it available to receive incoming calls using an anonymous port. We want it to return a Remote object, but using an anonymous TCP port, that's why we pass 0 as port number. But this is just to generate the stub. The guys that take care of really making an object available to receive remote calls in the localhost are the createRegistry method (which reserves a port in the localhost to receive remote calls) and the bind method (that binds the stub to the reserved port).

To get rid of the RemoteExceptions, here's what I did: I created an interface that extends the java.rmi.Remote interface, which has the same methods as the interface that was provided to me, but they also throw RemoteException. Here's a little bit of its code:



Here's a little bit of the code that implements this interface:



So, we use the Data class (which in my case is a singleton) in the implementation of the RMI server. That's why we can use UnicastRemoteObject.exportObject(this, 0); because "this" (which in this case is the DatabaseServer class) also implements the Remote interface.

Then start the server with the code I showed above, and that's pretty much it!
Payal Shah
Ranch Hand

Joined: Jul 10, 2006
Posts: 67
hmm
I am not sure you have guicontroller class or not but mine looks something like that.. How do you get around with the situation where you have two different objects being return..(remote and local)..I guess,, i need to think more about this. I have been stuck on this for last few days
GuiController:
private DBAccess dbAccess;
try
{
if(connectionType == ApplicationMode.STANDALONE_CLIENT)
{
dbAccess = suncertify.direct.RoomConnector.getLocal(dbLocation);
}
else
{
dbAccess = suncertify.remote.RoomConnector.getRemote(dbLocation, port);
}

Thank you
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2265
    
    3

In my case, when you start the server, I call the startServer method, passing the database location and the port number. When you start in standalone mode, I just call the constructor of the main class in my business/services layer, passing the database location. In my Data class, I keep the location in a String, and I have a getInstance(String) that sets this String, and a getInstance method that is used when the getInstance(String) method was called prior to this one.

Don't worry if you still didn't finish the Data class or the other stuff that surrond it. The first version of my Data class looks very different from the one I submitted for assessment.
Payal Shah
Ranch Hand

Joined: Jul 10, 2006
Posts: 67
ok.. thank you. I just need to think more about it.. thank you so much for all your help.
 
GeeCON Prague 2014
 
subject: URLyBird's [Version 1.2.3] and network side