2

I'm validating a xml against a xsd, and I'm finding that there are many cases where exceptions have to be handled.

I believe these are called checked exceptions in java?

SchemaFactory sf = ....

Schema schema = sf.newSchema(...)    // SAXException has to be handled
Validator validator = ...

validator.validate(xmlFile);   // IOException has to be handled again

How should I be writing this code block?

Do I use try/catch nested inside a try/catch?

Blankman
  • 259,732
  • 324
  • 769
  • 1,199

3 Answers3

2
try {
  SchemaFactory sf = ....

  Schema schema = sf.newSchema(...)    // SAXException has to be handled
  Validator validator = ...

  validator.validate(xmlFile);   // IOException has to be handled again
} catch (SAXException e) {
    // handle SAX error
} catch (IOException e) {
    // handle IO error
}
aishwarya
  • 1,970
  • 1
  • 14
  • 22
  • great thanks, as a side, should I be setting sf and schema variables to null in a finally block? – Blankman Nov 26 '11 at 15:52
  • @Blankman, there is no need to nullify variable in you case. Here is a good thread related to garbage collection: http://stackoverflow.com/questions/850878/does-setting-java-objects-to-null-do-anything-anymore – andbi Nov 26 '11 at 16:42
  • With Java 7 you can use catch(SAXException | IOException e) if you want to handle the exception in the same way. Many times you will just rewrap the exception in a higher level exception, with the original as the cause. In this case a "MyMessageValidationFailedException" would be logical. Only nest try/catch if you want to handle the exception differently, but you might be better off dividing up the method if the code gets too messy. – Maarten Bodewes Nov 26 '11 at 20:27
0

Do I use try/catch nested inside a try/catch?

IMO, no.

try {
    //...
} catch(SAXException e) {
    //handle SAXException
} catch(IOException e) {
    //handle IOException
}

I think the code looks cleaner like that than with nested try/catch.

How should I be writing this code block?

It depends on whether you need to handle the exception right there, in which case you use try/catch, or if need the caller to handle the exception, in which case you should propagate it to the caller by using the throws clause.

public void validateXml() throws SAXException, IOException {
    //...
Bhesh Gurung
  • 50,430
  • 22
  • 93
  • 142
0

Actually you are not supposed to handle checked exceptions if you don't have any recovery strategy.

Do you have another schema in case the one you use raise a Sax exception? Do you have another validator in case the one you use raise an IO exception? Any other recovery possible for these exceptions?

If you don't, you should probably wrap that exception inside a Runtime (unchecked) exception and let it be thrown to the top layer (where it will be catched). Eventually you can add an extra message in the wrapper class if needed to understand the problem.

Unless your program can work correctly without this sax schema (in this case you would catch Exception, to also be able to catch runtime exceptions), or your program have a recovery strategy, you are not supposed to catch an exception without rethrowing it.

If your recovery strategy fail, you can also wrap the recovery exception into an unchecked exception to let the top layer handle it (log + error 500 or something like that).

This is the principle of fail-fast.


Note that in Java there is a big controversy that exist for years about checked VS unchecked exceptions. Many influent people in Java really think introducing checked exceptions was an error.

The main reasons are:

  • People are lazy and tend to catch the exception in the wrong place, so that they are not bothered anymore.

  • People doesn't follow the sun recommandations: they throw checked exceptions just to "give a warning" at compile time for the client side of the API.

  • People tend to think that only methods declaring checked exceptions can raise exception, while ANY code/method CAN throw exceptions. You are not supposed to catch exception ONLY WHEN THE COMPILER SAYS SO: YOU HAVE TO THINK WHERE IT'S APPROPRIATE TO CATCH.

Are kinda agree with Bruce Eckel:

I think the problem is that this is an untested assumption we're making as language designers that falls into the field of psychology.

You can find many links on that subject. Many java developers are not aware of this, but also many mature frameworks now mainly use unchecked exceptions (Spring, EJB3...).

Also people doing C# (no checked exceptions) and Java tend to think it's better when there are no checked exceptions.

So you may do:

try {
    your code here
} catch (Exception e) {
    throw new RuntimeException("optionnal message",e);
}

You can eventually use a custom runtime exception if you think it will be useful


Sun sources:

http://docs.oracle.com/javase/tutorial/essential/exceptions/runtime.html

Here's the bottom line guideline: If a client can reasonably be expected to recover from an exception, make it a checked exception. If a client cannot do anything to recover from the exception, make it an unchecked exception.

http://docs.oracle.com/javase/specs/jls/se5.0/html/exceptions.html#11.5

The class Exception is the superclass of all the exceptions that ordinary programs may wish to recover from.


Bruce Eckel (Thinking in Java book): http://www.mindview.net/Etc/Discussions/CheckedExceptions

"Ignorable" in the previous paragraph is the other issue. The theory is that if the compiler forces the programmer to either handle the exception or pass it on in an exception specification, then the programmer's attention will always be brought back to the possibility of errors and they will thus properly take care of them. I think the problem is that this is an untested assumption we're making as language designers that falls into the field of psychology. My theory is that when someone is trying to do something and you are constantly prodding them with annoyances, they will use the quickest device available to make those annoyances go away so they can get their thing done, perhaps assuming they'll go back and take out the device later. I discovered I had done this in the first edition of Thinking in Java:

...
} catch (SomeKindOfException e) {}

reevesy
  • 3,452
  • 1
  • 26
  • 23
Sebastien Lorber
  • 89,644
  • 67
  • 288
  • 419
  • All that text, which does seem to be a bit too much for this question, and then following it up with catching instances of the base Exception. That's certainly a -1 to me, sorry. In most libraries and such, you don't want to catch e.g. OutOfMemoryExceptions. – Maarten Bodewes Nov 26 '11 at 20:20
  • 1
    OutOfMemory are errors, which are Throwables but are NOT exceptions! Thus catching Exception doesn't catch Errors! – Sebastien Lorber Nov 26 '11 at 20:59
  • From Checkstyle: "Rationale: Junior developers often simply catch Exception in an attempt to handle multiple exception classes. This unfortunately leads to code that inadvertantly catchs NPE, OutOfMemoryErrors, etc.". It seems I've been caught by bad documentation, I'll try and notify the checkstyle team. I'll remove the downvote, although I am still not sure about the effectiveness of the answer, or the catch(Exception e) for that matter. – Maarten Bodewes Nov 26 '11 at 22:24
  • It isn't because checkstyle says something that it's the truth. Think on your own and try to tell me why we shouldn't catch Exception? Why checkstyle did a rule like that? Checkstyle is ok to catch Sax, then IO then runtime, which is exactly the same, in this case, to catch directly Exception :) – Sebastien Lorber Nov 27 '11 at 02:56
  • Actually i think checkstyle just want to tell junior developers they shouldn't catch the runtime exceptions because (except exceptional cases) they should be handled in the top layer, displaying an error 500 or something. But if you rethrow them, there is no difference ;) – Sebastien Lorber Nov 27 '11 at 03:00