You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by "ggsoft@gmx.net" <gg...@gmx.net> on 2010/03/25 18:13:58 UTC

Spring CXF Client Header not threadsafe?

Hi all,

I have the following problem with CXF(2.2.5) and Spring (2.5.6):

The setup is

    <bean id="serviceWrapper" class="wrapperClass">
		<constructor-arg ref="cxf.service"/>
		<property name="address"><value>xxxx</value></property>
	</bean>
    <jaxws:client id="cxf.service"
                  serviceClass="serviceClass"/>

in the constructor of the wrapper class i set

		BindingProvider bp = (BindingProvider) service;
		bp.getRequestContext().put("thread.local.request.context", Boolean.TRUE); 

(also tried with bp.getRequestContext().put("thread.local.request.context",
"true");  as stated in FAQ)

the address is set like this (and this works):

		BindingProvider bp = (BindingProvider) service;
		bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, 
		  address);

before each request to the service i set the threadlocal
(Boolean.TRUE/"true) and the headers

bp.getRequestContext().put("thread.local.request.context", Boolean.TRUE); 
List<Header> headers = new ArrayList<Header>();
Header myHeader = new Header(new QName(MY_NS,	MY_LOC_N), "test123",
						new JAXBDataBinding(String.class));
headers.add(myHeader);

The header setting, the call all works. But when i do more threads, when
doing junit tests on this client
with more testclasses using the client class. The headers stay as set in the
first time.

In the testclasses i inject the wrapper like this:

@Resource
public ServiceWrapper serviceWrapper;

When i set the scope of the wrapper to prototype then all the tests pass.
The headers are not hold in
the wrapper but occur in the outgoing message (if not set to prototype).
So CXF holds them anywhere. So what is wrong with the setup?

Regards,
ggsoft
-- 
View this message in context: http://old.nabble.com/Spring-CXF-Client-Header-not-threadsafe--tp28032062p28032062.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Spring CXF Client Header not threadsafe?

Posted by "ggsoft@gmx.net" <gg...@gmx.net>.

Thanks, that helped me a lot.
I do not know how common this is, but perhaps this would help
others in the FAQ?

Beside that, CXF does a very great job and i like it very much! ;)


dkulp wrote:
> 
> 
> Well, it is "thread safe", nut it has an unusual side effect....
> 
> When implementing the thread safe context, the question came up as to what 
> should the context look like on a NEW thread.   Should it be empty?   That 
> idea really was not workable.   One common use case was the proxy is 
> "configured" at startup, then used on a bunch of threads.   Thus, that 
> configuration needs to be in the context.   
> 
> What we ended up doing was that when context is created on a new thread,
> the 
> initial values are copied from a non-thread local map.  All sets into any 
> context are also set into that map.   Thus, that map contains the last
> values 
> for every key that was set on any thread.    When a new thread is created,
> it 
> gets all the last values.   
> 
> My suggestion would be to call clear() or something when appropriate.
> 
> 
> Dan
> 
> 
> 
> On Thursday 25 March 2010 1:13:58 pm ggsoft@gmx.net wrote:
>> Hi all,
>> 
>> I have the following problem with CXF(2.2.5) and Spring (2.5.6):
>> 
>> The setup is
>> 
>>     <bean id="serviceWrapper" class="wrapperClass">
>> 		<constructor-arg ref="cxf.service"/>
>> 		<property name="address"><value>xxxx</value></property>
>> 	</bean>
>>     <jaxws:client id="cxf.service"
>>                   serviceClass="serviceClass"/>
>> 
>> in the constructor of the wrapper class i set
>> 
>> 		BindingProvider bp = (BindingProvider) service;
>> 		bp.getRequestContext().put("thread.local.request.context", 
> Boolean.TRUE);
>> 
>> (also tried with
>> bp.getRequestContext().put("thread.local.request.context",
>> "true");  as stated in FAQ)
>> 
>> the address is set like this (and this works):
>> 
>> 		BindingProvider bp = (BindingProvider) service;
>> 		
> bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
>> 		  address);
>> 
>> before each request to the service i set the threadlocal
>> (Boolean.TRUE/"true) and the headers
>> 
>> bp.getRequestContext().put("thread.local.request.context", Boolean.TRUE);
>> List<Header> headers = new ArrayList<Header>();
>> Header myHeader = new Header(new QName(MY_NS,	MY_LOC_N), "test123",
>> 						new JAXBDataBinding(String.class));
>> headers.add(myHeader);
>> 
>> The header setting, the call all works. But when i do more threads, when
>> doing junit tests on this client
>> with more testclasses using the client class. The headers stay as set in
>> the first time.
>> 
>> In the testclasses i inject the wrapper like this:
>> 
>> @Resource
>> public ServiceWrapper serviceWrapper;
>> 
>> When i set the scope of the wrapper to prototype then all the tests pass.
>> The headers are not hold in
>> the wrapper but occur in the outgoing message (if not set to prototype).
>> So CXF holds them anywhere. So what is wrong with the setup?
>> 
>> Regards,
>> ggsoft
> 
> -- 
> Daniel Kulp
> dkulp@apache.org
> http://dankulp.com/blog
> 
> 

-- 
View this message in context: http://old.nabble.com/Spring-CXF-Client-Header-not-threadsafe--tp28032062p28078480.html
Sent from the cxf-user mailing list archive at Nabble.com.


Re: Spring CXF Client Header not threadsafe?

Posted by Daniel Kulp <dk...@apache.org>.
Well, it is "thread safe", nut it has an unusual side effect....

When implementing the thread safe context, the question came up as to what 
should the context look like on a NEW thread.   Should it be empty?   That 
idea really was not workable.   One common use case was the proxy is 
"configured" at startup, then used on a bunch of threads.   Thus, that 
configuration needs to be in the context.   

What we ended up doing was that when context is created on a new thread, the 
initial values are copied from a non-thread local map.  All sets into any 
context are also set into that map.   Thus, that map contains the last values 
for every key that was set on any thread.    When a new thread is created, it 
gets all the last values.   

My suggestion would be to call clear() or something when appropriate.


Dan



On Thursday 25 March 2010 1:13:58 pm ggsoft@gmx.net wrote:
> Hi all,
> 
> I have the following problem with CXF(2.2.5) and Spring (2.5.6):
> 
> The setup is
> 
>     <bean id="serviceWrapper" class="wrapperClass">
> 		<constructor-arg ref="cxf.service"/>
> 		<property name="address"><value>xxxx</value></property>
> 	</bean>
>     <jaxws:client id="cxf.service"
>                   serviceClass="serviceClass"/>
> 
> in the constructor of the wrapper class i set
> 
> 		BindingProvider bp = (BindingProvider) service;
> 		bp.getRequestContext().put("thread.local.request.context", 
Boolean.TRUE);
> 
> (also tried with bp.getRequestContext().put("thread.local.request.context",
> "true");  as stated in FAQ)
> 
> the address is set like this (and this works):
> 
> 		BindingProvider bp = (BindingProvider) service;
> 		
bp.getRequestContext().put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
> 		  address);
> 
> before each request to the service i set the threadlocal
> (Boolean.TRUE/"true) and the headers
> 
> bp.getRequestContext().put("thread.local.request.context", Boolean.TRUE);
> List<Header> headers = new ArrayList<Header>();
> Header myHeader = new Header(new QName(MY_NS,	MY_LOC_N), "test123",
> 						new JAXBDataBinding(String.class));
> headers.add(myHeader);
> 
> The header setting, the call all works. But when i do more threads, when
> doing junit tests on this client
> with more testclasses using the client class. The headers stay as set in
> the first time.
> 
> In the testclasses i inject the wrapper like this:
> 
> @Resource
> public ServiceWrapper serviceWrapper;
> 
> When i set the scope of the wrapper to prototype then all the tests pass.
> The headers are not hold in
> the wrapper but occur in the outgoing message (if not set to prototype).
> So CXF holds them anywhere. So what is wrong with the setup?
> 
> Regards,
> ggsoft

-- 
Daniel Kulp
dkulp@apache.org
http://dankulp.com/blog