Después de encontrar que FutureTask
ejecutándose en un Executors.newCachedThreadPool()
en Java 1.6 (y desde Eclipse) se traga excepciones en el método Runnable.run()
, he intentado encontrar una forma de detectar estos sin agregar throw/catch a todas mis implementaciones Runnable
.Cómo detectar excepciones en FutureTask
La API sugiere que anulando FutureTask.setException()
debería ayudar en esto:
Causas este futuros reportar una ExecutionException con el throwable dada como su causa, a no ser que este futuro ya se ha establecido o se ha cancelado. Este método es invocado internamente por el método de ejecución al fallar el cálculo.
Sin embargo, no parece que este método sea llamado (que se ejecuta con el depurador muestra se detecta la excepción por FutureTask
, pero no setException
se llama). He escrito el siguiente programa para reproducir mi problema:
public class RunTest {
public static void main(String[] args) {
MyFutureTask t = new MyFutureTask(new Runnable() {
@Override
public void run() {
throw new RuntimeException("Unchecked exception");
}
});
ExecutorService service = Executors.newCachedThreadPool();
service.submit(t);
}
}
public class MyFutureTask extends FutureTask<Object> {
public MyFutureTask(Runnable r) {
super(r, null);
}
@Override
protected void setException(Throwable t) {
super.setException(t);
System.out.println("Exception: " + t);
}
}
Mi pregunta principal es: ¿Cómo puedo capturar excepciones lanzadas en un FutureTask? ¿Por qué no se llama a setException
?
También me gustaría saber por qué el mecanismo Thread.UncaughtExceptionHandler
no es utilizado por FutureTask
, ¿hay alguna razón para esto?
'setException' está bien utilizado. Copié y pegué tu código y funciona. También es posible que desee probar el try-catch de 'ExecutionException' al llamar al método' get() 'en la tarea. – Kru
Forma incorrecta de usar el combo Llamado/Futuro. El método future.get() proporciona la excepción envuelta en una ExecutionException. – Bhushan