如何使用命令行检查Java类的异常终止

Posted

技术标签:

【中文标题】如何使用命令行检查Java类的异常终止【英文标题】:how to use command line to check abnormal termination of Java Class 【发布时间】:2015-01-25 06:30:13 【问题描述】:

我有一个带有 main 函数的简单 Java 类。我使用 bat 文件中存在的命令行“command”运行这个类,我已安排 bat 文件每 2 小时运行一次。

这个 .class 使用了一些资源,这些资源在请求时有时不可用,并且由于超时,.class 异常终止。

我想要的是,如果 bat 异常终止,是否有办法检查它并再次运行它,直到它正常运行。

其次如果bat异常终止,有没有办法回滚这个.class在终止前执行的操作。可以说它正在更新文本文件中的一些文本。有没有办法回滚。

【问题讨论】:

您应该将所有复杂的逻辑和回滚移到 .class 中,因为 java 比批处理命令更强大。 Batch 无法撤消它自己没有完成的事情。 你能定义“异常终止”吗?您不能在代码中处理超时并重试吗? 【参考方案1】:

异常终止的原因很多。

您可以在这里采用一种启发式方法:

异常到达主线程并且未被捕获会导致 JVM 以退出代码 1 终止; 除上述异常外,包括OutOfMemoryError等异常;理解上面语句中的“异常”是“Throwable的任何实例”; ErrorThrowable 的子类,OutOfMemoryErrorError 的子类; 如果您希望程序因其他异常情况而终止,请使用System.exit() 并确保错误代码不是 1

其次如果bat异常终止,有没有办法回滚这个.class在终止前执行的操作。可以说它正在更新文本文件中的一些文本。有没有办法回滚。

没有通用的方法;这实际上取决于您的程序本身。如果您谈论的是文件 I/O,至少就编程语言本身而言,存在几种范式来确保文件的原始内容不会损坏;更严重的损坏情况委托给文件系统本身。


关于退出代码的旁注... 至少对于 Unix 系统,您应该警惕实际上“有效”退出代码的范围是 0 到 127;是的,那是 7 位。第 8 位用于表示进程终止是由信号引起的,在这种情况下,低 7 位将被解释(理解为“读取”)为触发程序终止的信号编号。

【讨论】:

【参考方案2】:

如果您想让 .bat 持续运行直到它在崩溃后正常运行,您可以通过创建 Windows 服务来实现。创建 Windows 服务时,您可以指定崩溃后发生的情况、再次运行脚本之前要等待多长时间以及应该尝试再次运行脚本的次数。

至于将脚本所做的恢复到文本文件,有多种解决方案:

    让您的脚本复制文件,您可以将其重命名为 original_new,然后操作新副本。在脚本结束时,您可以通过将 original_new 更改为 original 来删除原始文件并将其替换为副本。如果程序崩溃,您将有两个文件,因此在脚本的开头,检查 original_new 是否已经存在,如果存在,请将其删除然后复制原始文件。

    您可以记录脚本所做的一切,并在脚本启动时检查日志,如果日志不完整,则脚本首先恢复任何日志,直到达到最后一个完整标志然后运行脚本的实际含义。

【讨论】:

【参考方案3】:

听起来 bat 失败是因为 java 类作业失败。如果可以在批处理文件中检测到 java 作业失败,您应该可以从那里做任何您想做的事情。

首先,要确认 java 作业引发批处理识别的错误,在运行 java 类作业的行之后添加以下内容并对其进行测试。您应该会看到错误级别 0 表示成功,>0 表示错误:

REM THIS IS LINE THAT RUNS JAVA JOB
echo errorlevel is "%errorlevel%
pause

假设以上返回准确的退出信息,这里有一些实现其他答案并重新运行 java 作业的代码。

要不断重试 java 作业直到成功运行,请添加标签和 goto 语句:

REM Add following label to a line before the java class job
:runhere    

    REM THIS IS LINE THAT RUNS JAVA JOB

    rem Check errorlevel and retry if failure
            If not %errorlevel%==0 goto runhere
            Exit

要重试作业 n 次然后退出,即使尚未成功,请按照 @niebloomj 的建议创建备份文件并设置一个计数器。这会尝试运行作业 10 次。

set COPYCMD=/Y
set Outputfile=path\file.ext
set Outputbak=path\file_bak.ext
copy "%Outputfile%" "%Outputbak%"

Set /a count=0
:runhere    

    REM THIS IS LINE THAT RUNS JAVA JOB

          If %errorlevel%==0 (
              :: now have new good output file
              del "%Outputbak%"
              exit
        )
        rem Check count and retry
          If %count% LSS 10 (
             set /a count+=1
             goto runhere
        )
        rem When count = the "check" number above, replace old file and quit
            copy "%Outputbak%" "%Outputfile%"
            del "%Outputbak%"
            echo Java job failed after retries. "%Outputfile%" not updated.
            pause

    Exit

【讨论】:

以上是关于如何使用命令行检查Java类的异常终止的主要内容,如果未能解决你的问题,请参考以下文章

并发编程--锁--如何使用命令行和代码定位死锁

如何使用命令行cmd执行java程序

如何从命令行检查 TypeScript 代码中的语法错误?

Java:抛出异常后如何终止执行后面的代码?

Java:抛出异常后如何终止执行后面的代码?

调用加入时如何修复“终止调用而没有活动异常”