GlassFish:电子邮件日志处理程序

时间:2013-09-05 22:45:28

标签: java logging glassfish javamail

我们需要从GlassFish v3.1.2.2中的日志处理程序发送邮件。

我们尝试使用smtphandler-0.6和-0.7但成效有限。我们将jarfile安装到domain / lib / ext,并在domain / config / logging.properties中配置smtphandler的属性。我们尝试了两种方法来满足smtphandler对邮件导入的依赖:1)编辑其清单类路径以指向../../../../modules/javax.mail.jar,以及2)放置javax.mail域名/ lib / ext中的.jar和smtphandler jar一起。 (我们更喜欢前一种方法,以便在整个系统中使用相同的javamail类。但它似乎没有任何区别,也没有任何方法。)

使用这些安排中的任何一种行为都是相同的:

  • 处理程序加载正常,如JVM的verbose:class输出所示。
  • 有时会发送邮件以查找域启动期间发生的错误和警告(如过期的证书)。其他时候在发送邮件之前它如下所述失败。
  • 一旦我们部署了应用程序并记录了一些应用程序错误,它总是会失败。我们可以告诉处理程序被调用 - 这可以通过调试器和一些原始的System.out“logging”来证明。

根问题是NoSuchMethodException:com.sun.mail.smtp.SMTPTransport。[init](Session,URLName)。未能找到c'tor意味着无法创建传输对象;最终表现为NoSuchProtocolException。

我们可以看到SMTPTransport类已加载并且它具有请求的c'tor。我们最好的理论是类加载在某种程度上涉及,但我们无法弄清楚具体如何。 (然而。我们现在正在努力工作。)

问题:

  • 我们是否将处理程序部署到正确的位置(domain / lib / ext)?
  • 为什么(有时)在(空的,没有应用程序)域启动期间发送邮件,但是我们的应用程序发出的日志失败了?当然,这是一种竞争条件,但是这些线程偶尔会有什么作用然后可靠地失败呢?
  • 我们是否认为所有这些迹象共同意味着课堂加载问题?

我们在GlassFish版本3.1.2.2和4上使用JavaMail 1.4.4和1.5重现了这些症状。

提前感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

看起来已为此NoSuchMethodException when attempting to install log handler in GlassFish server报告了错误。这个问题是由Bug K6668 | GH144 - skip unusable Store and Transport classes fixed in JavaMail 1.5.3下的JavaMail团队提出的。升级glassfish中的JavaMail模块以及部署的所有其他副本应该可以解决问题。使用“glassfish / bin / asadmin start-domain -v”启动glassfish也很有帮助,这样你就可以看到所有引导消息。

  

•我们是否将处理程序部署到正确的位置(domain / lib / ext)

是。您可以部署到domain / lib / ext,但必须包含JavaMail 1.5.3,以便找到正确的传输服务。否则,您可以将jar部署到模块目录并添加HK2 metadata以使smtphandler看起来像服务。这可以通过包含新jar或修改现有的smtphandler jar来完成。

对于GlassFish 3,必须添加包含以下内容的文件META-INF/inhabitants/default

class=smtphandler.SMTPHandler,index=java.util.logging.Handler

对于GlassFish 4,必须添加包含以下内容的文件META-INF/hk2-locator/default

[smtphandler.SMTPHandler]
contract={java.util.logging.Handler}
scope=javax.inject.Singleton

然后必须将jar放在glassfish/modules文件夹中,同时升级javax.mail.jar。

另一个选择是将smtphandler子类化为HK2日志处理程序服务,并添加preDestroy方法以在关闭时触发电子邮件。 Oracle GlassFish Server 3.1管理指南第I部分第7节标题为Adding a Custom Logging Handler

中对此进行了描述

在GlassFish 4下,two different ways可以在logging.properties中找到处理程序。放置在domain/lib/ext中的处理程序使用属性文件中的标准handlers键。使用属性文件中的glassfish/modules键加载作为HK2服务放置在handlerServices中的处理程序。

#GF3 ext/endorsed or OSGI.  GF4 ext/endorsed only.
handlers=smtphandler.SMTPHandler

#GF4 OSGI only, 'handlerServices' should not contain any whitespace characters between handlers.
handlerServices=com.sun.enterprise.server.logging.GFFileHandler,smtphandler.SMTPHandler
  

•为什么(有时)在(空的,没有应用程序)域启动期间发送邮件,但是我们的应用程序发出的日志失败了?当然,这是一种竞争条件,但是这些线程做什么偶尔会有效,然后可靠地失败?

GF记录的消息与您的网络应用之间的context class loader差异。在JavaMail中使用CCL来定位传输。修补'sendBuffer'方法应修复行为:

@Override
protected void sendBuffer() {
    final Thread thread = Thread.currentThread();
    ClassLoader ccl = null;
    try {
        ccl = thread.getContextClassLoader();
        thread.setContextClassLoader(
                javax.mail.Transport.class.getClassLoader());
    } catch (SecurityException ignore) {
    }
    try {
        super.sendBuffer();
    } finally {
        try {
            thread.getContextClassLoader();
            thread.setContextClassLoader(ccl);
        } catch (SecurityException ignore) {
        }
    }
}
  

•我们是否认为所有这些迹象共同意味着课堂加载问题?

是。真正使这项工作正确的唯一方法是将smtphandler子类化或修补为看起来像HK2组件并修改CCL。

  

我们需要从GlassFish v3.1.2.2中的日志处理程序发送邮件。   我们尝试使用smtphandler-0.6和-0.7但成效有限。

免责声明:我是JavaMail项目中包含的MailHandler的内容开发人员。

smtphandler的替代方法是JavaMail参考实现中包含的com.sun.mail.util.logging.MailHandler

在GlassFish 4下,您必须glassfish/modules/javax.mail.jar JavaMail 1.5.3 or newer。可以从JavaMail API homepage下载更新版本,可用于替换GlassFish捆绑的版本。

接下来,您必须修改域的logging.properties。以下是您可以包含的示例配置,以帮助您入门。

#Ensure no whitespace between handler class names.
handlerServices=com.sun.enterprise.server.logging.GFFileHandler,com.sun.mail.util.logging.MailHandler    
com.sun.mail.util.logging.MailHandler.subject=com.sun.mail.util.logging.CollectorFormatter
#com.sun.mail.util.logging.CollectorFormatter.format=GlassFish 4.x:{0}{1}{2}{4,choice,-1#|0#|0<... {4,number,integer} more}
#com.sun.mail.util.logging.CompactFormatter.format=[%4$-7.7s] %7$#.140s
com.sun.mail.util.logging.MailHandler.level=WARNING
com.sun.mail.util.logging.MailHandler.filter=com.sun.mail.util.logging.DurationFilter
com.sun.mail.util.logging.MailHandler.pushLevel=WARNING
com.sun.mail.util.logging.MailHandler.mail.smtp.host=some-smtp-host
#com.sun.mail.util.logging.MailHandler.mail.user=some-user
#com.sun.mail.util.logging.MailHandler.authenticator=some-password
com.sun.mail.util.logging.MailHandler.mail.from=app@server.com
#com.sun.mail.util.logging.MailHandler.mail.sender=team@list.com
com.sun.mail.util.logging.MailHandler.mail.to=devs@bugfixers.com
com.sun.mail.util.logging.MailHandler.verify=resolve
com.sun.mail.util.logging.MailHandler.mail.smtp.quitwait=false
com.sun.mail.util.logging.MailHandler.mail.smtps.quitwait=false
com.sun.mail.util.logging.MailHandler.mail.smtp.connectiontimeout=45000
com.sun.mail.util.logging.MailHandler.mail.smtps.connectiontimeout=45000
com.sun.mail.util.logging.MailHandler.mail.smtp.timeout=45000
com.sun.mail.util.logging.MailHandler.mail.smtps.timeout=45000

对于GlassFish 3,您必须在domain/lib/extglassfish/lib/endorsed下安装JavaMail(javax.mail.jar),并测试这不会破坏您的任何应用程序。此类加载器配置也可在GlassFish 4下运行,并允许将MailHandler与MemoryHandler组合,后者可以模拟smtphandler的行为。

接下来,您必须修改域的logging.properties。除了必须使用标准handlers标记而不是handlerServices之外,您可以使用与GlassFish 4相同的示例。

handlers=java.util.logging.MemoryHandler
java.util.logging.MemoryHandler.target=com.sun.mail.util.logging.MailHandler
java.util.logging.MemoryHandler.size=512
java.util.logging.MemoryHandler.level=INFO
java.util.logging.MemoryHandler.push=WARNING
com.sun.mail.util.logging.MailHandler.capacity=512
com.sun.mail.util.logging.MailHandler.level=INFO
com.sun.mail.util.logging.MailHandler.pushLevel=WARNING
com.sun.mail.util.logging.MailHandler.filter=com.sun.mail.util.logging.DurationFilter
com.sun.mail.util.logging.DurationFilter.records=512
com.sun.mail.util.logging.DurationFilter.duration=5*60*1000