1

I'm getting an exception when I try to start my Java EE Spring+Hibernate application in Tomcat7. This used to work, but I think I screwed something up while migrating to Tomcat7. The exception is

Mar 29, 2013 11:38:33 PM org.apache.catalina.core.StandardContext filterStart
SEVERE: Exception starting filter hibernateFilter
java.lang.ClassCastException: org.springframework.orm.hibernate3.support.OpenSessionInViewFilter cannot be cast to javax.servlet.Filter
    at org.apache.catalina.core.ApplicationFilterConfig.getFilter(ApplicationFilterConfig.java:248)
    at org.apache.catalina.core.ApplicationFilterConfig.setFilterDef(ApplicationFilterConfig.java:368)
    at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:98)
    at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4193)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4801)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:988)
    at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:771)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:988)
    at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:275)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.core.StandardService.startInternal(StandardService.java:427)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:649)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:139)
    at org.apache.catalina.startup.Catalina.start(Catalina.java:585)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288)
    at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:415)
Mar 29, 2013 11:38:33 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error filterStart
Mar 29, 2013 11:38:33 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/ImageWar] startup failed due to previous errors

My web.xml is as follows:

<?xml version="1.0" encoding="UTF-8"?>
<web-app
    version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

    <!-- Attach a Hibernate session to each request using this filter -->
    <filter>
        <filter-name>hibernateFilter</filter-name>
        <filter-class>
            org.springframework.orm.hibernate3.support.OpenSessionInViewFilter
        </filter-class>
        <init-param>
            <param-name>sessionFactoryBeanName</param-name>
            <param-value>sessionFactory</param-value>
        </init-param>
        <init-param>
            <param-name>flushMode</param-name>
            <param-value>AUTO</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>hibernateFilter</filter-name>
        <url-pattern>/plus/*</url-pattern>
        <dispatcher>REQUEST</dispatcher>
        <dispatcher>FORWARD</dispatcher>
    </filter-mapping>           

    <servlet>
        <servlet-name>ImageWar</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>MyApp</servlet-name>
        <url-pattern>/xyz/*</url-pattern>
    </servlet-mapping>

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/ImageWar-dataSource.xml</param-value>
    </context-param>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>

</web-app>

All my Spring jars are 3.1.3.RELEASE, and I have the following two Hibernate dependencies:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>3.6.8.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
        <version>4.3.0.Final</version>
    </dependency>

I'm "providing" some of the standard JEE jars:

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>jstl</artifactId>
        <version>1.2</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>javax.servlet-api</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>

Here's the output from mvn dependency:tree :

[INFO] --- maven-dependency-plugin:2.1:tree (default-cli) @ ImageWar ---
[INFO] com.sodapopsoftware:ImageWar:war:0.0.1-SNAPSHOT
[INFO] +- javax.servlet:jstl:jar:1.2:provided
[INFO] +- javax.servlet:javax.servlet-api:jar:3.0.1:provided
[INFO] +- javax.servlet.jsp:javax.servlet.jsp-api:jar:2.2.1:provided
[INFO] +- javax.el:javax.el-api:jar:2.2.2:provided
[INFO] +- org.slf4j:slf4j-log4j12:jar:1.6.4:compile
[INFO] |  +- org.slf4j:slf4j-api:jar:1.6.4:compile
[INFO] |  \- log4j:log4j:jar:1.2.16:compile
[INFO] +- commons-logging:commons-logging:jar:1.1.1:compile
[INFO] +- commons-beanutils:commons-beanutils:jar:1.8.3:compile
[INFO] +- com.google.guava:guava:jar:13.0.1:compile
[INFO] +- org.imgscalr:imgscalr-lib:jar:4.2:compile
[INFO] +- taglibs:standard:jar:1.1.2:compile
[INFO] +- commons-fileupload:commons-fileupload:jar:1.2.2:compile
[INFO] +- org.apache.commons:commons-io:jar:1.3.2:compile
[INFO] +- junit:junit:jar:4.8.2:test
[INFO] +- org.easymock:easymock:jar:3.1:test
[INFO] |  +- cglib:cglib-nodep:jar:2.2.2:test
[INFO] |  \- org.objenesis:objenesis:jar:1.2:test
[INFO] +- org.springframework:spring-test:jar:3.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-core:jar:3.1.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-asm:jar:3.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-aop:jar:3.1.3.RELEASE:compile
[INFO] |  +- aopalliance:aopalliance:jar:1.0:compile
[INFO] |  \- org.springframework:spring-beans:jar:3.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-web:jar:3.1.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-context:jar:3.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-webmvc:jar:3.1.3.RELEASE:compile
[INFO] |  +- org.springframework:spring-context-support:jar:3.1.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-expression:jar:3.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-jdbc:jar:3.1.3.RELEASE:compile
[INFO] |  \- org.springframework:spring-tx:jar:3.1.3.RELEASE:compile
[INFO] +- org.springframework:spring-orm:jar:3.1.3.RELEASE:compile
[INFO] +- mysql:mysql-connector-java:jar:5.1.9:compile
[INFO] +- c3p0:c3p0:jar:0.9.1.1:compile
[INFO] +- org.hibernate:hibernate-core:jar:3.6.8.Final:compile
[INFO] |  +- antlr:antlr:jar:2.7.6:compile
[INFO] |  +- commons-collections:commons-collections:jar:3.1:compile
[INFO] |  +- dom4j:dom4j:jar:1.6.1:compile
[INFO] |  +- org.hibernate:hibernate-commons-annotations:jar:3.2.0.Final:compile
[INFO] |  +- org.hibernate.javax.persistence:hibernate-jpa-2.0-api:jar:1.0.1.Final:compile
[INFO] |  \- javax.transaction:jta:jar:1.1:compile
[INFO] +- org.hibernate:hibernate-validator:jar:4.3.0.Final:compile
[INFO] |  +- javax.validation:validation-api:jar:1.0.0.GA:compile
[INFO] |  \- org.jboss.logging:jboss-logging:jar:3.1.0.CR2:compile
[INFO] \- javassist:javassist:jar:3.12.1.GA:compile

Any idea why I'm getting this exception?

Marvo
  • 17,845
  • 8
  • 50
  • 74

1 Answers1

5

Sounds like you have a version of the servlet API in WEB-INF/lib. If you're using maven, find the offending dependency and make sure to exclude it's dependencies to servlet-api. The output of mvn dependency:tree can be helpful to track down unwanted transitive dependencies.

Edit:

If all seems correct, and you still experience this problem, one technique I use to find out where a class is loaded from is this:

Filter.class.getProtectionDomain().getCodeSource().getLocation()

It will give you the location of the jar/folder where the class has been loaded from. I would also suggest that you try to deploy your web application in a stand alone application server to rule out the IDE (e.g. server/deployment plugins) as the source of the problem.

NilsH
  • 13,705
  • 4
  • 41
  • 59
  • I don't think I understand. OpenSessionInViewFilter is a filter. I believe it's supposed to be dependent on the the javax.servlet.Filter class. – Marvo Mar 30 '13 at 22:03
  • Yes, but `servlet-api` is provided by the application server, and should not be in the `WEB-INF/lib` of the individual web application. So if you're using maven, make sure the servlet-api dependency has `provided` scope. – NilsH Mar 30 '13 at 22:08
  • I added some of the additional dependencies to my original question, and they are indeed marked `provided`. That said, I did find the servlet-api jar in Eclipse's server deployment directory. I deleted it, and still get the same error. Maybe it's picking up some other filter class and that's why it's complaining? (Thanks for your insights.) – Marvo Mar 30 '13 at 22:24
  • I see you have resolved the problem now, but to find out where transitive dependencies origin from, the output of `mvn dependency:tree` can be helpful. – NilsH Mar 30 '13 at 22:45
  • Even if I find them, how will I stop them? – Marvo Mar 30 '13 at 22:51
  • Use `excludes` on the offending dependencies – NilsH Mar 30 '13 at 22:56
  • I spoke too soon. It ran exactly once. Then I tried to run my tests, so it needed those dependencies I had comment out. I restored those, the tests ran, and now I can't get it to load. If I have "Serve modules without publishing" checked, I get the error in the OP. If I uncheck that, it can't find some of my own application classes. I'll see if I can do the excludes. – Marvo Mar 30 '13 at 23:01
  • I've added the dependency tree. You can see I've marked the JEE stuff as provided. (I also tried marking it as test to see if that would let me run my tests and run the app, but that doesn't work.) If you see something in the dependency tree that I'm not seeing, please let me know. – Marvo Mar 30 '13 at 23:38