我在开发Spring Batch作业时遇到了OutOfMemoryError。
调试此类错误的最常见方法是要求JVM在发生堆转储时生成它。这里的问题是Spring Batch正在捕获所有Throwable,因此它们可以在作业执行后通过jobExecution.getAllFailureExceptions()
使用。因此,由于JVM仍在运行,因此不会生成堆转储。
是期望的行为,还是AbstractJob
类(在Spring Batch中)应该仅捕获Exception
而不是Throwable
吗?
目前我的解决方案是执行以下操作:
@Override
public void afterJob(JobExecution jobExecution) {
[...]
Error error = (Error) jobExecution.getAllFailureExceptions().stream().filter(t -> t instanceof Error).findFirst().orElse(null);
if(error != null)
throw error;
}
我可以接受它,但是我还是不太喜欢它,因为这意味着我的应用程序在抛出OOME之后不久仍在运行,并且可能在其他线程中引起一些不良行为。 另外,如果您在开始生产和解决问题之前没有遇到问题,则可以使用在从某种错误“恢复”后仍可运行的应用程序,我认为这不是任何人想要的。
来自AbstractJob
类:
@Override
public final void execute(JobExecution execution) {
[...]
try {
[...]
} catch (Throwable t) {
logger.error("Encountered fatal error executing job", t);
execution.setExitStatus(getDefaultExitStatusForFailure(t, execution));
execution.setStatus(BatchStatus.FAILED);
execution.addFailureException(t);
}
我应该创建拉取请求吗?我猜这不是一个小小的改变...
编辑:根据要求创建一个Jira:https://jira.spring.io/browse/BATCH-2800