javatomcat7tomcat6displaytag

Displaytag + Tomcat -> silent failure


I'm trying to rehabilitate project which is approx 10 years old.

It is a java webapp which used to run well in Tomcat 6. There is a small cluster of modules which were variously built with Ant and Maven, using Java 5 and Java 6.

I've now got them all building correctly with Maven, using Java 6, deploying to Tomcat 7, trying to aim for the same version of dependencies - just to get it running, before attempting upgrades.

Some of the JSP pages use DisplayTag 1.2. If my Maven build includes the displaytag dependencies then the webapp doesn't run. There's no errors in the logs. It just reports a 404 for everywhere. If I exclude displaytag from the Maven build, everything works fine, except the JSP pages needing DisplayTag.

If I try to run the webapp in Tomcat 6, I get exception to do with incompatibilities between commons-logging and slf4j.

If a webapp silently fails like this, with no errors or exceptions in the logs, what should I suspect or investigate?


UPDATE

Based on Kayaman's answer, here is what I did:

  1. Any place in any pom.xml which had a dependency on commons-logging, add the following:

        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    
  2. Where there is an explicit dependency on commons-logging, mark it as provided:

    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
        <version>1.1.1</version>
        <scope>provided</scope>
    </dependency>
    
  3. When booting up the webapp now, this is what I saw in catalina.out:

    org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/webapp]]
    Caused by: java.lang.NoClassDefFoundError: Lorg/apache/commons/logging/Log;
            ... 10 more
    Caused by: java.lang.ClassNotFoundException: org.apache.commons.logging.Log
            ... 24 more
    
  4. Next I added to the top-level webapp pom.xml the SLF4J "re-router" for commons-logging:

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.6.4</version>
    </dependency>
    
  5. Also made sure that the SLF4J was wired up with Log4j, at the correct version (Log4J was the existing logging framework for this webapp, 10 years ago):

        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.16</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.6.4</version>
        </dependency>
    
  6. Now when booting the webapp, this allowed JSP errors and Exceptions to be seen in catalina.out, which I was able to debug successfully!


Solution

  • So including the displaytag dependency causes the jsp compilation to fail for all jsps, resulting effectively in the webapp not having any views, hence the 404s. At least a very plausible sequence of events.

    According to this any JSP compilation exceptions can be seen in tomcat's localhost_log.xxx file. However, the same thread goes on to complain that there's no info or not enough info, which probably means your logging config is borked.

    For that you probably need to set up your logging bridge.

    Since you're using slf4j, but other components are using commons-logging, you're losing the log information from the other components. For that you include commons-logging, but as provided, so it won't be pulled in by other libraries.

    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.1.1</version>
      <scope>provided</scope>
    </dependency>
    

    And then you include the jcl-over-slf4j (which is what provides commons-logging as we promised above).

    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>jcl-over-slf4j</artifactId>
      <version>2.0.0-alpha2-SNAPSHOT</version>
    </dependency>
    

    This should allow components using commons-logging to bridge their logs to your slf4j (and to the actual implementation, logback or whatever).

    Here's a link to Jasper's other config things, should they be necessary.