Saturday, December 18, 2010

How do you handle job failures in Quartz? There are a few things you can do:

Do nothing. Let the job fail and log the error.

Retry continuously until the job succeeds.

Retry n times and then disable the job.

In this post, I will describe how you can configure your jobs to be retried on failure.

Retrying continuously until success:
If you want to keep trying over and over again until the job succeeds, all you have to do is throw a JobExecutionException with a flag to tell the scheduler to fire it again when it fails. The following code shows how:

Retrying n times:
It gets a bit more complicated if you want to retry a certain number of times only. You have to use a StatefulJob and hold a retryCounter in its JobDataMap, which you increment if the job fails. If the counter exceeds the maximum number of retries, then you can disable the job if you wish.

Saturday, December 11, 2010

When you try to throw a checked exeption from a method in Java, the compiler will force you to either catch it or declare it to be thrown in the method declaration. For example, the following method fails to compile:

public void go(){
throw new IOException();
}

The compiler says:

Dummy.java:15: unreported exception java.io.IOException;
must be caught or declared to be thrown
throw new IOException();
^
1 error

However, if you declare it to be thrown in the method declaration, like this:

public void go() throws IOException{
throw new IOException();
}

then it compiles successfully.

But is it possible to throw a checked exception WITHOUT declaring it to be thrown? You could wrap it in a RuntimeException (for example, new RuntimeException(new IOException()), but then you lose the ability to catch the checked exception in the caller method, because you have changed the type of the exception.

There is another trick you can use. I first noticed this being done in the JDK's java.lang.Class#newInstance0 method:

As shown above, the method throws an InvocationTargetException but only declares the exceptions InstantiationException and IllegalAccessException to be thrown! The Sun utility class sun.misc.Unsafe is being used to throw a checked exception without declaring it. We could use the same approach, but unfortunately our code throws a security exception when we try to use it: java.lang.SecurityException: Unsafe. However, we can bypass this by using reflection to get hold of the unsafe variable directly, as shown below:

So, why did the JDK developers do it this way? I don't know, but I'm sure they had a good reason. Although this is a neat trick to impress your friends, I wouldn't recommend using it. This is non-standard, undocumented, Sun-specific code which could change in future releases and may not be compatible with all JVMs. It also makes code harder to understand for others and violates the POLA.

Subscribe to fahd.blog

Hi, I'm Fahd, a software developer at an investment bank in London. I am passionate about technology and work mainly with open source software, specialising in Java applications and Unix-based operating systems.

This blog is a place for me to share useful code snippets to solve problems that I have come across, and to write about ideas and experiences as a programmer.

All code on this blog has been written by me, unless stated otherwise, and you are free to use, share and adapt it for any purpose, under the terms of the GNU General Public License.

I love hearing back from my readers, so please feel free to leave comments! Thanks for reading and happy programming :-)