aspose file tools*
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes Design Opinion Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Spring in Action this week in the Spring forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "Design Opinion" Watch "Design Opinion" New topic
Author

Design Opinion

Travis Zimmerman
Greenhorn

Joined: Mar 06, 2002
Posts: 27
I would like some input on my initial design.
I have 3 packages db, client and server.
db packages:
DataInterface - Defines the public methods implemented in Data.
Data - Implements DataInterface. criteriaFind and lock/unlock are here.
RemoteDataInterface - Extends Remote, DataInterface. This is the interface for rmi calls.
DataAccessLocal - Implements DataInterface. This is used on the client side for connecting to the Data class. The Data class is wrapped within. The constructor takes a dbName as its argument.
DataAccessRemote - Implements DataInterface. Constructor takes in a RemoteDataInterface as its argument. This wraps the rmi calls.
DataFactory - Decides whether to return DataAccessLocal or DataAccessRemote, depending on constructor arguments. Only one method getDataClass() which returns a DataInterface object.

server packages:
DataServer - Extends UnicastRemoteObject implements RemoteDataInterface. Holds main for server side. This class is registered using Naming.rebind(). This function will also take care of client checks for lock/unlock using a LockManager( ? ), which I have not implemented yet. The thought is that it will keep track of client lock requests before making request to Data.lock() and validate that a client can unlock a record before the request is sent to Data.unlock().
ConnectionManager - I had thought of using a ConnectionFactory, but I have been unable to find information on using it with RMI. Nothing here at present.

client packages:
DataClient - Holds main for client side. Creates a FBNClient by passing it the return from the DataFactory.
FBNClient - This is the facade for the gui control portion. I am not yet sure how the gui will actually be kicked off yet.
This seems to be a good start anyway, any comments would be appreciated.
Thanks,
Travis Zimmerman
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

Pretty right on there Travis.
ConnectionManager/Factory is the way you want to go.
I am only wondering about having Data class implement the DataAccess interface. Is this necessary? (Don't take this as this being the wrong way to do it, it might not be.

RemoteDataInterface - Extends Remote, DataInterface. This is the interface for rmi calls.
DataAccessRemote - Implements DataInterface. Constructor takes in a RemoteDataInterface as its argument. This wraps the rmi calls.
I can see what you are getting at here, however, I believe that you will find only one needed. I know one is an interface and one is a class, but there is an easier solution here, along witht eh DataAccess interface.
Mark


Perfect World Programming, LLC - Two Laptop Bag - Tube Organizer
How to Ask Questions the Smart Way FAQ
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi Mark
My Design is somewhat similar to yours. However i am stuck at one place. My Design is :
I have used a connection factory binded in the registry which has getConection() method to generate unique RemoteObjects for each client
1) DataAccess (interface) : defines all the public methods of Data.java
2) Data : implements DataAccess contains lock() and unlock() and a reference of LockManager which performs the locking on its behalf
3) LocalDataAccess (class) : implements DataAccess
4) RemoteDataAccess (interface) : extends Remote , DataAccess
5) RemoteDataAccessImpl (class) : implements RemoteDataAccess , Unreferenced
This class is basically a connection which also contains a vector of all the records it(client) has locked. Every client will have its unique remote object generated ate the time of getConnection().
6) ConnectionFactory (interface) : for rmi calls
7) ConnectionFactoryImpl (class) : implemnts ConnectionFactory extends UnicastRemoteObject
8) RMIServer : binds ConnectionFactoryImpl in the registry
a) is This design correct ?

b) should RemoteDataAccess (interface) extends Remote or java.rmi.server.RemoteObject or PortableRemoteObject?
c) is it ok to use locking at 2 places, one at Data.java and other at RemoteDataAccess which stores what all records it has locked.
d) can RemoteDataAccess and RemoteDataAccessImpl be merged ? I mean do i really need interface RemoteDataAccess.
Pls Help
Amit
Travis Zimmerman
Greenhorn

Joined: Mar 06, 2002
Posts: 27
Mark,
Thanks for the input, it is appreciated.
I am only wondering about having Data class implement the DataAccess interface. Is this necessary? (Don't take this as this being the wrong way to do it, it might not be.

I originally did not have DataFactory so the DataClient was passing back either a copy of RemoteDataInterface or Data. I see that I no longer need to do this, so Data no longer implements DataInterface.
I can see what you are getting at here, however, I believe that you will find only one needed. I know one is an interface and one is a class, but there is an easier solution here, along witht eh DataAccess interface.

I was unsure of this myself so I made the following change.
DataAccessRemote - R.I.P. Is no more.
DataFactory - Now returns a RemoteDataInterface instead.
ConnectionManager/Factory is the way you want to go.

Does anyone happen to have a link for information on using this with RMI? Possibly a tutorial or examples? I have done a search and keep comming up empty and it is in none of my books.

Again, thanks for the input,
Travis Zimmerman
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

I was unsure of this myself so I made the following change.
DataAccessRemote - R.I.P. Is no more.
DataFactory - Now returns a RemoteDataInterface instead.

Actually I was thinking the other way around. Make it so that all the client knows it is getting is a DataAccess class. So your DataAccessRemote which implemented DataAccess will do that trick.
Amit-
which also contains a vector of all the records it(client) has locked

Try using an ArrayList or a HashMap instead of Vectors or Hashtables. Vectors and Hashtables are the old way of doing things, use the newer Collections classes.
a) is This design correct ?

b) should RemoteDataAccess (interface) extends Remote or java.rmi.server.RemoteObject or PortableRemoteObject?
c) is it ok to use locking at 2 places, one at Data.java and other at RemoteDataAccess which stores what all records it has locked.
d) can RemoteDataAccess and RemoteDataAccessImpl be merged ? I mean do i really need interface RemoteDataAccess.

a. Yes
b. It should extend Remote
c. Yes, that is exactly how mine worked. However, I rethought about using a LockManager, which sounds very good. Don't know much about implementing it though, but there are plenty of posts here that can explain it very well.
d. No you don't really need it, however you will then need to make the DataAccess interface methods throw RemoteExceptions, which is fine and won't hurt anything.
Travis - read my d answer here, and also note that looking at the design that you and Amit have are not wrong in having a RemoteDataInterface, it is just another way of doing it, and in some ways better than mine.
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi Mark
Thanks for the quick reply. You are really a bond of Java and specifically of this assignment.
I still have some doubts. Pls help
1) i have a lock manager at Data.java but there is no lock manager at RemoteDataAccess. Do i need a lock manager there also or not ? If yes can i reuse the same ? Right now Locking things are happening inside the RemoteDataAccess without any lock manager.
As far as reusing the lock manager is concerned, i think it can not be as the logic of both the lock manager will be different.
2) You have written that i should use Hashmap at RemoteDataAccess for storing the record no locked by the client, but Hashmap stores key=value pairs, however i have only the record no to be stored and not pairs ?
How can i use Hashmap? i think Hashset can be used at this place.
3) Inside RemoteDataAccess, for locking the whole database, should i use a boolean variable DataBaseLocked = true or should i take all the records from the db and add it into my Hashset / Vector after the lock(-1) is through at Data.java.
Problem is that if a client calls unlock(-1), how i will come to know whether that client has actually locked the db or not before processing his request.
I must tell u that inside LockManager of Data.java , if a request for lock(1) comes, i add all the records in the Hashset it is maintainig by calling lock(1..n) in iteration and lock(-1) leads to removing all the elements from HashSet . There is no boolean variable for DataBaseLocked = false/true in LockManager of Data.java. If i dont follow this in my RemotreDataAccess also will it be called as inconsistent coding ?
4) what should be the role of close() method inside RemoteDataAccess. One is obviously closing all the connections it is holding. What else ? I think after calling close() user should not be able to use it again. How can i do that ?
[ March 11, 2002: Message edited by: Amit Kr Kumar ]
Travis Zimmerman
Greenhorn

Joined: Mar 06, 2002
Posts: 27
Amit,
I believe you should only use a LockManager in RemoteDataAccess. Verify that a record can be locked/unlocked by a particular client, if it can then send the request on to the Data class. The Data class should keep a list of records that are locked.
You have two different jobs being done. The first is verifying what particular client can do with a particular record and hadling clients dropping before they unlock a record. The second is verifying a record against a list of records locked.
In the case of locking the entire database, I merely wait until there are no records in the list that the Data class holds. You could begin locking all the open records so no more clients could could lock those records out. This is something the LockManager would do for your RemoteDataAccess class would do.
Well, atleast those are my thoughts. Where did you get information on using a ConnectionFactory with RMI?
Travis Zimmerman
Travis Zimmerman
Greenhorn

Joined: Mar 06, 2002
Posts: 27
Mark,
I didn't really see a difference between taking out RemoteDataAccessInterface or taking out DataAccessRemote. The DataFactory hands out a DataInterface object to the client in both cases. The only difference seems to be is that in leaving in RemoteDataInterface you are handing out an interface and in leaving in DataAccessRemote you are handing out a class. It is apparent to me that having both is redundent, so I guess the question is whether or not something will need to be done to the data coming from the client facade before being sent to the server. This is a question I don't have the answer to as yet.
DataAccessLocal and DataAccessRemote / RemoteDataInterface extend from DataInterface. DataInterface methods throw Exception; DataAccessLocal throws DatabaseException; and DataAccessRemote / RemoteDataInterface throw both DatabaseException and RemoteException.
Travis Zimmerman
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

How can i use Hashmap? i think Hashset can be used at this place.

Yes, I actually meant a HashSet.
and Amit, check out Travis' answer to your other questions about LockManager
Travis, I agree, 6 of one, a half dozen of the other.
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi Mark
Thanks once again for the reply, but still i did not get solution to my problems (3) and (4)
ie
3) Inside RemoteDataAccess, for locking the whole database, should i use a boolean variable DataBaseLocked = true or should i take all the records from the db and add it into my Hashset / Vector after the lock(-1) is through at Data.java.
Problem is that if a client calls unlock(-1), how i will come to know whether that client has actually locked the db or not before processing his request.
I must tell u that inside LockManager of Data.java , if a request for lock(1) comes, i add all the records in the Hashset it is maintainig by calling lock(1..n) in iteration and lock(-1) leads to removing all the elements from HashSet . There is no boolean variable for DataBaseLocked = false/true in LockManager of Data.java. If i dont follow this in my RemotreDataAccess also will it be called as inconsistent coding ?
4) what should be the role of close() method inside RemoteDataAccess. One is obviously closing all the connections it is holding. What else ? I think after calling close() user should not be able to use it again. How can i do that ?
Amit
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

3) lock(-1) is for shutting down the server, no one will ever call unlock(-1), so don't worry about it.
4) just call the close method of the data class, that is all.
Mark
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi Mark
Well as far as close() method of RemoteDataAccess (ie remote connection object) is concerned, i have an idea. I think it will be better to call unexport(obj) so that client is not able to use it again instead of calling close() of Data.java as it will result into closing of database itself instead of connection only.

Closing of Data.java can be done when server is shutting down only.

Just a thought any comments ?

Another problem i am facing regarding generating stubs and skeletons. Since ConnectionFactory extends UnicastRemoteObject, thus i need to call rmic to ConnectionFactoryImpl
However RemoteDataAccess is a remote object and not UnicastRemoteObject. Do i need to call rmic on RemoteDataAccess also ?

Amit
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

Do i need to call rmic on RemoteDataAccess also ?

Nope
I think it will be better to call unexport(obj)

While true, The implementation of These interfaces still need to call the corresponding method of the Data class. Hence the requirement that you develop and interface that has all the method of the Data class.
Oh and by the way, my client never calls the close method anyway.
Mark
[ March 13, 2002: Message edited by: Mark Spritzler ]
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi Mark
I hope you are back from your vacations. How was the vacation ? Enjoyed ?
Mark i am still struggling with rmic option. I am getting Stub not found exception if i dont run rmic on RemoteDataAccessImpl. you have written that there is no need to run rmic on RemoteDataAccssImpl.
Its like this :
public interface DataAccess
{
all data.java method declaration throwing Remote and Local Exception. It does not extend Remote
}
public interface RemoteDataAccess extends Remote, DataAccess
{
// no method inside it
}
public class RemoteDataAccessImpl implements RemoteDataAccess, Unreferenced
{
RemoteDataAccessImpl(Data objData)
{
UnicastRemoteObject.exportObject(this);
}
// other method implementation
}

Every client gets his unique own remote object by calling getConnection() from connection factory which is binded in the registry.
how to pass remote object back to client without generating a stub for it specifically?
Pls help
Amit
Krishna Varma Adluru
Ranch Hand

Joined: Nov 24, 2001
Posts: 55
Amit,
IMHO, I think we need to have stubs for RemoteDataAccessImpl. Anything, which extends Remote should have it's stubs deployed to the
Client. So, we need to run "rmic" on RemoteDataAccessImpl. Questions, let me know.
Regards,
Krishna Varma
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

UnicastRemoteObject.exportObject(this);

Don't need to do this.
OK, and I must apologize for leading you down a wrong path. The DataRemoteImple does need to be rmic'd. Sorry about that. I relooked at my batch file and saw that it was in there. I just haven't looked at it for about three months.
Mark
Krishna Varma Adluru
Ranch Hand

Joined: Nov 24, 2001
Posts: 55
Mark,
IMHO, I think he needs to do either
"UnicastRemoteObject.exportObject(this)" or
he needs to "extend UnicastRemoteObject".
Otherwise, he will get "Serialization errors".
As we all know now that "Remote Objects" are passed by reference. If we do NOT extend "UnicastRemoteObject", how will Client get
"RMI link" to "RemoteDataAccessImpl" ..?
Please look at the post started by you :
http://www.javaranch.com/cgi-bin/ubb/ultimatebb.cgi?ubb=get_topic&f=25&t=001272
You were also getting "Serialization errors" ...
How did you solve "Serialization problem" if you
did not extend UnicastRemoteObject or if you
did not do "UnicastRemoteObject.exportObject(this)" ?
I think both "ConnectionFactory" and "RemoteDataAccessImpl" should extend UnicastRemoteObject.
Please let me know if my approach is wrong here.
Thank You,
Regards,
Krishna Varma Adluru
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

I was getting Serialization errors because my Remote interface did not extend Remote, and therefore was Serializing the object. What I really wanted, and got was a Remote Object, one for each user, that resided on the server, and is not bound in the Registry, or needs to extend Unicast or export itself.
Mark
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

Maybe I am too far removed from when I finished my submission. because I keep going back to my code and seeing the opposite of what I just wrote.
OK here it is my DataAccess class extends Remote, my DataAccessLocal implements DataAccess
my DataAccessRemote looks like this

so it does extend UnicastRemoteObject. DOH!!!
Mark
Krishna Varma Adluru
Ranch Hand

Joined: Nov 24, 2001
Posts: 55
Mark,
Thank You very much for the reply.
Regards,
Krishna
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Thanks a lot Mark and Krishna for your advice

Regards
Amit
Amit Kr Kumar
Ranch Hand

Joined: Feb 08, 2002
Posts: 100
Hi mark, Krishna
In the local mode i am giving the choice to the client to select the db.db file from his file system. And in case of remote mode, the user who will start the server will pasa the location of db.db as command line arguement.
Is this correct ?
Do i need to have 2 copies of db.db in my submission.jar, one for local mode and one for remote.
Amit
[ March 19, 2002: Message edited by: Amit Kr Kumar ]
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

Yes to both questions
Mark
Siddharth Mehrotra
Ranch Hand

Joined: Aug 21, 2001
Posts: 185
hi all
well i have gone through this post.
and through i'am very new to this developer exam.
i have been trying my hand at designing with the help of Java design patterns.
My design is still at a very naive stage, but it is pretty much like the one being discussed here.
what i wanted to know is that here in the client package there is a class called DataClient, as per the sun's requirement we have to have a dataclient that should implement all the public methods of data class.
which is not there here.
is that okay.


SCJP, SCJD.
Siddharth Mehrotra
Ranch Hand

Joined: Aug 21, 2001
Posts: 185
hi all
well i have gone through this post.
and through i'am very new to this developer exam.
i have been trying my hand at designing with the help of Java design patterns.
My design is still at a very naive stage, but it is pretty much like the one being discussed here.
what i wanted to know is that here in the client package there is a class called DataClient, as per the sun's requirement we have to have a dataclient that should implement all the public methods of data class.
which is not there here.
is that okay.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

what i wanted to know is that here in the client package there is a class called DataClient, as per the sun's requirement we have to have a dataclient that should implement all the public methods of data class.
which is not there here.
is that okay.

I don't think you want your DataClient in your client package. I think it should be in the data package. Kepp you server/connection classes in your server package, anything (and I mean anything) dealing with the data classes and your data interfaces and implimentation should be in the data package, and anything specific to the GUI, like the Controller, GUI class, TableModel, and any other GUI helper classes should be in the client package.
Mark
p.s. I hope that answers your wuestion, because I was a little confused at what your question was.
Jane Wang
Greenhorn

Joined: Mar 07, 2002
Posts: 16
Will it have an Error ?

public interface RemoteDataAccess extends Remote, DataAccess
{
// no method inside it
}

[ March 26, 2002: Message edited by: Jane Wang ]
dhana sekar
Greenhorn

Joined: Feb 25, 2002
Posts: 21
Hi,
It's not an error unless DataAccess is an interface and it has all the public method's of Data class.
-dhana
Jane Wang
Greenhorn

Joined: Mar 07, 2002
Posts: 16
If you have read the posts above, you will find DataAccess is really an interface.
And as I know, A class or interface can only extends one Class or Interface
dhana sekar
Greenhorn

Joined: Feb 25, 2002
Posts: 21
Hello ,
As for as i know java indirectly supports
multiple inheritance in case interface. So u can
extend any no of interface Ok.
-dhana
Forrest Xu
Greenhorn

Joined: Jan 30, 2002
Posts: 26
Can the methods in DataInterface or DataAccess talked above throw RemoteException, DatabaseException?
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

Can the methods in DataInterface or DataAccess talked above throw RemoteException, DatabaseException?

Yes, or you can just have them throw Exception, and in the implementation of the interface throw a more specific Exception.
Mark
Forrest Xu
Greenhorn

Joined: Jan 30, 2002
Posts: 26
Thanks Mark,
--------------------------------------------------------------------------------
Can the methods in DataInterface or DataAccess talked above throw RemoteException, DatabaseException?
--------------------------------------------------------------------------------
Yes, or you can just have them throw Exception, and in the implementation of the interface throw a more specific Exception.

Which one is better? and why?
Thanks Mark!
XIU
Forrest Xu
Greenhorn

Joined: Jan 30, 2002
Posts: 26
DataAccessLocal - Implements DataInterface. This is used on the client side for connecting to the Data class. The Data class is wrapped within. The constructor takes a dbName as its argument.
Why do we need DataAccessLocal? I think we can use
Data class to replace it. Is it possible?
Thx
XIU
dhana sekar
Greenhorn

Joined: Feb 25, 2002
Posts: 21
Hi,
Yes Its possible provided lock(),unlock(),ceriteriaFind() has their functionality their in the Data.java.
-dhana
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17257
    
    6

Why do we need DataAccessLocal? I think we can use
Data class to replace it. Is it possible?

Some people aren't implementing lock/unlock in the Data class, but using a LockManager instead.
the main reason why you want a DataAccessLocal is that it is cleaner, more OOP like, increases Extensibility, Maintainability. Decouples logic specific for Local from Data class.
And even if Data had al the code it needed for Local, it still is symetrical, to use a wrod that I am trying to convey an Idea or concept in which I can't think of a better word.
Mark
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Design Opinion