This week's book giveaway is in the Agile and Other Processes forum.
We're giving away four copies of The Little Book of Impediments (e-book only) and have Tom Perry on-line!
See this thread for details.
Win a copy of The Little Book of Impediments (e-book only) this week in the Agile and Other Processes forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

RecordNotFoundException dilema, pease help

 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi People

I have a question regarding the find method and the RecordNotFoundException exception.
In my specification the the method find looks like :

// 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)
throws RecordNotFoundException;

with an extra specification :

Any methods that throw RecordNotFoundException should do so if a specified record does not exist or is marked as deleted in the database file.



My question is : if find the method does not find any valid records for the specified criteria I must throw a RecordNotFoundException or not ?

In my opinion the method doesn't need to throw this exception, if in the database are no records to match the specified criteria it can return a empty array or even a null.

How you guys solve this problem ?


Regards, Mihai
 
Shlomo Hillel
Greenhorn
Posts: 14
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mine does not have any exceptions! So, I can only return an empty (non-null) array.

I think they are playing games with us!

Shlomo
 
Oliver Weikopf
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
My interface has the exception as well. The way I see it, "Any methods that throw RecordNotFoundException should do so if a specified record does not exist or is marked as deleted in the database file" is pretty straightforward. I throw a RecordNotFoundException when no record match the search criteria, even though I believe an empty array would make more sense.
 
B Chen
Ranch Hand
Posts: 89
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
You should always do what the interface specifies. Doing otherwise would surprise programmers who will be maintaining your code. In my assignment, I did not have the exception specification, so I chose to return an empty array.
 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys,


TanX for your attention.
I agree with you, the specs are straightforward even if they are not 100% logical. But this lead me to the next questions.

How I can signals other problems (like corrupted database) ?

How I make a difference between :
1.record not found because the database is not running case and
2.record not found because ther are no records that match the specified criteria ?


I have at least two(three) possibilities :
1.I can throw other exception(s) - RunTimeException subclasses
2.I can chain the exception on RecordNotFoundException and use the cause method to obtain the real cause for the exception.
3.I can change the Data interface

From begining I disagree with 3.
In my current I use the 2 - I chain the exception on RecordNotFoundException. So I respect the specs but I do a little bit more, I throw the RecordNotFoundException also if a specified record can not access for various reasons(database is corrunpted, the server is not running , etc).
Is this ok ?

How you guys solve this problem ?

Regards,
Mihai
[ June 08, 2006: Message edited by: Mihai Radulescu ]
 
Oliver Weikopf
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So far, I don't. I open the db file in the constructor and check its consistency (cookie, meta data) at that point. If the file is corrupt or missing, the according errors will occur in the constructor and I deal with them by throwing an Exception there - and of course notifying the user.

This means that whenever I encounter an error in any of the other methods, I assume neither a corrupted nor a missing db file to be the problem and thus throw a RecordNotFoundException.

I'm not sure this is the ideal approach, though, so I may still change it.
 
Jeroen T Wenting
Ranch Hand
Posts: 1847
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Bad design. It could also mean a corrupt disk, network error, or a host of other things (mainly indicated by IOExceptions or derived).
NEVER assume that things can go wrong outside your application, that way lies disaster.
 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys

Oliver, I think that Jeroen has right - what you do on the client side if your server crash after a while ?

I chose to chain the exceptions - it brings less overhead.
I "inspire" a little bit from this post :

http://www.coderanch.com/t/183822/java-developer-SCJD/certification/NX-Exception-handling-implementing-DBAccess

Jeroen, how you solve this problem ?

Regards M

[ June 09, 2006: Message edited by: Mihai Radulescu ]
[ June 09, 2006: Message edited by: Mihai Radulescu ]
 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys

Here is my exception work flow :

FileHandler ->FileHandlerExceprions-> Data ->RecordNotFoundException-> Client ->UIExceptions-> UI

I chain the exception, so if an UIException occurs I can get its real cause.

Any comment,critics, tips ?

Regards M
[ June 09, 2006: Message edited by: Mihai Radulescu ]
 
Oliver Weikopf
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Originally posted by Mihai Radulescu:
Oliver, I think that Jeroen has right - what you do on the client side if your server crash after a while ?
...


The way I see it - and I've only just arrived at this conclusion - this Interface is solely for the file access. I had originally intended to use it for the network communication - and thus as the RMI interface - as well, but from what it says in the instructions I got the feeling that this is not an interface the client should know or work with. Accordingly, my current thinking is to create my own client-server interface and use DBMain exclusively for direct file access. In this case, I don't need to deal with networking errors and the like.

File access exceptions (other than EOFExceptions) should not occur unless there's something seriously wrong (hard drive corrupted or crashed or somesuch). You were correct in pointing out to me that this should not be dealt with by simply throwing a RecordNotFoundException (as I had done so far). But since this is such a serious Exception, I'm now considerung using an Error for this since the server (or standalone version) won't be able to keep running if this happens, no matter what I do. After reading the thread Jeroen pointed to (thanks for that), I think this is the most valid option.
[ June 12, 2006: Message edited by: Oliver Weikopf ]
 
Jeroen T Wenting
Ranch Hand
Posts: 1847
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If the server crashes that's a RuntimeException, which aren't specified in the interface (because they don't have to be).
Or rather, if there is a network error (thus an IO exception of some sort) that's translated into a DatabaseException (which I defined as a RuntimeException) and handled.
That way I can provide transparency between local and network access as well as socket and RMI networking as all network exceptions as well as file handling exceptions are all IOExceptions of some sort and thus transported to the client through the same mechanism for handling (which essentially means throwing up an error message and closing the connection to the server).
 
Mihai Radulescu
Ranch Hand
Posts: 918
IntelliJ IDE Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi guys

TanX for your interest on the thema.

Oliver,

I don't think that the idea with the Error is to good


But since this is such a serious Exception, I'm now considerung using an Error for this since the server (or standalone version) won't be able to kee
p running if this happens, no matter what I do.


I think that a checkable exception will fit better and this for two reasons :
1.If you use a check exception you constrain the user to take care on some specific situation, if you use an Error the user(by user I mean a junior p
rogrammer) can ignore it and this can have some unpleasant effect.
2.Errors are used for serious cases ,just take a look on java API - there are just a few of them. IO problems are something normal(you can easy find
some) but error are not.

Jeroen,

If the server crashes that's a RuntimeException, which aren't specified in the interface (because they don't have to be).


Why you use RunntimeException here ?

By server crash I mean the server can not do its job (without an obvious reason). The server job is to serve some clients, each client expect that the server can crash, thats why any server interaction is done in a try/catch (/finally) - you can find the same logic by RMI(all the remote methods must throw RemoteException) or by Sockets(read/write methods).

If you decide to use a RTE (in your case the DatabaseException) is like you presume that the IO exception will never occurs - you clients will be not
constraint to take care of this kind of this special problems. Lets say that in the future a new client a new client will be added and the new (jun
ior) programmer does not read exact your API, he'll get a lot of troubles to understand why his application crashes.
It is true you win some transparence but you lose flexibility.

More than that, you must transport the exception from the server to the client. How you do this ? With a RTE I mean

I provide transparency between local and network(RMI or sockets) access as well just by using the IOException.

Regards M

P.S.

If the thema goes general(Exception vs RTE) is not fitting with the original thread thema. How about a new thread with a proper title ?

[ June 12, 2006: Message edited by: Mihai Radulescu ]
[ June 12, 2006: Message edited by: Mihai Radulescu ]
 
Oliver Weikopf
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just want to make a few points for the usage of an Error rather than a RTE.

  • The api for error says "An Error (...) indicates serious problems that a reasonable application should not try to catch". Sounds like something like a hd crash, for example. Note that I do not intend to use the error for rmi or network problems, just for hd access errors on the server side.
  • The api for RTE say, "RuntimeException (...) can be thrown during the normal operation of the Java Virtual Machine". That's to say, it would be inappropriate because throwing an RTE something the JVM does, not something your application does.
  • All literature I've read on RTE states that they should occur when a coding convention has been violated (negative array index, null parameter etc.) This is not the case here.
  • My biggest argument lies in Mustang: In JDK 1.6, there will be a new class IOError which seems to cover just this kind of behaviour - a serious I/O Error that is not to be handled because it will only occur under extreme conditions. So using an Error to deal with such problems seems to be along Sun's line of thinking.
  • So it seems to me an Error will be more appropriate than a RuntimeException. But I'm really not sure here, so other ideas are welcome.

    As for the question of RTE vs checked, I'm all in favor of checked exceptions normally, but the DBMain interface doesn't allow for additional Exceptions other than RecordNotFoundException and DuplicateKeyException, so a checked exception is not really a viable option when you encounter an IOException (other than EOFException, of course).

    Just to avoid misunderstandings: Obviously, this only holds true when talking about the DBMain interface. I'm not talking about the RMI interface here. That one can and should use checked exceptions.
     
    Mihai Radulescu
    Ranch Hand
    Posts: 918
    IntelliJ IDE Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi guys

    Oliver,

    1.I don't think that the hdd/system crash is above the SCJD purpose, I don't say that you must ignore it.
    Don't forget that the issue :

    A clear design, such as will be readily understood by junior programmers, will be preferred to a complex one, even if the complex one is a little more efficient. Code complexity, including nesting depth, argument passing, and the number of classes and interfaces, should be reasonable.

    The errors are strong stuff, there are suff that :

    a reasonable application should not try to catch


    2.If the you have

    hd access errors on the server side


    and you use an Error to signal that how you'll inform your client about it ?
    Remember catching Errors is not you task(at least not for this developer assignment).
    On the other side by other reasonable hardware problem the JVM throws also some errors so you are covered (for all this "reasonable" cases).

    3.The Mustang is still in beta mode and I am not shore that you can use it(or lay your decisions on) on this exam.

    4. How often you catch Error(s) until now ?

    5. RTE vs checked exception, from your last post :

    As for the question of RTE vs checked, I'm all in favor of checked exceptions normally, but the DBMain interface doesn't allow for additional Exceptions other than RecordNotFoundException and DuplicateKeyException, so a checked exception is not really a viable option when you encounter an IOException (other than EOFException, of course).



    Why you don't chain the exception(s) ?

    If you throw RTE (from your Data class) client you must translate this to RemoteException (or IOException) if you try to inform you client about possible problems on the server side. So you'll follow the schema :
    IOException -> RTE -> IOException
    or better :
    checked goes to non-checked and goes back in checked,
    the flow looks a little bit inconsistent to me. More if anything goes fishy on the non-checked steep and you may miss some exception them the clients can get act/react improper.

    An other thing about exception, on the client side is not important to know that a record can not be booked because "the system hdd swap is full and the extended memory allocated to the JVM is to small" on the client side is important that the operation is done or not.


    Regards M
    [ June 13, 2006: Message edited by: Mihai Radulescu ]
     
    Jeroen T Wenting
    Ranch Hand
    Posts: 1847
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    If the server goes down, that's not a fatal condition to the CLIENT JVM, therefore an Error is too strong a mechanism.
    As you can't use a checked exception without breaking the requirement of not modifying the DB interface, a runtime exception is the only alternative.

    Errors in general should only result from internal conditions inside the JVM (so never thrown directly by application code at any level), and never be handled (so leading to JVM termination).

    Throwing an Error is therefore both overkill and would (if properly handled, meaning not handled) lead to the client crashing fatally when the server goes down.
    Hardly an appropriate action, as it's not necessarilly a fatal condition to the client (he could connect to somewhere else instead for example).
     
    Mihai Radulescu
    Ranch Hand
    Posts: 918
    IntelliJ IDE Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Jeroen,


    a runtime exception is the only alternative.


    I think that you are wrong(thre are at least 7 alternatives).
    How about exception chaining ? The interafce remains intact and you follow the
    requirement also.

    Regards M.
    [ June 13, 2006: Message edited by: Mihai Radulescu ]
     
    B Chen
    Ranch Hand
    Posts: 89
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I think that when most programmer see RecordNotFoundException, they assume it means that the record really is not in the database (and the database is still healthy). Most programmers would not think RecordNotFoundException would mean anything else, and programmatically follow the chain to determine the real root cause and handle it appropiately. Just imagine how that code would look like.
    I like RuntimeException because you can handle any unexpected situation with one catch block (usually just log/display the error).
    [ June 13, 2006: Message edited by: B Chen ]
     
    Oricio Ocle
    Ranch Hand
    Posts: 284
    Debian Firefox Browser Netbeans IDE
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    An alternative:

    Provide a wrapper for Data class, with the desired checked exception behaviour.
    This way you isolate specific exception design (unchecked, error, ...), reducing decission impact, and clients can interact with data implementation in a standard way

    Regards
    [ June 13, 2006: Message edited by: Oricio Ocle ]
     
    Jeroen T Wenting
    Ranch Hand
    Posts: 1847
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Originally posted by Mihai Radulescu:
    Jeroen,

    I think that you are wrong(thre are at least 7 alternatives).
    How about exception chaining ? The interafce remains intact and you follow the
    requirement also.



    Nope.
    You still can't throw a checked exception other than the declared one(s) from a class deriving from the DB interface.
    To do exception chaining you'd have to do just that unless the wrapping exception were an unchecked exception which brings you right back to what I propose.
     
    Mihai Radulescu
    Ranch Hand
    Posts: 918
    IntelliJ IDE Java Linux
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Hi People

    I think that we are to abstract let's talk with some concrete stuff.
    I use the 3 tier architecture. I try to draw it :
    End -> Middle -> transport -> Front , I draw the transport with purpose.

    On the End tier I have the FileHandler and LockManager, both throw a lot of exception (checked and unchecked).

    On the Middle my Data class catch this exceptions and transforms them in middle layer specific exceptions(RecordNotFoundException & Duplicate...). This is one of middle layer the purpose -
    to transform the low level exceptions in some friendly exceptions.

    On the transport (or client) layer I need to warp the exception in transport specific exceptions IO Exception.

    So I reach on the last part of this chain the UI, here I get only client UI Exceptions.

    Why I do this ?

    Because the user does not need to know the low level reason for this failure.
    By example a web browser (it acts the same like my UI client) has only two possible failure cases:
    1.Server not found - the server is not running for any reasons
    2.Page not found - the server is running but the pages(like the record) can not be found by any reasons.


    Why I need to throw a RTE from my middel tier ? Please argue this using my model.



    Oricio,
    I provide a warper - this is my client.

    Jeroen,


    You still can't throw a checked exception other than the declared one(s) from a class deriving from the DB interface.

    This means to change the interface ?


    To do exception chaining you'd have to do just that unless the wrapping exception were an unchecked exception which brings you right back to what I propose.

    Can you reformulate ? I don't know what you mean.


    Regards, Mihai
    [ June 13, 2006: Message edited by: Mihai Radulescu ]
     
    • Post Reply
    • Bookmark Topic Watch Topic
    • New Topic