【问题标题】:How do I know when a Java EE app is undeployed?我如何知道 Java EE 应用程序何时取消部署?
【发布时间】:2010-07-23 07:55:29
【问题描述】:

我需要在取消部署我的 Java EE 应用程序时关闭一些流,以避免每次取消部署时 server.log 中出现异常页面。异常说:“输入流已被最终确定或强制关闭而没有明确关闭”。我知道如何关闭(使用 close() 方法),但我不知道何时关闭。

finallize() 来得太晚了,@PreDestroy 不仅在取消部署之前被调用,而且在正常操作模式下也被调用。应用程序如何知道何时取消部署?

编辑: 我在创建过程中调用它:

    decisionLogger = KnowledgeRuntimeLoggerFactory.newThreadedFileLogger(
    ksession, 
    config.getString("rules.logfilename"), 
    config.getInt("rules.loginterval"));

decisionLogger 是 KnowledgeRuntimeLogger 类型,它只有 close() 方法。在引擎盖下工作的线程没有吸气剂。轻轻关机,需要调用close方法,但是什么时候呢?

【问题讨论】:

  • 您能以某种方式连接到您正在使用的应用服务器的取消部署功能吗?我不确定应用程序是否可以知道它是否已取消部署。您还可以尝试在代码中使用流的地方吞下流所引发的异常。
  • 我使用 Glassfish 2.1。你怎么能挂接到那里的取消部署功能?吞下异常不是一种选择,因为我无法访问抛出它们的线程。它隐藏在 Drools 实现中。

标签: java deployment jakarta-ee stream


【解决方案1】:

没有一成不变的答案,因为 Java EE 包含许多具有不同生命周期的技术。

但我会在黑暗中试一试,建议你看看ServletContextListener。这将告诉您 Web 应用程序何时停止,这可能是您想要释放资源的时间 - 而不是应用程序卸载。

【讨论】:

  • 不幸的是,我在这个应用程序中没有网络模块。这只是纯粹的业务逻辑。一个 JMS 主题作为输入,一个规则引擎和一个邮件服务器作为输出。更多的理由包括良好的日志记录功能,但这正是抛出异常的地方。在取消部署期间记录器被销毁时。
【解决方案2】:

将 finalize() 方法添加到记录器或导致问题的任何类。从那里关闭流。除非您使用 System.exit() 退出,否则它将运行。如果 System.exit 被调用,你可以使用 Runtime.addShutdownHook

【讨论】:

  • 我使用 Drools 运行时的记录器。我无法更改它,也无法将其子类化,因为我也是从作为 Drools 运行时一部分的工厂获取它的。在使用它的对象的 finalize 方法中关闭它为时已晚。那时我仍然会遇到异常。
  • mckoi.com/database/maillist/msg00374.html。它获得了您可以做什么的基础知识。创建一个向 Runtime.addShutDownHook 注册的方法,当运行时停止时,它将执行。
  • 我试过了,发现它在 JEE 环境中不起作用,因为在取消部署应用程序时 JVM 没有关闭。当我取消部署时,永远不会调用 ShutdownHook。
  • 我找到了另一个可能的答案。它与 McDowell 关于 servlet 上下文侦听器 stackoverflow.com/questions/1862242/… 的说法有关。 drools 运行时仍然有一个 web.xml,您需要对其进行编辑才能向其中添加新的上下文侦听器。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-02-14
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2016-11-17
  • 2011-06-17
  • 2016-02-16
相关资源
最近更新 更多