可以使用 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 程序的退出代码来检测磁盘空间不足的异常吗?的主要内容,如果未能解决你的问题,请参考以下文章

有没有办法用 java 或其他语言检索可用的磁盘空间? [复制]

vas代码

是否可以检测应用程序的退出?

为啥我们在 Java 中有退出代码?

java 如何获得磁盘名称

[磁盘空间]lsof处理文件恢复句柄以及空间释放问题