Activity

Issue #1: Client is a one shot object, what I mean is, that it is neither thread safe nor multi-request capable if used asynchronously, because it wrappes the matching point for the response to the request. If you send several asynchrounos requests in a row, you'd need a fresh client for every request which leads to initialisation overhead.

Mika Goeckel
added a comment - 17/Feb/06 9:41 AM Issue #1: Client is a one shot object, what I mean is, that it is neither thread safe nor multi-request capable if used asynchronously, because it wrappes the matching point for the response to the request. If you send several asynchrounos requests in a row, you'd need a fresh client for every request which leads to initialisation overhead.

Issue #2: Client uses CommonsHttpClient underneath (with httptransport) which would enable it to maintain a session. But there is no way to keep the instance of the CommonsHttpClient, so the session handling capabilities can't be used. Neither can the connection pooling capabilities be used which would improve performance.

Mika Goeckel
added a comment - 17/Feb/06 9:43 AM Issue #2: Client uses CommonsHttpClient underneath (with httptransport) which would enable it to maintain a session. But there is no way to keep the instance of the CommonsHttpClient, so the session handling capabilities can't be used. Neither can the connection pooling capabilities be used which would improve performance.

Mika, I don't think its possible to make Client multithreaded safe. Christoph and I were talking last night and it needs to maintain state for asynchronous transports. I am inclined to mark this issue as closed and keep things this way Any objections/thoughts?

Dan Diephouse
added a comment - 05/Apr/06 4:53 PM Mika, I don't think its possible to make Client multithreaded safe. Christoph and I were talking last night and it needs to maintain state for asynchronous transports. I am inclined to mark this issue as closed and keep things this way Any objections/thoughts?

I'm no xfire developer so I'm not sure if I can be a part of this discussion. My thought is that you MUST have a multithreaded-capable client. What if an application makes several requests to a service? it could be even the same service? I can not afford to get an exception back. Also AXIS is multithreaded so it can deffinetly be done.

I'm using synchronous web service calls to an XFire web service (simple echo example) and I'm trying to create some load to see how it behaves, but my code throws exceptions all over.

Here is the stacktrace:

org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: Unexpected character 'w' (code 119) in prolog; expected '<'
at [row,col {unknown-source}]: [1,129]
org.codehaus.xfire.fault.XFireFault: Unexpected character 'w' (code 119) in prolog; expected '<'
at [row,col {unknown-source}]: [1,129]
at org.codehaus.xfire.fault.XFireFault.createFault(XFireFault.java:89)
at org.codehaus.xfire.client.Client.onReceive(Client.java:467)
at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:182)
at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:67)
at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:98)
at org.codehaus.xfire.client.Client.invoke(Client.java:360)
at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
at $Proxy1.echo(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
at com.verizon.snm.performance.PerformanceInterceptor.invoke(PerformanceInterceptor.java:18)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy0.echo(Unknown Source)
at com.verizon.snm.echo.EchoServiceClientTest.performTest(EchoServiceClientTest.java:71)
at com.verizon.snm.echo.EchoServiceClientTest.run(EchoServiceClientTest.java:66)
at java.lang.Thread.run(Unknown Source)
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'w' (code 119) in prolog; expected '<'
at [row,col {unknown-source}]: [1,129]
at com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:600)
at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:1889)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1026)
at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:44)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:98)
at org.codehaus.xfire.client.Client.onReceive(Client.java:450)
... 22 more

This exception happens when two (or more) threads invoke the line on Client.java:450 (version 1.1) at the same time.

Andres Bernasconi
added a comment - 26/May/06 9:02 AM Hi,
I'm no xfire developer so I'm not sure if I can be a part of this discussion. My thought is that you MUST have a multithreaded-capable client. What if an application makes several requests to a service? it could be even the same service? I can not afford to get an exception back. Also AXIS is multithreaded so it can deffinetly be done.
I'm using synchronous web service calls to an XFire web service (simple echo example) and I'm trying to create some load to see how it behaves, but my code throws exceptions all over.
Here is the stacktrace:
org.codehaus.xfire.XFireRuntimeException: Could not invoke service.. Nested exception is org.codehaus.xfire.fault.XFireFault: Unexpected character 'w' (code 119) in prolog; expected '<'
at [row,col {unknown-source}]: [1,129]
org.codehaus.xfire.fault.XFireFault: Unexpected character 'w' (code 119) in prolog; expected '<'
at [row,col {unknown-source}]: [1,129]
at org.codehaus.xfire.fault.XFireFault.createFault(XFireFault.java:89)
at org.codehaus.xfire.client.Client.onReceive(Client.java:467)
at org.codehaus.xfire.transport.http.HttpChannel.sendViaClient(HttpChannel.java:182)
at org.codehaus.xfire.transport.http.HttpChannel.send(HttpChannel.java:67)
at org.codehaus.xfire.handler.OutMessageSender.invoke(OutMessageSender.java:26)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:98)
at org.codehaus.xfire.client.Client.invoke(Client.java:360)
at org.codehaus.xfire.client.XFireProxy.handleRequest(XFireProxy.java:77)
at org.codehaus.xfire.client.XFireProxy.invoke(XFireProxy.java:57)
at $Proxy1.echo(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:335)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:181)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:148)
at com.verizon.snm.performance.PerformanceInterceptor.invoke(PerformanceInterceptor.java:18)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)
at $Proxy0.echo(Unknown Source)
at com.verizon.snm.echo.EchoServiceClientTest.performTest(EchoServiceClientTest.java:71)
at com.verizon.snm.echo.EchoServiceClientTest.run(EchoServiceClientTest.java:66)
at java.lang. Thread .run(Unknown Source)
Caused by: com.ctc.wstx.exc.WstxUnexpectedCharException: Unexpected character 'w' (code 119) in prolog; expected '<'
at [row,col {unknown-source}]: [1,129]
at com.ctc.wstx.sr.StreamScanner.throwUnexpectedChar(StreamScanner.java:600)
at com.ctc.wstx.sr.BasicStreamReader.nextFromProlog(BasicStreamReader.java:1889)
at com.ctc.wstx.sr.BasicStreamReader.next(BasicStreamReader.java:1026)
at org.codehaus.xfire.soap.handler.ReadHeadersHandler.invoke(ReadHeadersHandler.java:44)
at org.codehaus.xfire.handler.HandlerPipeline.invoke(HandlerPipeline.java:98)
at org.codehaus.xfire.client.Client.onReceive(Client.java:450)
... 22 more
This exception happens when two (or more) threads invoke the line on Client.java:450 (version 1.1) at the same time.
recvContext.setInPipeline(inPipe);
inPipe.invoke(context); //<------------ this line
MessageInfo msgInfo = exchange.getOperation().getOutputMessage();
In my humble user opinion, this is a must to be fixed.
My 2 cents.
Regards,
Andrés B.

Hi, I'm with the Mule ESB project and fixed our XFire multithreading yesterday (http://jira.symphonysoft.com/browse/MULE-820) so I can maybe add my point of view.
It is important to distinguish between "thread-safe" and "concurrent". I agree that it would be nice to have the Client threadsafe instead of letting it explode, though I don't know how difficult it would be to synchronize on all shared state for all operations.
It would certainly be easier than to make the Client truly concurrent, which is not such a good idea as it first sounds. Applications that are in control of their concurrency requirements can easily add a pool of Client objects that are acquired per thread's request and then returned; this approach is actually much better since usually SOAP calls are pretty expensive in terms of latency, and the last thing you want is hundreds of web sessions smashing into your SOAP service at the same time. The pool provides a much more adaptable/tuneable solution for the applications' concurrency behaviour as an internally concurrent Client object could ever manage itself.

Holger Hoffstätte
added a comment - 27/May/06 6:42 AM Hi, I'm with the Mule ESB project and fixed our XFire multithreading yesterday ( http://jira.symphonysoft.com/browse/MULE-820 ) so I can maybe add my point of view.
It is important to distinguish between "thread-safe" and "concurrent". I agree that it would be nice to have the Client threadsafe instead of letting it explode, though I don't know how difficult it would be to synchronize on all shared state for all operations.
It would certainly be easier than to make the Client truly concurrent , which is not such a good idea as it first sounds. Applications that are in control of their concurrency requirements can easily add a pool of Client objects that are acquired per thread's request and then returned; this approach is actually much better since usually SOAP calls are pretty expensive in terms of latency, and the last thing you want is hundreds of web sessions smashing into your SOAP service at the same time. The pool provides a much more adaptable/tuneable solution for the applications' concurrency behaviour as an internally concurrent Client object could ever manage itself.

I looked at the new Client class and it is still not threadsafe. The access to the static "invocations" ArrayList is not synchronized, so two Threads calling invoke() at the same time have an (admittedly narrow) window for causing a ConcurrentModificationException in add() or remove(). The ArrayList may also not be the best data structure since this it will cause endless linear searches and array copying. I don't understand enough about the Invocations and why they need to be kept/ordered etc. but a sync HashSet might be more sound overall.
Just a suggestion

Holger Hoffstätte
added a comment - 06/Jun/06 12:18 PM I looked at the new Client class and it is still not threadsafe. The access to the static "invocations" ArrayList is not synchronized, so two Threads calling invoke() at the same time have an (admittedly narrow) window for causing a ConcurrentModificationException in add() or remove(). The ArrayList may also not be the best data structure since this it will cause endless linear searches and array copying. I don't understand enough about the Invocations and why they need to be kept/ordered etc. but a sync HashSet might be more sound overall.
Just a suggestion

Dan Diephouse
added a comment - 10/Jun/06 1:11 PM Alright, I fixed the threading issue, but it probably still isn't ideal because there is a synchronized:
http://svn.xfire.codehaus.org/changelog/xfire/?cs=1612
But, I'm closing this issue for now and we can revisit the sync.