Search code examples
springmavenjakarta-eecxfcxfrs

Why does CXF 2.7.5 (for jax-rs) / Spring 3.x / Hibernate 4.x results in java.lang.ClassNotFoundException: org.springframework.asm.ClassVisitor?


I'm building a RESTful service via CXF 2.7.5 and am using the cxf-servlet approach. javax-servlet 3.0 API, Spring 3.x, and Hibernate 4.x are all part of the picture.

Before incorporating Spring JPA, Spring ORM, and Hibernate into my maven POM file, I could build a war-file that actually served a well-defined endpoing (established through JAX-RS).

In any case, now the war-file does not deploy into Tomcat 7.x; instead the exception shown in the title occurs:

    java.lang.ClassNotFoundException: org.springframework.asm.ClassVisitor

Some things I've already checked:

  • Tomcat 7.x is running with javax-servlet 3.x compliant APIs.
  • The package with ClassVisitor (org.springframework.asm) is uniquely listed among the jars-files in WEB-INF/lib. In fact, it is now downloaded as part of the spring-core.

I've browsed a number of articles that explain similar circumstances. But most end up suggesting the obvious: make sure ClassVisitor is referenced in the classpath.

I'm listing my POM file (modulo a few exemptions at the top), along with the web.xml deployment descriptor for the war-file, and the applicationContext.xml. At the bottom, I've also re-listed the exception, with context.

maven 3.x POM:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.acme.etorf</groupId>
  <artifactId>etorf</artifactId>
  ...
  <version>1</version>
  <packaging>war</packaging>

  <properties>
    <cxf.version>2.7.5</cxf.version>
    <spring.version>3.2.2.RELEASE</spring.version>
    <spring.asm.version>3.1.4.RELEASE</spring.asm.version>
    <spring.jpa.version>2.0.8</spring.jpa.version>
    <hibernate.version>4.2.2.Final</hibernate.version>
    <hibernate.jpa.api.version>2.0-cr-1</hibernate.jpa.api.version>
    <mysql.connector.version>5.1.25</mysql.connector.version>
    <c3p0.version>0.9.1.2</c3p0.version>
    <slf4j.version>1.7.5</slf4j.version>
  </properties>

  <build>
    <pluginManagement>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugin</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.1</version>
            <configuration>
              <source>1.6</source>
              <target>1.6</target>
            </configuration>
          </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>2.1</version>
          <configuration>
            <webXml>WebContent/WEB-INF/web.xml</webXml>
          </configuration>
        </plugin>
        </plugins>
      </pluginManagement>
  </build>

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

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-frontend-jaxrs</artifactId>
      <version>${cxf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http</artifactId>
      <version>${cxf.version}</version>
    </dependency>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http-hc</artifactId>
      <version>${cxf.version}</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-orm</artifactId>
      <version>${spring.version}</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jpa</artifactId>
      <version>${spring.jpa.version}</version>
      <exclusions>
        <exclusion>
          <groupId>javax.servlet</groupId>
          <artifactId>servlet-api</artifactId>
        </exclusion>
      </exclusions>
    </dependency>

        <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>${mysql.connector.version}</version>
        </dependency>
        <dependency>
      <groupId>org.hibernate</groupId>
      <artifactId>hibernate-entitymanager</artifactId>
      <version>${hibernate.version}</version>
        </dependency>

    <dependency>
      <groupId>c3p0</groupId>
      <artifactId>c3p0</artifactId>
      <version>${c3p0.version}</version>
    </dependency>

        <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-log4j12</artifactId>
          <version>${slf4j.version}</version>
        </dependency>
  </dependencies>
</project>

web.xml:

<web-app
  version="3.0"
  xmlns="http://java.sun.com/xml/ns/javaee"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name>etorf</display-name>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

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

  <servlet>
    <servlet-name>cxf</servlet-name>
    <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
  </servlet>

  <servlet-mapping>
    <servlet-name>cxf</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

  <session-config>
    <session-timeout>60</session-timeout>
  </session-config>
</web-app>

applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!--
  Licensed to the Apache Software Foundation (ASF) under one
  or more contributor license agreements. See the NOTICE file
  distributed with this work for additional information
  regarding copyright ownership. The ASF licenses this file
  to you under the Apache License, Version 2.0 (the
  "License"); you may not use this file except in compliance
  with the License. You may obtain a copy of the License at

  http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing,
  software distributed under the License is distributed on an
  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  KIND, either express or implied. See the License for the
  specific language governing permissions and limitations
  under the License.
-->
<beans
  xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:jaxrs="http://cxf.apache.org/jaxrs"
  xmlns:http-conf="http://cxf.apache.org/transports/http/configuration"
  xmlns:tx="http://www.springframework.org/schema/tx"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
                      http://www.springframework.org/schema/beans/spring-beans.xsd
                      http://cxf.apache.org/jaxrs
                      http://cxf.apache.org/schemas/jaxrs.xsd
                      http://cxf.apache.org/transports/http/configuration
                      http://cxf.apache.org/schemas/configuration/http-conf.xsd
                                            http://www.springframework.org/schema/tx
                                            http://www.springframework.org/schema/tx/spring-tx.xsd">

  <import resource="classpath:META-INF/cxf/cxf.xml" />
  <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
      <property name="location">
        <value>classpath:hibernate.properties</value>
      </property>
    </bean>

  <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
    <property name="driverClass" value="${hibernate.connection.driver_class}" />
    <property name="jdbcUrl" value="${hibernate.connection.url}" />
    <property name="user" value="${hibernate.connection.username}" />
    <property name="password" value="${hibernate.connection.password}" />
    <property name="acquireIncrement" value="5" />
    <property name="minPoolSize" value="5" />
    <property name="maxPoolSize" value="150" />
    <property name="maxIdleTime" value="1800" />
  </bean>

  <bean id="hibernateJpaDialect" class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/>
  <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
    <property name="database" value="MYSQL" />
    <!-- <property name="showSql" value="true" /> -->
    <!--<property name="generateDdl" value="true" /> -->
  </bean>

  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="dataSource" ref="dataSource" />

    <property name="persistenceXmlLocation" value="classpath:persistence.xml" />
    <property name="persistenceUnitName" value="Forte-Persistence-Unit" />
    <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter" />

    <property name="jpaPropertyMap">
      <map>
        <entry key="hibernate.transaction.flush_before_completion" value="true" />
        <entry key="hibernate.transaction.auto_close_session" value="true" />
        <entry key="hibernate.current_session_context_class" value="jta" />
        <entry key="hibernate.connection.release_mode" value="auto" />
        <!-- <entry key="hibernate.show_sql" value="true" />-->
      </map>
    </property>

    <property name="jpaDialect" ref="hibernateJpaDialect" />
  </bean>

  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory" />
  </bean>
  <tx:annotation-driven transaction-manager="transactionManager" />

  <bean id="helloservice" class="com.kornferry.service.HelloServiceImpl"/>
  <jaxrs:server id="helloworld" address="/">
    <jaxrs:serviceBeans>
      <ref bean="helloservice"/>
    </jaxrs:serviceBeans>                  
  </jaxrs:server>

</beans>

Exception from catalina.out:

INFO: Refreshing Root WebApplicationContext: startup date [Mon Jul 08 22:47:52 PDT 2013]; root of context hierarchy
Jul 8, 2013 10:47:52 PM org.springframework.web.context.ContextLoader initWebApplicationContext
SEVERE: Context initialization failed
java.lang.NoClassDefFoundError: org/springframework/asm/ClassVisitor
        at org.springframework.context.support.AbstractRefreshableApplicationContext.customizeBeanFactory(AbstractRefreshableApplicationContext.java:218)
        at org.springframework.context.support.AbstractRefreshableApplicationContext.refreshBeanFactory(AbstractRefreshableApplicationContext.java:129)
        at org.springframework.context.support.AbstractApplicationContext.obtainFreshBeanFactory(AbstractApplicationContext.java:467)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:397)
        at org.springframework.web.context.ContextLoader.createWebApplicationContext(ContextLoader.java:282)
        at org.springframework.web.context.ContextLoader.initWebApplicationContext(ContextLoader.java:204)
        at org.springframework.web.context.ContextLoaderListener.contextInitialized(ContextLoaderListener.java:47)
        at org.apache.catalina.core.StandardContext.listenerStart(StandardContext.java:4887)
        at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5381)
        at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
        at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:901)
        at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:877)
        at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:633)
        at org.apache.catalina.startup.HostConfig.deployWAR(HostConfig.java:976)
        at org.apache.catalina.startup.HostConfig$DeployWar.run(HostConfig.java:1653)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:439)
        at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:303)
        at java.util.concurrent.FutureTask.run(FutureTask.java:138)
        at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:895)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:918)
        at java.lang.Thread.run(Thread.java:680)
Caused by: java.lang.ClassNotFoundException: org.springframework.asm.ClassVisitor
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1714)
        at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1559)
        ... 21 more
Jul 8, 2013 10:47:52 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Error listenerStart
Jul 8, 2013 10:47:52 PM org.apache.catalina.core.StandardContext startInternal
SEVERE: Context [/cxf-library] startup failed due to previous errors

Solution

  • See my last comment. The missing ClassVisitor exception was triggered by cxf-library.war, a separate war-file from my own. After removing cxf-libray.war (and its unpacked folder), then restarting Tomcat, the exception went away.