spring-cloud-gateway
spring-cloud-gateway copied to clipboard
Support Websockets in gateway server webmvc
I'm trying to get the secure websocket or non-secure websockets to work with the gateway in version 4.1.4. I get the same error using wss or ws.
I'm getting this error on startup:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'routerFunctionMapping' defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/WebMvcAutoConfiguration$EnableWebMvcConfiguration.class]: Error creating bean with name 'gatewayCompositeRouterFunction': Error creating bean with name 'scopedTarget.gatewayRouterFunctionHolder': Failed to instantiate [org.springframework.cloud.gateway.server.mvc.config.GatewayMvcPropertiesBeanDefinitionRegistrar$RouterFunctionHolder]: Factory method 'routerFunctionHolderSupplier' threw exception with message: Unable to find HandlerFunction for scheme: wss
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1788) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:975) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:962) ~[spring-context-6.1.8.jar:6.1.8]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:624) ~[spring-context-6.1.8.jar:6.1.8]
at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:146) ~[spring-boot-3.3.0.jar:3.3.0]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:754) ~[spring-boot-3.3.0.jar:3.3.0]
at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:456) ~[spring-boot-3.3.0.jar:3.3.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:335) ~[spring-boot-3.3.0.jar:3.3.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1363) ~[spring-boot-3.3.0.jar:3.3.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1352) ~[spring-boot-3.3.0.jar:3.3.0]
at com.alphabet.webservices.WebservicesApplication.main(WebservicesApplication.java:25) ~[classes/:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.boot.devtools.restart.RestartLauncher.run(RestartLauncher.java:50) ~[spring-boot-devtools-3.3.0.jar:3.3.0]
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'gatewayCompositeRouterFunction': Error creating bean with name 'scopedTarget.gatewayRouterFunctionHolder': Failed to instantiate [org.springframework.cloud.gateway.server.mvc.config.GatewayMvcPropertiesBeanDefinitionRegistrar$RouterFunctionHolder]: Factory method 'routerFunctionHolderSupplier' threw exception with message: Unable to find HandlerFunction for scheme: wss
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:607) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:337) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:335) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.DefaultListableBeanFactory$1.orderedStream(DefaultListableBeanFactory.java:473) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.web.servlet.function.support.RouterFunctionMapping.initRouterFunctions(RouterFunctionMapping.java:152) ~[spring-webmvc-6.1.8.jar:6.1.8]
at org.springframework.web.servlet.function.support.RouterFunctionMapping.afterPropertiesSet(RouterFunctionMapping.java:130) ~[spring-webmvc-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1835) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1784) ~[spring-beans-6.1.8.jar:6.1.8]
... 21 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.gatewayRouterFunctionHolder': Failed to instantiate [org.springframework.cloud.gateway.server.mvc.config.GatewayMvcPropertiesBeanDefinitionRegistrar$RouterFunctionHolder]: Factory method 'routerFunctionHolderSupplier' threw exception with message: Unable to find HandlerFunction for scheme: wss
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:648) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:485) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1337) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1167) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:562) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:522) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$1(AbstractBeanFactory.java:376) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.cloud.context.scope.GenericScope$BeanLifecycleWrapper.getBean(GenericScope.java:375) ~[spring-cloud-context-4.1.3.jar:4.1.3]
at org.springframework.cloud.context.scope.GenericScope.get(GenericScope.java:179) ~[spring-cloud-context-4.1.3.jar:4.1.3]
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:373) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:200) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35) ~[spring-aop-6.1.8.jar:6.1.8]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:704) ~[spring-aop-6.1.8.jar:6.1.8]
at org.springframework.cloud.gateway.server.mvc.config.GatewayMvcPropertiesBeanDefinitionRegistrar$RouterFunctionHolder$$SpringCGLIB$$0.getRouterFunction(<generated>) ~[spring-cloud-gateway-server-mvc-4.1.4.jar:na]
at org.springframework.cloud.gateway.server.mvc.config.GatewayMvcPropertiesBeanDefinitionRegistrar$DelegatingRouterFunction.accept(GatewayMvcPropertiesBeanDefinitionRegistrar.java:140) ~[spring-cloud-gateway-server-mvc-4.1.4.jar:4.1.4]
at org.springframework.cloud.gateway.server.mvc.common.ArgumentSupplierBeanPostProcessor.postProcessBeforeInitialization(ArgumentSupplierBeanPostProcessor.java:52) ~[spring-cloud-gateway-server-mvc-4.1.4.jar:4.1.4]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsBeforeInitialization(AbstractAutowireCapableBeanFactory.java:422) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1780) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:600) ~[spring-beans-6.1.8.jar:6.1.8]
... 31 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.springframework.cloud.gateway.server.mvc.config.GatewayMvcPropertiesBeanDefinitionRegistrar$RouterFunctionHolder]: Factory method 'routerFunctionHolderSupplier' threw exception with message: Unable to find HandlerFunction for scheme: wss
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:177) ~[spring-beans-6.1.8.jar:6.1.8]
at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:644) ~[spring-beans-6.1.8.jar:6.1.8]
... 49 common frames omitted
Caused by: java.lang.IllegalStateException: Unable to find HandlerFunction for scheme: wss
at org.springframework.cloud.gateway.server.mvc.config.RouterFunctionHolderFactory.getRouterFunction(RouterFunctionHolderFactory.java:172) ~[spring-cloud-gateway-server-mvc-4.1.4.jar:4.1.4]
at org.springframework.cloud.gateway.server.mvc.config.RouterFunctionHolderFactory.lambda$routerFunctionHolderSupplier$1(RouterFunctionHolderFactory.java:119) ~[spring-cloud-gateway-server-mvc-4.1.4.jar:4.1.4]
at java.base/java.util.ArrayList.forEach(ArrayList.java:1511) ~[na:na]
at org.springframework.cloud.gateway.server.mvc.config.RouterFunctionHolderFactory.routerFunctionHolderSupplier(RouterFunctionHolderFactory.java:118) ~[spring-cloud-gateway-server-mvc-4.1.4.jar:4.1.4]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:na]
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) ~[na:na]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:na]
at java.base/java.lang.reflect.Method.invoke(Method.java:568) ~[na:na]
at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:140) ~[spring-beans-6.1.8.jar:6.1.8]
... 50 common frames omitted
This is my application.yml:
cloud:
gateway:
mvc:
routes:
- id: websocket
uri: wss://example.com:9443
predicates:
- Path=/example/**
Here is the dependency:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway-mvc</artifactId>
<version>4.1.4</version>
</dependency>
Is there something misconfigured?
Yes, websockets are not supported yet in MVC gateway
So they're supported in the spring-cloud-starter-gateway?
Yes the reactive version has websocket support.
I just spent a few days migrating our gateway from reactive to mvc (because I need some Tomcat features), just to find out that websockets arent supported. This renders it useless for us...
Would be good to have an comparing overview of the two approaches in the documentation.
It is a planned feature
I agree with @HSKC. I lost several days because this isn't clearly documented. This thread is the only documentation that it doesn't work. I'd love to see something more explicit in the readme.
Does anyone already know why it is not supported yet? I maybe need that feature. I have already several workarounds in place so I could add another one here in my implementation, if I know where to start. :)
Is they any eta of this feature ? I would be very nice !
Will this feature gain some traction someday on Spring Cloud MVC? I'm on a special situation, we migrated from reactive to mvc, but the lack of websockets on mvc left us with 2 simultaneous api gateways, one for the websockets (reactive) and the other (mvc) for everything else, which is no ideal.