This post is part of a series delving into the details of the JSR-352 (Java Batch) specification. Each post examines a very specific part of the specification and looks at how it works and how you might use it in a real batch application.To start at the beginning, follow the link to the first post.The next post in the series is
here.
This series is also available as a podcast on iTunes, Google Play, Stitcher, or use the link to the RSS feed. -----
Wow..this sounds really really boring. I’m writing it and I don’t really want to read it.
For a song title, I’m going with “I’m gonna sit right down and write myself a letter”, recorded by a lot of people. You’ll see why when we get to the end.
Well, the syntax is a bit goofy and certainly not what I would have thought was an obvious way to handle it. So, it seemed worth spending one post just to go through how this works. Likely all you will remember from reading this, if you do, is that the syntax is goofy and if you decide to try to do retry and retry-rollback processing, you should look it up. Good idea. If you remember that, you got the point. You can probably stop reading now. If you even got this far.
Ok, so to specify that you want to do retry processing with a rollback you have to specify what exception(s) you want to handle that way. Here’s an example (stolen from the spec):
<retryable-exception-classes>
<include class=”java.io.IOException”/>
<exclude class=”java.io.FileNotFoundException”/>
</retryable-exception-classes>
That says that any IOException
should trigger retry-rollback processing unless it is a FileNotFoundException
(or any subclass of FileNotFound
).
Ok, well enough. We’ve been talking about retry-rollback so it seems a bit odd that the JSL clause just says retryable and nothing about rollback, but ok, fine. But then…how do you specify an exception that you want to just do retry processing without the rollback? That’s where it gets weird.
The retryable-exception-classes
element specifies exceptions that will retry. Maybe with rollback and maybe without rollback. What determines which one is whether or not the exception is ALSO listed in the no-rollback-exception-classes
element. Suppose we wanted to do rollback processing for IOExceptions
(except FileNotFound
), but not do rollback processing for an end-of-file exception? Then we need to ALSO specify this in our JSL:
<no-rollback-exception-classes>
<include class=”java.io.EOFException”/>
</no-rollback-exception-classes>
Because the EOF exception is a subclass of IOException
it will be included in the exceptions for which retry processing will occur. Because it is listed in the no-rollback-exception-classes
it won’t do rollback, but all the other IOException
subclasses will.
As you can see, this is a bit tricky. If you aren’t doing something with subclass exceptions, you can end up listing the exact same exceptions in both clauses. Suppose we just wanted to do retry processing (with no rollback) for any IOException
. Then you would need this:
<retryable-exception-classes>
<include class=”java.io.IOException”/>
</retryable-exception-classes>
<no-rollback-exception-classes>
<include class=”java.io.IOException”/>
</no-rollback-exception-classes>
Just listing an exception in the no-rollback-exception-classes
element does nothing at all. That element only applies to exceptions (or parent class exceptions) that are specified in the retryable-exception-classes
element.
Bottom line: If you decide to use retry processing, with or without rollback, be sure to put some nice comments in your JSL to explain what you intended. The year-from-now-you will appreciate it when you’re puzzling over it.