Affects: 6.0.x (and all prior versions)
Using a standard implementation of the org.springframework.web.reactive.socket.WebSocketHandler
class, it is not currently possible to send binary messages using the org.springframework.web.reactive.socket.WebSocketSession.binaryMessage(Function<DataBufferFactory,DataBuffer> payloadFactory)
function, at least on my system (Windows 10 + Microsoft Build of OpenJDK 17.0.6).
It seems as if the default WebSocketSession
implementation used is the TomcatWebSocketSession
. To send messages it relies on this method which creates a read only copy of the ByteBuffer, blocking visibility to the underlying byte[]
. This byte[]
is required later in the sending processes (i.e. here), however when requested through the array()
method, only produces a ReadOnlyBufferException
.
Is the proper solution to this issue to change the readableByteBuffers()
call here to writableByteBuffers()
even though this allows for array modification, or to create a non-readOnly deep copy that permits access to a copy of the underlying byte[]
at the cost of performance?
Comment From: simonbasle
hey @markkoszykowski,
do you have other examples where this exception is raised? I don't think it's wrong to use readonly ByteBuffer
s per se on Jakarta WebSocket RemoteEndpoint
s. At least I couldn't find anything in the spec or the documentation...
On the other hand, obtaining the bytes of a ByteBuffer
via array()
must be guarded with hasArray()
per the JDK documentation. There are other means of obtaining the byte[]
that are portable to both direct buffers and read-only buffers, but this one is not.
Unfortunately, the Tomcat PerMessageDeflate
class doesn't appear to check for hasArray()
. I think that is an issue there and not in the Spring Framework.
Comment From: simonbasle
Created bug report in Tomcat: https://bz.apache.org/bugzilla/show_bug.cgi?id=66575
Comment From: markkoszykowski
After doing a quick local test, changing this line to use the setInput(ByteBuffer input)
method instead of directly trying to access the array seemed to get binary messages to go through. Thanks for the help!
Comment From: simonbasle
Thanks for confirming this, closing this as invalid
/for:external-project
as a result 👍