Java log4j Appender被捕获的异常关闭

Java log4j Appender被捕获的异常关闭,java,exception,log4j,quartz-scheduler,rollingfileappender,Java,Exception,Log4j,Quartz Scheduler,Rollingfileappender,历史背景:这个问题最终与我想象的完全不同。原因和解决方案如下,但原始帖子留作参考 我正在开发一个简单的框架,用于定期轮询目录中的.properties文件,然后根据它们的配置执行SQL查询和发送电子邮件。由于每个.properties文件具有相同的操作范围,因此它们都由相同的任务类进行解释。但由于它们各自代表不同的逻辑操作,因此它们各自获得单独的日志文件 这是通过共享log4j RollingFileAppender的一个实例,并根据.properties文件中的值动态更改其输出文件来实现的。因

历史背景:这个问题最终与我想象的完全不同。原因和解决方案如下,但原始帖子留作参考

我正在开发一个简单的框架,用于定期轮询目录中的.properties文件,然后根据它们的配置执行SQL查询和发送电子邮件。由于每个.properties文件具有相同的操作范围,因此它们都由相同的任务类进行解释。但由于它们各自代表不同的逻辑操作,因此它们各自获得单独的日志文件

这是通过共享log4j RollingFileAppender的一个实例,并根据.properties文件中的值动态更改其输出文件来实现的。因为这是一个单线程应用程序,所以工作正常

但是,我注意到,在某些情况下,这个RollingFileAppender将关闭,应用程序将继续运行,只是现在没有日志记录发生。多亏了控制台输出,我只在操作中捕获了一次,因为该服务通常作为Linux服务器上的后台进程运行。发生的事情如下:

1) 主类StartScheduler每分钟创建一个TaskPoller的新实例

2) TaskPoller扫描目录,从每个.properties文件中加载一些信息,并确定是否应该运行它。它也有自己独立的RollingFileAppender,通过Logger.getLogger(TaskPoller.class)检索。如果任务应该运行,那么它将实例化一个任务对象,并传入要运行的特定.properties文件

3) 任务获取其RollingFileAppender,然后调用fileAppender.setFile(“newtaskname.log”)和fileAppender.activateOptions()来更改输出文件的位置。然后,在执行过程中,会发生如下情况:

[TaskPoller]
...
task = new Task(fileName); //Points RollingFileAppender to the right place
if (!task.Execute())
    logger.warn(fileName + " returned with an error code."); //Succeeds
[Task.Execute]
...
try {
    dbDAO.Connect();
} catch (Exception e) {
    logger.fatal{"Database connection error.", e}; //Different RFA; Fails
    return false;
}
[DBDAO.Connect throws SQLException, ClassNotFoundException]
...
try {
    Class.forName(dbDriver); //Dynamically loaded jdbc driver class name
    connection = DriverManager.getConnection(urlString, userName, password);
} catch (SQLException e) {
    if (connection != null)
        try { connection.close(); } catch (Exception e2) { ; }
    throw e;
}
发生的情况是,在DBDAO.Connect()期间,有时我会得到一个com.mysql.jdbc.exceptions.jdbc4.CommunicationsException(或者从任何加载的jdbc类中获得的其他意外异常)。Connect()将不会捕捉到这一点,但Execute()将捕捉到这一点

不知何故,此过程导致任务的RollingFileAppender关闭。我能想到的唯一一件事是,与它的一致和稳定的正常操作相反,在这种情况下,抛出的异常不是由Connect()声明为抛出的。但我不认为这会导致log4j Appender关闭

所以我的问题是,是什么原因导致这个appender在与其配置无关的方法中意外关闭

--编辑--
看起来我完全被误导了;问题出在Quartz和log4j之间的交互中,我用它让TaskPoller每分钟开火一次。我还不完全理解它的原因,但[这个解决方案][1]似乎解决了这个问题。直到现在,它才表现为一个观察到的问题,所以我认为它与最近发生的事情有关。

这个问题的真正原因是Quartz调度程序和我使用log4j的方式之间的交互。事实证明,如果在Quartz工作线程上修改log4j的属性(我通过调用fileAppender.setFile(fileName)和fileAppender.activateOptions())的话(即使Quartz被配置为一次只运行一个线程),事情就会崩溃。这是通过在使用工作线程的每个新实例之前重新加载log4j属性来解决的,我是这样完成的:

[Task() Constructor]
Properties props = new Properties();
URL url = ClassLoader.getSystemResource("log4j.properties");
try {
    props.load(url.openStream());
    PropertyConfigurator.configure(props);
} catch (Exception e) {
    //The logger that never got renamed never stopped working.
    Logger.getLogger(TaskPoller.class).error("Diagnostics!");
}
logger = Logger.getLogger(Task.class);

+1.研究和分享解决方案的意愿。我的建议是:在顶部加一个粗体的标题,说问题已经解决,解决方案在底部;其余部分保持原样,并将解决方案附加到底部。这样,我们就不会失去这个问题的历史以及它是如何演变的。事实上,你应该把这篇文章的答案部分向下移动到一个实际的答案,这样它就可以被提升,你就可以接受它了。这会出现在未答复的账单上,而且它真的不应该出现。