2010-07-30 19 views
13

En .net, la clase AggregateException le permite lanzar una excepción que contiene múltiples excepciones.¿Cuál es el equivalente de Java de AggregateException de .net?

Por ejemplo, le gustaría arrojar una excepción agregada si ejecutó varias tareas en paralelo y algunas de ellas fallaron con excepciones.

¿Java tiene una clase equivalente?

El caso específico quiero utilizarlo en:

public static void runMultipleThenJoin(Runnable... jobs) { 
    final List<Exception> errors = new Vector<Exception>(); 
    try { 
     //create exception-handling thread jobs for each job 
     List<Thread> threads = new ArrayList<Thread>(); 
     for (final Runnable job : jobs) 
      threads.add(new Thread(new Runnable() {public void run() { 
       try { 
        job.run(); 
       } catch (Exception ex) { 
        errors.add(ex); 
       } 
      }})); 

     //start all 
     for (Thread t : threads) 
      t.start(); 

     //join all 
     for (Thread t : threads) 
      t.join();    
    } catch (InterruptedException ex) { 
     //no way to recover from this situation 
     throw new RuntimeException(ex); 
    } 

    if (errors.size() > 0) 
     throw new AggregateException(errors); 
} 
+0

No estoy al tanto de uno. Sin embargo, nunca he buscado uno tampoco. – Powerlord

Respuesta

3

No conozco ninguna clase incorporada o de biblioteca, ya que nunca antes había querido hacer esto antes (por lo general, simplemente cadenas las excepciones), pero no sería tan difícil escribete a ti mismo

Usted probablemente querrá escoger una de las excepciones a ser "primaria" por lo que se puede utilizar para rellenar stacktraces, etc.

public class AggregateException extends Exception { 

    private final Exception[] secondaryExceptions; 

    public AggregateException(String message, Exception primary, Exception... others) { 
     super(message, primary); 
     this.secondaryExceptions = others == null ? new Exception[0] : others; 
    } 

    public Throwable[] getAllExceptions() { 

     int start = 0; 
     int size = secondaryExceptions.length; 
     final Throwable primary = getCause(); 
     if (primary != null) { 
      start = 1; 
      size++; 
     } 

     Throwable[] all = new Exception[size]; 

     if (primary != null) { 
      all[0] = primary; 
     } 

     Arrays.fill(all, start, all.length, secondaryExceptions); 
     return all; 
    } 

} 
0

Realmente no veo por qué debería utilizar excepciones en el primer lugar para marcar tareas como incompleta/no, pero en cualquier caso, shouldn No será difícil crear uno tú mismo. ¿Tienes algún código para compartir para que podamos ayudarte con una respuesta más específica?

+0

No lo estoy usando para 'marcar' nada, solo quiero indicar al menos un error. He editado la publicación principal para incluir el código. –

+0

Un ejemplo que es útil es para la validación. En lugar de lanzar una excepción sobre la primera propiedad inválida, valide toda la clase para que el consumidor pueda entender por qué la carga no es válida. Esta es una manera mucho más agradable de descubrir una API. – Brandon

1

Puede representar múltiples taska como

List<Callable<T>> tasks 

Entonces, si desea que el equipo para realmente ellos lo hacen en el uso paralelo

ExecutorService executorService = .. initialize executor Service 
List<Future<T>> results = executorService.invokeAll () ; 

Ahora se puede repetir a través de los resultados.

try 
{ 
    T val = result . get () ; 
} 
catch (InterruptedException cause) 
{ 
    // this is not the exception you are looking for 
} 
catch (ExecutionExeception cause) 
{ 
    Throwable realCause = cause . getCause () // this is the exception you are looking for 
} 

Así realCause (si existe) es cualquier excepción de lo arrojado en su tarea asociada.

+0

Es agradable ver que ya hay formas de ejecutar tareas al mismo tiempo. Sin embargo, su solución no aborda el lanzamiento de una excepción que representa fallas de tareas múltiples. –

Cuestiones relacionadas