Ero solito pensare che non lo fosse, ma ieri dovevo farlo. Si tratta di un'applicazione che utilizza Akka (un'implementazione del sistema di attori per la JVM) per elaborare lavori asincroni. Uno degli attori esegue alcune manipolazioni di PDF e, poiché la libreria è bacata, muore con StackOverflowError
di tanto in tanto.
Il secondo aspetto è che Akka è configurato per arrestare l'intero sistema degli attori se viene rilevato un errore fatale JVM (ad esempio StackOverflowError).
Il terzo aspetto è che questo sistema di attori è incorporato in un'app Web (per motivi WTF, legacy, motivi), quindi quando il sistema dell'attore viene chiuso, l'app web non lo è. L'effetto netto è che su una StackOverflowError
la nostra applicazione di elaborazione dei lavori diventa solo un'app web vuota.
Come soluzione rapida ho dovuto rilevare il lancio di StackOverflowError
, in modo che il pool di thread del sistema degli attori non venisse eliminato. Questo mi ha portato a pensare che forse a volte va bene catturare tali errori, specialmente in contesti come questo? Quando c'è un pool di thread che elabora attività arbitrarie? A differenza di OutOfMemoryError
non riesco a immaginare come un StackOverflowError
possa lasciare un'applicazione in uno stato incoerente. Lo stack viene cancellato dopo un tale errore, quindi il calcolo può continuare normalmente. Ma forse mi manca qualcosa di importante.
Inoltre, si noti che sono tutto per correggere l'errore in primo luogo (in effetti ho già risolto un SOE in questa stessa app qualche giorno fa), ma in realtà non lo faccio sapere quando potrebbe verificarsi questo tipo di situazione.
Perché sarebbe meglio riavviare il processo JVM invece di prendere il StackOverflowError
, contrassegnarlo come fallito e continuare con la mia attività?
C'è qualche ragione convincente per non catturare mai gli SOE? Tranne "best practice", che è un termine vago che non mi dice nulla.