我正在通过 CXF 2.7.5 构建一个 RESTful 服务,并且正在使用 cxf-servlet 方法。javax-servlet 3.0 API、Spring 3.x 和 Hibernate 4.x 都是其中的一部分。
在将 Spring JPA、Spring ORM 和 Hibernate 合并到我的 maven POM 文件中之前,我可以构建一个实际服务于明确定义的端点(通过 JAX-RS 建立)的 war-file。
无论如何,现在 war 文件不会部署到 Tomcat 7.x 中;而是出现标题中显示的异常:
java.lang.ClassNotFoundException: org.springframework.asm.ClassVisitor
我已经检查过的一些事情:
- Tomcat 7.x 使用符合 javax-servlet 3.x 的 API 运行。
- 带有 ClassVisitor (org.springframework.asm) 的包在 WEB-INF/lib 中的 jars 文件中唯一列出。事实上,它现在作为 spring-core 的一部分下载。
我浏览了许多解释类似情况的文章。但大多数人最终都提出了显而易见的建议:确保在类路径中引用了 ClassVisitor。
我列出了我的 POM 文件(顶部有一些例外情况),以及 war 文件的 web.xml 部署描述符和 applicationContext.xml。在底部,我还重新列出了异常,并附有上下文。
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>
网页.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>
应用程序上下文.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>
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