为什么 JBoss 5.1 中 ShutdownHook 中的 java.util.Logger 并不总是打印到 server.log?
我在 JBoss 5.1 中有一个 EJB3-Timer。 编辑: ShutdownHook 应该设置一个标志,以便 doTimeOut() 可以正常终止(否则它将完成作业,并且关闭将停止,直到该计时器完成)。
@Stateless
class Timer {
private static Thread hook;
static {
hook = new ShutdownHook();
}
@Timeout
public void doTimeOut(){
//some code
}
private class ShutdownHook implements Runnable(){
Logger.getLogger(ShutdownHook.class.getName()).log(Level.INFO, "MyBEAN.ShutdownHook execute hook " + hook); // Not always printed to log
Logger.getAnonymousLogger().log(Level.INFO, "MyBEAN.ShutdownHook execute hook " + hook); // throwns Exception
System.out.println("MyBEAN.ShutdownHook execute hook " + hook);
[...] // some code
}
}
我找到了这两篇文章,但它们来自 2005 年,并且 bug 被标记为已关闭:
http://www.pankaj-k.net/archives/2005/08/jboss_shutdown.html
http://jira.jboss.com/jira/browse/JBAS-2087
匿名记录器抛出的异常是空指针:
2011-02-02 09:16:33,120 ERROR [STDERR] Exception in thread "Thread-33"
2011-02-02 09:16:33,122 ERROR [STDERR] java.lang.NullPointerException
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.CategoryKey.<init>(CategoryKey.java:31)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:261)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:242)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.LogManager.getLogger(LogManager.java:188)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.Logger.getLogger(Logger.java:104)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.jboss.logbridge.LogBridgeHandler.publish(LogBridgeHandler.java:71)
2011-02-02 09:16:33,122 ERROR [STDERR] at java.util.logging.Logger.log(Unknown Source)
2011-02-02 09:16:33,122 ERROR [STDERR] at java.util.logging.Logger.doLog(Unknown Source)
2011-02-02 09:16:33,122 ERROR [STDERR] at java.util.logging.Logger.log(Unknown Source)
2011-02-02 09:16:33,122 ERROR [STDERR] at com.demo.MyBEAN$ShutdownHook.run(MyBEAN.java:202)
有什么想法吗?
I have a EJB3-Timer within a JBoss 5.1.
edit:
The ShutdownHook should set a flag, that the doTimeOut() can terminate graceful (otherwise it would complete the job, and the shutdown is stopped until this timer has finished).
@Stateless
class Timer {
private static Thread hook;
static {
hook = new ShutdownHook();
}
@Timeout
public void doTimeOut(){
//some code
}
private class ShutdownHook implements Runnable(){
Logger.getLogger(ShutdownHook.class.getName()).log(Level.INFO, "MyBEAN.ShutdownHook execute hook " + hook); // Not always printed to log
Logger.getAnonymousLogger().log(Level.INFO, "MyBEAN.ShutdownHook execute hook " + hook); // throwns Exception
System.out.println("MyBEAN.ShutdownHook execute hook " + hook);
[...] // some code
}
}
I've found this two posts, but they are from 2005 and the bug is marked as CLOSED:
http://www.pankaj-k.net/archives/2005/08/jboss_shutdown.html
http://jira.jboss.com/jira/browse/JBAS-2087
The Exception thrown by the anonymousLogger is a NullPointer:
2011-02-02 09:16:33,120 ERROR [STDERR] Exception in thread "Thread-33"
2011-02-02 09:16:33,122 ERROR [STDERR] java.lang.NullPointerException
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.CategoryKey.<init>(CategoryKey.java:31)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:261)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.Hierarchy.getLogger(Hierarchy.java:242)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.LogManager.getLogger(LogManager.java:188)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.apache.log4j.Logger.getLogger(Logger.java:104)
2011-02-02 09:16:33,122 ERROR [STDERR] at org.jboss.logbridge.LogBridgeHandler.publish(LogBridgeHandler.java:71)
2011-02-02 09:16:33,122 ERROR [STDERR] at java.util.logging.Logger.log(Unknown Source)
2011-02-02 09:16:33,122 ERROR [STDERR] at java.util.logging.Logger.doLog(Unknown Source)
2011-02-02 09:16:33,122 ERROR [STDERR] at java.util.logging.Logger.log(Unknown Source)
2011-02-02 09:16:33,122 ERROR [STDERR] at com.demo.MyBEAN$ShutdownHook.run(MyBEAN.java:202)
Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
由于 Log4j 已关闭,记录器可能不可用,这显然是在 JVM 关闭挂钩运行之前发生的。如果您需要在关闭时记录某些内容,我建议您连接 JBoss 机制,例如使用 @PreDestroy.
然后你的代码就变成了
The logger might not be available since Log4j has shut down, which obviously happens before the JVM shutdown hook is run. If you need to log something at shutdown, I suggest you hook into the JBoss mechanisms , for instance using @PreDestroy.
Your code then becomes
我建议您阅读 Shutdown Hooks爪哇?它们是如何使用的?
摘要:关闭钩子不能保证每次都会被执行。它们是关闭机制的一部分,您不应该真正使用它们来创建新对象,例如您的情况下的新记录器。
我建议将计时器类内部的记录器初始化为私有静态最终记录器变量(通常这样做),然后在关闭挂钩中引用该实例。
但即便如此,您也不能 100% 确定它会运行(除非 JBoss 使用一些技巧来保证这一点)。
I'd suggest you read Shutdown Hooks in Java? How are they used?
Summary: shutdown hooks aren't guaranteed to get executed everytime. They are a part of shutdown mechanism and you shouldn't really be using them to create new objects such as new loggers in your case.
I'd suggest initializing a logger inside of timer class as a
private static final Logger
variable (as it's usually done) and then refer to that instance in your shutdown hook.But even then, you won't be 100% certain that it will get run (unless JBoss is using some trickery to guarantee that).