Question

Edit: Using logback-1.0.13.jar and JDK 1.6u34.

I have a Java web app (WAR) with the following WEB-INF/classes/logback.xml:

<configuration debug="true" scan="true" scanPeriod="5 minutes">
    <appender name="logManager-smtpAppender" class="ch.qos.logback.classic.net.SMTPAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARN</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>NEUTRAL</onMismatch>
        </filter>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>

        <asynchronousSending>false</asynchronousSending>

        <sessionViaJNDI>true</sessionViaJNDI>
        <jndiLocation>java:comp/env/mail/Session-local</jndiLocation>

        <subject>%logger{20} - %m</subject>
        <layout class="ch.qos.logback.classic.html.HTMLLayout"/>
        <cyclicBufferTracker class="ch.qos.logback.core.spi.CyclicBufferTracker">
            <bufferSize>25</bufferSize>
        </cyclicBufferTracker>
    </appender>

    <root level="ALL">
        <appender-ref ref="logManager-consoleAppender" />
        <appender-ref ref="logManager-dbAppender" />
        <appender-ref ref="logManager-smtpAppender" />
    </root>
</configuration>

And the following ${TOMCAT_HOME}/conf/context.xml (global context.xml for all web apps):

<Context>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>

    <Resource
        name="mail/Session-local"
        auth="Container"
        type="javax.mail.Session"
        mail.smtp.host="my.smtp.server"
        mail.user="smtp_user"
        mail.password="smtp_password"
        mail.transport.protocol="smtp"
        mail.smtp.auth="true"
        mail.smtp.port="25"
        mail.smtp.starttls.enable="true"
    />
</Context>

And have the Java Mail API 1.4.3 (which I have verified contains a javax.mail.Authenticator class) on my runtime classpath at WEB-INF/lib/javax-mail-1.4.3.jar).

And am getting the following stack trace:

21:42:58,291 |-INFO in ch.qos.logback.core.joran.action.AppenderAction - Naming appender as [logManager-smtpAppender]
21:42:58,311 |-INFO in ch.qos.logback.classic.net.SMTPAppender[logManager-smtpAppender] - Looking up javax.mail.Session at JNDI location [java:comp/env/mail/Session-local]
Failed to instantiate [ch.qos.logback.classic.LoggerContext]
Reported exception:
java.lang.NoClassDefFoundError: javax/mail/Authenticator
    at org.apache.naming.factory.MailSessionFactory.getObjectInstance(MailSessionFactory.java:105)
    at org.apache.naming.factory.ResourceFactory.getObjectInstance(ResourceFactory.java:140)
    at javax.naming.spi.NamingManager.getObjectInstance(NamingManager.java:304)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:793)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:140)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:781)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:140)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:781)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:140)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:781)
    at org.apache.naming.NamingContext.lookup(NamingContext.java:153)
    at org.apache.naming.SelectorContext.lookup(SelectorContext.java:152)
    at javax.naming.InitialContext.lookup(InitialContext.java:392)
    at ch.qos.logback.core.net.SMTPAppenderBase.lookupSessionInJNDI(SMTPAppenderBase.java:153)
    at ch.qos.logback.core.net.SMTPAppenderBase.start(SMTPAppenderBase.java:123)
    at ch.qos.logback.classic.net.SMTPAppender.start(SMTPAppender.java:64)
    at ch.qos.logback.core.joran.action.AppenderAction.end(AppenderAction.java:96)
    at ch.qos.logback.core.joran.spi.Interpreter.callEndAction(Interpreter.java:317)
    at ch.qos.logback.core.joran.spi.Interpreter.endElement(Interpreter.java:196)
    at ch.qos.logback.core.joran.spi.Interpreter.endElement(Interpreter.java:182)
    at ch.qos.logback.core.joran.spi.EventPlayer.play(EventPlayer.java:62)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:149)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:135)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:99)
    at ch.qos.logback.core.joran.GenericConfigurator.doConfigure(GenericConfigurator.java:49)
    at ch.qos.logback.classic.util.ContextInitializer.configureByResource(ContextInitializer.java:75)
    at ch.qos.logback.classic.util.ContextInitializer.autoConfig(ContextInitializer.java:148)
    at org.slf4j.impl.StaticLoggerBinder.init(StaticLoggerBinder.java:85)
    at org.slf4j.impl.StaticLoggerBinder.<clinit>(StaticLoggerBinder.java:55)
    at org.slf4j.LoggerFactory.bind(LoggerFactory.java:128)
    at org.slf4j.LoggerFactory.performInitialization(LoggerFactory.java:107)
    at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:295)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:269)
    at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:281)
    at com.myappapp.server.DummyServlet.<init>(Unknown Source)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
    at java.lang.Class.newInstance0(Class.java:355)
    at java.lang.Class.newInstance(Class.java:308)
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1116)
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:809)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:129)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:298)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:859)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:588)
    at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489)
    at java.lang.Thread.run(Thread.java:662)
Caused by: java.lang.ClassNotFoundException: javax.mail.Authenticator
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
... 53 more

Any ideas as to why I'm getting the ClassNotFoundException on javax.mail.Authenticator? Do I have the wrong version of Javax Mail on the runtime classpath (perhaps URLClassLoader is using a constructor that isn't defined, etc.)? Is something not configured correctly? Is this a bug? Thanks in advance!

Was it helpful?

Solution

Since you are configuring a container-managed resource (the mail session), put the mail JAR in tomcat's lib folder and not in your app's WEB-INF/lib.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top