파란하늘의 지식창고
반응형

spring boot 2.3.0에서 아무것도 없이 빈 web을 띄울 때 아래 에러가 발생했다.

자체 구현한 autoConfigure 모듈을 사용한 아무것도 없는 빈 프로젝트 구축의 경우였다.

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'resourceHandlerMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:656)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:636)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1338)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1177)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:557)
	at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:517)
	at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:323)
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:226)
	at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:321)
	at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:895)
	at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:878)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:550)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:143)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:758)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:750)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
	at [mypackage].Application.main(Application.java:11)
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.web.servlet.HandlerMapping]: Factory method 'resourceHandlerMapping' threw exception; nested exception is java.lang.IllegalStateException: No ServletContext set
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
	at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:651)
	... 18 common frames omitted
Caused by: java.lang.IllegalStateException: No ServletContext set
	at org.springframework.util.Assert.state(Assert.java:73)
	at org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport.resourceHandlerMapping(WebMvcConfigurationSupport.java:534)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
	... 19 common frames omitted

계속 debug를 하다 보니 대략의 원인은 AnnotationConfigServletWebServerApplicationContext를 생성하고 embeded tomcat을 생성하면 AnnotationConfigServletWebServerApplicationContext 클래스 변수로 tomcat의 ServletContext가 설정되고 그 이후 ServletContextAware를 구현한 빈들이 생성되면서 AnnotationConfigServletWebServerApplicationContext의 ServletContext를 사용하게 되는데 어찌 된 일인지 embeded tomcat 이 생성되기 전에 ServletContextAware를 구현한 빈들이 수행되면서 위와 같은 에러가 발생한 것이다.

정확한 발생 동기는 아직 찾지 못했다..

다만 해결이 되는 방법은 찾았는데 그게 왜 해결이 되는지는 찾지 못했다...

<dependency>
    <groupId>org.hibernate.validator</groupId>
    <artifactId>hibernate-validator</artifactId>
</dependency>

위 참조를 하면 ValidationAutoConfiguration이 실행되고 해당 현상이 발생하지 않게 된다.

왜 이 현상이 발생했는지, 관련 이슈가 있는지 아직 찾지 못한 상태이다.

이런 경우를 겪어본 사람이 또 있는지 모르겠다.


2020-06-09 이 issue가 관련 있어 보인다.

https://github.com/spring-projects/spring-boot/issues/16936

 

Perform failure analysis of sliced tests that fail to bootstrap due to an IllegalStateException: No ServletContext set caused by

When annotating a test with @JpaDataTest, I get the No ServletContext set exception, with no explanation, context, or advice. This error message should be more verbose, or there needs to be better ...

github.com

 

반응형
profile

파란하늘의 지식창고

@Bluesky_

내용이 유익했다면 광고 배너를 클릭 해주세요