@Override
        public void write(Object msg, ChannelPromise promise) {
            assert eventLoop().inEventLoop();

            ChannelOutboundBuffer outboundBuffer = this.outboundBuffer;
            if (outboundBuffer == null) {
                // If the outboundBuffer is null we know the channel was closed and so
                // need to fail the future right away. If it is not null the handling of the rest
                // will be done in flush0()
                // See https://github.com/netty/netty/issues/2362
                close(voidPromise());
                ReferenceCountUtil.release(msg);
                throw new RuntimeException("Unable to write", initialCloseCause);
            }

            int size;
            try {
                msg = filterOutboundMessage(msg);
                // Reflection due to privacy
                Method estimatorHandle = DefaultChannelPipeline.class.getDeclaredMethod("estimatorHandle");
                estimatorHandle.setAccessible(true);
                MessageSizeEstimator.Handle handle = (MessageSizeEstimator.Handle) estimatorHandle.invoke(pipeline);
                // end of reflection
                size = handle.size(msg);
                if (size < 0) {
                    size = 0;
                }
            } catch (Throwable t) {
                close(voidPromise());
                ReferenceCountUtil.release(msg);
                logger.error("Problem during write", t);
                throw new RuntimeException("Problem during write", t);
            }

            outboundBuffer.addMessage(msg, size, promise);
        }
Copied and adapted from {@link io.netty.channel.nio.AbstractNioChannel.AbstractNioUnsafe}
plc4j/transports/serial/src/main/java/org/apache/plc4x/java/transport/serial/SerialChannel.java