<html>
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hello,<br>
    <br>
    I tried to centralize logging in our docker environment by using
    logback as default logging framework. The idea is to use logback in
    our core application which compiles to a *.war file which is
    deployed in an Apache Tomcat v8.5.<br>
    <br>
    We now use Docker and I want to get a logging setup in our swarm
    like that:<br>
    <br>
    <img src="cid:part1.3999FA51.9FB80D42@simonschabel.com" alt=""
      class=""><br>
    <br>
    <br>
    Our own *.war file is already successfully logging to STDOUT with
    logback and the logstash-logback-encoder. After I deployed the war
    to Tomcat running within a Docker container I realized that more
    information coming from Tomcat is logged via STDOUT and this is not
    in JSON format. <br>
    <br>
    I also read about logback-access and how to use it in Tomcat so I
    first added logback-access to the classpath of Tomcat and added a
    logback-access.xml config file as well. In the server.xml I added
    <Valve
    className="ch.qos.logback.access.tomcat.LogbackValve"/>. The
    server.xml looks like:<br>
    <br>
    <?xml version="1.0" encoding="UTF-8"?><br>
    <Server port="8005" shutdown="SHUTDOWN"><br>
        <!--<Listener
    className="org.apache.catalina.startup.VersionLoggerListener"/>--><br>
        <Listener
    className="org.apache.catalina.core.AprLifecycleListener"
    SSLEngine="on"/><br>
        <Listener
className="org.apache.catalina.core.JreMemoryLeakPreventionListener"/><br>
        <Listener
className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener"/><br>
        <Listener
className="org.apache.catalina.core.ThreadLocalLeakPreventionListener"/><br>
        <GlobalNamingResources><br>
            <Resource name="UserDatabase" auth="Container"<br>
                      type="org.apache.catalina.UserDatabase"<br>
                      description="User database that can be updated and
    saved"<br>
                     
    factory="org.apache.catalina.users.MemoryUserDatabaseFactory"<br>
                      pathname="conf/tomcat-users.xml"/><br>
        </GlobalNamingResources><br>
        <Service name="Catalina"><br>
            <Connector port="8080" protocol="HTTP/1.1"<br>
                       connectionTimeout="20000"<br>
                       redirectPort="8443"/><br>
            <Connector port="8009" protocol="AJP/1.3"
    redirectPort="8443"/><br>
            <Engine name="Catalina" defaultHost="localhost"><br>
                <Realm
    className="org.apache.catalina.realm.LockOutRealm"><br>
                    <Realm
    className="org.apache.catalina.realm.UserDatabaseRealm"
    resourceName="UserDatabase"/><br>
                </Realm><br>
                <Host name="localhost" appBase="webapps"
    unpackWARs="true" autoDeploy="true"><br>
                    <Valve
    className="ch.qos.logback.access.tomcat.LogbackValve" /><br>
                </Host><br>
            </Engine><br>
        </Service><br>
    </Server><br>
    <br>
    Running our war like this works.<br>
    <br>
    Now I wanted to make Tomcat to use logback as default logging
    framework as well and integrated<br>
    ADD logback-core-1.2.3.jar /usr/local/tomcat/lib/<br>
    ADD logback-classic-1.2.3.jar /usr/local/tomcat/lib/<br>
    ADD logstash-logback-encoder-5.3.jar /usr/local/tomcat/lib/<br>
    ADD jackson-databind-2.9.8.jar /usr/local/tomcat/lib/<br>
    ADD jul-to-slf4j-1.7.26.jar /usr/local/tomcat/lib/<br>
    ADD slf4j-api-1.7.26.jar /usr/local/tomcat/lib/<br>
    ADD jackson-core-2.9.8.jar /usr/local/tomcat/lib/<br>
    ADD jackson-annotations-2.9.8.jar /usr/local/tomcat/lib/<br>
    <br>
    to the lib folder as well as to the classpath via setenv.sh:<br>
    <br>
    export
CLASSPATH="$CATALINA_HOME/lib/jul-to-slf4j-1.7.26.jar:$CATALINA_HOME/lib/slf4j-api-1.7.26.jar:$CATALINA_HOME/lib/logback-classic-1.2.3.jar:$CATALINA_HOME/lib/logstash-logback-encoder-5.3.jar:$CATALINA_HOME/lib/jackson-databind-2.9.8.jar:$CATALINA_HOME/lib/jackson-core-2.9.8.jar:$CATALINA_HOME/lib/jackson-annotations-2.9.8.jar:$CATALINA_HOME/lib/logback-access-1.2.3.jar:$CATALINA_HOME/lib/logback-core-1.2.3.jar:$CATALINA_HOME/conf/logback/"<br>
    <br>
    <br>
    I also added a proper logback.xml for Tomcat.<br>
    <br>
    <br>
    Unfortunately in this situation the Tomcat server process is not
    starting up correctly as the following error occurs:<br>
    <br>
    java.lang.NoClassDefFoundError: org/apache/catalina/Lifecycle<br>
            at java.lang.ClassLoader.defineClass1(Native Method)<br>
            at java.lang.ClassLoader.defineClass(ClassLoader.java:763)<br>
            at
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)<br>
            at
    java.net.URLClassLoader.defineClass(URLClassLoader.java:468)<br>
            at
    java.net.URLClassLoader.access$100(URLClassLoader.java:74)<br>
            at java.net.URLClassLoader$1.run(URLClassLoader.java:369)<br>
            at java.net.URLClassLoader$1.run(URLClassLoader.java:363)<br>
            at java.security.AccessController.doPrivileged(Native
    Method)<br>
            at
    java.net.URLClassLoader.findClass(URLClassLoader.java:362)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)<br>
            at
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:411)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)<br>
            at
org.apache.tomcat.util.digester.ObjectCreateRule.begin(ObjectCreateRule.java:116)<br>
            at
org.apache.tomcat.util.digester.Digester.startElement(Digester.java:1250)<br>
            at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)<br>
            at
com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1339)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)<br>
            at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)<br>
            at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)<br>
            at
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)<br>
            at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)<br>
            at
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)<br>
            at
    org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)<br>
            at
    org.apache.catalina.startup.Catalina.load(Catalina.java:611)<br>
            at
    org.apache.catalina.startup.Catalina.load(Catalina.java:662)<br>
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
    Method)<br>
            at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)<br>
            at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)<br>
            at java.lang.reflect.Method.invoke(Method.java:498)<br>
            at
    org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)<br>
            at
    org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)<br>
    Caused by: java.lang.ClassNotFoundException:
    org.apache.catalina.Lifecycle<br>
            at
    java.net.URLClassLoader.findClass(URLClassLoader.java:382)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)<br>
            at
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)<br>
            ... 35 common frames omitted<br>
    java.lang.NoClassDefFoundError: org/apache/catalina/Lifecycle<br>
            at java.lang.ClassLoader.defineClass1(Native Method)<br>
            at java.lang.ClassLoader.defineClass(ClassLoader.java:763)<br>
            at
    java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)<br>
            at
    java.net.URLClassLoader.defineClass(URLClassLoader.java:468)<br>
            at
    java.net.URLClassLoader.access$100(URLClassLoader.java:74)<br>
            at java.net.URLClassLoader$1.run(URLClassLoader.java:369)<br>
            at java.net.URLClassLoader$1.run(URLClassLoader.java:363)<br>
            at java.security.AccessController.doPrivileged(Native
    Method)<br>
            at
    java.net.URLClassLoader.findClass(URLClassLoader.java:362)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)<br>
            at
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:411)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)<br>
            at
org.apache.tomcat.util.digester.ObjectCreateRule.begin(ObjectCreateRule.java:116)<br>
            at
org.apache.tomcat.util.digester.Digester.startElement(Digester.java:1250)<br>
            at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.startElement(AbstractSAXParser.java:509)<br>
            at
com.sun.org.apache.xerces.internal.parsers.AbstractXMLDocumentParser.emptyElement(AbstractXMLDocumentParser.java:182)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanStartElement(XMLDocumentFragmentScannerImpl.java:1339)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2784)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:602)<br>
            at
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:505)<br>
            at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:842)<br>
            at
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:771)<br>
            at
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:141)<br>
            at
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1213)<br>
            at
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:643)<br>
            at
    org.apache.tomcat.util.digester.Digester.parse(Digester.java:1518)<br>
            at
    org.apache.catalina.startup.Catalina.load(Catalina.java:611)<br>
            at
    org.apache.catalina.startup.Catalina.load(Catalina.java:662)<br>
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native
    Method)<br>
            at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)<br>
            at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)<br>
            at java.lang.reflect.Method.invoke(Method.java:498)<br>
            at
    org.apache.catalina.startup.Bootstrap.load(Bootstrap.java:309)<br>
            at
    org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:492)<br>
    Caused by: java.lang.ClassNotFoundException:
    org.apache.catalina.Lifecycle<br>
            at
    java.net.URLClassLoader.findClass(URLClassLoader.java:382)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:424)<br>
            at
    sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)<br>
            at java.lang.ClassLoader.loadClass(ClassLoader.java:357)<br>
            ... 35 more<br>
    <br>
    <br>
    Now if I commend out the line <Valve
    className="ch.qos.logback.access.tomcat.LogbackValve" /> from the
    server.xml the startup is running fine and Tomcat logs via
    logback-classic - but logback-access is not used.<br>
    <br>
    <br>
    I found a question on stackoverflow.com where people seem to have
    the same problem but no solution is provided:<br>
    <br>
    <a
href="https://stackoverflow.com/questions/32134974/added-logback-to-tomcat-got-java-lang-classnotfoundexception-org-apache-catali"
      moz-do-not-send="true">https://stackoverflow.com/questions/32134974/added-logback-to-tomcat-got-java-lang-classnotfoundexception-org-apache-catali</a><br>
    <br>
    <img src="cid:part3.558CF584.03193807@simonschabel.com" alt=""
      class=""><br>
    <br>
    <br>
    Does anyone has a hint for me what is going wrong?<br>
    <br>
    Best<br>
    Simon
  </body>
</html>