David Sham

Ranch Hand
+ Follow
since Apr 19, 2005
Cows and Likes
Total received
In last 30 days
Total given
Total received
Received in last 30 days
Total given
Given in last 30 days
Forums and Threads
Scavenger Hunt
expand Ranch Hand Scavenger Hunt
expand Greenhorn Scavenger Hunt

Recent posts by David Sham

One other thing I just realized. My unusually low score for the Network Server section may also have been due in part to how I answered the essay exam question that dealt with the server implementation of the project. I answered the question consistently with what I put in my choices doc, but then I put some nonsense about the flip-side of using RMI (trying not to give away too much about the essay question here). I was not quite sure what to put to answer that part of the question, so I put some rubbish that resulted in a very weak argument for that particular part of my answer. So perhaps how you answer the essay questions on the essay exam may affect your score as well.
16 years ago

is this switching stuff really necessary ? i fail to see requirements leading to this decision from all i have read so far.

Switching modes, database file locations, etc. was not required by my assignment, and I would guess probably not required by other's assignments either. Everyone's assignments may have slightly different requirements. But I put in this funtionality as a nicety. You should be able to pass without such functionality though.

My apologies if I've come across as "puffed up". This is not my intention. Just want to share my experience. Thanks.
16 years ago

But is this not effectively the same as locking the DB ?
I mean when 1 client is creating in your app can another client be reading ?

If you have only 1 RAF and its operations are synchronized, then only 1 read-from or write-to operation can occur at a time. If the RAF operations are synchronized, this ensures that the thread executing the RAF operation will not slice out mid-operation. So in a sense it is like locking the entire DB, but only for the duration of the execution of the synchronized code. This is why it is not necessary to lock the entire database file if you have only 1 RAF.

If you have multiple RAFs, then you may need to lock the entire database file somehow.

It's just a matter of interpretation of course, but I think if you document your decision with reasonable supporting arguments, they can't punish you with a deduction as large as the one David got.

I do not believe the user should be able to change the database file location that the server is using from the remote client GUI. How would you account for other remote clients concurrently interacting with the server? This would adversely affect them.

I think it would be good to implement this functionality, but do it from the server. Some kind of GUI may have to be provided so that the user can change the database file location the server is using. But this would be done on the server, not from a remote client.

The question then becomes how to notify all of the remote clients that the database file location has changed on the server. The clients could remain bound to the RMI server (for an RMI solution), but they would need to know that their requests are now being communicated to a different database file.

I also documented my decisions with 13 pages of my choices.txt. Perhaps I did not write enough about my server implementation, but I think that my low score in that area might be due to the fact that I did not implement this functionality, but allowed for everything else (switching modes, switching servers in remote mode, and switching database locations in local mode).
16 years ago
Wait, wait, wait!! Let me clarify something here. Just by synchronizing the create() method, this will not prevent a different thread from executing the delete() method.

If you have only 1 Data class and RandomAccessFile, then what needs to be synchronized is the read from and write to operations with the RAF. This is because if there is only 1 RAF and its operations are synchronized, then the executing method (create() or delete(), etc.) will have total control over the RAF for the during of the synchronized code enclosing the RAF. If the create() method is synchronized and it handles the RAF operations, then that should prevent a delete from occuring while the create method is executing.

But if the create() method does not handle the RAF operations to the database file, then simply synchronizing it will not prevent a delete() method operation from occuring on the file.

As for the lock DB. My create() method is already fully synchronized and I have only 1 Data instance.
But does this stop thread from clientA switching out half way thru create() and clientB running delete() to effectively change the ground under clientA's feet as it were ?

If your create method is synchronized (in the method signature, public void synchronized create(){}), then yes it should prevent clientA from slicing out during the execution of the create method. This is due to the fact that a synchronized method only allows 1 thread at a time to execute it. Therefore only clientA's thread must complete execution of the create method before clientB's thread can delete a record.

Andrew, please advise if I am wrong here, but that is my understanding of how synchronized code works.
I understand what you are saying now John. Your server must have had a GUI of some kind that allowed the user to change the database file the server was connected to. Interesting. My solution did not allow for this. If the user wanted to connect to a different remote database, they would have to connect to a different server that is already up and running, which would then be connected to the desired database file.

I did not even think of allowing the user to change database files within the server. I only gave them the ability to switch servers if in remote mode or switch database files if in local mode. I also allowed them to switch modes as well.

But your point is an interesting one which might account for the big deduction in my Network Server score.
16 years ago

Ok but how does clientB get lockCookie1 ?

It does not matter how clientB gets lockCookie1. The fact that you are implementing a solution which would prevent this from happening adds another layer of security. Realistically, clientB should never get lockCookie1. But from a maintainability argument, you could say that by implementing this additional level of security (via a second Hashtable), clientB is prevented from executing a locked-record operation with the wrong lockCookie.

What about the case Zee mentioned where I have to reuse deleted records when creating new ones if possible.
clientA does a read() and figures that record 2 is deleted.
Meanwhile clientB goes and deletes record 1
ClientA creates a new record over record 2.
This is not a big deal really but to be correct they should have used record 1.

By locking the whole DB I can avoid this.

What am I missing here ?

I think you are missing the KISS principle! (Keep It Simple Stupid) Try to keep it as simple as possible. As long as you check to see if a record is deleted (to reuse it) when doing a create new record operation you should be fine.

One suggestion would be to synchronize the entire create new record operation and call a searchForDeletedRecord() method within that operation. If the create new record operation (or method) is synchronized then the executing thread cannot slice out mid-operation. Since it is synchronized, only 1 thread at a time can execute that operation. Therefore, the scenario you described should not occur. This is how I designed my solution.

However, this will not work if you are using multiple Data class instances with each instance using its own RandomAccessFile to read from and write to the database file. I had only 1 Data class and RAF in my solution (which resided in my RMI Remote Implementation object) - because of the requirement to use lockCookies.

The way I understand your server design is that the database file name must be specified at the time when the server is started. In other words, if the client wanted to connect to a database with a different name, the server would need to be restarted. If that's correct, I am speculating that it was the reason for a big deduction on the server design.

No, this is not the case. I allowed for the user to switch servers while in networked mode. They could do this from the client GUI. In such a case, all I did was take the newly specified server name (and port) and send that data to my database factory class that did a RMI naming-lookup for the name and port. It then returned a RMI Remote Implementation under the guise of my db interface. Of course, the server I was switching to had to already be up and running to do this. The server switched to might be connected to a different database file. The server itself was not restarted. I just did a naming-lookup call to get the desired Remote Implementation reference from the server. So I'm still not sure why I got such a low score for the Network Server section.
16 years ago

2. You say you keep a hashtable of Client ID and lockCookie to ensure that the holding client accesses the correct record when performing an operation that requires locking.

I'm a bit confused.
When I successfully lock a record I get back a lockCookie.
Now any methods that change the data must pass in a recordNum and the lockCookie. If they don't match then you can't do it.

I can't see why you need the second hashtable ?

I used the following criteria for my locking solution:

Hastable 1: holdingClientID, lockCookie
If the passed in lockCookie does not equal the lockCookie for the passed in holdingClientID, then throw a SecurityException. This ensures that the correct client is attempting to access the desired record no with the correct lockCookie.

Hashtable 2: lockCookie, recordNo
If the passed in recordNo does not equals the recordNo for the passed in lockCookie, then throw a SecurityException. This ensures that the correct lockCookie is used to access the desired record no.

Otherwise how do you account for the wrong client accessing a record no with the right lockCookie? In other words:

clientA has lockCookie1 for record7
clientB has lockCookie2 for record7

Both clients want access to record7 simultaneously.

clientA obtains the lock for record7 first and then is passed back lockCookie1. Now, what is to prevent clientB from using lockCookie1 to work with or unlock record7? Technically, clientB should not get access to lockCookie1, but having a second Hashtable to keep track of the client-lockCookie relationship adds another level of security to the whole locking mechanism. This ensures that only clientA has access to lockCookie1, and that clientB cannot access record7 (until it is unlocked) because clientB does not have lockCookie1.

BTW, locking the entire database is not necessary. You should only account for locking the record in question.

public long lockRecord(final long recNo) { long cookie = //get the cookie as identifier try { //cookies is the hashmap to store the locked record. synchronized (cookies) { while (cookies.containsKey(new Long(recNo)) || cookies.containsKey(new Long(LOCK_DB))) { cookies.wait(); } cookies.put(new Long(recNo), new Long(cookie)); } } catch (InterruptedException e) { ////// } return cookie;}

I just received my exam scores and somehow got a perfect score on the locking mechanism for my project(am still surprised ). So Zee asked for my 2 cents.

From the code above, the only thing I can offer is that the synchronization occurs on a Hashtable object within the method. It is also within a try/catch block which catches an InterruptedException. From a maintainability standpoint, somebody could add additional code within the try/catch, but outside the synchronized block. This added code may not pertain to the enclosing try/catch block which would mean the try/catch block would be encompassing unrelated code. This could become difficult to maintain.

Another approach would be to just synchronize the entire method and only put in the method what needs to be synchronized. I did this in my solution. This way, I'm not calling wait() on the synchronized object, but on the executing thread intstead. My unlock method was also synchronized, and I just called notifyAll() on the executing thread there as well.

Now, there are really 2 parts to the locking mechanism that must be accounted for. One is tracking the holding client (the client holding the locked record) with the lock cookie used (assuming you are using lock cookies in your assignment). The other is tracking the lock cookie to the locked record. This is to ensure that the holding client accesses the correct record when performing an operation that requires locking. I used 2 Hashtables: 1 to track the holding client ID (a unique Integer value) and the lock cookie, and the other to hold the lock cookie and record number.

My solution used a timeout option in which the locking manager forced an unlock if a lock on a record timed out (after 30 seconds). This prevents thread deadlock from occuring.

Otherwise, who knows why people get the scores they do. I got a perfect score for locking, but got only 7/40 for network server .

Congratulations Zee on passing the certification. Don't let your locking score get to you. The important thing is that you're now an SCJD!!
It took only 2 weeks for them to reply with my score. I was surprised. I was expecting it to take 4 - 6 weeks as it seems to be for many people.

My network server was extremely simple, maybe too simple. It was only a few lines of code with no methods in it except for the constructor. The constructor took in the database file location and then instantiated the RMI Remote Implementation reference, created the registry, and then bound the remote implementation to the registry. I put System.out.printlns throughout the process for updates to the user. I also bound the remote reference last in case of an error/exception (so the remote reference would not get bound if an error occurred). Other than the startup dialog, there was no GUI for my server.

Compared to the rest of my project, perhaps the server was not robust enough. I don't know why else I lost so many points for that section of the project.

My advise would be to document all major decisions you made thoroughly in your choices document. Just pick out the things you feel were important and explain in detail why you did what you did (or why you did not do something). My document was 13 pages when I was finished, but they gave me full points for doc. I think that as long as you can explain yourself as to why you implemented your solution the way you did, you'll do fine. The essay exam is also just a reiteration of this. I would imagine you do not need 13 pages or so to have a thorough choices doc, that is just what I ended up with.

Also many thanks to all who answered so many of my stupid questions on this forum!!! Thanks to Frans, Darya, Andrew, Wei Ju, Zee, Paul, and anyone else I am forgetting. Good luck to those still working on it!!

Zee, I will reply regarding you locking question on your thread.

Thanks again and God bless!!!
16 years ago
I passed my SCJD!! The grading breakdown is as follows:

Grade: P
Score: 335
Comment: This report shows the total number of points awarded for each section. The maximum number of points is 400, to pass you need a score of 320.

Section Summary:
Section Max Actual Points Points
General Con: 100 88
Documentation: 70 70
OOD: 30 30
GUI: 40 40
Locking: 80 80
Data Store: 40 20
Network Server: 40 7
Total: 400 335

Don't know why I got only 7/40 for Network Server, and only half credit for Data Store. Also am surprised I got full credit for locking, as most people seem to get docked points there.

I had the B&S assignment with lock cookies. I used only 1 RMI Remote Implementation reference in networked mode (and only 1 Data class reference) because of the requirement for lock cookies, instead of a Remote Implementation for each client.

I had a simple search functionality that did both "begins-with" and "exact-match" searches for the search criteria.

I did allow for switching between modes from the GUI.

I used a timeout option for my locking mechanism. It times out after 30 seconds for a locked record, so the locking manager forces an unlock for any locked records that timeout.

My design choices doc was also about 13 pages long. I did not want to leave anything out, so I was a bit thorough.
16 years ago
So, then how do you link your javadoc to the core classes API javadoc? Or is this required?

Thanks for any input!
I have a stupid question about the javadoc for the assignment. I have about 18 java source files and after I ran javadoc for my project it generated about 43 html files. In the Exam Cram 2 Java 2 Developer book by Alain Trottier he said he had 10 source files that produced 100 javadoc html files.

Are we supposed to somehow link our javadoc to the J2SE javadoc API? Otherwise, references to any J2SE core classes do not show up as links in my javadoc. I would think this is ok - that we do not need to link to the core API.

Just wondering since my project did not generate as many javadoc files as the Exam Cram book related to.

Thanks for any input!!