[concurrency-interest] backport: unchecked exceptions swallowed by executor service

Tim Peierls tim at peierls.net
Tue May 2 20:19:07 EDT 2006


Please note that implementations of Callable may use more restrictive throws
signatures than "throws Exception". If your Callable only throws IE and IOE,
then you can just say so:

public class MyCallable<T> implements Callable<T> {
    public T call() throws InterruptedException, IOException { ... }
}

Exceptions thrown during execution are not eaten, they are rethrown by
Future.get, wrapped in an ExecutionException.

And as Joe said, talking specifically about Tom Sugden's
FutureTask.doneissue, you can also override afterExecute to get common
exception handling
for a thread pool.

--tim


On 5/2/06, Andrew Lentvorski <bsder at allcaps.org> wrote:
>
> Tom Sugden wrote:
> > Hi,
> >
> > I was surprised by the behaviour that occurs when an unchecked exception
> is
> > raised by an overridden implementation of FutureTask#done() method. The
> > exception seems to be swallowed and the executor maintains a user thread
> for
> > some time afterwards. This isn't causing any problems for me at the
> moment,
> > but I was just wondering whether it was the intended behaviour? It could
> be
> > difficult to debug if your done() implementation had a programming error
>
> > that raised an unchecked exception.
>
> I got burnt by something similar.  The big problem is that you get into
> the habit of assuming that unchecked exceptions will always squawk when
> programming Java.  That fails when you start using concurrent.
>
> I understand *why* they needed to use Exception, but, man, the first
> time you get burnt by a NullPointerException which silently shuts down
> your Callable you pull your hair out.
>
> I now wrap all code that might let exceptions into Executor/Callables
> like so:
>
> >               public Object captiveCall() throws InterruptedException,
> IOException {
> >                       return obj;
> >               }
> >
> >               public Object call() throws Exception {
> >                       Object retval = null;
> >                       try {
> >                               retval = captiveCall();
> >                       } catch (InterruptedException e) {
> >                               l4j.debug("InterruptedException", e);
> >                               throw e;
> >                       } catch (IOException e) {
> >                               l4j.debug("IOException", e);
> >                               throw e;
> >                       } catch (Exception e) {
> >                               // This normally bad code of catch on
> Exception is here for a *reason*.
> >                               // Future *eats* all exceptions
> *silently*.  This clause at least allows
> >                               // the exception to emit noise for
> debugging.  This is particularly pernicious
> >                               // if you have something like a
> NullPointerException
> >                               l4j.debug("Exception", e);
> >                               throw e;
> >                       }
> >
> >                       return retval;
> >               }
>
> -a
> _______________________________________________
> Concurrency-interest mailing list
> Concurrency-interest at altair.cs.oswego.edu
> http://altair.cs.oswego.edu/mailman/listinfo/concurrency-interest
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: /pipermail/attachments/20060502/9339c30d/attachment-0001.html


More information about the Concurrency-interest mailing list