This week's book giveaway is in the OO, Patterns, UML and Refactoring forum. We're giving away four copies of Refactoring for Software Design Smells: Managing Technical Debt and have Girish Suryanarayana, Ganesh Samarthyam & Tushar Sharma on-line! See this thread for details.
I think this should be very quick for you guys. I have been following Andrew's book but as you know his DBClient interface throws IOException which is a super class of RemoteException. RMI works fine with his interface, while suncertify.db.DBMain interface doesn't throw RemoteException, it throws RecordNotFoundException and DuplicateRecordException; so when used with RMI an illegal exception is thrown.
To work around it I have changed the "Data" class to be serializable and created a copy of the DBMain interface called DBMainRemote that throws RemoteException in all methods to make RMI happy! I have added a new method called getDB that returns the "Data" object to be used as the Connection for networking.
All methods work fine through RMI except the getDB function, it returns a "Data" object, with a null database variable (DvdFileAccess in Andrew's book). I have changed the DvdFileAccess to implement serializable but still I am getting a null variable.
While debugging I noticed the server is initializing the database variable correctly and it contains all records, however the client isn't receiving it.
I would appreciate any help on this.
Joined: May 19, 2009
I have made a work around that I don't like; I have made two private variables in GuiController.java, one is the original connection in Andrew's book and another one called RMIconnection. I have also added a connectionType member variable that indicates whether it is a direct or RMI connection and changed all the refrences to connection to an if else statement. if the connectionType is direct then call the methods from connection else call the methods in RMIconnection.
public DvdTableModel find(String searchString) throws
Now the project runs fine but I don't like this approach, I would prefer the getDB to work so that I have only one connection variable but if I can't get that to work would you suggest a better way of doing this without the if else statements.
I see where you are heading. Your current approach may work but as you found out it's not the best approach.
Think about this way. What do your client code want? "Either" local connection or remote connection. How to achieve this?
If you have 2 Data classes - one each for local and remote having to respecify the methods throwing RemoteException in the remote class... why not have a "super interface" then have the local interface is the DBMain and one for remote.
I'm not sure if you are actually doing the real SCJD assignment but the idea is the same.
You may also search for RMI issues in this forum for some insights.
Yes this is for the real SCJD exam. I don't have much experience in Java; I am taking the exam to force myself into learning it and hopefully SCJD will look good on my resume
If I understand correctly, your idea is to repeat the same methods of DBMain in another interface with different names then derive "Data" from both and have the new interface methods call DBMain methods and for the RMI connection, DBMain is totally ignored; it will be derived from the new interface, then in the GUIControler I would use the new interface and totally discard DBMain.
This is a great idea and definitely will get rid of the annoying if else statements. I will give it a try.
I really appreciate your help K. Tsang
Now for my original question, any idea why the database is not being transferred? I just need to know for the sake of learning, the more I think about it, I am convinced that it is not a good idea to have the database transferred to the client because then I will have to refresh it every time I need to get the DVDs list or perform any action.
The idea of the super interface is NOT to "repeat" the same methods as the DBMain. But provide the methods for the client. Eg what do the clients need to do? Search and book are the must. You may also expose the lock functions but I don't recommend because the locking should be done in the service layer.
Talking about service layer, the super interface is your service layer.
Then you need a implementation class for each interface. The local implementation "implements" Sun's interface DBMain. You should able to figure out how to do the same for remote implementation.
Now for the client code... how are you initializing the Data class? Or which interface get called?
If you are working on the real assignment, focus on that. The DVD example only gives you reference not the solution.
K. Tsang forgot to extend from Services to create the RemoteServices. This is the correct code:
K. Tsang wrote:You may also expose the lock functions but I don't recommend because the locking should be done in the service layer.
I followed the same approach as K. Tsang (thin client), but another approach would be to expose every method from the DBMain interface (including lock and unlock) and call these methods from your client (thick client). So it will all come down to which kind of client you want to create: thick or thin? And of course don't forget to explain this decision in your choices.txt
And to make Andrew happy here is a link about a very big discussion about exposing the lock methods to the client.