I have checked / debugged the Wildfly code and in my opinion there are several bugs in both the server and the client code of the HTTP2 protocol marshalling/unmarshalling implementation.
First bug: The server sends suddenly (mostly on bigger objects) in the middle of the data stream a FRAME_TYPE_RST_STREAM (i.e. see io.undertow.protocols.http2.Http2FrameHeaderParser:191 --> type = header[3] & 0xff;),
which marks the stream as broken (see io.undertow.server.protocol.framed.AbstractFramedStreamSourceChannel:684 -->state |= STATE_STREAM_BROKEN;)
and afterwards causes "ClosedChannelExceptions" on stream reads in the client (see org.wildfly.httpclient.common.WildflyClientInputStream:58 -->int res = streamSourceChannel.read(pooled.getBuffer());)
Second bug (initiated by the above fact) : The client can't handle correctly this "ClosedChannelExceptions" (i.e reset stream), because it freezes. This should not happen under any circumstances!
So, client keeps reading from the channel and after each read it invokes the wait(0) on its own lock Object (see . org.wildfly.httpclient.common.WildflyClientInputStream:147 --> lock.wait();)
Normally this wait(0) is wake up by channel notifications on invoking the notifyAll() of same lock Object (in case of ClosedChannelExceptions it is the org.wildfly.httpclient.common.WildflyClientInputStream:94 --> lock.notifyAll();
Unluckily after the last read and therefore invoked wait(0), there is no more the notifyAll() invoked, so the EJB client call freezes for ever. This should not happen under any circumstances!
My solution I found is, and I have to admit I'm not happy with that, to disable the HTTP2 protocol on the server and use HTTP1.
<https-listener name="https" socket-binding="https" ssl-context="CHA-SSL-CONTEXT" enable-http2="false" />
Making the EJB calls over HTTP/1 works then also for huge Objects.
Involved classes with line numbers are all taken from Wildlfy 26.0.0 Client jar:
I hope some Wildfly Guru will read this and react.