aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Data class and server code 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 "Data class and server code" Watch "Data class and server code" New topic
Author

Data class and server code

K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Hi all, I have a question: What kind of methods/functionalities should the server code have? According to the instructions, the Data class is part of the server so to speak as well as the networking (RMI or sockets), which for me goes under the package "suncertify.db". So should I put the networking code in the "suncertify.db" package as well? Also besides the remote connection and able to support multithreading, what else is there to implement for the networking code?

If I use RMI, do I need to modify my Data class's methods to throw RemoteException as well? Would this mean I'm changing Sun's orginal interface?


K. Tsang JavaRanch SCJP5 SCJD/OCM-JD OCPJP7 OCPWCD5 OCPBCD5
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2267
    
    3

Hey partner, please take a look here. I think it might help you!


Cheers, Bob "John Lennon" Perillo
SCJP, SCWCD, SCJD, SCBCD - Daileon: A Tool for Enabling Domain Annotations
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Thanks Rob for your quick response, I better read the RMI tutorial first.
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Hi Rob, I've read the RMI tutorial and have the following questions:

I have an interface called DBRemote that looks exactly the same as Sun's original interface DBMain except with RemoteException thrown.

Then I have a RemoteData class that implements DBRemote interface. OK now instead of duplicating the entire content method for method I suppose just to use Data class's methods. But my Data class has 2 constructors bith private (singleton per se) - one no-arg and the other with a File instance:



Technically the no-arg contructor is useless because we need the file name. So in the RemoteData class, how do I get an instance of Data with the filename? Do I just hard code the file name on the server?? But the specs say users call choose the location of the database. Also the methods in DBRemote interface throws RemoteException, do I need to explicitly cater this eg throw RemoteException when such and such occurs?

Also will I need to make my contructor for RemoteData also private?

The 2nd question is in my server class I did something like:


Now when I try to run this I get a ClassCastException with this line:
DBRemote data = (DBRemote) RemoteData.getInstance(f);

Will this problem be solved if I sort out RemoteData class??
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2267
    
    3

Hey, my buddy!

Well, your approach looks pretty much like mine. My Data class is also a singleton, but I have only one no-arg private constructor. You can't hardcode the path to the db file, simply because of what you said (the user has to be able to indicate which file to be used). I have 2 getInstance methods: one with no arguments, and another one that takes a String. So, since it is a singleton, it is necessary to primarily call the one that takes a String, indicating the db path. This sets a local static variable called databaseLocation (has to be static because the getInstance(String) method is also static). Then, after this method sets the db path, then we can normally call the getInstance method. When we call getInstance and the databaseLocation variable is null, then I throw an IllegalStateException.

There's no need to make the constructor of the server class private. I at least didn't. There I just have one no-arg public constructor. I have a method called startServer, which also takes a String, and there I call Data's getInstance(String) method.

About the ClassCastException problem... make sure the DBRemote interface extends java.rmi.Remote, then, you can do this in the implementation of this interface:

DBRemote stub = (DBRemote) UnicastRemoteObject.exportObject(this, 0);
...
registry.bind(name, stub);

Please take a look at this other thread. I think it will also be helpful! And if you have further questions, please let us know!!!
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

Roberto Perillo wrote:
I have 2 getInstance methods: one with no arguments, and another one that takes a String. So, since it is a singleton, it is necessary to primarily call the one that takes a String, indicating the db path. This sets a local static variable called databaseLocation (has to be static because the getInstance(String) method is also static). Then, after this method sets the db path, then we can normally call the getInstance method. When we call getInstance and the databaseLocation variable is null, then I throw an IllegalStateException.

There's no need to make the constructor of the server class private. I at least didn't. There I just have one no-arg public constructor. I have a method called startServer, which also takes a String, and there I call Data's getInstance(String) method.


OK I finally got the RMI server connected so to speak.

About your databaseLocation variable, do you set it from within your startServer method? If so, how do you know what string to pass? I doubt I can get it from the properties file.

I don't quite get how your getInstance(String) method can be called.
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2267
    
    3

Hey, my buddy!

About your databaseLocation variable, do you set it from within your startServer method? If so, how do you know what string to pass? I doubt I can get it from the properties file.


Everytime the application starts in server mode, the user provides the database location. This is the String passed to the startServer method, and this method sends it to the Data.getInstance(String) method. This String is also written in the .properties file; next time you start the application, the JTextField where the .db path is inserted will be populated with it.

Assume I got the string settle which I haven't yet, and go on to create the remote object ... I now get a java.rmi.ConnectException: Connection refused: connect. Further checking it ultimately calls Socket class's Socket(String host, int port) constructor.


The string is the .db path, right? I used the approach I addressed above to take the user's input to the Data class. It's GUI -> Controller (ActionListener calls new Server(), then server.startServer(portNumber, dbLocation);). In a nutshell, the code of the startServer is:



This binds the server object to the Registry. On the client, I call:



Where ApplicationConstants.SERVER_NAME is a String used to identify the sever object in the Registry and the server variable is a static variable, which keeps a reference to the server. This code is in a static method of a class called DatabaseServerReference called saveServerReference, and everytime I need to make remote calls, I call the other method called getServerReference, which returns me the remote interface implementation (that is, the reference saved previously).

Also is there any difference between registry.rebind() and registry.bind()?


As far as I understood, the difference is that, when you call bind, the object identified by a particular String still doesn't exist in the Registry; when you call rebind, it already exists and you want to replace it there.

While I'm at it, for the client side, can I pass in a string that looks like "//host:port/filename" for remote connection when creating my Data class? Yes I changed my Data contructor to string instead of using File earlier. Since my local connection is simply "filename".

in my remote connection I have:
Registry registry = LocateRegistry.getRegistry(address, port); // address and port got from properties
DBRemote dbr = (DBRemote) registry.lookup(name);

But then I still need to return an instance of Data through Data.getInstance(String). Or do I return DBRemote for remote connections?


Well, you wouldn't really have to pass this string, you would be able to do exactly what you have in your remote connection. Then, you'll use this reference in the client side to make calls to the remote server, so you wouldn't return the Data object to the user, you would return DBRemote.
K. Tsang
Bartender

Joined: Sep 13, 2007
Posts: 2584
    
    9

OK so your approach is when user runs the network client, they choose the db location then save it to properties file then you start the server?

But I thought, at least mine is, start server is independent from running the network client. Of course I can do it like your way which is even more simpler.

Also for remote connection, did you use a JFileChooser to locate your db file? Cos I'm thinking the file chooser can't possibly know which IP address you are going to use even if file chooser can indeed browse remote file using URL or some other means.
Roberto Perillo
Bartender

Joined: Dec 28, 2007
Posts: 2267
    
    3

OK so your approach is when user runs the network client, they choose the db location then save it to properties file then you start the server?


Exactly!

But I thought, at least mine is, start server is independent from running the network client. Of course I can do it like your way which is even more simpler.


Certainly! That's the idea. Start the server, then when clients want to connect to it, it will be available.

Also for remote connection, did you use a JFileChooser to locate your db file? Cos I'm thinking the file chooser can't possibly know which IP address you are going to use even if file chooser can indeed browse remote file using URL or some other means.


Hum... no. What I did is, when starting the server, the user provides the database location in a JTextField and the port number in which the server will run, also in a JTextField. I first try to save these values in the .properties file of the server, then I start the server, based on these values.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Data class and server code