I am trying to use tomcat instead netty. To achive this i have excluded netty from dependencies and included tomcat, so my build.gradle dependecies:
dependencies {
compile (group: 'org.springframework.cloud', name: 'spring-cloud-starter-gateway', version: '2.0.0.M4') {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-netty'
}
compile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: '2.0.0.M7'
compile group: 'org.springframework.boot', name: 'spring-boot-starter-webflux'
}
Hower it is not enough, i get ClassCastException:
java.lang.ClassCastException: org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory
at org.springframework.cloud.gateway.filter.NettyWriteResponseFilter.lambda$filter$0(NettyWriteResponseFilter.java:61) ~[spring-cloud-gateway-core-2.0.0.M4.jar:2.0.0.M4]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) ~[reactor-core-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at reactor.core.publisher.Mono.subscribe(Mono.java:2913) ~[reactor-core-3.1.1.RELEASE.jar:3.1.1.RELEASE]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:167) ~[reactor-core-3.1.1.RELEASE.jar:3.1.1.RELEASE]
Is it possible to use tomcat with gateway instead netty?
Thanks!
Not currently.
I already have code for this that just needs to be formalized. The difficulty will be running all the tests with other containers.
@spencergibb can u provide code ?
@spencergibb How is the progress now? Thank you
None so far
Hi,
I am also facing the same issue and the error is as below
java.lang.ClassCastException: org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory
at org.springframework.cloud.gateway.filter.NettyWriteResponseFilter.lambda$filter$0(NettyWriteResponseFilter.java:61) ~[spring-cloud-gateway-core-2.0.0.BUILD-SNAPSHOT.jar:2.0.0.BUILD-SNAPSHOT]
@ghoddg this is likely not going to happen in 2.0.0. For now you have to use netty.
Hi @spencergibb .. I am starting my api gateway service with tomcat. The service is started properly but when i hit api, it is giving me the above error
Also, my requirement is that I want to deploy it on weblogic as war and then also it should work
is it possible?
No
@spencergibb Thanks for update.
@spencergibb , from above communication, i got understanding that, API Gateway Service with Spring Cloud Gateway will not work with Tomcat as well as Weblogic for now and it will work only with netty.
is my understanding correct?
Hello, I have a similar problem without Tomcat nor Jetty in classpath. The error I am getting is the following:
java.lang.ClassCastException: org.springframework.core.io.buffer.DefaultDataBufferFactory cannot be cast to org.springframework.core.io.buffer.NettyDataBufferFactory
at org.springframework.cloud.gateway.filter.NettyWriteResponseFilter.lambda$filter$0(NettyWriteResponseFilter.java:61) ~[spring-cloud-gateway-core-2.0.0.M6.jar:2.0.0.M6]
at reactor.core.publisher.MonoDefer.subscribe(MonoDefer.java:44) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.Mono.subscribe(Mono.java:3006) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.drain(MonoIgnoreThen.java:167) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreMain.ignoreDone(MonoIgnoreThen.java:185) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.MonoIgnoreThen$ThenIgnoreInner.onComplete(MonoIgnoreThen.java:234) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.FluxPeek$PeekSubscriber.onComplete(FluxPeek.java:245) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.FluxMap$MapSubscriber.onComplete(FluxMap.java:130) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.FluxRetryPredicate$RetryPredicateSubscriber.onComplete(FluxRetryPredicate.java:107) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.core.publisher.MonoCreate$DefaultMonoSink.success(MonoCreate.java:140) ~[reactor-core-3.1.3.RELEASE.jar:3.1.3.RELEASE]
at reactor.ipc.netty.channel.PooledClientContextHandler.fireContextActive(PooledClientContextHandler.java:84) ~[reactor-netty-0.7.3.RELEASE.jar:0.7.3.RELEASE]
at reactor.ipc.netty.http.client.HttpClientOperations.onInboundNext(HttpClientOperations.java:551) ~[reactor-netty-0.7.3.RELEASE.jar:0.7.3.RELEASE]
at reactor.ipc.netty.channel.ChannelOperationsHandler.channelRead(ChannelOperationsHandler.java:134) ~[reactor-netty-0.7.3.RELEASE.jar:0.7.3.RELEASE]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.CombinedChannelDuplexHandler$DelegatingChannelHandlerContext.fireChannelRead(CombinedChannelDuplexHandler.java:438) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:310) ~[netty-codec-4.1.20.Final.jar:4.1.20.Final]
at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:297) ~[netty-codec-4.1.20.Final.jar:4.1.20.Final]
at io.netty.handler.codec.ByteToMessageDecoder.callDecode(ByteToMessageDecoder.java:413) ~[netty-codec-4.1.20.Final.jar:4.1.20.Final]
at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:265) ~[netty-codec-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.CombinedChannelDuplexHandler.channelRead(CombinedChannelDuplexHandler.java:253) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:340) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1412) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:362) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:348) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:943) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:141) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:645) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:580) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:497) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:459) ~[netty-transport-4.1.20.Final.jar:4.1.20.Final]
at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:886) ~[netty-common-4.1.20.Final.jar:4.1.20.Final]
at java.lang.Thread.run(Thread.java:748) ~[na:1.8.0_151]
Is there another dependency that could cause this problem?
My Spring boot 2.0.0.RC1 dependencies are the following:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-core</artifactId>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-contract-wiremock</artifactId>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
I just noticed that this error occurs only in the testing mode. When run normally the gateway forwarding works fine.
Another thing I noticed is that when I use WebClient in tests instead of WebTestClient all is fine. Should using WebTestClient in spring-gateway based applications be prohibited?
It's not. It is used to test the gateway
@spencergibb It is indeed. The source of my problem was using the @AutoConfigureWebTestClient annotation. Without it my tests are working fine. When I use it I get the ClassCastException mentioned earlier. Do you think this calls for a separate issue?
are u open to pr's for tomcat support? for 2.0 or 2.1
@drdamour I already have code https://github.com/spring-cloud/spring-cloud-gateway/issues/145#issuecomment-358772643. The trouble is testing everything.
yeah i assumed you meant unit test and thus PR.
what type of testing are you referring to then?
Basically all the integration tests. Anything that spins up a container then makes real network calls thru the gateway.
k...how are you hoping to structure the tests...duality for every netty test have a tomcat test. or just abstract away the backing implementation in all the tests?
or is there some prior art you are looking to follow?
My guess is rerunning all the tests with some system properties. Copied tests is prohibitive. Most have a base class already.
how will that work with your maven circle build? just 2+ surefire/failsafe executions?
jenkins is our canonical build
ok doesn't change anything right? still just calls maven goals (i'm assuming) and i'm guessing you want to test all reactive containers supported on each build?
There's another problem of including tomcat, jetty etc...
def could make the netty container the default profile and have other profiles that bring in the others & exclude netty..but the build couldn't be done as one command AFAIK (don't think you can switch profiles/classpaths with extra executions of surefire or failsafe). Never tried though..maybe. could do the tests as other modules..but that'd either mean sharing a test jar from core or copy paste tests over.
good problem...
Maybe you can try to cancel the dependency ---providedRuntime('org.springframework.boot:spring-boot-starter-tomcat')
I am also facing the same issue and i do not want to migrate my services from tomcat to netty. Any idea, when can we expect the fix?
There is no timeline
I need my gateway to support SSE. I am not sure if it is the right place to ask, but is it possible to enable SSE in spring cloud netflix zuul by using RxJava ?
This is not the place to ask questions about zuul
Can i redirect to services running in tomcat from spring cloud gateway running in netty ?
Yes, just like you could use nginx or Apache to forward as well
same problem when i running in undertow.
No need for comments like that as Netty is the only supported runtime at the moment.
I'm having the same issue when I try to test using spring-cloud-contract stub runners.
I believe SCC stub runner uses Wiremock underneath but have no idea what to do atm
Actually, I'm blocked testing my gateway using SCC Stub Runners
any idea?
Not sure if "Writing Tests Section" in this guide helps
https://spring.io/guides/gs/gateway/
If not you might want to open an issue in SCC.
Well, as far as I can see in the logs and looking into the debug logs etc. SCC does his part with Wiremock and I can see it picks up the right response and returns that back but when it comes to the gateway I receive this error
I guess SCG missing a filter, not sure but it could be. I
might have to spend some time to see if I can create my own filter to resolve this but don't think so
The filters already exist (See WebClient*Filter).
I cannot find any in 2.1.1.RELEASE
This mode is not supported yet, hence this issue, but they are there https://github.com/spring-cloud/spring-cloud-gateway/blob/master/spring-cloud-gateway-core/src/main/java/org/springframework/cloud/gateway/filter/WebClientHttpRoutingFilter.java
Thanks @spencergibb
adding this bean resolves 1 issue. the response status code is not 500 anymore but responseBody is null!
any ideas?
Actually, I see it ignored the body for GET
Adding latter bean results in same 500 response as before
This mode is not supported yet
There are likely bugs.
OK. thanks
any plan to support ?
When we do you'll see updates here
I seem to have hit that same issue when trying to test a gateway application, and am trying to understand my options. Specifically I have a gateway application with some routes that I want to stub out for unit testing.
It looks like this makes the gateway incompatible with every mock server I've tried (okhttp mockserver, wiremock, mockserver-netty), as the mock response is not castable to NettyDataBufferFactory.
Does this sound right so far? If so has anyone came up with a workaround for testing? I'm thinking, instead of using a mock server, stubbing WebClient out might be a suitable option also?
Is this issue resolved with Greenwich.SR3 release. Is there a sample pom to use Tomcat with spring cloud gateway?
@spencergibb : Is this issue resolved with Greenwich.SR3 release. Is there a sample pom to use Tomcat with spring cloud gateway?
No. It won't be in Greenwich, it will be in a Hoxton Service Release (SR)
85193a0d98fb9f8b1caabc30071a8a9041d69536 may have fixed this functionality. The class cast exceptions mentioned here https://github.com/spring-cloud/spring-cloud-gateway/issues/145#issue-284704955 are now gone.
Remaining items:
WebSocketClient per container (see here for appropiate class conditions)// workaround for tomcat
@Bean
@Primary
TomcatWebSocketClient tomcatWebSocketClient() {
return new TomcatWebSocketClient();
}
Hmm those would be tests inside the gateway or some separate ones? Cause we could even embed running those tests inside the gateway build.
Just all the tests already in gateway
See #1544 for progress
@spencergibb Is it possible to use tomcat with gateway now?
Hi @spencergibb
I wanna use WebClientHttpRoutingFilter and WebClientWriteResponseFilter with Netty.
Is there any issue with Netty?
And is there any way to disable NettyRoutingFilter?
@dlsrb6342 it's unrelated to this issue. There's no way to disable the netty beans at this moment.
Most helpful comment
WebClientHttpRoutingFilterandWebClientWriteResponseFilter