可以使用 Java 程序的退出代码来检测磁盘空间不足的异常吗?
Posted
技术标签:
【中文标题】可以使用 Java 程序的退出代码来检测磁盘空间不足的异常吗?【英文标题】:Can one use the exit code of a Java program to detect out of disk space exceptions? 【发布时间】:2015-10-01 07:58:12 【问题描述】:我的 Java 程序是从 Windows 脚本调用的。
是否可以在 Java 程序仍在从 JAR 文件加载类文件时使用 Java 退出代码来确定 Java 程序是否由于磁盘空间不足而提前终止?
我尝试了内存不足异常,它返回退出代码 1,但磁盘空间不足返回退出代码 0。这是正确的行为吗?
子类方法:
public int executeBatch()
logger.info("executeBatch() - Send Email Alert Start");
try
alertTransactionMgr.sendEmailAlert();
catch (Exception e)
throw new Exception(e);
logger.info("executeBatch() - Send Email Alert End");
return 0;
父方法:
public int execute()
this.trx = createTransaction();
try
returnCode = executeBatch();
catch (Exception e)
printLogErrorMsg("Job Failed caused by the Exception.", e);
returnCode = -1;
trx.setStatus("Failure");
updateBatchTransaction(trx);
return returnCode;
Windows 批处理脚本
@echo off
set ERRLVL=0
java -cp %CLASSPATH% com.test.runner.MainBatchRunner
if not (%ERRORLEVEL%)==() (
set ERRLVL=%ERRORLEVEL%
)
echo Delete Files that are more than 30 old
forfiles /p "%BATCH_LOG_DIR%" /s /m %2*.log /d -%ARCHIVE_DAYS% /c "cmd /c echo del %BATCH_LOG_DIR%\@file"
forfiles /p "%BATCH_LOG_DIR%" /s /m %2*.log /d -%ARCHIVE_DAYS% /c "cmd /c del %BATCH_LOG_DIR%\@file"
echo Program exit %ERRLVL%
echo Program exit %ERRLVL% >> %BATCH_LOG_FILE%
exit /B %ERRLVL%
OutOfMemory 的输出: [信息][2015-06-29 18:05:01,960][org.springframework.context.support.ClassPathXmlApplicationContext] - 刷新 org.springframework.context.support.ClassPathXmlApplicationContext@4b222f:显示名称 [org.springframework.context.support .ClassPathXmlApplicationContext@4b222f];启动日期 [Mon Jun 29 18:05:01 SGT 2015];上下文层次的根 [INFO][2015-06-29 18:05:02,050][org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - 从文件 [D:\batch\dev\batch_home\bin\spring\applicationContext 加载 XML bean 定义-test.xml]
删除超过 30 个旧文件
del D:\batch\dev\batch_home\log\"TEST_20150629_173016.log" 程序出口 1
磁盘空间不足的输出: [信息][2015-06-29 19:05:01,960][org.springframework.context.support.ClassPathXmlApplicationContext] - 刷新 org.springframework.context.support.ClassPathXmlApplicationContext@4b222f:显示名称 [org.springframework.context.support .ClassPathXmlApplicationContext@4b222f];启动日期 [Mon Jun 29 19:05:01 SGT 2015];上下文层次的根 [INFO][2015-06-29 19:05:02,050][org.springframework.beans.factory.xml.XmlBeanDefinitionReader] - 从文件 [D:\batch\dev\batch_home\bin\spring\applicationContext 加载 XML bean 定义-test.xml]
删除超过 30 个旧文件
del D:\batch\dev\batch_home\log\"TEST1_20150629_180030.log" 程序出口0
【问题讨论】:
请显示问题的代码和输出;如果程序根本无法加载,则退出代码 0 是高度可疑的。另外值得注意的是,任何从主线程重新抛出的异常都会导致 JVM 以 1 退出,因此这并不是真正有意义的退出代码。 我同意@fge。OutOfMemoryException
应该返回一个非零退出代码。
OutOfMemory
与工作内存无关,而不是磁盘空间?
嗨...我遇到的错误是日志文件假脱机的磁盘空间不足。所以我可以说程序确实执行了,但是由于磁盘空间不足,它失败了,程序以 0 退出
从批处理/命令行运行程序获得的“ERRORLEVEL”由进程退出代码决定 - 通过 System.exit() 设置,请参阅:***.com/questions/2441036/return-type-of-main-in-java。您应该捕获您关心的任何异常并调用 System.exit(n) 其中“n”是批处理脚本可以通过 %ERRORLEVEL% 检查的数字
【参考方案1】:
您的批处理文件已损坏。 ERRORLEVEL 永远不会为空,它总是有一个数字,除非你做了一些愚蠢的事情,比如将它设置为一个字符串。
@echo off
set ERRLVL=0
java -cp %CLASSPATH% com.test.runner.MainBatchRunner
@rem if not (%ERRORLEVEL%)==() (
@rem set ERRLVL=%ERRORLEVEL%
@rem)
if %ERRORLEVEL% != 0 set ERRLVL=%ERRORLEVEL%
echo Delete Files that are more than 30 old
forfiles /p "%BATCH_LOG_DIR%" /s /m %2*.log /d -%ARCHIVE_DAYS% /c "cmd /c echo del %BATCH_LOG_DIR%\@file"
forfiles /p "%BATCH_LOG_DIR%" /s /m %2*.log /d -%ARCHIVE_DAYS% /c "cmd /c del %BATCH_LOG_DIR%\@file"
echo Program exit %ERRLVL%
echo Program exit %ERRLVL% >> %BATCH_LOG_FILE%
exit /B %ERRLVL%
【讨论】:
【参考方案2】:我想知道为什么您的 java 应用程序会因为磁盘空间已满而中断。您提到JVM的启动,或多或少是关于将文件读入RAM。如果计算机已经大量交换,这里涉及的唯一磁盘空间可能是虚拟内存 - 这将导致 OutOfMemoryException,但不会导致磁盘空间问题。
一旦您的应用程序被加载,它就可以检查文件系统根目录并决定剩余的磁盘空间。如果还不够,它可以使用 system.exit(int) 终止,并为操作系统或批处理文件提供您选择的有意义的退出代码。
0 表示应用程序运行正常 1-127 表示您定义的任何内容 128- 通常是操作系统错误,例如“找不到可执行文件”或“权限被拒绝”...
【讨论】:
以上是关于可以使用 Java 程序的退出代码来检测磁盘空间不足的异常吗?的主要内容,如果未能解决你的问题,请参考以下文章