[ https://issues.apache.org/jira/browse/CXF-6930?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15384027#comment-15384027 ]
Tobias Schöneberg commented on CXF-6930: ---------------------------------------- today i banged my head again, because i had negelected to switch off inbound data logging... any news on this issue? > Race-Condition with JMS-transport, LoggingInInterceptor spoils the payload > while logging it > ------------------------------------------------------------------------------------------- > > Key: CXF-6930 > URL: https://issues.apache.org/jira/browse/CXF-6930 > Project: CXF > Issue Type: Bug > Components: JMS > Affects Versions: 3.1.6 > Reporter: Tobias Schöneberg > > Hi, > I think we stumbled over a problem with cxf and the JMS-transport, > if the {{LoggingFeature}} is used to log incoming response messages. > The problem is that sometimes, {{ClientProxyImpl.invoke(...)}} returns > {{null}}, > but from the logged message payload, it's clear that there is a not-null > response payload coming from the sever. > I believe, I just figured out that it is in fact the logging of that very > payload which causes {{ClientProxyImpl.invoke(...)}} to return {{null}}. > How? > There is a race between the actual "client thread" which waited for the > server's response > (i.e. {{exchange.wait()}} in {{JMSConduit.sendAndReceiveMessage(...)}} ) > until notified by the ActiveMQ Session Task thread > (i.e. {{exchange.notifyAll()}} in {{JMSConduit.processReplyMessage(...)}} ) > one one side and the ActiveMQ Session Task thread itself on the other side. > Once the client thread is notified, it goes on with {{preProcessResult(...)}} > and {{handleResponse(...)}} and somewhere in there the message's > {{ByteArrayStream}} is read and the return object is created. > However, at the same time, back in the ActiveMQ thread, the interceptor chain > is run. > In my case it contains the {{LoggingInInterceptor}} which accesses the > message's *same* {{ByteArrayInputStream}}, in the method > {{LoggingInInterceptor.logInputStream(...)}} ). > Now, in {{logInputStream(...)}}, we have > {code:java} > IOUtils.copyAtLeast(bis, bos, limit == -1 ? Integer.MAX_VALUE : limit); > bos.flush(); > bis = new SequenceInputStream(bos.getInputStream(), bis); > // restore the delegating input stream or the input stream > if (is instanceof DelegatingInputStream) { > ((DelegatingInputStream)is).setInputStream(bis); > } else { > message.setContent(InputStream.class, bis); > } > {code} > My problem happens if the client thread tries to read the message while > "{{bis}}" was read, but not yet restored. During that time, "{{bis}}" is > closed for the in the client thread and it will skip over it (or throw an > Exception, based on its config). > My current best and maybe naive guess on how to solve this is to change the > method {{JMSConduit.processReplyMessage(...)}} > and execute the if-block around {{exchange.notifyAll();}} only after the > if-block around {{incomingObserver.onMessage(exchange.getInMessage());}} > WDYT? > Best reagards > Tobias -- This message was sent by Atlassian JIRA (v6.3.4#6332)