【问题标题】:GlassFish: email log handlerGlassFish:电子邮件日志处理程序
【发布时间】:2013-09-05 22:45:27
【问题描述】:

我们需要从 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 .jar 在 domain/lib/ext 旁边的 smtphandler jar。 (我们更喜欢前一种方法,以便在整个系统中使用相同的 javamail 类。但它似乎没有任何区别,任何一种方式都不起作用。)

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

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

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

我们可以看到 SMTPTransport 类已加载并且它具有请求的 c'tor。我们最好的理论是类加载以某种方式参与其中,但我们无法确切地弄清楚如何。 (然而。我们现在正在研究这个角度。)

问题:

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

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

提前感谢您的帮助。

【问题讨论】:

    标签: java logging glassfish jakarta-mail


    【解决方案1】:

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

    •我们是否将处理程序部署到正确的位置(域/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 方法以在关闭时触发电子邮件。这在标题为 Adding a Custom Logging Handler 的 Oracle GlassFish Server 3.1 管理指南第一部分第 7 节中进行了描述。

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

    #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 差异。 CCL 在 JavaMail 中用于定位传输。修补 '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 与可以模拟 smtphandler 的行为的 MemoryHandler 结合使用。

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

    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
    

    【讨论】:

      猜你喜欢
      • 2017-12-18
      • 1970-01-01
      • 2011-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-20
      • 2019-04-21
      相关资源
      最近更新 更多