ThreadLocal usage in enterprise application - java

If my web application and ejb application are on the same machine (on same JVM) and all the ejb calls are local calls , will the use of ThreadLocal create any issue while passing information from web to ejb?
Any workaround if the ejb calls are remote? Will ThreadLocal information be available from web application to ejb application? Is use of ThreadLocal advisable in such scenario?

For the first question, there is no problem as long as you remove the ThreadLocal variables at the end of every call. This is important because containers (servlet or ejb) typically use threadpools and therefore reuse threads, this has two effects: one "call" may see threadlocal info coming from a previous call, and if you remove an app from the container without stopping the JVM some classes may not be garbage collected because they are still referenced by a container thread. So put data in a threadlocal in a try / finally block and remove in the finally part.
Here is a post showing one way to handle the problem: ThreadLocal in web applications
For the second question as data is threadlocal it will not come with a remote call, you have to add a parameter to your interfaces, extract threadlocal data on one side and recreate it on the other side...

When using EJB 3.1 you can pass around contextual information in the EJBContext using its context data. This is just a Map<String,Object>.

ThreadLocal shouldn't be used in EJB contexts. One cannot guarantee that the EJB method invocations are all on the same thread (of course the should be).
In EJB there is a different approach call TransactionSyncrhonizationRegistry. See Explanation/Usage for further details.

all the ejb calls are local calls , will the use of ThreadLocal create
any issue while
No, you answered your question yourself. Since calls are local they are executed in the context of one thread.
Any workaround if the ejb calls are remote?
In case of remote calls, the Java EE container will be run in an other JVM, it will spawn its own threads to handle incoming RMI request, there is no way for a remote Java EE container to know about thread local variables that were declared on the other side. Pass it as a parameter object.

It depends what information you are passing! The first question it too generic. I suggest to read the JavaDoc related to ThreadLocal here.
ThreadLocal lives from the server side of the application and are used to let Thread-safe the calls of your Thread objects.

For local calls, the ThreadLocal should work fine, as long as everything is done in the same thread.
For remote calls, which can potentially run on a different server, you will need to come up with something else. Either pass all values as parameters (which will work, but introduces complexity in the code) or use something like a distributed cache, e.g. Hazelcast, which will function like a global HashMap, which all cluster nodes have access to.

ThreadLocal cannot be used with 100% certainty in web applications. You simply do not have the guarantee that one thread will be used for one session. In my point of view this can get a very hard to find security hole!
ctx.getContextData() does not work for me, it always returns null!
I also tried TransactionSynchronizationRegistry, but I get null as well.
The only thing that worked is using JAAS as a workaround.But it is not a nice solution.

Related

timeout a job on jboss

i'm running jboss AS 4.2 with java 1.6 and my problem is as follows:
our application is distributed as an ear and a war containing some servlets.
these servlets call the needed EJBs which do some processing and then return the result.
i'm looking for a way to determine a timeout, which in case the processing takes too much time, and it'll just return and end the processing (the processing involves several EJBs).
i can use ThreadLocal and add some code that will check at the beginning of each method if it exceeded the time - but is there some other mechanism i can use without adding such code to my application?
any idea / reference will be good.
There might be different ways, but very first thing comming to my mind based on your requiremens are interceptors.
So that you would intercept all your problematic (possibly long taking calls) and throw exception in case they exceeded the time.
And yes, threadlocal could do the job for keeping the start time (In case you don't use asynchronous stateless session bean calls).
To get some idea, of what interceptors are capable of, see: http://www.adam-bien.com/roller/abien/entry/interceptors_ejb_3_for_absolute
The main advantage of this solution is that you would have clear separation of timeout functionality (in Interceptor) from your bussiness logic (in EJBs).

JSP/Servlet design question - Make request/response globally available via JNDI

In PHP one is always able to access the current request or response from any part of their code. This concept is fundamental to PHP programming. Request data, response data, session data (etc) are always there!
This does not happen in Java Servlets! In order to have access to the HttpServletRequest, HttpServletResponse, HttpSession (etc) in your code you need to pass them around as function variables. This means that you cannot code a web framework that inherently "knows" about all these and removes the complexity of passing them around.
So, I have devised this solution:
Create anf register a ServletRequestListener.
Upon the requestInitialized event bind the current HttpServletRequest to the JNI context giving in the name of the current Thread (Thread.currentThread().getName());
Upon the requestDestroyed event unbind the above JNI resource to cleanup.
This way one has access to the current request/response from any place of their code, since they are always there in the JNI context and can be retrieved by providing the current thread's name.
All known servlet container implement the single-thread model for each request, so there is no way for the requests to get mixed up (of course one must not forget to clean them up).
Also the JNI resources of each web application are separated by default so there are no concerns of mixing them up or of security issues that could arise from one web application having access to the requests of the others.
Kinda twisted, but nice and simple...
What do you think?
I think some web frameworks (GWT, Axis) already do that, but in a much simpler way: by using a ThreadLocal static variable (or accessible from a singleton). Spring also has this possibility.
I'm not sure it works with all the containers, though. If the container uses non-blocking IO and reuses the same thread to handle multiple requests in parallel, it won't work anymore.
See Get the HttpServletRequest (request) object from Java code for a similar question (and its answers).
If you are worried about different requests getting messed up (and then think about "sub requests" like a model window), perhaps you'd rather think about using Seam? They use an abstraction called a "Session" to handle a LOT of the things that we developers try to hack around with other traditional web technology stacks. Seam is built on JSF just as an fyi. You don't have to use EJB 3 or Hibernate with it, but it does integrate nicely with both of those as well. Something to think about.

Does it make sense to synchronize web-service method?

I'm creating a web-service written in Java and hosted on JBoss AS. I'm not a professional in web-service design yet but do I get it correctly and each call to the service initiates a new thread and not a new process? Does it make sense to have synchronized methods in my service? I need to have a method which is invoked only for one user at a time not simultaneously for multiple.
Yes, requests are handled by individual handler threads. There is a single process for all of JBoss.
Synchronization can be problematic if your application ends up getting hosted across multiple nodes in a cluster. The locks won't propagate across multiple JVMs without the help of some magic like Terracotta. For a simple solution you can use a pessimistic row lock in your database to control access. One would of course be inclined to challenge the entire design that requires a blocking method and look for an alternative that can run in parallel.
Also, Locks from the java.util.concurrent package are preferred to the synchronized keyword if you are going that route.

can anybody elaborate single threded model in webapp?

When do we need single threded model in webapp while designing web application in java.
The single-threaded model should almost always be avoided. (I'm assuming you're talking about the SingleThreadModel interface.) Basically it was introduced in an attempt to save people from having to think about concurrency, but it was a bad idea. Concurrency is inherent in web applications - introducing a bottleneck like the single threaded model is the wrong solution. The right solution is to educate developers about concurrency better, and introduce better building blocks for handling it.
The interface is deprecated as of the Java Servlet API 2.4, with this note:
Note that SingleThreadModel does not
solve all thread safety issues. For
example, session attributes and static
variables can still be accessed by
multiple requests on multiple threads
at the same time, even when
SingleThreadModel servlets are used.
It is recommended that a developer
take other means to resolve those
issues instead of implementing this
interface, such as avoiding the usage
of an instance variable or
synchronizing the block of the code
accessing those resources. This
interface is deprecated in Servlet API
version 2.4.
When your Servlet has state (which is a bad idea) and you want to prevent multiple requests in stepping on their own toes (or data).
I would recommend you avoid it because at some point you will mess something up. Also, performance drops like a brick.
The single thread model for servlets is used to signal that the servlet cannot handle multiple concurrent threads from client connections. Setting a servlet to the single threading model results in the servlet container (application server) to create a servlet instance per client.
It is best practice not to use the single thread model for servlets. Data kept per client connection is typically stored in the client Session object.

How to start a background process in Java EE

I want to start a background process in a Java EE (OC4J 10) environment. It seems wrong to just start a Thread with "new Thread" But I can't find a good way for this.
Using a JMS queue is difficult in my special case, since my parameters for this method call are not serializable.
I also thought about using an onTimeout Timer Method on a session bean but this does not allow me to pass parameters (as far as I know).
Is there any "canon" way to handle such a task, or do I just have to revert to "new Thread" or a java.concurrent.ThreadPool.
Java EE usually attempts to removing threading from the developers concerns. (It's success at this is a completely different topic).
JMS is clearly the preferred approach to handle this.
With most parameters, you have the option of forcing or faking serialization, even if they aren't serializable by default. Depending on the data, consider wrapping it in a serializable object that can reload the data. This will clearly depend on the parameter and application.
JMS is the Java EE way of doing this. You can start your own threads if the container lets you, but that does violate the Java EE spec (you may or may not care about this).
If you don't care about Java EE generic compliance (if you would in fact resort to threads rather than deal with JMS), the Oracle container will for sure have proprietary ways of doing this (such as the OracleAS Job Scheduler).
Don't know OCJ4 in detail but I used the Thread approach and a java.util.Timer approach to perform some task in a Tomcat based application. In Java 5+ there is an option to use one of the Executor services (Sheduled, Priority).
I don't know about the onTimeout but you could pass parameters around in the session itself, the app context or in a static variable (discouraged would some say). But the name tells me it is invoked when the user's session times out and you want to do some cleanup.
Using the JMS is the right way to do it, but it's heavier weight.
The advantage you get is that if you need multiple servers, one server or whatever, once the servers are configured, your "Threading" can now be distributed to multiple machines.
It also means you don't want to send a message for a truly trivial amount of work or with a massive amount of data. Choose your interface points well.
see here for some more info:
stackoverflow.com/questions/533783/why-spawning-threads-in-j2ee-container-is-discouraged
I've been creating threads in a container (Tomcat, JBoss) with no problem, but they were really simple queues, and I don't rely on clustering.
However, EJB 3.1 will introduce asynchronous invocation that you may find useful:
http://www.theserverside.com/tt/articles/article.tss?track=NL-461&ad=700869&l=EJB3-1Maturity&asrc=EM_NLN_6665442&uid=2882457
Java EE doesn't really forbid you to create your own threads, it's the EJB spec that says "unmanaged threads" arn't allowed. The reason is that these threads are unknown to the application server and therefore the container cannot manage things like security and transactions on these threads.
Nevertheless there are lots of frameworks out there that do create their own threads. For example Quartz, Axis and Spring. Changes are your already using one of these, so it's not that bad to create your own threads as long as you're aware of the consequences. That said I agree with the others that the use of JMS or JCA is preferred over manual thread creation.
By the way, OC4J allows you to create your own threads. However it doesn't allow JNDI lookups from these unmanaged threads. You can disable this restriction by specifying the -userThreads argument.
I come from a .NET background, and JMS seems quite heavy-weight to me. Instead, I recommend Quartz, which is a background-scheduling library for Java and JEE apps. (I used Quartz.NET in my ASP.NET MVC app with much success.)

Categories

Resources