File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Developer Certification (SCJD/OCMJD) and the fly likes about the search method Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Soft Skills this week in the Jobs Discussion forum!
JavaRanch » Java Forums » Certification » Developer Certification (SCJD/OCMJD)
Bookmark "about the search method" Watch "about the search method" New topic
Author

about the search method

Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
Hi, guys
I am going to implement the search method by calling "find" and then "read". Is it true that in the whole process of search, I have to lock all the records of the db file? Since I don't want another thread change the record after my "find" method returns.
And I think there are two ways to do it. One is using a loop to call lock method on each record, the other is to create a new method of "lockall". Which is the better approach? Thanks
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
And also a related question about the find() method, In what case should find() method throw a RecordNotFoundException? When no record is matched? I am thinking just return an empty int[] will be fine, isn't it? Thanks.
Mark Spritzler
ranger
Sheriff

Joined: Feb 05, 2001
Posts: 17260
    
    6

Well, first. You will not lock any records when doing a search. Second the requirements asks for a criteriaSearch method to be added to handle find.
The find method in the Data class takes a record number as a parameter, so if a record number is passed that does not exist, then the Exception is thrown.
The two are not related, in the manner that you are thinking. You do want to get every record read, then compare it to the criteria string, and if it matches that is a record to pass back. The criteriaFind method will actually call the read method only, and not the find method. Well at least in my submission it didn't. There might be room for arguments here that I wouldn't refute right away.
Hope that helps.
Mark


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

Joined: Oct 14, 2003
Posts: 146
I'm doing the bodgitt and scarper contractor assignment and my specification didnt say anything about adding a criteriaSearch() method. Are there different versions to this assignment or are you just merely pointing out a way to implement the search? just curious
Dave


SCJP 1.4, SCJD 1.4, SCWCD 1.3, SCBCD 1.3, IBM Certified Solution Developer -WebSphere Studio V5.0
Chris Harris
Ranch Hand

Joined: Sep 21, 2003
Posts: 231
Hi,
I am also doing the B&S assigment and can not find anything about a method called criteriaSearch.
// Returns an array of record numbers that match the specified
// criteria. Field n in the database file is described by
// criteria[n]. A null value in criteria[n] matches any field
// value. A non-null value in criteria[n] matches any field
// value that begins with criteria[n]. (For example, "Fred"
// matches "Fred" or "Freddy".)
public int[] find(String[] criteria);

It looks like my approach is close to Peter's. I do not cache any records so the find method calls the read method (x the number of records in DB) to check if the records match the criteria. I know this is not the most efficient way of doing it but the assignment says nothing about performance . If no records are found I return a empty array.


SCJP 1.2, SCWCD, SCBCD
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
Are there different versions to this assignment
There are different versions of the asignments out there. Sometimes this is just a change of name, e.g. some people have a criteriaSearch() method that might work exactly like your find(); in many other cases, other parts of the method insterface may be different, like parameter types, return type, exceptions thrown, etc. And this doesn't always break down as B&S vs. URLyBird. Doing B&S you may see some other people discussing URLyBird with methods very similar to yours, and other people discussing B&S with methods different from yours. Sun is intentionally trying to confuse us, it seems. So for any advice you may receive here, check it against your own instructions and see if it makes sense in that context, or if it needs to be modified.
[ October 17, 2003: Message edited by: Jim Yingst ]

"I'm not back." - Bill Harding, Twister
Yuan Ye
Ranch Hand

Joined: Mar 05, 2003
Posts: 172
Hi, guys
In my assignment, the find() method of Data class has following signature:
public int [] find(String [] criteria) throws RecordNotFoundException;
which will return a type of int[] as the array of mathched record ids. So in order to fully utilize the result, I am think I have to lock all records between the return of find() and my successively action of retriver records. Or the other way I have to cache all my records before find(). Is that true? Other question is in what situation should this find() method throws a RecordNotFoundException, I don't understand.
[ October 18, 2003: Message edited by: Peter Ye ]
Bharat Ruparel
Ranch Hand

Joined: Jul 30, 2003
Posts: 493
Hello Peter,
You wrote:

which will return a type of int[] as the array of mathched record ids. So in order to fully utilize the result, I am think I have to lock all records between the return of find() and my successively action of retriver records. Or the other way I have to cache all my records before find(). Is that true? Other question is in what situation should this find() method throws a RecordNotFoundException, I don't understand.

This will be true if you are taking a true snapshot of the matching data, but you are not required to. Therefore, I am not bothering to lock the entire database when I execute the find method against the RandomAccessFile. What you must guard against however, it the fact that the data in a particular record is not updated in the middle of your read operation. Say you are reading record number 3 for example, and you have read the first two fields, if the third field is updated while you are reading it then you will have inconsistent data for the record just read. You can avoid this situation by using a couple of clever techniques for reading data from the Random Access File:
1. Use the method that reads the entire record in a byte array in one fell-swoop and it blocks while it is doing the read.
2. Make sure that your file pointer is synchronized during this process since you don't want it to be moved when you are reading this particular record.
If write your logic with the aforementioned two points in mind, your code will not do an inconsistent read operation. Dirty reads are OK.
Concerning RecordNotFoundException - You are right that this exception will not be thrown logically since you are not being given a record number or a set of record numbers to find. However, there are going to be IOExceptions in the program as a result of data being read etc. What I do is to wrap these in RecordNotFoundException and rethrow them. This way, you respect the method signature given to you in the assignment.
Hope this helps.
Bharat
[ October 18, 2003: Message edited by: Bharat Ruparel ]

SCJP,SCJD,SCWCD,SCBCD,SCDJWS,SCEA
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Mark S]: The find method in the Data class takes a record number as a parameter, so if a record number is passed that does not exist, then the Exception is thrown.
That's surprising to me - why would a find method take a recNo as parameter? I confess I don't understand how that might work. Isn't the objective of the find method to find the record numbers that satisfy certain criteria? What would you do with this recNo as part of the find method?
To Peter Ye:
In my own instructions, the find() method does not take a recNo parameter (same as Peter), but it also does not throw any RecordNotFoundException (unlike Peter). So be aware that my advice may not apply to you. However I think you should seriously consider the possibilty of simply not throwing FileNotFoundException from find(), ever. The fact that the method is declared as "throws RecordNotFoundException" simply means that you would be allowed to throw RecordNotFoundException, if you had a reason to - you're not compelled to do so. If they don't provide any other documentation about when this exception should be thrown (in the context of find()), you don't have to actually throw it. I think this may be an example of a deliberately ambiguous spec which you can interpret more than one way. In my own instructions, the find() method doesn't have this silly ambiguity, but create() does - it has a DuplicateKeyException which I believe should not really be thrown. Others here disagree, and you can do a search on DuplicateKeyException to see many discussions of this, but my point is just that there is a significant possibility that Sun doesn't actually expect you to throw this exception. Give that possibility some thought anyway. Cheers...
[ October 18, 2003: Message edited by: Jim Yingst ]
Bharat Ruparel
Ranch Hand

Joined: Jul 30, 2003
Posts: 493
Hello Jim,
You wrote:

The fact that the method is declared as "throws RecordNotFoundException" simply means that you would be allowed to throw RecordNotFoundException, if you had a reason to - you're not compelled to do so. If they don't provide any other documentation about when this exception should be thrown (in the context of find()), you don't have to actually throw it.

I have the same instructions as Peter so this is of interest to me too. I am more or less done with my assignment and am in the testing phase. I have implemented find and as you point out above, I don't have a logical place to throw RecordNotFoundException. However, there are a couple of places where my code must "handle" IOException. My dilemma is I don't want to throw an unchecked exception from a checked exception that is fairly routine. Therefore, I am wrapping the IOException in RecordNotFoundException and rethrowing it in this method. Any suggestions that you have are welcome.
Regarding the create method, you wrote:

but create() does - it has a DuplicateKeyException which I believe should not really be thrown. Others here disagree, and you can do a search on DuplicateKeyException to see many discussions of this, but my point is just that there is a significant possibility that Sun doesn't actually expect you to throw this exception. Give that possibility some thought

Again, I agree with you and would point out in the choices.txt file that the DuplicateKeyException should never be thrown, but it could be used to rethrow the IOException. That is what I am planning on doing anyway, otherwise, how do you communicate to the calling classes programs that there is a possibility of something going wrong in these methods. Specifically the IOException that is common to both these methods, how do you propose that we handle it?
Thanks for your time.
Bharat
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
I agree that those IOExceptions are annoying, and integrating them into the APIs we've been given is a bit of a challenge, since there seems to be no ideal solution. Personally what I do is to wrap the IOException in a custom DBAccessException which extends RuntimeException, so I can throw it anywhere. I know that checked exceptions are generally viewed as a Good Thing, and I regret losing that benefit. However I'm not so enamored with them as many other people are; I'm willing to use unchecked exceptions if necessary. The problem I have with using the checked exceptions from the API is that the few that have been allowed to us are misleading in name. RecordNotFoundException and DuplicateKeyException just aren't really appropriate for an IOException, in my opinion.
RecordNotFoundException might be sort of OK - to me it implies that we successfully looked at where the record was supposed to be, and either the recNo was out of range, or the record had been deleted. Either way, you're sure that the record really isn't there, and you can report "That record doesn't exist." With an IOException though, it could be something else, like a network failure, or some other process acquiring an exclusive lock on our file, or moving it or deleting it, after we were told that wouldn't happen. :roll: My feeling is that if this sort of thing ever happens, (a) you probably can't access any other records anyway; the whole DB is hosed (for now at least), and (b) you want to tell the user clearly that something is seriously wrong; it's not just a case of one record missing, and they should probably either plug the network cable back in ), or call tech support. I don't really want the user to keep trying to use the program in this situation; it will just frustrate and confuse them, and they'll end up blaming the program which is giving them confusing error messages rather than directing their anger at whoever is really responsible.
Now maybe I could live with throwing RecordNotFound in case of IOException. I suppose. But what about the create() method, which can't thow RNFE? The only allowed checked exception is DuplicateKeyException - which makes no sense at all for an IO problem. If I throw that, the user has a good chance of seeing a completely erroneous error message. Or some other programmer might decide to do something to change the key, and try again, which might reult in an infinite loop, or maybe they luck out and it works, but the data has been changed and they weren't supposed to do that, and the data wasn't really the problem. No, I'd rather throw some sort of RuntimeException that correctly says what the problem is, without misleading anyone. And once I'm doing that for create(), I'm even more reluctant to use RecordNotFound for the other methods. I want to be consistent. So all my methods that might have an IOException handle it by throwing DBAccessException. It's not a perfect solution, but it works reasonably well.
Incidentally, my networking code provides a RemoteDB which implements the same DB interface Data does. To do this I needed an adapter which caught all those pesky RemoteExceptions - and translated them into DBAccessExceptions. So the above discussion can apply to RemoteExceptions as well.
Note that when doing something like this, using an unchecked exception when you'd rather be using a checked exception, I've found that it's useful during development to have the exception extend Exception rather than RuntimeException, so it's now a checked exception. This means that, for development only, the DB interface is also changed to include new exceptions. This lets you use the compiler to remind you where the exception may be thrown, and decalre it or handle it otherwise. Then just before final submission, change DBAccessException back to a RuntimeException, and replace the DB interface with the original version, which makes no mention of DBAccessException. But now all the other classes do document the excption, even though they don't have to, and probably handle it correctly, even though DB does not say anything about it. Admittedly, this won't prevent junior programmers from coming along later and screwing things up, now that it's no longer a checked exception - but at least the code that's submitted has a good chance of handling the exception correctly. Ought to be worth something at least.
To do something like this, you have to have a fairly reliable mechanism for maing sure that you haven't accidentally left the edited version of DB in place for the final submission. Using eclipse, I find that I can just put a
// TODO: restore to original form
into the DB.java file, and the system will keep a listing for me inthe task list until I finally get around to removing it. I'm pretty sure I'll remember to do that eventually, as most things I'm doing now are revisiting minor issues that I'd previous tagged with TODO, and watching the list gradually shrink.
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Hi Jim,
However I think you should seriously consider the possibilty of simply not throwing FileNotFoundException from find(), ever.

Agreed.
As yours, my find method doesn't throw RecordNotFoundException, meaning that if no records are found it's obvious that we must return an empty array of record numbers.
But with Peter's signature (which is silly - I agree with you), would it be so silly to throw RecordNotFoundException in that case ? Programmers of another existing application, coding to the same db interface, could interpret RecordNotFoundException as such an indicator that no record was found (I mean no record matches the criteria). So I think that Peter must make a choice here.
Best,
Phil.
Andrew Monkhouse
author and jackaroo
Marshal Commander

Joined: Mar 28, 2003
Posts: 11524
    
100

Hi Jim
Originally posted by Jim Yingst:
I know that checked exceptions are generally viewed as a Good Thing, and I regret losing that benefit. However I'm not so enamored with them as many other people are; I'm willing to use unchecked exceptions if necessary.

You might be interested in reading Does Java need Checked Exceptions? by Bruce Eckel (author: "Thinking in Java", "Thinking in Patterns" and many others). He makes an interesting case that forcing people to catch checked exceptions is a failed experiment resulting in bad coding. I'm fence sitting at the moment - I can see his point, but I also think that forcing people to catch exeptions can help force people to think about what to do when an exception happens (as long as they're not lazy).
Regards, Andrew


The Sun Certified Java Developer Exam with J2SE 5: paper version from Amazon, PDF from Apress, Online reference: Books 24x7 Personal blog
Philippe Maquet
Bartender

Joined: Jun 02, 2003
Posts: 1872
Bharat,
I do exactly the same as Jim (wrapping IOException in some extended RuntimeException) and I agree 100% with all his arguments.
Jim:
Note that when doing something like this, using an unchecked exception when you'd rather be using a checked exception, I've found that it's useful during development to have the exception extend Exception rather than RuntimeException, so it's now a checked exception. This means that, for development only, the DB interface is also changed to include new exceptions. This lets you use the compiler to remind you where the exception may be thrown, and decalre it or handle it otherwise. Then just before final submission, change DBAccessException back to a RuntimeException, and replace the DB interface with the original version, which makes no mention of DBAccessException. But now all the other classes do document the excption, even though they don't have to, and probably handle it correctly, even though DB does not say anything about it. Admittedly, this won't prevent junior programmers from coming along later and screwing things up, now that it's no longer a checked exception - but at least the code that's submitted has a good chance of handling the exception correctly. Ought to be worth something at least.

Very nice trick Jim ! I'll now use it too.
Best,
Phil.
Bharat Ruparel
Ranch Hand

Joined: Jul 30, 2003
Posts: 493
Jim/Andrew/Phil,
Thank you. Exception handling is of immense interest to me. As I might have mentioned in some other thread, we have a rather large J2EE application that could have used better exception handling and logging; maintaining it is not easy. A top town exception handling strategy coupled with a well thought-out logging use might have made things a lot easier.
Andrew, I want to thank you for urging me to consider putting logging in my application. I have done it. It has been very useful in debugging and even more important understanding the finer details of concurrent "booking" of the hotel rooms.
Regards.
Bharat
Jim Yingst
Wanderer
Sheriff

Joined: Jan 30, 2000
Posts: 18671
[Philippe]: I agree 100% with all his arguments


[Andrew]: You might be interested in reading Does Java need Checked Exceptions? by Bruce Eckel
Yup, I'd seen that, but it's a good reminder. See also CheckedExceptionsAreOfDubiousValue. I too am on the fence here; checked exceptions alternate between being annoying and being useful. But I should note that my DBAccessException was originally a RuntimeException, which made initial development simpler. Uncertain what to do about an excption or other error condition? Just convert it to a DBAccessException, throw it, and worry about it later. But when I recently switched DAE to Runtime (temporarily), it was instructive to see the results. On one had, it was a bit tedious to go through a bunch of methods and have them explicitly declare new throws clauses (even if eclipse makes this reasonably simple). But it also forced me to look at everywhere the exceptions were being propagated, and I did find some areas where my handling of them had been less than optimal. So if I had an ongoing contract with Bodgett & Scarper, I'd probably be lobbying them to revise the DB API and let DAE be a checked exception. With the caveat that any programmer found wrting an empty catch block (with no comment explaining why it's OK in a particular case) shoud be summarily beaten.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: about the search method