【问题标题】:Any alternative to System.exit(STATUS_CODE) or best practice around returning an error code from JavaSystem.exit(STATUS_CODE) 的任何替代方法或从 Java 返回错误代码的最佳实践
【发布时间】:2014-02-26 16:58:16
【问题描述】:

我们有一个通过 Shell 脚本实用程序触发的 Java 作业。这计划定期运行。

现在,shell 脚本需要一个退出代码,以防作业失败,以便触发其他警报点。因此,我们的主类中有 System.exit(STATUS_CODE),当发生任何异常时,它会在 catch 块中调用。主要方法如下所示。我们正在使用 Spring。我们还在 Logger 中配置了 smtp,以便所有 ERROR 级别的日志都通过电子邮件发送。现在,我们注意到 System.exit 在退出 JVM 时突然停止了记录器和其他线程。因此,我们添加了一个 Thread.sleep(10000) 以在调用 System.exit 之前完成任何日志记录。

这是从 java 向脚本发送 ERROR 状态代码的最佳方式吗?我们可以在不使用 System.exit 调用的情况下发送状态吗?需要 System.exit 时有什么最佳实践或建议(shudownhook…)? Spring 中的任何替代方法可以在 DI 容器退出时发送错误代码?

   private static Logger LOG = LoggerFactory.getLogger(Application.class);
   public static void main(final String[] args) throws InterruptedException {
          LOG.info("Starting Timeout Service...");
          try {
                 final AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
                 final SomeBean somebean = ctx.getBean(SomeBean.class);
                 somebean.doSomething();
          } catch (final Exception exception) {
                 LOG.error(exception.getMessage(), exception);
                 waitForLogToProcessAndExit();
          }
          LOG.info("Timeout Service Completed");

   }

   private static void waitForLogToProcessAndExit() throws InterruptedException {
          Thread.sleep(10000); //Waiting for any logging to complete before firing System.exit
          System.exit(1);
   }

【问题讨论】:

  • 我猜你可以使用 finally 块
  • 对不起。为什么不通过 CommandLineJobRunner.class 进行春季批处理。它已经实现了带有退出代码的命令执行器。

标签: java spring


【解决方案1】:

您为什么不在调用System.exit 之前简单地完成所有报告/错误处理? 据我所知,除了使用 System.exit() 之外,没有其他方法可以强制 JVM 返回除 0 以外的退出代码(正如@fge 指出的那样,我错了,因为异常会返回 1) AS logger probalby 使用单独的线程来发送电子邮件,您将不得不等待它实际发送,或者实现电子邮件服务,该服务将从某种队列中获取要发送的消息并在您的进程旁边运行它(想想这个是最好的选择,因为它可以用于您将来需要此类解决方案的每个组件。

【讨论】:

  • 是的,有:main() 抛出的异常将使 JVM 退出 1
【解决方案2】:

(旁注:你可以使用TimeUnit.SECONDS.sleep(10)代替Thread.sleep(10000)

这里的“bug”可能是记录器使用了守护线程;当 JVM 退出时,它将等待此类线程完成。直接的结果是,如果线程在System.exit() 之前未能发送您的邮件,则您没有邮件。

解决方法:

  • 通过一些谷歌搜索,我看到至少使用 log4j,如果您有对您的附加程序的引用,.close() 在您退出之前:它将确保队列中的所有消息都被刷新;或者您可以先配置您的附加程序不使用守护线程?
  • 只需使用普通的cron 和适当的MAILTO 并登录到stdout:cron 默认情况下会将stdout 和stderr 的内容邮寄到给定的邮件地址。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多