You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomee.apache.org by is_maximum <mn...@gmail.com> on 2009/03/10 14:10:22 UTC

Webservices (stateless SB) and ThreadLocal

Hello

In our application we contract to have request informations in all the DTOs
coming from the clients. So in order to make these information accessible
across the application in request scope I have defined a class in which a
ThreadLocal is defined as final static and also a default interceptor that
extract the request information from the method parameter using the
InvocationContext. 

But now it seems that this ThreadLocal doesn't work in container. Since
inside a service method a bunch of services from other SLSBs will be called,
my gues is that container may or may not create new threads for them so we
can't rely on this ThreadLocal benefits.

My question is if I am right how we can make this information accessible in
request scope across the application just like old programs that uses the
magic of thread local.

I appreciate of you share your experience on this



-----
--
Regards

Mohammad Norouzi

Help each other to reach the future faster

http://pixelshot.wordpress.com Pixelshot Photoblog 

http://brainable.blogspot.com Brainable Blog 


-- 
View this message in context: http://www.nabble.com/Webservices-%28stateless-SB%29-and-ThreadLocal-tp22433874p22433874.html
Sent from the OpenEJB User mailing list archive at Nabble.com.


Re: Webservices (stateless SB) and ThreadLocal

Posted by David Blevins <da...@visi.com>.
On Mar 14, 2009, at 11:17 PM, is_maximum wrote:

> Just one more question.
>
> Does this InheritableThreadLocal work well in clustered platform?

Threads and clusters aren't really related topics, so I'm not entirely  
sure how to answer the question.  Better said a thread is a concept  
that applies to a single JVM and not something capable of spanning  
multiple JVMs.  When one JVM calls to another JVM, say in a cluster or  
other client/server architecture, there are always at least two  
threads involved (one in each JVM) and those threads will have zero  
visibility or awareness of each other.

The one "cluster" caveat is the Azul appliance, which is different  
than other clustering environments in that it operates as one giant JVM.

-David


Re: Webservices (stateless SB) and ThreadLocal

Posted by is_maximum <mn...@gmail.com>.
Just one more question. 

Does this InheritableThreadLocal work well in clustered platform? 



-----
--
Regards

Mohammad Norouzi

Help each other to reach the future faster

http://pixelshot.wordpress.com Pixelshot Photoblog 

http://brainable.blogspot.com Brainable Blog 


-- 
View this message in context: http://www.nabble.com/Webservices-%28stateless-SB%29-and-ThreadLocal-tp22433874p22520416.html
Sent from the OpenEJB User mailing list archive at Nabble.com.


Re: Webservices (stateless SB) and ThreadLocal

Posted by David Blevins <da...@visi.com>.
On Mar 12, 2009, at 11:12 PM, is_maximum wrote:

> As you said If bean A invokes bean B over bean B's
> webservice interface.  That is essentially making a remote call
> locally and bean B will be executed in a different thread than bean A.
>
> You mean even if our webservices tagged with both @Webservice and  
> @Stateless
> they will call each other by making remote call and with different  
> thread?

That is the case if this bean (we'll call it B) has only the  
@WebService annotation and does not implement any interfaces.  Then,  
yes, the only way to invoke bean B is via a webservice call which is  
essentially going to "leave" the VM and come back in through the HTTP  
port.  A very simple way to avoid webservice calls from bean to bean  
inside the same VM is to add an @Local interface in addition to the  
@WebService support.

> I've defined a default interceptor for all business interfaces to  
> catch
> incoming DTO and extract the request header sent by client and then  
> set them
> as RequestHeader in a ThreadLocal. Now in DAO layer before we go to  
> persist
> an entity or more (we know all entities are coming from the same  
> client to
> be persisted if we rely on information of ThreadLocal) we can get the
> RequestHeader from ThreadLocal. Also in other places across the  
> application
> we need to know the locale sent by client and we can use the data.
>
> But if the rule of webservices are so I think we can't use that and  
> I think
> that's true because in action, we get NPE every often which is not  
> clear at
> what condition it happens

I'm not sure I understood all of that, but definitely right in that it  
isn't safe to rely on webservice calls being executed in the same  
thread as the caller.  Certainly if the caller is in a different jvm  
that will always be the case.  For calls inside the same vm that will  
still usually be the case due to how webservices are typically  
implemented.  Some vendors might support optimizations that avoid  
sockets (and therefore the thread jumping) but that would be a vendor  
specific feature.


-David


> David Blevins wrote:
>>
>>
>> On Mar 10, 2009, at 6:10 AM, is_maximum wrote:
>>
>>>
>>> Hello
>>>
>>> In our application we contract to have request informations in all
>>> the DTOs
>>> coming from the clients. So in order to make these information
>>> accessible
>>> across the application in request scope I have defined a class in
>>> which a
>>> ThreadLocal is defined as final static and also a default
>>> interceptor that
>>> extract the request information from the method parameter using the
>>> InvocationContext.
>>>
>>> But now it seems that this ThreadLocal doesn't work in container.
>>> Since
>>> inside a service method a bunch of services from other SLSBs will be
>>> called,
>>> my gues is that container may or may not create new threads for them
>>> so we
>>> can't rely on this ThreadLocal benefits.
>>>
>>> My question is if I am right how we can make this information
>>> accessible in
>>> request scope across the application just like old programs that
>>> uses the
>>> magic of thread local.
>>>
>>> I appreciate of you share your experience on this
>>
>> ThreadLocals definitely work, we use them extensively.  There's  
>> only a
>> few places in our code that will launch a new thread.
>>
>>  - EJB Times. We have a thread pool for executing the bean's @TimeOut
>> method.
>>
>>  - Any calls made on the RemoteInitialContextFactory.  It uses one
>> thread to call the blocking serverSocket.accept(), when a connection
>> is made and the socket is handed over to a thread pool for execution.
>> All calls made on this are going to be from user code, meaning we
>> don't have any internal code that relies on it.  Internally all non-
>> webservice calls are made over the IntraVM Server (i.e.
>> LocalInitialContextFactory) which doesn't create any threads.  So
>> calls made from one EJB to another over a business interface are
>> guaranteed to be in the same thread.
>>
>>  - WebService calls.  If bean A invokes bean B over bean B's
>> webservice interface.  That is essentially making a remote call
>> locally and bean B will be executed in a different thread than bean  
>> A.
>>
>>  - MessageDriven bean calls.  All of these are asynchronous and
>> guaranteed to be executing in a different thread than the code that
>> produced the message.
>>
>>
>> You mentioned in a previous email that you had code that created jobs
>> and executed them in a separate thread.  I'd double check that if you
>> haven't already.  Any ThreadLocal state you or we set in the bean's
>> thread A are not going to be seen by the job in new thread B.
>>
>> Technically speaking the ejb spec says starting new threads is  
>> against
>> the rules as new threads by definition are completely outside the
>> management of the container's thread state where security,
>> transactions, jndi naming, and other state is kept.
>>
>> Despite it being illegal, starting your own threads can be awfully
>> handy.  If it is your new thread that is lacking the state you set in
>> the parent thread, you could possibly use a
>> java.lang.InheritableThreadLocal to get the state propagated.
>>
>>
>> -David
>>
>>
>>
>
>
> -----
> --
> Regards
>
> Mohammad Norouzi
>
> Help each other to reach the future faster
>
> http://pixelshot.wordpress.com Pixelshot Photoblog
>
> http://brainable.blogspot.com Brainable Blog
>
>
> -- 
> View this message in context: http://www.nabble.com/Webservices-%28stateless-SB%29-and-ThreadLocal-tp22433874p22490829.html
> Sent from the OpenEJB User mailing list archive at Nabble.com.
>
>


Re: Webservices (stateless SB) and ThreadLocal

Posted by is_maximum <mn...@gmail.com>.
Again a complete answer. You're my savior David.

Regarding my last post on jobs, I want to say that those operations are
actually Fiscal Year End for banking issues and those operation will take
place at the end of fiscal year but this problem is normal webservice call.

As you said If bean A invokes bean B over bean B's  
webservice interface.  That is essentially making a remote call  
locally and bean B will be executed in a different thread than bean A.

You mean even if our webservices tagged with both @Webservice and @Stateless
they will call each other by making remote call and with different thread?

I've defined a default interceptor for all business interfaces to catch
incoming DTO and extract the request header sent by client and then set them
as RequestHeader in a ThreadLocal. Now in DAO layer before we go to persist
an entity or more (we know all entities are coming from the same client to
be persisted if we rely on information of ThreadLocal) we can get the
RequestHeader from ThreadLocal. Also in other places across the application
we need to know the locale sent by client and we can use the data.

But if the rule of webservices are so I think we can't use that and I think
that's true because in action, we get NPE every often which is not clear at
what condition it happens





David Blevins wrote:
> 
> 
> On Mar 10, 2009, at 6:10 AM, is_maximum wrote:
> 
>>
>> Hello
>>
>> In our application we contract to have request informations in all  
>> the DTOs
>> coming from the clients. So in order to make these information  
>> accessible
>> across the application in request scope I have defined a class in  
>> which a
>> ThreadLocal is defined as final static and also a default  
>> interceptor that
>> extract the request information from the method parameter using the
>> InvocationContext.
>>
>> But now it seems that this ThreadLocal doesn't work in container.  
>> Since
>> inside a service method a bunch of services from other SLSBs will be  
>> called,
>> my gues is that container may or may not create new threads for them  
>> so we
>> can't rely on this ThreadLocal benefits.
>>
>> My question is if I am right how we can make this information  
>> accessible in
>> request scope across the application just like old programs that  
>> uses the
>> magic of thread local.
>>
>> I appreciate of you share your experience on this
> 
> ThreadLocals definitely work, we use them extensively.  There's only a  
> few places in our code that will launch a new thread.
> 
>   - EJB Times. We have a thread pool for executing the bean's @TimeOut  
> method.
> 
>   - Any calls made on the RemoteInitialContextFactory.  It uses one  
> thread to call the blocking serverSocket.accept(), when a connection  
> is made and the socket is handed over to a thread pool for execution.   
> All calls made on this are going to be from user code, meaning we  
> don't have any internal code that relies on it.  Internally all non- 
> webservice calls are made over the IntraVM Server (i.e.  
> LocalInitialContextFactory) which doesn't create any threads.  So  
> calls made from one EJB to another over a business interface are  
> guaranteed to be in the same thread.
> 
>   - WebService calls.  If bean A invokes bean B over bean B's  
> webservice interface.  That is essentially making a remote call  
> locally and bean B will be executed in a different thread than bean A.
> 
>   - MessageDriven bean calls.  All of these are asynchronous and  
> guaranteed to be executing in a different thread than the code that  
> produced the message.
> 
> 
> You mentioned in a previous email that you had code that created jobs  
> and executed them in a separate thread.  I'd double check that if you  
> haven't already.  Any ThreadLocal state you or we set in the bean's  
> thread A are not going to be seen by the job in new thread B.
> 
> Technically speaking the ejb spec says starting new threads is against  
> the rules as new threads by definition are completely outside the  
> management of the container's thread state where security,  
> transactions, jndi naming, and other state is kept.
> 
> Despite it being illegal, starting your own threads can be awfully  
> handy.  If it is your new thread that is lacking the state you set in  
> the parent thread, you could possibly use a  
> java.lang.InheritableThreadLocal to get the state propagated.
> 
> 
> -David
> 
> 
> 


-----
--
Regards

Mohammad Norouzi

Help each other to reach the future faster

http://pixelshot.wordpress.com Pixelshot Photoblog 

http://brainable.blogspot.com Brainable Blog 


-- 
View this message in context: http://www.nabble.com/Webservices-%28stateless-SB%29-and-ThreadLocal-tp22433874p22490829.html
Sent from the OpenEJB User mailing list archive at Nabble.com.


Re: Webservices (stateless SB) and ThreadLocal

Posted by David Blevins <da...@visi.com>.
On Mar 10, 2009, at 6:10 AM, is_maximum wrote:

>
> Hello
>
> In our application we contract to have request informations in all  
> the DTOs
> coming from the clients. So in order to make these information  
> accessible
> across the application in request scope I have defined a class in  
> which a
> ThreadLocal is defined as final static and also a default  
> interceptor that
> extract the request information from the method parameter using the
> InvocationContext.
>
> But now it seems that this ThreadLocal doesn't work in container.  
> Since
> inside a service method a bunch of services from other SLSBs will be  
> called,
> my gues is that container may or may not create new threads for them  
> so we
> can't rely on this ThreadLocal benefits.
>
> My question is if I am right how we can make this information  
> accessible in
> request scope across the application just like old programs that  
> uses the
> magic of thread local.
>
> I appreciate of you share your experience on this

ThreadLocals definitely work, we use them extensively.  There's only a  
few places in our code that will launch a new thread.

  - EJB Times. We have a thread pool for executing the bean's @TimeOut  
method.

  - Any calls made on the RemoteInitialContextFactory.  It uses one  
thread to call the blocking serverSocket.accept(), when a connection  
is made and the socket is handed over to a thread pool for execution.   
All calls made on this are going to be from user code, meaning we  
don't have any internal code that relies on it.  Internally all non- 
webservice calls are made over the IntraVM Server (i.e.  
LocalInitialContextFactory) which doesn't create any threads.  So  
calls made from one EJB to another over a business interface are  
guaranteed to be in the same thread.

  - WebService calls.  If bean A invokes bean B over bean B's  
webservice interface.  That is essentially making a remote call  
locally and bean B will be executed in a different thread than bean A.

  - MessageDriven bean calls.  All of these are asynchronous and  
guaranteed to be executing in a different thread than the code that  
produced the message.


You mentioned in a previous email that you had code that created jobs  
and executed them in a separate thread.  I'd double check that if you  
haven't already.  Any ThreadLocal state you or we set in the bean's  
thread A are not going to be seen by the job in new thread B.

Technically speaking the ejb spec says starting new threads is against  
the rules as new threads by definition are completely outside the  
management of the container's thread state where security,  
transactions, jndi naming, and other state is kept.

Despite it being illegal, starting your own threads can be awfully  
handy.  If it is your new thread that is lacking the state you set in  
the parent thread, you could possibly use a  
java.lang.InheritableThreadLocal to get the state propagated.


-David