Kengo Seki created CAMEL-20124:
----------------------------------
Summary: camel-netty - Fix ChannelHandlerFactories to create a new
ByteArrayDecoder instance for each newByteArrayDecoder method call
Key: CAMEL-20124
URL: https://issues.apache.org/jira/browse/CAMEL-20124
Project: Camel
Issue Type: Bug
Components: camel-netty
Reporter: Kengo Seki
Assignee: Kengo Seki
Recently I tried to set up a simple TCP proxy relaying any byte stream
leveraging the Netty component, just like:
{code}
///usr/bin/env jbang "$0" "$@" ; exit $?
//DEPS org.apache.camel:camel-bom:4.2.0@pom
//DEPS org.apache.camel:camel-core
//DEPS org.apache.camel:camel-main
//DEPS org.apache.camel:camel-netty
//DEPS org.apache.camel:camel-support
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.component.netty.ChannelHandlerFactories;
import org.apache.camel.main.Main;
import org.apache.camel.support.DefaultRegistry;
class proxy {
public static void main(String... args) throws Exception {
Main main = new Main();
main.configure().addRoutesBuilder(new RouteBuilder() {
public void configure() throws Exception {
DefaultRegistry registry = (DefaultRegistry)
getContext().getRegistry();
registry.bind("bytesDecoder",
ChannelHandlerFactories.newByteArrayDecoder("tcp"));
registry.bind("bytesEncoder",
ChannelHandlerFactories.newByteArrayEncoder("tcp"));
from("netty:tcp://0.0.0.0:1234?decoders=#bytesDecoder&encoders=#bytesEncoder")
.to("netty:tcp://localhost:5678?decoders=#bytesDecoder&encoders=#bytesEncoder")
;
}
});
main.run();
}
}
{code}
But sending data through this proxy fails with the following messages, and the
client doesn't get any response:
{code}
WARNING: Failed to initialize a channel. Closing: [id: 0x45bcede1]
io.netty.channel.ChannelPipelineException:
io.netty.handler.codec.bytes.ByteArrayDecoder is not a @Sharable handler, so
can't be added or removed multiple times.
at
io.netty.channel.DefaultChannelPipeline.checkMultiplicity(DefaultChannelPipeline.java:600)
at
io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:202)
at
io.netty.channel.DefaultChannelPipeline.addLast(DefaultChannelPipeline.java:195)
at
org.apache.camel.component.netty.DefaultClientInitializerFactory.addToPipeline(DefaultClientInitializerFactory.java:102)
at
org.apache.camel.component.netty.DefaultClientInitializerFactory.initChannel(DefaultClientInitializerFactory.java:72)
...
{code}
This is because [{{ChannelHandlerFactories}} wraps {{ByteArrayDecoder}} with
{{ShareableChannelHandlerFactory}}|https://github.com/apache/camel/blob/camel-4.2.0/components/camel-netty/src/main/java/org/apache/camel/component/netty/ChannelHandlerFactories.java#L110],
but [it's not actually sharable (doesn't have a {{@ChannelHandler.Sharable}}
annotation)|https://github.com/netty/netty/blob/netty-4.1.100.Final/codec/src/main/java/io/netty/handler/codec/bytes/ByteArrayDecoder.java#L52].
A factory class that returns a new {{ByteArrayDecoder}} instance for each
{{newByteArrayDecoder()}} call is required here, [as the document
explained|https://camel.apache.org/components/4.0.x/netty-component.html#_using_non_shareable_encoders_or_decoders].
--
This message was sent by Atlassian Jira
(v8.20.10#820010)