#java #spring #spring-boot
#java #весна #весенняя загрузка
Вопрос:
Я пытаюсь запустить какое-либо загрузочное приложение Spring, но я получаю проблему ниже:
:: Built with Spring Boot :: 2.3.1.RELEASE
2020-08-30 17:43:17.953 GMT 05:30 INFO rid=NA cid=NA 21756 --- [ main] o.s.s.petclinic.PetClinicApplication : Starting PetClinicApplication v2.3.1.BUILD-SNAPSHOT on saasas-WX-3 with PID 21756 (C:
workupstreamfault-tolerance-demotargetspring-petclinic-2.3.1.BUILD-SNAPSHOT.jar started by krsoni in C:workupstreamfault-tolerance-demo)
2020-08-30 17:43:17.959 GMT 05:30 INFO rid=NA cid=NA 21756 --- [ main] o.s.s.petclinic.PetClinicApplication : No active profile set, falling back to default profiles: default
2020-08-30 17:43:19.799 GMT 05:30 WARN rid=NA cid=NA 21756 --- [ main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org
.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'dispatcherServlet' defined in class path resource [com/mycompany/asr/autoconfigure/asr/ASRAutoConfiguration
.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=com.mycompany.asr.
autoconfigure.asr.ASRAutoConfiguration; factoryMethodName=getDispatcherServlet; initMethodName=null; destroyMethodName=(inferred); defined in class path resource [com/mycompany/asr/autoconfigure/asr/ASRAutoConfigur
ation.class]] for bean 'dispatcherServlet': There is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBea
nName=org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration$DispatcherServletConfiguration; factoryMethodName=dispatcherServlet; initMethodName=null; destroyMethodName=(inferred)
; defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration$DispatcherServletConfiguration.class]] bound.
2020-08-30 17:43:19.811 GMT 05:30 INFO rid=NA cid=NA 21756 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-08-30 17:43:19.813 GMT 05:30 ERROR rid=NA cid=NA 21756 --- [ main] o.s.b.d.LoggingFailureAnalysisReporter :
***************************
APPLICATION FAILED TO START
***************************
Description:
The bean 'dispatcherServlet', defined in class path resource [com/mycompany/asr/autoconfigure/asr/ASRAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path r
esource [org/springframework/boot/autoconfigure/web/servlet/DispatcherServletAutoConfiguration$DispatcherServletConfiguration.class] and overriding is disabled.
Action:
Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true
Класс, в котором это определение компонента приведено ниже. И это сторонний jar , который не может быть изменен:
@Configuration
@PropertySource("asr.properties")
@EnableConfigurationProperties(AsrProperties.class)
public class ASRAutoConfiguration {
@Autowired
AsrProperties asrProperties;
@Bean
public EmbeddedServletContainerCustomizer getEmbeddedServletContainerCustomizer() {
// this property is accessed from many Contexts, so setting in system is the easiest
System.setProperty("org.apache.catalina.STRICT_SERVLET_COMPLIANCE", "true");
// configure Tomcat based on properties
AsrTomcatProperties asrTomcatProperties = new AsrTomcatProperties();
asrTomcatProperties.setConnectionTimeout(asrProperties.getServer().getConnectionTimeout());
asrTomcatProperties.setMaxSwallowSize(asrProperties.getServer().getMaxSwallowSize());
return new AsrEmbeddedTomcatCustomizer(asrTomcatProperties);
}
/**
* This is done to disable Spring MVC dispatcherServlet
*/
@Bean(name = "dispatcherServlet")
public String getDispatcherServlet() {
return "";
}
@Bean
public WebApplicationExceptionResponseBuilder getWebApplicationExceptionResponseBuilder() {
return new WebApplicationExceptionResponseBuilder();
}
@Bean
public ScmContext getScmContext() {
return new ScmContext();
}
}
Я следил за этими потоками https://brudenko.com/spring-bean-override , https://blog.tratif.com/2018/03/08/when-two-beans-collide / . Но если я устанавливаю spring.main.allow-bean-definition-overriding=true в application.properties. Я начинаю получать ошибку ниже:
2020-08-30 18:24:14.438 GMT 05:30 INFO rid=NA cid=NA 13076 --- [ main] o.s.s.petclinic.PetClinicApplication : Starting PetClinicApplication v2.3.1.BUILD-SNAPSHOT on sasas-WX-3 with PID 13076 (C:
workupstreamfault-tolerance-demotargetspring-petclinic-2.3.1.BUILD-SNAPSHOT.jar started by krsoni in C:workupstreamfault-tolerance-demo)
2020-08-30 18:24:14.444 GMT 05:30 INFO rid=NA cid=NA 13076 --- [ main] o.s.s.petclinic.PetClinicApplication : No active profile set, falling back to default profiles: default
2020-08-30 18:24:16.293 GMT 05:30 ERROR rid=NA cid=NA 13076 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Error processing condition on de.codecentric.spring.boot.chaos.monkey.configuration.ChaosMonkeyConfiguration.chaosMonkeyRestEndpoint
at org.springframework.boot.autoconfigure.condition.SpringBootCondition.matches(SpringBootCondition.java:60)
at org.springframework.context.annotation.ConditionEvaluator.shouldSkip(ConditionEvaluator.java:108)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:184)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass(ConfigurationClassBeanDefinitionReader.java:144)
at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitions(ConfigurationClassBeanDefinitionReader.java:120)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.processConfigBeanDefinitions(ConfigurationClassPostProcessor.java:331)
at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:236)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:280)
at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:96)
at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:707)
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:533)
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 org.springframework.boot.SpringApplication.run(SpringApplication.java:1237)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.samples.petclinic.PetClinicApplication.main(PetClinicApplication.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at org.springframework.boot.loader.JarLauncher.main(JarLauncher.java:88)
Caused by: java.lang.IllegalStateException: Failed to introspect Class [com.mycompany.asr.autoconfigure.asr.ASRAutoConfiguration] from ClassLoader [org.springframework.boot.loader.LaunchedURLClassLoader@5197848c]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481)
at org.springframework.util.ReflectionUtils.doWithMethods(ReflectionUtils.java:358)
at org.springframework.util.ReflectionUtils.getUniqueDeclaredMethods(ReflectionUtils.java:414)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.lambda$getTypeForFactoryMethod$2(AbstractAutowireCapableBeanFactory.java:743)
at java.util.concurrent.ConcurrentHashMap.computeIfAbsent(Unknown Source)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.getTypeForFactoryMethod(AbstractAutowireCapableBeanFactory.java:742)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.determineTargetType(AbstractAutowireCapableBeanFactory.java:681)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.predictBeanType(AbstractAutowireCapableBeanFactory.java:649)
at org.springframework.beans.factory.support.AbstractBeanFactory.isFactoryBean(AbstractBeanFactory.java:1608)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 46 common frames omitted
2020-08-30 18:24:16.299 GMT 05:30 WARN rid=NA cid=NA 13076 --- [ main] o.s.boot.SpringApplication : Unable to close ApplicationContext
java.lang.IllegalStateException: Failed to introspect Class [com.mycompany.asr.autoconfigure.asr.ASRAutoConfiguration] from ClassLoader [org.springframework.boot.loader.LaunchedURLClassLoader@5197848c]
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:481)
Caused by: java.lang.NoClassDefFoundError: org/springframework/boot/context/embedded/EmbeddedServletContainerCustomizer
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Unknown Source)
at java.lang.Class.getDeclaredMethods(Unknown Source)
at org.springframework.util.ReflectionUtils.getDeclaredMethods(ReflectionUtils.java:463)
... 29 common frames omitted
Caused by: java.lang.ClassNotFoundException: org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at org.springframework.boot.loader.LaunchedURLClassLoader.loadClass(LaunchedURLClassLoader.java:151)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 33 common frames omitted
Комментарии:
1.
spring-boot-starter-web
автоконфигурирует компонент с именемdispatcherServlet
типаorg.springframework.web.servlet.DispatcherServlet
, поэтому вы не можете переопределить его как компонент типаString
, если вы этого не разрешите. — Когда вы это разрешаете, ваш компонент типаString
заменяет компонент типаDispatcherServlet
. Почему вы хотите определить компонент с таким очень особенным именем с этим типом? Это не имеет смысла. Веб-автоконфигурация ищет компонент с именемdispatcherServlet
и пытается принудительно ввести найденный компонентDispatcherServlet
, но вы не можете создатьDispatcherServlet
изString
.2. @Andreas: Компонент строкового типа определен в каком-либо стороннем jar. Я не определил это. Теперь, как решить эту проблему, поскольку я не могу вносить изменения в стороннюю jar
3. Сторонний jar, который создает компонент с
String
именемdispatcherServlet
, не может использоваться сspring-boot-starter-web
. Вероятно, предполагается, что он используется с Spring, а не с Spring Boot. — Попробуйте исключить@Configuration
компонент, у которого есть@Bean
метод, из проверки компонентов, чтобы он не испортил ваш контейнер.
Ответ №1:
‘Если у вас есть дополнительные сервлеты, вы можете объявить @Bean типа Servlet или ServletRegistrationBean для каждого, и Spring Boot прозрачно зарегистрирует их в контейнере. Поскольку сервлеты регистрируются таким образом, они могут быть сопоставлены с подконтекстом DispatcherServlet без его вызова.
Настройка DispatcherServlet самостоятельно необычна, но если вам действительно нужно это сделать, также необходимо указать @Bean типа DispatcherServletPath, чтобы указать путь к вашему пользовательскому DispatcherServlet.’