Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Missing servlet context in spring tests

  1. #1

    Default Missing servlet context in spring tests

    Hey everyone.

    I started switching my spring mvc 3.1 application from xml-based configuration to JavaConfig. Everything works fine when I start my application via tomcat:run using maven.

    But when I run tests via spring-test, they fail with the following exception:

    Code:
    ERROR: org.springframework.test.context.TestContextManager - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@2bffef5a] to prepare test instance [net.findme.server.repository.RoleRepositoryTest@9abd962]
    java.lang.IllegalStateException: Failed to load ApplicationContext
    	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:157)
    	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:321)
    	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:15)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:290)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231)
    	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
    	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
    	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
    	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
    	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71)
    	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174)
    	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
    Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.web.servlet.HandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()] threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:581)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1015)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:911)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:485)
    	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    	at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:103)
    	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
    	at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
    	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
    	... 24 more
    Caused by: org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.web.servlet.HandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()] threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:169)
    	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:570)
    	... 39 more
    Caused by: java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
    	at org.springframework.util.Assert.notNull(Assert.java:112)
    	at org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer.<init>(DefaultServletHandlerConfigurer.java:54)
    	at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping(WebMvcConfigurationSupport.java:253)
    	at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$b96b3c4c.CGLIB$defaultServletHandlerMapping$7(<generated>)
    	at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$b96b3c4c$$FastClassByCGLIB$$c0f11b77.invoke(<generated>)
    	at net.sf.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228)
    	at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:280)
    	at org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration$$EnhancerByCGLIB$$b96b3c4c.defaultServletHandlerMapping(<generated>)
    	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:601)
    	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:149)
    	... 40 more
    My test class:

    Code:
    @RunWith(SpringJUnit4ClassRunner.class)
    @TransactionConfiguration(transactionManager="transactionManager", defaultRollback=true)
    @ContextConfiguration(loader=AnnotationConfigContextLoader.class, classes = {DataSourceConfig.class})
    @Transactional
    public class RoleRepositoryTest {
    	/**
    	 * EntityManager for verifying the results of data manip1ulation by the {@code RoleRepository} interface
    	 */
    	@PersistenceContext
    	private EntityManager _entityManager;
    	
    	@Inject
    	private RoleRepository _repository;
    	
    	@Inject
    	private RoleGenerator _roleGenerator;
    	
    	@Test
    	public void testSaveRole() {
    ...	
    	}
    ...
    }

  2. #2

    Default

    DataSourceConfig:

    Code:
    @Configuration
    @ComponentScan("net.findme.server")
    @PropertySource("classpath:datasource.properties")
    @ImportResource("classpath:spring/datasource-config.xml")
    @EnableTransactionManagement
    public class DataSourceConfig
    {	
    	@Inject
    	Environment env;
    	/**
    	 * @return
    	 */
    	@Bean
    	public PlatformTransactionManager transactionManager() {
    		final JpaTransactionManager transactionManager = new JpaTransactionManager();
    		transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());
    		return transactionManager;
    	}
    	
    	/**
    	 * @return
    	 */
    	@Bean
    	public DriverManagerDataSource dataSource() {
    		final DriverManagerDataSource datasource = new DriverManagerDataSource();
    		datasource.setUsername(env.getProperty("jdbc.username"));
    		datasource.setPassword(env.getProperty("jdbc.password"));
    		datasource.setDriverClassName(env.getProperty("jdbc.driverClassName"));
    		datasource.setUrl(env.getProperty("jdbc.url"));
    		return datasource;
    	}
    	
    	/**
    	 * @return
    	 */
    	@Bean
    	public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() {
    		final LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
    		emf.setDataSource(dataSource());
    		emf.setPersistenceUnitName(env.getProperty("jdbc.persistenceUnit"));
    		emf.setJpaVendorAdapter(jpaVendorAdapter());
    		return emf;
    	}
    	
    	/**
    	 * @return
    	 */
    	@Bean
    	public JpaVendorAdapter jpaVendorAdapter() {
    		final  HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
    	    hibernateJpaVendorAdapter.setShowSql(Boolean.parseBoolean(env.getProperty("jdbc.showSql")));
    	    hibernateJpaVendorAdapter.setGenerateDdl(Boolean.parseBoolean(env.getProperty("jdbc.generateDdl")));
    	    hibernateJpaVendorAdapter.setDatabasePlatform(env.getProperty("jdbc.databasePlattform"));
    	    hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
    	    return hibernateJpaVendorAdapter;
    	}
    }
    WebConfig:

    Code:
    @Configuration
    @EnableWebMvc
    @ComponentScan("net.findme.server.controller")
    public class WebConfig extends WebMvcConfigurerAdapter
    {
    	@Bean
    	public static InternalResourceViewResolver jspViewResolver() {
            InternalResourceViewResolver bean = new InternalResourceViewResolver();
            bean.setPrefix("/WEB-INF/views/");
            bean.setSuffix(".jsp");
            return bean;
    	}
    
    	/* (non-Javadoc)
    	 * @see org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter#addResourceHandlers(org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry)
    	 */
    	@Override
    	public void addResourceHandlers(ResourceHandlerRegistry registry) {
    		registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    	}
    ...
    }
    At last, my web.xml:

    Code:
    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" 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_2_5.xsd">
    
    	<!-- The definition of the Root Spring Container shared by all Servlets and Filters -->
       <context-param>
          <param-name>contextClass</param-name>
          <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
       </context-param>
    	<context-param>
    		<param-name>contextConfigLocation</param-name>
    		<param-value>net.findme.server.config</param-value>
    	</context-param>
    	
    	<!-- Creates the Spring Container shared by all Servlets and Filters -->
    	<listener>
    		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    	</listener>
    
    	<!-- Processes application requests -->
    	<servlet>
    		<servlet-name>rest</servlet-name>
    		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    		      <init-param>
             <param-name>contextClass</param-name>
             <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
          </init-param>
    		<init-param>
    			<param-name>contextConfigLocation</param-name>
    			<param-value>net.findme.server.config</param-value>
    		</init-param>
    		<load-on-startup>1</load-on-startup>
    	</servlet>
    		
    	<servlet-mapping>
    		<servlet-name>rest</servlet-name>
    		<url-pattern>/</url-pattern>
    	</servlet-mapping>
    	
    	   <!-- Disables servlet container welcome file handling. Needed for compatibility 
          with Servlet 3.0 and Tomcat 7.0 -->
       <welcome-file-list>
          <welcome-file />
       </welcome-file-list>
    </web-app>
    Anyone an idea? I cannot figure out the missing piece..
    Thanks in advance!!
    Markus

  3. #3
    Join Date
    Jun 2006
    Location
    The Netherlands
    Posts
    13,625

    Default

    Have you actually read the stacktrace?

    Code:
    Error creating bean with name 'defaultServletHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Instantiation of bean failed; nested exception is org.springframework.beans.factory.BeanDefinitionStoreException: Factory method [public org.springframework.web.servlet.HandlerMapping org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.defaultServletHandlerMapping()] threw exception; nested exception is java.lang.IllegalArgumentException: A ServletContext is required to configure default servlet handling
    You are trying to instantatie web based beans outside of a web context for some beans this isn't going to work. If you want to test this you will need to fake (mock or stub) your web environment.
    Marten Deinum
    Java Consultant / Pragmatist / Open Source Enthousiast / Author


    Pro Spring MVC: With Web Flow
    Conspect

    Have you read the reference guide.
    Use the [ code ] tags, young padawan

  4. #4

    Default

    Thanks for your reply.
    Yes I did read it, but didn't really understand, because I just adapted my xml configuration into @Bean definitions in @Configuration classes. Thought loading my configuration classes via AnnotationConfigContextLoader in my tests would be sufficient...I'll have a look at the MockServletContext, etc, classes...

  5. #5

    Default

    Does anyone know how to "plug" a ServletContext" into my test?

  6. #6

    Default

    Do you really need it? Make some testConfig class in your test package that pulls in only the beans and configuration you need, and use that in your @ContextConfiguration. There is no need to test the framework or pull in the web context in most cases.

  7. #7
    Join Date
    Feb 2012
    Posts
    15

    Default

    Yes I did read it, but didn't really understand, because I just adapted my xml configuration into @Bean definitions in @Configuration classes. g.gif

  8. #8

    Default

    @wgorder
    Thanks!
    No, I think I don't..The test above is just about testing my data access layer via spring-data-jpa..But even when I just load my DataSourceConfig via "loader=AnnotationConfigContextLoader.class, classes = {DataSourceConfig.class} in my test case", it's still the same exception as above...I have really no Idea, because there's no need to mock a servlet context...I think!...But maybe I'm totally wrong..really need help! :\

  9. #9
    Join Date
    Feb 2012
    Posts
    15

    Default

    Yes I did read it, but didn't really understand, because I just adapted my xml configuration into @Bean definitions in @Configuration classes. g.gif

  10. #10

    Default

    The DataSourceConfig you have listed has an import of this xml

    @ImportResource("classpath:spring/datasource-config.xml")

    What is the contents of datasource-config.xml? Also where on the classpath is it located, is it in src/main/resources?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •