Spring websocket EOFException - spring-boot

My project is using spring-boot web socket and embedded tomcat to implement chat server. Everything is ok but sometimes I got EOFException, and then the client cannot send a message to chat server until I restart tomcat then everything worked ok. I don't know when EOFException will happen. Pls help me
[TRACE] 2017-10-23 06:17:10.707 [http-nio-7755-exec-4]
NativeWebSocketSession - Sending TextMessage payload=[{"result":..],
byteCount=164, last=true], StandardWebSocketSession[id=42b, uri=/chat]
[DEBUG] 2017-10-23 06:17:29.670 [http-nio-7755-exec-8]
LoggingWebSocketHandlerDecorator - Transport error in
StandardWebSocketSession[id=42b, uri=/chat] java.io.EOFException: null
at
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer(NioEndpoint.java:1242)
~[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.read(NioEndpoint.java:1182)
~[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:72)
~[tomcat-embed-websocket-8.5.16.jar!/:8.5.16] at
org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:171)
~[tomcat-embed-websocket-8.5.16.jar!/:8.5.16] at
org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:151)
~[tomcat-embed-websocket-8.5.16.jar!/:8.5.16] at
org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:148)
[tomcat-embed-websocket-8.5.16.jar!/:8.5.16] at
org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:54)
[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:53)
[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:868)
[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1455)
[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
[?:1.8.0_131] at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
[?:1.8.0_131] at
org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
[tomcat-embed-core-8.5.16.jar!/:8.5.16] at
java.lang.Thread.run(Thread.java:748) [?:1.8.0_131] [DEBUG] 2017-10-23
06:17:29.671 [http-nio-7755-exec-8] LoggingWebSocketHandlerDecorator -
StandardWebSocketSession[id=42b, uri=/chat] closed with
CloseStatus[code=1006, reason=null]

Yup, i solved it. This exception will happen after client or server was interrupted or stopped without calling close socket method(maybe lost internet, or shutdown laptop or mobile when using socket). So if we would like to solve this problem, we have to implement ping/pong mechanism, after interval if we cannot get pong response from client, we will close this socket. Another way, we can catch this exception, then we will close old socket.
Thanks,
Andy

Well, I couldn't follow that. So here's my solution.
I was getting mysterious EOFExceptions when user sessions ended, and my solution was to beef up error handling (use a more detailed onError function) in the websocket onError method, like this.
I credit my rooting and rutting around javacodegeeks for eventually pointed me in the right direction.
#OnError
public void onError(Session sess, Throwable e) {
Throwable cause = e.getCause();
/* normal handling... */
if (cause != null)
System.out.println("Error-info: cause->" + cause);
try {
// Likely EOF (i.e. user killed session)
// so just Close the input stream as instructed
sess.close();
} catch (IOException ex) {
System.out.println("Handling eof, A cascading IOException was caught: " + ex.getMessage());
ex.printStackTrace();
} finally {
System.out.println("Session error handled. (likely unexpected EOF) resulting in closing User Session.");
}
}

Related

STOMP over WebSockets: Spring Boot expects JSON; NodeJs STOMP.js client fails to connect

When trying out STOMP over WebSockets, I noticed inconsistencies between different implementations, namely between a Spring Boot Java implementation and a NodeJs client written with STOMP.js.
When debugging into it, the difference is that in the Spring Boot app, the CONNECT message is expected to be a JSON array. For instance, this message is sent by their test client (written in JavaScript using the SocksJS library):
["CONNECT\naccept-version:1.1,1.0\nheart-beat:10000,10000\n\n\u0000"]
In contrast, my NodeJs STOMP.js test client (code is below) sends the following frame:
CONNECT
accept-version:1.0,1.1,1.2
heart-beat:4000,4000
^#
Unfortunately, I am not experienced with STOMP, but after reading through the specification, I did not understand why Spring Boot expects the data to be represented as a JSON array. Is this a known problem?
To demonstrate, let me share two example runs. One successful run to connect to RabbitMQ, followed by a failed attempt to connect against the Java Spring Boot app. (A reproducible setup with the code can be found at the end.)
Connect to RabbitMQ instance, which is configure to use STOMP over WebSockets (running on ws://localhost:15674/ws):
$ node client.js
Opening Web Socket...
Web Socket Opened...
>>> CONNECT
accept-version:1.0,1.1,1.2
heart-beat:4000,4000
Received data
<<< CONNECTED
server:RabbitMQ/3.8.8
session:session-WkKD6rN5BNc_ObKpziikYA
heart-beat:4000,4000
version:1.2
connected to server RabbitMQ/3.8.8
send PING every 4000ms
check PONG every 4000ms
onConnect called
<<< PONG
Received data
<<<
<<< PONG
>>> PING
Received data
<<<
Now connect (unsuccessfully) against the Spring Boot app (ws://localhost:5555/chat/123/k2qn3dl7/websocket):
node client.js
Opening Web Socket...
Web Socket Opened...
>>> CONNECT
accept-version:1.0,1.1,1.2
heart-beat:4000,4000
Received data
<<< o
Received data
<<< c[1007,""]
Connection closed to ws://localhost:5555/chat/123/k2qn3dl7/websocket
STOMP: scheduling reconnection in 5000ms
Opening Web Socket...
Web Socket Opened...
>>> CONNECT
accept-version:1.0,1.1,1.2
heart-beat:4000,4000
Received data
<<< o
^C
The reason why it fails is that Jackson (the JSON parser) failed to parse that payload:
CONNECT
accept-version:1.0,1.1,1.2
heart-beat:4000,4000
^#
As said, in the client that comes with the Spring Boot example, the payload looked like that:
["CONNECT\naccept-version:1.1,1.0\nheart-beat:10000,10000\n\n\u0000"]
Here is the full error in the Spring Boot app:
2021-07-22 13:58:59.546 INFO 74313 --- [nio-5555-exec-1] o.s.web.servlet.DispatcherServlet : Completed initialization in 1 ms
2021-07-22 13:58:59.594 ERROR 74313 --- [nio-5555-exec-1] s.w.s.s.t.s.WebSocketServerSockJsSession : Broken data received. Terminating WebSocket connection abruptly
com.fasterxml.jackson.core.JsonParseException: Unrecognized token 'CONNECT': was expecting (JSON String, Number, Array, Object or token 'null', 'true' or 'false')
at [Source: (String)"CONNECT
accept-version:1.0,1.1,1.2
heart-beat:4000,4000
"; line: 1, column: 8]
at com.fasterxml.jackson.core.JsonParser._constructError(JsonParser.java:2337) ~[jackson-core-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.core.base.ParserMinimalBase._reportError(ParserMinimalBase.java:720) ~[jackson-core-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._reportInvalidToken(ReaderBasedJsonParser.java:2903) ~[jackson-core-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser._handleOddValue(ReaderBasedJsonParser.java:1949) ~[jackson-core-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.core.json.ReaderBasedJsonParser.nextToken(ReaderBasedJsonParser.java:781) ~[jackson-core-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ObjectMapper._initForReading(ObjectMapper.java:4684) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:4586) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3548) ~[jackson-databind-2.12.3.jar:2.12.3]
at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:3516) ~[jackson-databind-2.12.3.jar:2.12.3]
at org.springframework.web.socket.sockjs.frame.Jackson2SockJsMessageCodec.decode(Jackson2SockJsMessageCodec.java:64) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.sockjs.transport.session.WebSocketServerSockJsSession.handleMessage(WebSocketServerSockJsSession.java:187) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.sockjs.transport.handler.SockJsWebSocketHandler.handleTextMessage(SockJsWebSocketHandler.java:93) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.handler.AbstractWebSocketHandler.handleMessage(AbstractWebSocketHandler.java:43) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.handleTextMessage(StandardWebSocketHandlerAdapter.java:114) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter.access$000(StandardWebSocketHandlerAdapter.java:43) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:85) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.springframework.web.socket.adapter.standard.StandardWebSocketHandlerAdapter$3.onMessage(StandardWebSocketHandlerAdapter.java:82) ~[spring-websocket-5.3.8.jar:5.3.8]
at org.apache.tomcat.websocket.WsFrameBase.sendMessageText(WsFrameBase.java:415) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.server.WsFrameServer.sendMessageText(WsFrameServer.java:129) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.WsFrameBase.processDataText(WsFrameBase.java:515) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.WsFrameBase.processData(WsFrameBase.java:301) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.WsFrameBase.processInputBuffer(WsFrameBase.java:133) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.server.WsFrameServer.onDataAvailable(WsFrameServer.java:85) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.server.WsFrameServer.doOnDataAvailable(WsFrameServer.java:183) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.server.WsFrameServer.notifyDataAvailable(WsFrameServer.java:162) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.upgradeDispatch(WsHttpUpgradeHandler.java:156) ~[tomcat-embed-websocket-9.0.46.jar:9.0.46]
at org.apache.coyote.http11.upgrade.UpgradeProcessorInternal.dispatch(UpgradeProcessorInternal.java:60) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:59) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:893) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1707) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128) ~[na:na]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628) ~[na:na]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) ~[tomcat-embed-core-9.0.46.jar:9.0.46]
at java.base/java.lang.Thread.run(Thread.java:829) ~[na:na]
2021-07-22 13:59:04.610 ERROR 74313 --- [nio-5555-exec-2] s.w.s.s.t.s.WebSocketServerSockJsSession : Broken data received. Terminating WebSocket connection abruptly
Path to reproduce:
NodeJs client code
Spring Boot test app
RabbitMQ test instance
Client code written in NodeJs:
// Required dependencies:
// "#stomp/stompjs": "6.1.0"
// "websocket": "1.0.34"
// Polyfills. For details see:
// https://stomp-js.github.io/guide/stompjs/rx-stomp/ng2-stompjs/pollyfils-for-stompjs-v5.html
Object.assign(global, { WebSocket: require('websocket').w3cwebsocket });
const StompJs = require('#stomp/stompjs');
const client = new StompJs.Client({
//brokerURL: 'ws://localhost:15674/ws', // RabbitMQ (should work)
brokerURL: 'ws://localhost:5555/chat/123/k2qn3dl7/websocket', // Spring app (should fail)
reconnectDelay: 5000,
heartbeatIncoming: 4000,
heartbeatOutgoing: 4000,
logRawCommunication: true,
debug: (x) => console.log(x),
});
client.onConnect = function (frame) {
console.log('onConnect called');
};
client.activate();
The Spring Boot app can be found here. I started it on port 5555:
git clone git#github.com:eugenp/tutorials.git
cd tutorials/spring-websockets
SERVER_PORT=5555 mvn spring-boot:run
Note: if you then go to http://localhost:5555, you will see a chat application served by the Spring Boot app. When you click connect, a STOMP connection will be established.
To start RabbitMQ, you can use the Docker container used for the tests in STOMP.js:
git clone git#github.com:stomp-js/stompjs.git
cd stompjs
sudo docker build -t myrabbitmq rabbitmq/
sudo docker run --rm -p 15674:15674 myrabbitmq
In short: The JSON messages were not "STOMP over native WebSockets" but "STOMP over SocksJS". The additional JSON layer was introduced by the SocksJS protocol, which is used in the Spring Boot example application.
Here is the longer story. It turned out, that my endpoint was wrong. Instead of
'ws://localhost:5555/chat/123/k2qn3dl7/websocket'
it should have been
'ws://localhost:5555/chat'
It had the wrong URI because I was copying the output that I saw in the browser. Instead I should have looked at the configuration:
#Override
public void registerStompEndpoints(final StompEndpointRegistry registry) {
registry.addEndpoint("/chat");
registry.addEndpoint("/chat").withSockJS();
registry.addEndpoint("/chatwithbots");
registry.addEndpoint("/chatwithbots").withSockJS();
}
Now the confusing part. As can be seen from the configuration, the Spring Boot application defines fallbacks with SocksJS.
If you remove the fallback, the confusing error message goes away. Yet when the fallback is active, Spring will try to process the request as SocksJS. That is why it tries to parse the STOMP frame as JSON, which results in the misleading error message.
In addition, I got confused by the JavaScript client used in the Spring Boot example:
function connect() {
var socket = new SockJS('/chat');
stompClient = Stomp.over(socket);
stompClient.connect({}, function(frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/messages', function(messageOutput) {
showMessageOutput(JSON.parse(messageOutput.body));
});
});
}
It is not connected over native WebSocket but over SocksJS. That explains why Firefox shows JSON requests, not the expected STOMP frames.

Jetty websocket client issue

Use Eclipse IDE in an attempt to create a java websocket client for an OpenHab project, thus using default Jetty websocket library. The OpenHab project intend to connect to a websocket endpoint requiring token authorization, send a request message and retrieve live/continuous measurements.
So, I have
public static final String SUBSCRIPTION_URL = "wss://api.tibber.com/v1-beta/gql/subscriptions";
Further, my WS open code:
public void open() throws Exception {
if (isConnected()) {
logger.warn("Open: connection is already open");
}
logger.warn("Connecting to: {}", SUBSCRIPTION_URL);
sslContextFactory = new SslContextFactory(true);
sslContextFactory.setTrustAll(true);
client = new WebSocketClient(sslContextFactory);
client.setMaxIdleTimeout(360 * 1000);
TibberWebSocketListener socket = new TibberWebSocketListener();
request = new ClientUpgradeRequest();
String token = new StringBuilder("Bearer ").append(configuration.getToken()).toString();
request.setHeader("Authorization", token);
request.setSubProtocols("graphql-subscriptions");
client.start();
client.connect(socket, new URI(SUBSCRIPTION_URL), request);
}
However, with this code it seems like I get connected, but end up with an IOException: Broken pipe after 1 minute. I get the same error both if I just connect without message / connect with send message.
13:59:15.987 [safeCall-1] WARN o.o.b.t.i.handler.TibberHandler:346 - Connecting to: wss://api.tibber.com/v1-beta/gql/subscriptions
13:59:16.390 [#1379116703-141] WARN o.o.b.t.i.handler.TibberHandler:385 - Connected to Server
14:00:16.430 [#1379116703-142] WARN o.o.b.t.i.handler.TibberHandler:392 - Closing a WebSocket due to Disconnected
14:00:16.434 [#1379116703-139] WARN o.o.b.t.i.handler.TibberHandler:399 - Error during websocket communication: Broken pipe
java.io.IOException: Broken pipe
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.flush(SslConnection.java:928)
at org.eclipse.jetty.io.WriteFlusher.flush(WriteFlusher.java:422)
at org.eclipse.jetty.io.WriteFlusher.write(WriteFlusher.java:277)
at org.eclipse.jetty.io.AbstractEndPoint.write(AbstractEndPoint.java:381)
at org.eclipse.jetty.websocket.common.io.FrameFlusher.flush(FrameFlusher.java:264)
at org.eclipse.jetty.websocket.common.io.FrameFlusher.process(FrameFlusher.java:193)
at org.eclipse.jetty.util.IteratingCallback.processing(IteratingCallback.java:241)
at org.eclipse.jetty.util.IteratingCallback.iterate(IteratingCallback.java:223)
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.outgoingFrame(AbstractWebSocketConnection.java:516)
at org.eclipse.jetty.websocket.client.io.WebSocketClientConnection.outgoingFrame(WebSocketClientConnection.java:72)
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.close(AbstractWebSocketConnection.java:184)
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:458)
at org.eclipse.jetty.websocket.common.io.AbstractWebSocketConnection.onFillable(AbstractWebSocketConnection.java:428)
at org.eclipse.jetty.io.AbstractConnection$ReadCallback.succeeded(AbstractConnection.java:311)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ssl.SslConnection$DecryptedEndPoint.onFillable(SslConnection.java:426)
at org.eclipse.jetty.io.ssl.SslConnection.onFillable(SslConnection.java:320)
at org.eclipse.jetty.io.ssl.SslConnection$2.succeeded(SslConnection.java:158)
at org.eclipse.jetty.io.FillInterest.fillable(FillInterest.java:103)
at org.eclipse.jetty.io.ChannelEndPoint$2.run(ChannelEndPoint.java:117)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.runTask(EatWhatYouKill.java:336)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.doProduce(EatWhatYouKill.java:313)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.tryProduce(EatWhatYouKill.java:171)
at org.eclipse.jetty.util.thread.strategy.EatWhatYouKill.run(EatWhatYouKill.java:129)
at org.eclipse.jetty.util.thread.ReservedThreadExecutor$ReservedThread.run(ReservedThreadExecutor.java:367)
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:782)
at org.eclipse.jetty.util.thread.QueuedThreadPool$Runner.run(QueuedThreadPool.java:918)
at java.lang.Thread.run(Thread.java:748)
14:00:16.435 [#1379116703-139] WARN o.o.b.t.i.handler.TibberHandler:392 - Closing a WebSocket due to Broken pipe
java.io.IOException: Broken pipe
That means the OS or network below Java (and Jetty) detected that the connection was closed.
"Broken Pipe" is actually fairly common, especially with mobile devices or wireless networking.
Not much Java or Jetty can do about it either, it happened outside of its control.

ConnectionClosedException: Premature end of chunk coded message body with apache hhtpclient 4.5.5

I am trying to parse http response from a GET request but it throws following exception.
org.apache.http.ConnectionClosedException: Premature end of chunk coded message body: closing chunk expected
at org.apache.http.impl.io.ChunkedInputStream.getChunkSize(ChunkedInputStream.java:266) ~[httpcore-4.4.10.jar!/:4.4.10]
at org.apache.http.impl.io.ChunkedInputStream.nextChunk(ChunkedInputStream.java:225) ~[httpcore-4.4.10.jar!/:4.4.10]
at org.apache.http.impl.io.ChunkedInputStream.read(ChunkedInputStream.java:184) ~[httpcore-4.4.10.jar!/:4.4.10]
at org.apache.http.conn.EofSensorInputStream.read(EofSensorInputStream.java:135) ~[httpclient-4.5.6.jar!/:4.5.6]
at java.base/sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284) ~[na:na]
at java.base/sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326) ~[na:na]
at java.base/sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178) ~[na:na]
at java.base/java.io.InputStreamReader.read(InputStreamReader.java:185) ~[na:na]
at java.base/java.io.Reader.read(Reader.java:229) ~[na:na]
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:227) ~[httpcore-4.4.10.jar!/:4.4.10]
at org.apache.http.util.EntityUtils.toString(EntityUtils.java:308) ~[httpcore-4.4.10.jar!/:4.4.10]
My code to parse the response is
String parseResponse(HttpResponse resp) {
try {
return org.apache.http.util.EntityUtils.toString(resp.getEntity());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
I used org.apache.httpcomponents:httpcore:4.5.6
The GET endpoint(spring boot application) which I invoke is as follows
public ResponseEntity<org.springframework.data.domain.
Page<JSONObject>> getList() {
}
I read here https://github.com/jersey/jersey/issues/3629 If I use org.apache.httpcomponents:httpclient:4.5.5 then it should work fine but it did not work for me.
Can someone please give some pointers.
I saw a similar question org.apache.http.ConnectionClosedException: Premature end of chunk coded message body: closing chunk expected but it did not help me.
Understood the issue. I was closing CloseableHttpClient and then trying to use the HTTPResponse.
Follwing post helped
https://stackoverflow.com/a/50136644/1053496

Spring Integration RSS Feed - 403 Error

I am trying to use Spring Integration to poll RSS feeds and I'm using SO user feed URL as an example. However when the application runs I get the following error:
Disconnected from the target VM, address: '127.0.0.1:58603', transport: 'socket'
2016-03-04 19:34:36.252 ERROR 2345 --- [ask-scheduler-4] o.s.integration.handler.LoggingHandler : org.springframework.messaging.MessagingException: Failed to retrieve feed at url 'http://stackoverflow.com/feeds/user/813852'; nested exception is com.rometools.fetcher.FetcherException: Authentication required for that resource. HTTP Response code was:403
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.getFeed(FeedEntryMessageSource.java:216)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.populateEntryList(FeedEntryMessageSource.java:182)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.doReceive(FeedEntryMessageSource.java:157)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.receive(FeedEntryMessageSource.java:122)
at org.springframework.integration.endpoint.SourcePollingChannelAdapter.receiveMessage(SourcePollingChannelAdapter.java:175)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.doPoll(AbstractPollingEndpoint.java:224)
at org.springframework.integration.endpoint.AbstractPollingEndpoint.access$000(AbstractPollingEndpoint.java:57)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:176)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$1.call(AbstractPollingEndpoint.java:173)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller$1.run(AbstractPollingEndpoint.java:330)
at org.springframework.integration.util.ErrorHandlingTaskExecutor$1.run(ErrorHandlingTaskExecutor.java:55)
at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50)
at org.springframework.integration.util.ErrorHandlingTaskExecutor.execute(ErrorHandlingTaskExecutor.java:51)
at org.springframework.integration.endpoint.AbstractPollingEndpoint$Poller.run(AbstractPollingEndpoint.java:324)
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54)
at org.springframework.scheduling.concurrent.ReschedulingRunnable.run(ReschedulingRunnable.java:81)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
Caused by: com.rometools.fetcher.FetcherException: Authentication required for that resource. HTTP Response code was:403
at com.rometools.fetcher.impl.AbstractFeedFetcher.throwAuthenticationError(AbstractFeedFetcher.java:183)
at com.rometools.fetcher.impl.AbstractFeedFetcher.handleErrorCodes(AbstractFeedFetcher.java:170)
at com.rometools.fetcher.impl.HttpURLFeedFetcher.retrieveAndCacheFeed(HttpURLFeedFetcher.java:186)
at com.rometools.fetcher.impl.HttpURLFeedFetcher.retrieveFeed(HttpURLFeedFetcher.java:140)
at com.rometools.fetcher.impl.HttpURLFeedFetcher.retrieveFeed(HttpURLFeedFetcher.java:99)
at org.springframework.integration.feed.inbound.FeedEntryMessageSource.getFeed(FeedEntryMessageSource.java:204)
... 22 more
The URL loads fine through the browser (even in incognito mode so the error message is probably misleading). I downloaded an RSS reader and the feed worked fine.
This is how I configured the feed:
<int-feed:inbound-channel-adapter id="stackOverflow"
channel="log"
url="http://stackoverflow.com/feeds/user/813852">
<int:poller fixed-rate="10000" max-messages-per-poll="100" />
</int-feed:inbound-channel-adapter>
<int:logging-channel-adapter id="log" level="DEBUG" />
I also tried another RSS feed URL and it worked. Any ideas what could be wrong?
I just ran a wireshark trace and it looks like StackOverflow doesn't like the java user agent:
User-Agent: Java/1.8.0_66\r\n
...
<p>The owner of this website (stackoverflow.com) has banned your access based
on your browser's signature (27e797571e1923de-ua21).</p>\n
Setting a custom user agent goes around this restriction:
public class CustomFeedFetcher extends HttpURLFeedFetcher {
#Override
public void setUserAgent(String s) {
super.setUserAgent("AgentName");
}
}

ActiveMQ connect, unknow data type: 49

I'm using ActiveMQ to send files from an application to another and I've encountered this error when the consumer attempt to connect at ActiveMQ server.
Here is the connect method
public void connect()
{
connectionFactory = new ActiveMQConnectionFactory(
"tcp://" + Configuration.getInstance().getServerAddress() +
":61616?jms.blobTransferPolicy.defaultUploadUrl=" + "http://" +
Configuration.getInstance().getServerAddress() + ":8161/fileserver/"
+ "&connectionTimeout=0&soTimeout=0&soWriteTimeout=0"
+ "&useInactivityMonitor=false");
try
{
connection = connectionFactory.createConnection();
session = (ActiveMQSession) connection.createSession(false,
Session.AUTO_ACKNOWLEDGE);
destination = session.createQueue(Configuration.getInstance().getQueueName());
consumer = session.createConsumer(destination);
connection.start();
// System.out.println("Consumer connected");
} catch (JMSException e) {
logger.error("PACS", e);
e.printStackTrace();
}
}
This is exactly the same method I use to connect the producer to ActiveMQ and in that case it works perfectly, at the consumer side I have the following error:
javax.jms.JMSException: Unknown data type: 49
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSuppo
rt.java:54)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnect
ion.java:1417)
at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(Activ
eMQConnection.java:1522)
at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnecti
on.java:328)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.connect(CloudPacsConsum
er.java:74)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.start(CloudPacsConsumer
.java:91)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.run(CloudPacsConsumer.j
ava:135)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.init(CloudPacsConsumer.
java:57)
at com.kratossrl.pacs.consumer.CloudPacsConsumer$1.call(CloudPacsConsume
r.java:39)
at com.kratossrl.pacs.consumer.CloudPacsConsumer$1.call(CloudPacsConsume
r.java:1)
at javafx.concurrent.Task$TaskCallable.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by: java.io.IOException: Unknown data type: 49
at org.apache.activemq.openwire.OpenWireFormat.doUnmarshal(OpenWireForma
t.java:348)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.
java:268)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTranspo
rt.java:221)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.jav
a:213)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:
196)
... 1 more
javax.jms.JMSException: Unknown data type: 49
at org.apache.activemq.util.JMSExceptionSupport.create(JMSExceptionSuppo
rt.java:54)
at org.apache.activemq.ActiveMQConnection.syncSendPacket(ActiveMQConnect
ion.java:1417)
at org.apache.activemq.ActiveMQConnection.ensureConnectionInfoSent(Activ
eMQConnection.java:1522)
at org.apache.activemq.ActiveMQConnection.createSession(ActiveMQConnecti
on.java:328)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.connect(CloudPacsConsum
er.java:74)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.start(CloudPacsConsumer
.java:91)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.run(CloudPacsConsumer.j
ava:135)
at com.kratossrl.pacs.consumer.CloudPacsConsumer.init(CloudPacsConsumer.
java:57)
at com.kratossrl.pacs.consumer.CloudPacsConsumer$1.call(CloudPacsConsume
r.java:39)
at com.kratossrl.pacs.consumer.CloudPacsConsumer$1.call(CloudPacsConsume
r.java:1)
at javafx.concurrent.Task$TaskCallable.call(Unknown Source)
at java.util.concurrent.FutureTask.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Caused by:
java.io.IOException: Unknown data type: 49
at org.apache.activemq.openwire.OpenWireFormat.doUnmarshal(OpenWireForma
t.java:348)
at org.apache.activemq.openwire.OpenWireFormat.unmarshal(OpenWireFormat.
java:268)
at org.apache.activemq.transport.tcp.TcpTransport.readCommand(TcpTranspo
rt.java:221)
at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.jav
a:213)
at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:
196)
... 1 more
I have seek in the web for this error but I have not found the '49' value.
Anyone has encountered my situation or knows the cause/solution of this problem?
Thanks in advice and sorry for my not perfect English
double-check your ActiveMQ versions, it almost appears that the client is more recent than the server and when they're negotiating the protocol the client sends something not understood by the server and the exception is thrown

Resources