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 ByteBuffers per se on Jakarta WebSocket RemoteEndpoints. 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 👍