2013-10-30 20 views
23

Tôi đang sử dụng Sping MVC trong ứng dụng của mình và viết các trường hợp kiểm tra JUnit cho một DAO. Khi tôi chạy thử nghiệm, tôi nhận được lỗi: java.lang.ClassNotFoundException: javax.servlet.ServletContext.Nhận java.lang.ClassNotFoundException: javax.servlet.ServletContext trong JUnit

Trong ngăn xếp, tôi thấy lỗi này được gây ra trong thời gian getApplicationContext. Trong số applicationContext, tôi chưa định nghĩa bất kỳ servlet nào. Bản đồ Servlet chỉ được thực hiện trong web.xml vì vậy tôi không hiểu tại sao tôi nhận được lỗi này.

Đây là tôi applicationContext.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans 
xmlns="http://www.springframework.org/schema/beans" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd 
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd" 

xmlns:tx="http://www.springframework.org/schema/tx"> 

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> 
    <property name="driverClass" value="com.mysql.jdbc.Driver"/> 
    <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/testdb"/> 
    <property name="user" value="username"/> 
</bean> 

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"> 
    <property name="dataSource" ref="dataSource"/> 
    <property name="hibernateProperties"> 
     <props> 
      <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> 
      <prop key="hibernate.connection.driver_class">com.mysql.jdbc.Driver</prop> 
      <prop key="hibernate.connection.url">jdbc:mysql://localhost:3306/myWorld_test</prop> 
      <prop key="hibernate.connection.username">username</prop> 
     </props> 
    </property> 
    <property name="packagesToScan"> 
     <list> 
      <value>com.myprojects.pojos</value> 
     </list> 
    </property> 
</bean> 

<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate"> 
    <property name="sessionFactory" ref="sessionFactory"/> 
</bean> 

<tx:annotation-driven transaction-manager="transactionManager"/> 

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> 
    <property name="sessionFactory" ref="sessionFactory" /> 
</bean> 

<context:component-scan base-package="com.myprojects"/> 

<context:annotation-config/> 
<mvc:annotation-driven/> 
</beans> 

Đây là stacktrace:

java.lang.NoClassDefFoundError: javax/servlet/ServletContext 
at java.lang.Class.getDeclaredMethods0(Native Method) 
at java.lang.Class.privateGetDeclaredMethods(Class.java:2521) 
at java.lang.Class.getDeclaredMethods(Class.java:1845) 
at org.springframework.core.type.StandardAnnotationMetadata.hasAnnotatedMethods(StandardAnnotationMetadata.java:161) 
at org.springframework.context.annotation.ConfigurationClassUtils.isLiteConfigurationCandidate(ConfigurationClassUtils.java:106) 
at org.springframework.context.annotation.ConfigurationClassUtils.checkConfigurationClassCandidate(ConfigurationClassUtils.java:88) 
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:253) 
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:223) 
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:630) 
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:461) 
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:120) 
at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:60) 
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.delegateLoading(AbstractDelegatingSmartContextLoader.java:100) 
at org.springframework.test.context.support.AbstractDelegatingSmartContextLoader.loadContext(AbstractDelegatingSmartContextLoader.java:248) 
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContextInternal(CacheAwareContextLoaderDelegate.java:64) 
at org.springframework.test.context.CacheAwareContextLoaderDelegate.loadContext(CacheAwareContextLoaderDelegate.java:91) 
at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:122) 
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109) 
at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75) 
at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:312) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:211) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:288) 
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:284) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:88) 
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) 
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) 
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) 
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) 
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) 
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27) 
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) 
at org.junit.runners.ParentRunner.run(ParentRunner.java:309) 
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) 
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:80) 
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:47) 
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69) 
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:49) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) 
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) 
at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32) 
at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93) 
at com.sun.proxy.$Proxy2.processTestClass(Unknown Source) 
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:103) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
at java.lang.reflect.Method.invoke(Method.java:606) 
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35) 
at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24) 
at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355) 
at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:66) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) 
at java.lang.Thread.run(Thread.java:724) 
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext 
at java.net.URLClassLoader$1.run(URLClassLoader.java:366) 
at java.net.URLClassLoader$1.run(URLClassLoader.java:355) 
at java.security.AccessController.doPrivileged(Native Method) 
at java.net.URLClassLoader.findClass(URLClassLoader.java:354) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:424) 
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308) 
at java.lang.ClassLoader.loadClass(ClassLoader.java:357) 
... 62 more 

Kiểm tra lớp:

import org.junit.After; 
import org.junit.AfterClass; 
import org.junit.Before; 
import org.junit.BeforeClass; 
import org.junit.Test; 
import static org.junit.Assert.*; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = {"classpath:applicationContext.xml"}) 
public class UserServiceTest { 

@Autowired 
private UserService service; 

public UserServiceTest() { 
} 

@BeforeClass 
public static void setUpClass() { 
} 

@AfterClass 
public static void tearDownClass() { 
} 

@Before 
public void setUp() { 
} 

@After 
public void tearDown() { 
} 
} 

Thậm chí trước khi viết bất kỳ phương pháp kiểm tra, tôi đã nhận lỗi này.

+0

Do '', điều này yêu cầu lớp web phải khả dụng trên đường dẫn lớp. –

+0

@ M.Deinum Trong trường hợp này, bạn có đề xuất di chuyển đến ngữ cảnh servlet thay vì ngữ cảnh ứng dụng gốc không? – coder

+0

Không, bạn cần thêm API servlet vào đường dẫn lớp. Bạn thực hiện bài kiểm tra như thế nào? Maven? Kiến? Gradle? IDE của bạn? – Kkkev

Trả lời

41

Bạn có một tệp xml duy nhất cho số ApplicationContext trong tệp này có thẻ <mvc:annotation-driven />. Thẻ này tải các tài nguyên liên quan đến web khác nhau (các trình phân giải chế độ xem, ánh xạ xử lý, v.v.) và do đó yêu cầu api servlet khả dụng.

Bạn đã có api servlet trên đường dẫn lớp của bạn như là một phụ thuộc được cung cấp trong maven.

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

Bên cạnh đó bạn có thể muốn xóa thẻ <mvc:annotation-driven /> và đặt thẻ đó vào tệp cấu hình riêng biệt. Đây cũng là một thẻ nên (nói chung) được tải bởi DispatcherServlet. (Tôi giả định ở đây tệp applicationContext.xml, theo mặc định, được tải bởi ContextLoaderListener).

+1

Có một artifactId trên kho lưu trữ maven được gọi là "servlet-api" thay vì "javax.servlet-api". Không có phiên bản 3.0.1 cho cái này. Tôi đã sử dụng sự phụ thuộc ở trên và nó đã giải quyết được điều "java.lang.ClassNotFoundException: javax.servlet.ServletContext" của tôi. – raonirenosto

+0

Tôi đã thử nó nhưng nó đã không làm việc cho tôi, tuy nhiên tôi thấy http://stackoverflow.com/a/24394329/1515111 nó nói rằng chúng ta cần một thực hiện cho API servlet, là nó như vậy? – rd22

+0

Tôi cũng phải thêm '' để giải quyết ngoại lệ. – rd22

1

Maven không thể tải javax.servlet-api trong phiên bản 3.0.1:/

sự phụ thuộc này giải quyết vấn đề của tôi:

<dependency> 
     <groupId>org.apache.geronimo.specs</groupId> 
     <artifactId>geronimo-servlet_3.0_spec</artifactId> 
     <version>1.0</version> 
     <scope>test</scope> 
    </dependency> 

Nó chứa tất cả các lớp học của javax.servlet.

0

Đối với tôi, tôi đã thêm @WebAppConfiguration và nó đã khắc phục được sự cố của tôi.

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(classes = {TestConfig.class}) 
@WebAppConfiguration 
public class WebAppTest { 


    @Test 
    public void test() throws Exception { 

    } 

} 
Các vấn đề liên quan