I am working on a web service and creating thread local instances and only want to remove them during app shutdown (once a threadlocal object is created for thread I want use that object during different service calls on that thread). As threads are created and owned by tomcat , is there any way to remove those threadlocals during application shutdown ??
Tomcat 6 has memory leak detection in place, and Tomcat 7 has actual removal logic - it will automatically remove all thread local objects for you: http://wiki.apache.org/tomcat/MemoryLeakProtection
Ideally you should remove all objects from thread local after request is completed, since the same thread is going to be put back to thread pool and used to serve other requests - in this case thread local values may interfere with subsequent request logic, and cause all kind of security issues.
But if you're specifically looking to keep values in thread local for the whole duration of Tomcat webapp lifetime - Tomcat 7 will take care of cleaning it up for you on webapp shutdown, think of it as garbage collection.
Related
I am currently writing a web app when I need to run a method simultaneously on a large number of threads. I have constructed the method and it calls an Async EJB however, only 6 EJBs are spawned. Are there some settings in Glassfish other that the EJB pool size that I sould be chnaging to allow more EJBs threads to be spawned?
Thanks
There is also a Max Thread Pool Size setting that you may want to check.
Configurations->configuration-name->Thread Pools->thread-pool-name as stated in the Glassfish documentation.
I'm working on a web application that's running using Tomcat (it's very Tomcat-oriented, with inclusion of Tomcat jars on the development stage and so on), and i need to bind an action to an event of returning Tomcat thread to it's pool. Is there way to do it?
Alternatively, is there any Tomcat-related thread local logic (like in java ThreadLocal class), that will consider same thread that have been taken from tomcat pool, returned back and taken again as two different "threads"?
I have an independent JMS listening and Responding service.
I want to invoke it as a independent thread from the servet.
so that the thread's execution will continue even the servlet finishes its execution.
Is it possible?
(Thanks in advance for your kind help.)
Yes, you can do that (unless you are on App Engine or some other severely restricted platform).
Instead of just spawning a new thread directly from the servlet, consider using an ExecutorService, that you can create and shut down in a ServletContextListener (so that when the container decides to stop your application, it does not leave active background threads around that cannot be cleaned up).
I've got an app that creates a load of Daemon threads, I'd like each one to shut down when the app is shut down.
I'm a little worried thought that Websphere 7 might not be shutting them all down.
Does anyone know if Websphere 7 treats Daemons threads differently? (I know it should do)
Note:
I know what shouldn't create threads manually, and that I should probably use WebSphere WorkManager or something, but this app has to run in Tomcat and WebSphere.
I know that I should tie in all threads to some context/shutdown mechanism, this is in progress.
Each WAS server runs a single JVM, and daemon threads are tied to the JVM's lifecycle, not the app's lifecycle. Therefore, you should not expect any daemon threads to be shut down when your app stops.
As you've already indicated, you should not create threads manually; the Java EE specs forbid this and the behavior in a Java EE container is different than a standalone Java application as you've already found. Unfortunately, there is currently no Java EE standard for a WorkManager equivalent; however, JSR-236 (Concurrency Utilities for Java EE) may be back as a candidate for inclusion in Java EE 7.
In the meantime, on WAS, you can use the asynchronous beans (WorkManager). We have successfully used this method to tie threads to the application lifecycle.
However, since you need to run in another container as well (Tomcat), there may be some other options to consider handling concurrency in your applications:
CommonJ WorkManager
Servlet 3.0 Asynchronous Servlets
ServletContextListener to hook into the web app lifecycle
Some other potential options for handling concurrency include the following, but these require EJBs, which may not be available in Tomcat:
EJB 3.0 Timer Service
EJB 3.1 Asynchronous Beans
Here are a few related threads on the topic of concurrency in Java EE:
Replacing Websphere's WorkManager in JBoss?
Getting thread from Container?
As has been mentioned you're not supposed to do this, but there isn't a good way to do it. This hasn't caused any problems for me.
This approach requires centralized thread-creation and the use of a listener to terminate threads when the app is stopping.
You'll have to do a few things:
Centralize all thread creation in a single class (call it ThreadService). When a thread is created here put it in a list so you can later loop through the list to stop them all.
Make an interface that your threads implement that allows you to stop each thread via the same interface. Each thread you have has to implement it's own mechanism for handling this. For example if your Thread uses a loop and Thread.sleep() then set stopped=true and interrupt the thread. The loop should check this and break from the loop when stopped=true.
Make a listener and implement ServletContextListener. When contextDestroyed() is called call ThreadService.stopThreads(). Register this listener in web.xml.
Websphere is just a java application. It cannot respect or do not respect deamon threads that are the feature of JVM or java runtime environment. So, if you create deamon thread inside Java EE application it will be deamon in every application server.
Moreover as far as I know even if you create regular thread it will not prevent application server from shutting down: the shutdown mechanism of every application server tries to close all its components and in the end runs System.exit() to win the criminals :) that open threads manually.
I'm writing an app which uses MDBs, EJBs and needs ThreadLocal to pass and log a variable across multiple EJBs and Helper classes until the transaction is complete.
The flow is
Starting with MDB onMessage()
-> some business delegate EJBs
-> some helpers
Question:
This app runs within Weblogic and Weblogic re-uses Threads from within it's ThreadPool. So is there a possibility of data corruption across threads? Is the solution to use ThreadLocal.remove() safe enough?
Is there an alternative to ThreadLocal other than passing around the Object as a parameter to all methods?
WebLogic does not reset user set ThreadLocal variables when the thread is returned back to the pool - the user is responsible for managing them. When such threads are reused, its likely they will interfere. You may run into memory leaks since the thread local reference isn't cleaned up. You can safely reset your thread locals prior to returning the thread back to the container. The ThreadLocal.remove() call should clean it up (ensure that its done in a finally block)
Note that if any async or rmi calls are involved, your thread locals will not propagate. You may want to consider the WebLogic WorkArea feature which allows context propagation across threads, clients & servers. More details can be found at http://download.oracle.com/docs/cd/E17904_01/web.1111/e13706/context.htm#i1058690
You can't reliably use a ThreadLocal in the EJB tier. Even if your code seems to 'work' now, what happens if someone deploys one of your beans remotely? From EJB Restrictions:
Why is thread creation and management disallowed?
The EJB specification assigns to the EJB container the responsibility
for managing threads. Allowing enterprise bean instances to create and
manage threads would interfere with the container's ability to control
its components' lifecycle. Thread management is not a business
function, it is an implementation detail, and is typically complicated
and platform-specific. Letting the container manage threads relieves
the enterprise bean developer of dealing with threading issues.
Multithreaded applications are still possible, but control of
multithreading is located in the container, not in the enterprise
bean.
If you need to share state, you should pass it in to the EJB method as a parameter. Is there a reason this approach won't work for you? Another option would be to temporarily dump it into a transaction enlisted database or cache.
#JoseK: though I have not tried what you described in your issue, but here are my thoughts:-
Both MDB and Session beans are thread-safe. It means let us say if there is pool of 10 beans, only 10 requests will be handled simultaneously. Other requests would be queued for their turn. So one running thread local data should not interfere with other thread.
If you confident to use always local EJBs in future also, then I don't really see any issue in using thread local data. Because you are not really creating threads.
Though weblogic provides thread from thread-pool but that thread is given dedicately to each request flow, I don't think its local data should become corrupted ever.
As I said I have not tried myself, what I would try is:-
In MDB layer(your first layer), do Thread.getCurrentThread.setName(name)
and in subsequent layers print thread names like Thread.getCurrentThread.getName)
Perform multiple runs with different size of ejb pool, thread pool. Give a different thread name to each request flow. Try running multiple requests same time. And see if you ever get thread name mixed.
5.Having said above, to keep things simpler and furture remote EJB support, I would also pass CallingContext Interface to each layer.