为什么Spring Boot中的反应式网关不支持外部tomcat servlet容器,Invalid bean定义'errorAttributes'这个错误?

问题描述 投票:0回答:1
2024-04-27T20:19:27.808+05:30  INFO 4868 --- [GATEWAY] [           main] com.hajeri.gateway.GatewayApplication    : Starting GatewayApplication using Java 21.0.1 with PID 4868 (C:\Users\Admin\Desktop\Deploy Hajeri Micro-service\gateway\webapps\ROOT\WEB-INF\classes started by Admin in C:\Users\Admin\Desktop\Deploy Hajeri Micro-service\gateway\bin)
2024-04-27T20:19:27.820+05:30  INFO 4868 --- [GATEWAY] [           main] com.hajeri.gateway.GatewayApplication    : No active profile set, falling back to 1 default profile: "default"
2024-04-27T20:19:32.691+05:30  WARN 4868 --- [GATEWAY] [           main] ConfigServletWebServerApplicationContext : Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'errorAttributes' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; factoryMethodName=errorAttributes; initMethodNames=null; destroyMethodNames=[(inferred)]; defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]] for bean 'errorAttributes' since there is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; factoryMethodName=errorAttributes; initMethodNames=null; destroyMethodNames=[(inferred)]; defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/error/ErrorWebFluxAutoConfiguration.class]] bound.
2024-04-27T20:19:32.743+05:30  INFO 4868 --- [GATEWAY] [           main] .s.b.a.l.ConditionEvaluationReportLogger :

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2024-04-27T20:19:32.922+05:30 ERROR 4868 --- [GATEWAY] [           main] o.s.b.d.LoggingFailureAnalysisReporter   :

***************************
APPLICATION FAILED TO START
***************************

Description:

The bean 'errorAttributes', defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/error/ErrorWebFluxAutoConfiguration.class] and overriding is disabled.

Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

27-Apr-2024 20:19:32.923 SEVERE [main] org.apache.catalina.startup.HostConfig.deployDirectory Error deploying web application directory [C:\Users\Admin\Desktop\Deploy Hajeri Micro-service\gateway\webapps\ROOT]
        java.lang.IllegalStateException: Error starting child
                at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:686)
                at org.apache.catalina.core.ContainerBase.addChild(ContainerBase.java:658)
                at org.apache.catalina.core.StandardHost.addChild(StandardHost.java:712)
                at org.apache.catalina.startup.HostConfig.deployDirectory(HostConfig.java:1130)
                at org.apache.catalina.startup.HostConfig$DeployDirectory.run(HostConfig.java:1933)
                at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
                at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
                at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
                at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:123)
                at org.apache.catalina.startup.HostConfig.deployDirectories(HostConfig.java:1041)
                at org.apache.catalina.startup.HostConfig.deployApps(HostConfig.java:425)
                at org.apache.catalina.startup.HostConfig.start(HostConfig.java:1629)
                at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:303)
                at org.apache.catalina.util.LifecycleBase.fireLifecycleEvent(LifecycleBase.java:114)
                at org.apache.catalina.util.LifecycleBase.setStateInternal(LifecycleBase.java:402)
                at org.apache.catalina.util.LifecycleBase.setState(LifecycleBase.java:345)
                at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:893)
                at org.apache.catalina.core.StandardHost.startInternal(StandardHost.java:845)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
                at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1332)
                at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1322)
                at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
                at org.apache.tomcat.util.threads.InlineExecutorService.execute(InlineExecutorService.java:75)
                at java.base/java.util.concurrent.AbstractExecutorService.submit(AbstractExecutorService.java:145)
                at org.apache.catalina.core.ContainerBase.startInternal(ContainerBase.java:866)
                at org.apache.catalina.core.StandardEngine.startInternal(StandardEngine.java:240)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
                at org.apache.catalina.core.StandardService.startInternal(StandardService.java:433)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
                at org.apache.catalina.core.StandardServer.startInternal(StandardServer.java:921)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
                at org.apache.catalina.startup.Catalina.start(Catalina.java:757)
                at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:103)
                at java.base/java.lang.reflect.Method.invoke(Method.java:580)
                at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:345)
                at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:473)
        Caused by: org.apache.catalina.LifecycleException: Failed to start component [StandardEngine[Catalina].StandardHost[localhost].StandardContext[]]
                at org.apache.catalina.util.LifecycleBase.handleSubClassException(LifecycleBase.java:419)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:186)
                at org.apache.catalina.core.ContainerBase.addChildInternal(ContainerBase.java:683)
                ... 35 more
        Caused by: org.springframework.beans.factory.support.BeanDefinitionOverrideException: Invalid bean definition with name 'errorAttributes' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]: Cannot register bean definition [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration; factoryMethodName=errorAttributes; initMethodNames=null; destroyMethodNames=[(inferred)]; defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/error/ErrorMvcAutoConfiguration.class]] for bean 'errorAttributes' since there is already [Root bean: class [null]; scope=; abstract=false; lazyInit=null; autowireMode=3; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration; factoryMethodName=errorAttributes; initMethodNames=null; destroyMethodNames=[(inferred)]; defined in class path resource [org/springframework/boot/autoconfigure/web/reactive/error/ErrorWebFluxAutoConfiguration.class]] bound.
                at org.springframework.beans.factory.support.DefaultListableBeanFactory.registerBeanDefinition(DefaultListableBeanFactory.java:1017)
                at org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod(ConfigurationClassBeanDefinitionReader.java:277)
                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:428)
                at org.springframework.context.annotation.ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(ConfigurationClassPostProcessor.java:289)
                at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanDefinitionRegistryPostProcessors(PostProcessorRegistrationDelegate.java:349)
                at org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(PostProcessorRegistrationDelegate.java:118)
                at org.springframework.context.support.AbstractApplicationContext.invokeBeanFactoryPostProcessors(AbstractApplicationContext.java:788)
                at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:606)
                at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146)
                at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754)
                at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456)
                at org.springframework.boot.SpringApplication.run(SpringApplication.java:334)
                at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.run(SpringBootServletInitializer.java:174)
                at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.createRootApplicationContext(SpringBootServletInitializer.java:154)
                at org.springframework.boot.web.servlet.support.SpringBootServletInitializer.onStartup(SpringBootServletInitializer.java:96)
                at org.springframework.web.SpringServletContainerInitializer.onStartup(SpringServletContainerInitializer.java:171)
                at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:4880)
                at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:171)
                ... 36 more
27-Apr-2024 20:19:32.933 INFO [main] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory [C:\Users\Admin\Desktop\Deploy Hajeri Micro-service\gateway\webapps\ROOT] has finished in [20,886] ms
27-Apr-2024 20:19:32.942 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler ["http-nio-1002"]
27-Apr-2024 20:19:32.986 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [23395] milliseconds

我正在尝试使用 war 文件在外部 tomcat 上部署 Spring Boot 反应式网关。在Intellij中运行正常。这是我的依赖部分。

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <version>3.2.2</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>

                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-webflux</artifactId>
                </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-actuator</artifactId>
                </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter</artifactId>
        </dependency>
                <dependency>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-web</artifactId>
                </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-circuitbreaker-resilience4j</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.projectreactor</groupId>
            <artifactId>reactor-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
        <finalName>reactive-gateway</finalName>
    </build>  
java spring-boot servlets spring-webflux tomcat10
1个回答
0
投票

它在reactive gateway官方文档中有描述(强调我的):

Spring Cloud Gateway 需要 Spring Boot 和 Spring Webflux 提供的 Netty 运行时。 它在传统的 Servlet 容器中或构建为 WAR 时不起作用

因此,您不能在 Tomcat 环境中使用反应式网关,也不能将 Spring Webflux 与 Tomcat 一起使用。对于此类技术,您必须将 Spring Boot 应用程序构建为 Jar,并直接使用 java 运行它。这可能是您的 IDE 在幕后所做的事情。

如果您需要 Tomcat,则可以使用 Gateway MVC 服务器 而不是反应式服务器。

© www.soinside.com 2019 - 2024. All rights reserved.