"IOException: Strange I/O stream" in CXF service client - java

We are seeing an intermittent error in CXF. The response is fairly large (several hundred KB), MTOM is enabled, and enabling DEBUG for the CXF request/response logging interceptors fixes the issue, similarly to this post (which is unresolved). Our project is leveraging CXF version 2.2.9.
javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: [was class java.io.IOException] Strange I/O stream, returned 0 bytes on read
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:146)
at com.sun.proxy.$Proxy751.browseFiles(Unknown Source)
…
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.RuntimeException: [was class java.io.IOException] Strange I/O stream, returned 0 bytes on read
at com.ctc.wstx.util.ExceptionUtil.throwRuntimeException(ExceptionUtil.java:18)
at com.ctc.wstx.sr.StreamScanner.throwLazyError(StreamScanner.java:731)
at com.ctc.wstx.sr.BasicStreamReader.safeFinishToken(BasicStreamReader.java:3657)
at com.ctc.wstx.sr.BasicStreamReader.getTextCharacters(BasicStreamReader.java:830)
at com.sun.xml.bind.v2.runtime.unmarshaller.StAXStreamConnector.handleCharacters(StAXStreamConnector.java:323)
…
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:124)
... 51 more
Caused by: java.io.IOException: Strange I/O stream, returned 0 bytes on read
at com.ctc.wstx.io.BaseReader.reportStrangeStream(BaseReader.java:148)
at com.ctc.wstx.io.UTF8Reader.loadMore(UTF8Reader.java:373)
…
I initially thought this was caused by a bad/invalid character (encoding?) in the response data; however, it is now looking more like a network issue. It is very odd, the service has been operating for a long time (years) without issue prior to running into this problem.
Why does this error occur? Is there a way to resolve this without enabling debug logging?

Likely an upgrade to a newer version of CXF may fix this. There were some bugs in the CXF mime streams. In particular, this looks very similar to:
https://issues.apache.org/jira/browse/CXF-3068

Based on this and considering the source code of com.ctc.wstx.io.UTF8Reader.loadMore, the problem is possible when the buffer passed to mBuffer through BaseReader(ReaderConfig, InputStream, byte[], int, int) is zero length.
Is the loadMore() method implementation correct? Should they do that if read() return 0?

Related

Redistribution fails for large messages in ActiveMQ Artemis

I'm using ActiveMQ Artemis version 2.19.1, and I'm facing an issue in a 6-node (3 masters) cluster where redistribution is failing for large messages with the below warning logs:
23:35:05,551 WARN [org.apache.activemq.artemis.core.server] AMQ222303: Redistribution by Redistributor[TEST_QUEUE/2244] of messageID = 196,950,715 failed: java.lang.UnsupportedOperationException: Method not supported with Large Messages
at org.apache.activemq.artemis.protocol.amqp.broker.AMQPLargeMessage.getData(AMQPLargeMessage.java:311) [artemis-amqp-protocol-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage.anyMessageAnnotations(AMQPMessage.java:1374) [artemis-amqp-protocol-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.protocol.amqp.broker.AMQPMessage.hasScheduledDeliveryTime(AMQPMessage.java:1352) [artemis-amqp-protocol-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.core.postoffice.impl.PostOfficeImpl.processRoute(PostOfficeImpl.java:1499) [artemis-server-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.core.server.cluster.impl.Redistributor$1.run(Redistributor.java:169) [artemis-server-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.utils.actors.OrderedExecutor.doTask(OrderedExecutor.java:42) [artemis-commons-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.utils.actors.OrderedExecutor.doTask(OrderedExecutor.java:31) [artemis-commons-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.utils.actors.ProcessorBase.executePendingTasks(ProcessorBase.java:65) [artemis-commons-2.19.1.jar:2.19.1]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [rt.jar:1.8.0_322]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [rt.jar:1.8.0_322]
at org.apache.activemq.artemis.utils.ActiveMQThreadFactory$1.run(ActiveMQThreadFactory.java:118) [artemis-commons-2.19.1.jar:2.19.1]
Later I see broker is removing consumers with below warning since properties=null:
00:10:28,280 WARN [org.apache.activemq.artemis.core.server] AMQ222151: removing consumer which did not handle a message, consumer=ServerConsumerImpl [id=57, filter=null, binding=LocalQueueBinding [address=TEST_QUEUE, queue=QueueImpl[name=TEST_QUEUE, postOffice=PostOfficeImpl [server=ActiveMQServerImpl::name=localhost], temp=false]#9c000b7, filter=null, name=TEST_QUEUE, clusterName=TEST_QUEUE1e359f55-c92b-11ec-b908-005056a3af3f]], message=Reference[157995028]:RELIABLE:AMQPLargeMessage( [durable=true, messageID=157995028, address=TEST_QUEUE, size=0, scanningStatus=SCANNED, applicationProperties={VER=05, trackingId=62701757c80c3004d037ded6}, messageAnnotations={}, properties=null, extraProperties = TypedProperties[_AMQ_AD=TEST_QUEUE]]: java.lang.IllegalArgumentException: Array must not be empty or null
at org.apache.qpid.proton.codec.CompositeReadableBuffer.append(CompositeReadableBuffer.java:688) [proton-j-0.33.10.jar:]
at org.apache.qpid.proton.engine.impl.DeliveryImpl.send(DeliveryImpl.java:345) [proton-j-0.33.10.jar:]
at org.apache.qpid.proton.engine.impl.SenderImpl.send(SenderImpl.java:74) [proton-j-0.33.10.jar:]
at org.apache.activemq.artemis.protocol.amqp.proton.ProtonServerSenderContext$LargeMessageDeliveryContext.deliverInitialPacket(ProtonServerSenderContext.java:686) [artemis-amqp-protocol-2.19.1.jar:2.19.1]
at org.apache.activemq.artemis.protocol.amqp.proton.ProtonServerSenderContext$LargeMessageDeliveryContext.deliver(ProtonServerSenderContext.java:587) [artemis-amqp-protocol-2.19.1.jar:2.19.1]
I have 6 consumers for this queue if one message out of many (let's say 1,000) is large - it should process other messages but, the processing is stopped completely with 0 consumers on the queue.
When you send large messages, within the first block sent the large message is parsed for properties. Most likely you are using large properties in a way the server is not being able to parse the first few bytes of the message. You should avoid using large properties and let the large portion only for the client.
We tried following up with many tests on this JIRA, and the only plausible scenarios would be through large properties, or some incomplete message your client is generating in a way the server can't parse it.
https://issues.apache.org/jira/browse/ARTEMIS-3837
if you provide a reproducer showing how the property is failing to be parsed we will follow up with a possible fix.
Please move any discussion regarding this to the JIRA. It could be a bug caused by your anti-pattern.

Web service call returns "Fault string, and possibly fault code, not set"

I have a java application (A) that calls the webservice.
1)Then I have another app (B) that uses the A jar.
The call is successful and needed data are returned.
2)Then I have web application that also uses the A jar.
In this case when the web service method is called from A app, an exception is thrown.
Since the class that executes the webservice call is the same in both cases, I'm not sure where the problem is.
The webservice is on https server. But I authenticate using credentials.
I think maybe something should be set in the web application, but I don't know what..
The exception is:
09:21:48.009 [http-nio-8084-exec-33] WARN o.a.cxf.phase.PhaseInterceptorChain - Interceptor for {http://www.myserver.com/ci}ci2#{http://www.myserver.com/ci}GetCertPath has thrown exception, unwinding now
java.lang.UnsupportedOperationException: null
at java.util.AbstractMap.put(AbstractMap.java:209) ~[na:1.8.0_92]
at org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor.setSoapAction(SoapPreProtocolOutInterceptor.java:122) ~[cxf-rt-bindings-soap-2.7.16.jar:2.7.16]
javax.xml.ws.soap.SOAPFaultException: Fault string, and possibly fault code, not set
at org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor.handleMessage(SoapPreProtocolOutInterceptor.java:63) ~[cxf-rt-bindings-soap-2.7.16.jar:2.7.16]
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:158)
at org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor.handleMessage(SoapPreProtocolOutInterceptor.java:47) ~[cxf-rt-bindings-soap-2.7.16.jar:2.7.16]
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272) ~[cxf-api-2.7.16.jar:2.7.16]
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:572) [cxf-api-2.7.16.jar:2.7.16]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:481) [cxf-api-2.7.16.jar:2.7.16]
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382) [cxf-api-2.7.16.jar:2.7.16]
at com.sun.proxy.$Proxy318.getCertPath(Unknown Source)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335) [cxf-api-2.7.16.jar:2.7.16]
..... more lines here :) .....
at java.util.AbstractMap.put(AbstractMap.java:209)
at org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor.setSoapAction(SoapPreProtocolOutInterceptor.java:122)
at org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor.handleMessage(SoapPreProtocolOutInterceptor.java:63)
Fault string, and possibly fault code, not set
at org.apache.cxf.binding.soap.interceptor.SoapPreProtocolOutInterceptor.handleMessage(SoapPreProtocolOutInterceptor.java:47)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
at org.apache.cxf.endpoint.ClientImpl.doInvoke(ClientImpl.java:572)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:481)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:382)
at org.apache.cxf.endpoint.ClientImpl.invoke(ClientImpl.java:335)
at org.apache.cxf.frontend.ClientProxy.invokeSync(ClientProxy.java:96)
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:136)
... 59 more
Any ideas?
Thank you.
EDIT:
Does it have to have any headers set? When connecting in case 1, there is nothing specific set and it's working.
Ok, so I have found the issue. The request should have included the content-type. Which is strange that it didn't threw an exception in the first case...
I have added Content-Type: application/soap+xml; charset=utf-8 and the web application is working too.
As I found out the javax.xml.ws.soap.SOAPFaultException: Fault string, and possibly fault code, not set is mostly connected to missing content-type..
In my case, this was due to a simple badly formatted URL in a placeholder. http:/xxx.yyu (note the single /)
CXF wasn't very clear running in JDK6 but running in JDK8 was more explicit

Receiving corrupted Stream on Server

I've an application that sends requests to a Server using Spring Remoting (HttpInvokerServiceExporter). Normaly that works fine. But some Requests causes an error on the server because of a corrupted Byte Stream. Then I get Errors like this:
java.io.StreamCorruptedException: invalid handle value: 0050001A
at java.io.ObjectInputStream.readHandle(ObjectInputStream.java:1433)
java.lang.ClassNotFoundException: org.smitch.debol.service.bo.type.MinPoadAmount
at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1387)
java.lang.ClassCastException: cannot assign instance of java.lang.Integer to field java.math.BigDecimal.intVal of type java.math.BigInteger in instance of java.math.BigDecimal
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2032)
org.springframework.web.servlet.DispatcherServlet: Could not complete request
java.io.StreamCorruptedException: invalid handle value: 005001DB
at java.io.ObjectInputStream.readHandle(ObjectInputStream.java:1433)
org.springframework.web.servlet.DispatcherServlet: Could not complete request
java.io.StreamCorruptedException: invalid type code: 50
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
The ClassNotFoundException I've quietly often.
org.smitch.debol.service.bo.type.MinPoadAmount
org.smitch.Pebol.service.bo.type.CashAmount
org.smitch.debol.service.bo.type.CaPhAmount
org.smitch.debol.serviPe.bo.type.EmvProfile
Then it's always a P somewhere in the Classname that should not be there.
But there can be 100 Requests in a Row without Problem.
Any hint's what's shaking my beautiful Stream?
Thanks,
Boskop

Does CXF with SOAP 1.1 have a maximum content length for text sent in a request?

Is there a maximum content length for text sent over CXF with SOAP 1.1? I'm running into an issue where one SOAP request is failing while the other succeeds. The only difference I have pinpointed between these request so far has been the bytes of text I am sending.
I see an error like the following:
checkException (UnexpectedServiceExceptionCheckImpl.java:35) - An unexpected exception was found from source=[DesignService.generate] type=[class javax.xml.ws.soap.SOAPFaultException] message=[Unmarshalling Error: [was class java.io.IOException] Strange I/O stream, returned 0 bytes on read ]:
javax.xml.ws.soap.SOAPFaultException: Unmarshalling Error: [was class java.io.IOException] Strange I/O stream, returned 0 bytes on read
at org.apache.cxf.jaxws.JaxWsClientProxy.invoke(JaxWsClientProxy.java:145)
at $Proxy146.generate(Unknown Source)
I don't believe there are any maximums except for memory usage. Are you seeing any errors? Can you trace the transaction using wireshark or something?

Problem getting Java Streams in HP Tandem (Non-Stop)

We are porting a simple Java application between Tandem NonStop systems, from G-Series to H-Series. Java version is 1.5.0_02.
When performing basic I/O tasks like getting output stream from or opening a client socket, we receive exceptions like
java.io.IOException: Value out of range
or
java.net.SocketException: Value out of range
("value out of range" is Tandem native jargon for, well, quite everything I suppose).
Has anybody got similar issues? i.e. I/O corruption while for example messing with JNI?
I suppose there is something wrong with the system, but where might it be?
Thank you.
EDIT:
adding snippets as requested
sample snippet (a) - using Runtime.exec () (adapted)
Properties envVars = new Properties();
Process p = r.exec("/bin/env");
envVars.load(p.getInputStream());
Stack trace (a):
java.io.IOException: Value out of range (errno:4034)
at java.io.FileInputStream.readBytes(Native Method)
at java.io.FileInputStream.read(FileInputStream.java:194)
at java.lang.UNIXProcess$DeferredCloseInputStream.read(UNIXProcess.java:221)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:254)
at java.io.BufferedInputStream.read(BufferedInputStream.java:313)
at sun.nio.cs.StreamDecoder$CharsetSD.readBytes(StreamDecoder.java:411)
at sun.nio.cs.StreamDecoder$CharsetSD.implRead(StreamDecoder.java:453)
at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:183)
at java.io.InputStreamReader.read(InputStreamReader.java:167)
at java.io.BufferedReader.fill(BufferedReader.java:136)
at java.io.BufferedReader.readLine(BufferedReader.java:299)
at java.io.BufferedReader.readLine(BufferedReader.java:362)
at util.Environment.getVariables(Environment.java:39)
Last line fails, and output gets redirected to console (!).
sample snippet (b) - using HttpURLConnection:
public WorkerThread (HttpURLConnection conn, String requestData, Logger logger)
{
this.conn = conn;
...
}
public void run ()
{
OutputStream out = conn.getOutputStream ();
}
Stack trace (b):
java.net.SocketException: Value out of range (errno:4034)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:333)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:195)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:182)
at java.net.Socket.connect(Socket.java:507)
at sun.net.NetworkClient.doConnect(NetworkClient.java:155)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:365)
at sun.net.www.http.HttpClient.openServer(HttpClient.java:477)
at sun.net.www.protocol.https.HttpsClient.<init>(HttpsClient.java:280)
at sun.net.www.protocol.https.HttpsClient.New(HttpsClient.java:337)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.getNewHttpClient(AbstractDelegateHttpsURLConnection.java:176)
at sun.net.www.protocol.http.HttpURLConnection.plainConnect(HttpURLConnection.java:736)
at sun.net.www.protocol.https.AbstractDelegateHttpsURLConnection.connect(AbstractDelegateHttpsURLConnection.java:162)
at sun.net.www.protocol.http.HttpURLConnection.getOutputStream(HttpURLConnection.java:828)
at sun.net.www.protocol.https.HttpsURLConnectionImpl.getOutputStream(HttpsURLConnectionImpl.java:230)
Case (a) can be avoided because it was a workaround for other issues with previous JRE version (!), but same behaviour with sockets is really nasty.
Error code 4034 seem to indicate that a specific server is not running in your NonStop cluster. Are you sure that your system is setup properly?
Update: The problem was caused by a spurious .so library.

Categories