Failed to introspect annotated ** org.springframework.boot.web.support.SpringBootServletInitializer

一个spring-boot项目想以外部的tomcat部署而不是内嵌的方式,这个时候需要让spring-boot入口类继承至SpringBootServletInitializer并重载configure方法,并给项目的打包方式改为war,同时添加如下依赖:


            org.springframework.boot
            spring-boot-starter-tomcat
            provided
        
做完这些工作以后,mvn package就会打包出war包了,可以部署外部的tomcat而不是使用内嵌的tomcat,

但是这个时候直接在入口类里执行main方法的时候,报了如下错误,以下是异常栈:

2017-11-23 10:24:26.746  WARN 548080 --- [           main] s.c.a.AnnotationConfigApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.ranguisheng.blog.template.ApplicationBoot]; nested exception is java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer
2017-11-23 10:24:26.774 ERROR 548080 --- [           main] o.s.b.f.s.DefaultListableBeanFactory     : Destroy method on bean with name 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory' threw an exception

java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: org.springframework.context.annotation.AnnotationConfigApplicationContext@166ebe0: startup date [Thu Nov 23 10:24:26 CST 2017]; root of context hierarchy
	at org.springframework.context.support.AbstractApplicationContext.getApplicationEventMulticaster(AbstractApplicationContext.java:414) [spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.support.ApplicationListenerDetector.postProcessBeforeDestruction(ApplicationListenerDetector.java:97) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:253) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroyBean(DefaultSingletonBeanRegistry.java:578) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingleton(DefaultSingletonBeanRegistry.java:554) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingleton(DefaultListableBeanFactory.java:961) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.destroySingletons(DefaultSingletonBeanRegistry.java:523) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.destroySingletons(FactoryBeanRegistrySupport.java:230) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.beans.factory.support.DefaultListableBeanFactory.destroySingletons(DefaultListableBeanFactory.java:968) [spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.destroyBeans(AbstractApplicationContext.java:1030) [spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:556) [spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at com.ranguisheng.blog.template.ApplicationBoot.main(ApplicationBoot.java:22) [classes/:na]

2017-11-23 10:24:26.812 ERROR 548080 --- [           main] o.s.boot.SpringApplication               : Application startup failed

org.springframework.beans.factory.BeanDefinitionStoreException: Failed to parse configuration class [com.ranguisheng.blog.template.ApplicationBoot]; nested exception is java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:181) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:308) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:228) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:272) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:92) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:687) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:525) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:303) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107) [spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]
	at com.ranguisheng.blog.template.ApplicationBoot.main(ApplicationBoot.java:22) [classes/:na]
Caused by: java.lang.IllegalStateException: Failed to introspect annotated methods on class org.springframework.boot.web.support.SpringBootServletInitializer
	at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:163) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.retrieveBeanMethodMetadata(ConfigurationClassParser.java:380) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.doProcessConfigurationClass(ConfigurationClassParser.java:314) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.processConfigurationClass(ConfigurationClassParser.java:245) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:198) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	at org.springframework.context.annotation.ConfigurationClassParser.parse(ConfigurationClassParser.java:167) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	... 12 common frames omitted
Caused by: java.lang.NoClassDefFoundError: javax/servlet/ServletContext
	at java.lang.Class.getDeclaredMethods0(Native Method) ~[na:1.8.0_65]
	at java.lang.Class.privateGetDeclaredMethods(Class.java:2701) ~[na:1.8.0_65]
	at java.lang.Class.getDeclaredMethods(Class.java:1975) ~[na:1.8.0_65]
	at org.springframework.core.type.StandardAnnotationMetadata.getAnnotatedMethods(StandardAnnotationMetadata.java:152) ~[spring-core-4.3.12.RELEASE.jar:4.3.12.RELEASE]
	... 17 common frames omitted
Caused by: java.lang.ClassNotFoundException: javax.servlet.ServletContext
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381) ~[na:1.8.0_65]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424) ~[na:1.8.0_65]
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) ~[na:1.8.0_65]
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357) ~[na:1.8.0_65]
	... 21 common frames omitted


Process finished with exit code 1

百度搜了半天就是搜不出来解决方法,google一下就出来答案,悲哀啊,大百度就会整点狗血的东西

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

这个链接里给了答案,当然这是spring的官方github问题区,不算事bug讨论的地方,所以里面的维护人员友好的建议去stackoverflow里看看,并附了有答案的连接:

https://stackoverflow.com/questions/32531422/spring-boot-jsp-error-noclassdeffounderror

意思是说这属于idea的一个bug,并不是一个框架或者程序的bug,这也是为什么执行main不能运行但是mvn spring-boot:run的时候能跑起来的原因,解决方案如下:

idea bug链接:

https://youtrack.jetbrains.com/issue/IDEA-107048

https://youtrack.jetbrains.com/issue/IDEA-78410

  • Manually configure the classpath in IDEA
  • Run the samples on the command line using mvn spring-boot:run
  • Remove all occurrences of provided from the pom. This will mean that app can't be deployed as a war to Tomcat or similar
第一个方法比较麻烦,第二个其实就是绕过了问题没有解决问题,第三个其实不可行,如果项目需要外部tomcat部署的话,这个scope是需要的,别担心还有其他办法:

You can use the provided as suggested in the Spring documentation, and then go into your Project Settings in IntelliJ. For the module in question, in the Dependencies tab, you should see that the dependencies related to spring-boot-starter-tomcat are all listed as "Provided". Changing them to "Compile" should force IntelliJ to add them to the classpath.

It has the advantage of both not requiring any modifications to your pom.xml and allowing you to use the Spring Boot integration provided by IntelliJ.

tomcat-embed-websocket also had to be changed to compile in my case. Thanks a lot  


If you run your project using command line directly, you will lose the debug function provided by IDE. You can click the Maven Project tab, find the spring-boot:run goal, right click then select debug XXXX. By using this way you can get full debug feature that your IDE gives.


从上面的回答中,我们可以得到两个信息,一个是更改项目的settings,将spring-boot-starter-tomcat的依赖手动改为Compile,这样去强制idea将其加到classpath里面,这样的好处是我们不用修改项目的pom.xml


你可能感兴趣的:(善假于物)