This week's book giveaways are in the Java EE and JavaScript forums.
We're giving away four copies each of The Java EE 7 Tutorial Volume 1 or Volume 2(winners choice) and jQuery UI in Action and have the authors on-line!
See this thread and this one for details.
The moose likes EJB and other Java EE Technologies and the fly likes regarding SLSB and ThreadLocals Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of The Java EE 7 Tutorial Volume 1 or Volume 2 this week in the Java EE forum
or jQuery UI in Action in the JavaScript forum!
JavaRanch » Java Forums » Java » EJB and other Java EE Technologies
Bookmark "regarding SLSB and ThreadLocals" Watch "regarding SLSB and ThreadLocals" New topic
Author

regarding SLSB and ThreadLocals

Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
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
my.blog | my.photoblog | Add your name to SCJP Wall Of Fame
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mohammed,

Not sure what you are trying to accomplish exactly, but the only portable solution would be using method parameters to pass context from the HTTP request.

Hope it helps,
Reza


Independent Consultant — Author, EJB 3 in Action — Expert Group Member, Java EE 6 and EJB 3.1
Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
Reza Rahman wrote:Mohammed,

Not sure what you are trying to accomplish exactly, but the only portable solution would be using method parameters to pass context from the HTTP request.

Hope it helps,
Reza


This is the first idea that comes to mind but the logic of each service method is so complicated and passing the parameter is not a good idea because all the methods (more than 50 methods) should add a new argument as their signature.

BTW, the request header I said is not HTTP request, it's a structure we have define as a contract between clients and the server.

Any other idea?
PavanPL KalyanK
Ranch Hand

Joined: Feb 28, 2009
Posts: 212
Its not compulsory to use Thread Local . Why don't you put all your request data in a Collection and pass it on .
Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
PavanPL KalyanK wrote: Its not compulsory to use Thread Local . Why don't you put all your request data in a Collection and pass it on .


As I stated earlier, there are more than 50 services. we can't change all the method signatures to accept a new parameter. Apart from that there are many methods in DAO layer of the application in which we need these information so we should change all the DAO methods as well. Do you think this is a good idea?
RaviNada Kiran
Ranch Hand

Joined: Jan 30, 2009
Posts: 528
As far as i know Thread Local is used in applications where they would require a Resource per Client.

If you think ThreadLocal satisfies your requirement , then why don't you make a normal java class made as singleton and with static setters and getters methods??

I want to know what are the features you are expecting from THreadLocal.
PLease reply so that we can further discuss


If you want something you never had do something which you had never done
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mohammed,

Look into the DTO pattern/domain objects. It is designed to solve exactly the problem you are describing - put better abstractions around parameters so you don't have long parameter chains that you are bound to.

Regards,
Reza
Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
RaviNada Kiran wrote:As far as i know Thread Local is used in applications where they would require a Resource per Client.

If you think ThreadLocal satisfies your requirement , then why don't you make a normal java class made as singleton and with static setters and getters methods??

I want to know what are the features you are expecting from THreadLocal.
PLease reply so that we can further discuss


a singleton class contains data shared for all the requests but what I exactly want is data which is valid only during a request process and then it should be expired. ThreadLocal can hold these information in a thread so the other request cannot access it. As I have used already in a struts application ThreadLocal worked very well but it seems in EJB does not.

I tried to set my data in SessionContext using getMessageContext().setProperty() but I get an IllegalStateException.

----

And in reply to Reza, I should say that we are using the same DTO model and these information are placed in the DTOs but in DAO layers we have "entities" so each time we are going to persist an entity we need to set those request information from DTO to Entity and this happens in all business methods. What I'm trying to do is avoiding this, reducing code, decoupling business methods from request information which is contains security data, username, etc.

Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mohammad,

Here is my two cents.

I understand the desire to pass data transparently between layers using some kind of context. In practice though, I have seen this lead to a lot of convoluted code that is difficult to read, especially via Javadocs and especially if you were not the original developer of the code. You are often forced to look into implementation needlessly and the client code to figure out what really is going on. This is kind of like the "bad old days" of C global variables that are set some place up the client chain and read in an arbitrary place somewhere down the call chain. Like global variables, using context for business logic can be considered an anti-pattern for this reason.

This is why all modern business tier platforms and frameworks discourage this kind of usage in favor of DTOs and domain objects, with all required context data needed by an object is explicitly passed in via method parameters. Here is a pretty good write-up on this issue: http://blog.objectmentor.com/articles/2007/09/04/thread-local-a-convenient-abomination.

As to reducing the size of the code base, I recommend passing JPA entities (domain objects) from the root of the invocation chain (the web tier). This is the DDD (domain driven design) "Nirvana" and I have done it successfully quite a few times. Alternatively, I have seen folks using DDD create transformer/converter methods (e.g. EmployeeDTO.toEmployee() -> Employee) to better encapsulate conversion code in the presentation or service tier.

This make sense? If not let me know. Please do me a favor and take your time to sketch out how the object model would look like though. I think you might find that this is a cleaner approach to the problem, especially in the long-run.

Hope it helps,
Reza
Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
Reza Rahman wrote:Mohammad,

Here is my two cents.

I understand the desire to pass data transparently between layers using some kind of context. In practice though, I have seen this lead to a lot of convoluted code that is difficult to read, especially via Javadocs and especially if you were not the original developer of the code. You are often forced to look into implementation needlessly and the client code to figure out what really is going on. This is kind of like the "bad old days" of C global variables that are set some place up the client chain and read in an arbitrary place somewhere down the call chain. Like global variables, using context for business logic can be considered an anti-pattern for this reason.

This is why all modern business tier platforms and frameworks discourage this kind of usage in favor of DTOs and domain objects, with all required context data needed by an object is explicitly passed in via method parameters. Here is a pretty good write-up on this issue: http://blog.objectmentor.com/articles/2007/09/04/thread-local-a-convenient-abomination.

As to reducing the size of the code base, I recommend passing JPA entities (domain objects) from the root of the invocation chain (the web tier). This is the DDD (domain driven design) "Nirvana" and I have done it successfully quite a few times. Alternatively, I have seen folks using DDD create transformer/converter methods (e.g. EmployeeDTO.toEmployee() -> Employee) to better encapsulate conversion code in the presentation or service tier.

This make sense? If not let me know. Please do me a favor and take your time to sketch out how the object model would look like though. I think you might find that this is a cleaner approach to the problem, especially in the long-run.

Hope it helps,
Reza


Thanks Reza for the article and your reply.

Actually what I'm looking for is the same unit-of-work which is stated in above article.
About DTOs, fortunately we have the same model and each DTO has its own assembler (the same transformer you said) in which the DTO will be converted into entity, but I'm a little reluctant on this request information. I believe this kind of data should be separated from the main purpose of the DTOs and the whole application logic. I am considering this data as metadata and something in top of app. Maybe I'm wrong I don't know but I always search and share it with people to find the best answer and best design.

so far I am convinced that we can't use ThreadLocal in this matter but I think they should feature the next version of EJB to support a session (or the same unit-of-work) with more functionality.

Again, thanks both of you for spending your time on this thread
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mohammed,

I am still not entirely sure what you mean. EJB does support sessions via stateful session beans. It does not support the idea of a context for the use of business logic (equivalent to an HTTP session context perhaps) for the reasons I just mentioned and I really don't think it ever should. Indeed, if you are using Seam, JSF, Struts or pretty such any other modern web application framework, you would never manipulate the session or request "context" objects directly. Rather, you would focus on your object model and the mapping from the HTTP request/session to the object model is generally handled by the framework.

Could you post a UML-ish diagram of your current object model? Maybe that will shed some light? What web tier framework are you using (if any at all)?

Regards,
Reza
Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
Reza Rahman wrote:Mohammed,

I am still not entirely sure what you mean. EJB does support sessions via stateful session beans. It does not support the idea of a context for the use of business logic (equivalent to an HTTP session context perhaps) for the reasons I just mentioned and I really don't think it ever should. Indeed, if you are using Seam, JSF, Struts or pretty such any other modern web application framework, you would never manipulate the session or request "context" objects directly. Rather, you would focus on your object model and the mapping from the HTTP request/session to the object model is generally handled by the framework.

Could you post a UML-ish diagram of your current object model? Maybe that will shed some light? What web tier framework are you using (if any at all)?

Regards,
Reza


Well, what I am trying to do is separating the management of those data related to the request such as user id, desired locale for a request, date of sending request etc from the main logic of business interfaces.

For example we have an exception-interceptor in which if an exception occurs the related message according to the request locale will be loaded from the bundle and the user-id and the time he sent his request will be logged in DB

In my point of view, passing those information all the time across the application just for the reason that somewhere we need it, is not a good idea. Also creating a transformer for each DTO is not efficient since there are many methods which accepts or returns a list of objects and in this case we should loop through all the objects to set this kind of information

but using a context which is valid in request scope is really performant and easy to maintain.
I've just read an article on ThreadLocals and InheritableThreadLocal that was very useful and persuade me that newer versions of thread local is highly performant even than a pool and also in the javadocs of the InheritableThreadLocal it's been said that it is useful for keeping user id, transaction id etc.

http://www.ibm.com/developerworks/java/library/j-threads3.html

Now I'm going to make use of InheritableThreadLocal to see if it works fine.

Thanks
RaviNada Kiran
Ranch Hand

Joined: Jan 30, 2009
Posts: 528
Strange requirement , got frustrated ask your Architect.
Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
RaviNada Kiran wrote:Strange requirement , got frustrated ask your Architect.


Maybe but since this is a part of a core banking system which is located at a critical section of the system and they need some special features such as logging any error and mistaken happens in the system or having a history for the changes of any record etc. However they will provide mainframe and expensive computers as server but performance is still the issue as well

Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mohammed,

If you absolutely must do this, try binding the values you need in JNDI: http://publib.boulder.ibm.com/infocenter/iwedhelp/v6r0/index.jsp?topic=/com.ibm.mqe.doc/des10116.html. I would use a context path such as /sessions/{a unique session id}/yourValue. Be careful to clean up the values from JNDI when the session times out. You can do that via a a HTTP servlet context listener.

Hope it helps,
Reza
Mohammad Norouzi
Ranch Hand

Joined: Jul 12, 2005
Posts: 71
Reza Rahman wrote:Mohammed,

If you absolutely must do this, try binding the values you need in JNDI: http://publib.boulder.ibm.com/infocenter/iwedhelp/v6r0/index.jsp?topic=/com.ibm.mqe.doc/des10116.html. I would use a context path such as /sessions/{a unique session id}/yourValue. Be careful to clean up the values from JNDI when the session times out. You can do that via a a HTTP servlet context listener.

Hope it helps,
Reza


Thanks Reza, that seems very interesting to me and one question is that Does it work in a distributed area as well?
Reza Rahman
author
Ranch Hand

Joined: Feb 01, 2005
Posts: 580
    
    5
Mohammad,

Depends on the application server. I know WebLogic will replicate all JNDI entries.

Regards,
Reza
RaviNada Kiran
Ranch Hand

Joined: Jan 30, 2009
Posts: 528

setting every user requested information in JNDI ??
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: regarding SLSB and ThreadLocals