Using CommonJ WorkManagerTaskExecutor Spring 3 for multithreading - java

Hello everyone I am new to the forum and I just had a question about working with Spring's commonj WorkManagerTaskExecutor. I have been on a bunch of forums looking for better information on the subject but I haven't seen anything detailed on the subject. So here is my situation.
My application uses multiple threads which were being handled by ThreadPoolTaskExecutor which a friend told me he thought would not be the correct choice since we are using websphere 7.0 application server. I had everything working correctly and with some minor tweaking was able to replace the ThreadPoolTaskExecutor with a WorkManagerTaskExecutor. When I run the application the threads fire off via the default work manager on the websphere server. The problem that seems to be happening though is that even though I am using the workManagerTaskExecutor.waitForAll(collection,timeout); It never actually waits for the threads to complete. I know that it is working that is the threads are executing their respective methods because if you issue a lengthy for loop after all of this the data is there where as if you do not the data is not there. I was wondering the following two things.
Is the WorkManagerTaskExecutor the way to go? Or would using a ThreadPoolTaskExecutor be sufficient for handling multiple threads on a enterprise web application?
If the WorkManagerTaskExecutor is the way to go? Any ideas as to why the waitForAll method is completing as if the methods are done? When clearly they are not? After the page loads I can see in the logging that the methods are still running and eventually completeing.
Any help would be much appreciated. If I left anything out I will gladly try and give more information about the issue as I truly appreciate any help that might be given.
Thanks in Advance,
Bill

You should implement your concurrent class by extending the java.util.concurrent.Executor interface built into JavaSE, and then using the Spring IoC container, you can inject in an implementation class of WorkManagerTaskExecutor when running under Websphere.
This will give you flexibility if you ever want to run on another Java app server, and even works if you run outside a container directly on the JVM, since you could inject in a ThreadPoolTaskExecutor and not have to change any code.
You should avoid coding against the CommonJ WorkManager API (JSR 237) directly, such as using the waitForAll method, since it only works on IBM Websphere and Oracle WebLogic.

The final winning combination to this problem for me ended up being:
List<Callable<?>> callables = new ArrayList<Callable<?>>();
List<Future<?>> futures = new ArrayList<Future<?>>();
for (int i = 0; i<callers.length;i++){
callables.add(new MainTaskExecutor(this,entity,callers[i]));
}
for (Callable c:callables){
futures.add(workTaskExecutor.submit(c));
}
for (Future<?> f:futures){
do{}while(!f.isDone());
}

Related

Limit concurrent resource usage in a Java EE application

There is a Java EE application where we have batches of jobs to process. Processing involves calling an external service that has a limitation so that we can send only N number of requests concurrently. This bottleneck has to be implemented in our application logic and I am wondering how could we achieve this in the best way. Fortunately clustering is not a requirement, so we can confine the problem to a single server instance.
My first idea would be using an ExecutorService backed by a
ThreadPool with N working threads so that the ThreadPool object
would act as the regulator. Of course this is not an EE solution.
My second idea would be somehow configuring such a ThreadPool in
the container and using that, but I have not found any feature like
this so far.
The third idea is using a Semaphore(N) object in a #Singleton
EJB.
The fourth idea is somehow creating a limited pool of stateless
session beans and putting the limited-resource access in those. As
the bean number is managed by the container, the resource usage will
be limited as well
(To clarify: a general solution would be the best, but it is known that we're running on Glassfish 3.1.1 and maybe later on JBoss 6.x)
Could you suggest me a good architecture for this problem and/or comment on my ideas to help my decision?
Why don't you use Works? Have a look here for an overview of how to use Works in JBoss and Weblogic. I don't know about Glasshfish, I'll leave the research to you now ;)
In short, Works are EE compliant threads.
The canonical solution for concurrent message processing in Java EE is to use MDBs. You can limit the number of concurrently running tasks by limiting the MDB pool size.
Setting MDB Pool Size in Glassfish
JBoss 7 EJB3 Subsystem Configuration Guide

Creating threads a Webapplication which is deployed in Tomcat

I am working on a web application which is deployed in Tomcat. We are using Spring, Hibernate, GWT at the client side).
One of the functionality of this application is to send alerts ( emails ) to Users when any entity is created, updated or deleted. ( Alerts can be added by Users on the fly, so there is some processing involved - to decide which users should be notified by email ).
Alert mechanism ideally should be asynchronous and it should be affect the performance of CRUD operation.
First thing which came in my mind is to create a thread and have a blocking queue. Thread keeps polling blocking queue to see if it has got any events. But creating thread in web application is something which is discouraged by many Containers.
Can someone advice/ suggest - is this the correct way of doing it ? or There are better ways of doing the same thing .
Any pointers would be highly appreciated.
Thanks in advance,
Sachin
The restriction on creating threads in a container was really just a suggestion to keep inexperienced developers from shooting themselves in the foot. No container actually prohibits you from doing this. With java.util.concurrent classes, creating threads should be less error prone and I wouldn't worry about this restriction too much.
If your requirements are simple, it's easy enough to just create a single thread / runnable in a ServletContextListener. Create and start the thread in contextInitialized() and shut it down in contextDestroyed(). . Use a ScheduledExecutorService created by Executors.newSingleThreadScheduledExecutor(). The Runnable you pass to the Executor would read from a BlockingQueue.
If your requirements change and you need something more complicated, you probably want to looks at JMS / MDBs or a scheduler like Quartz.
You could use a scheduler to run jobs regularly or use the Spring equivalent of Message Driven Beans (some documentation on JMS and Spring) which are executed by the container which does the queue polling for you.
You can try using Spring 3.x asynchronous method invocation. Caller method will return immediately and the actual execution happens asynchronously
applicationContext:
<task:annotation-driven executor="asyncExecutor" mode="aspectj"/>
<task:executor id="asyncExecutor" pool-size="${executor.poolSize}"/>
On your bean:
#Async
public void sendEmail(...) {
// ...
}
please refer to Spring documentation for further details: Spring 3.x Task Execution and Scheduling
There are ways of doing it, the simplest (besides simply creating an unmanaged thread) is to use the commonj WorkManager. Certainly you can go the simple thread route, but it does have shortcomings in the environment you are operating in (as described in the link).

Running scheduled methods on tomcat

I am trying to set up a method that will be automatically run by the server at a specific time. For instance, a method that sends out emails to contacts every Friday at 9.00 am. I have seen methods that are run when the server is first started and was wondering if what I want to do is possible. If it is possible, can someone point me to where I can start reading up how to do this. Any help will be highly appreciated.
There is an excellent library quartz which can help you create scheduled tasks within your application. See e.g., the Job Scheduling in Java guide by o'reilly.
If you really want to do it manually (and not use specific tools like Quartz), you could use a Timer, which would be created when the application is deployed and canceled when the application is destroyed, using a ServletContextListener declared in your web.xml.
Be prepared for additional complexity if your application is clustered on multiple servers, though.
I also recommend using Quartz as Johan already suggested, it is a well-established solution for job scheduling in Java applications and also allows for central job storage in a database and clustering of multiple Tomcat instances.
In case your web application uses the Spring Framework, you could instead use the built-in scheduling support instead.

How to use Quartz with EJB3?

I want to be able to :
define different jobs and triggers.
modify the expirations dates and intervals on demand
pause or cancel an execution (trigger)
the jobs would be ejbs or call ejbs and i would want to manage everything from the website (the user will have to define the executions)
So i looked at the timerservice, timerobjects, timer and timerhandle. But i think it can't answer to all my needs
Quartz, on the other hand, allows me to do every thing that i want, but i haven't the slightest clue on how to integrate this into my jboss.
I read that quartz uses its own threadpool, and i don't know how to handle all this.
I use Jboss Seam in my project, but the seam/quartz integration is very limited (or the documentation is) and not 100% safe (seen on their forum : 'run forever' tasks end after only a few weeks)
If someone managed to integrate a good scheduler into his application server (jboss is a plus) and could give me directions, advices, or even code snippets, i would be thrilled.
Thanks in advance.
I have some experience integrating Quartz into a Weblogic (no jboss experience, sorry) application server. Quartz has a built in listener class that will be called upon server startup (per J2EE specs) that automatically configure the Quartz scheduler. Then in another startup class you can retrieve that scheduler, add jobs and begin serving those jobs.
You generally don't need to worry about the threadpool, Quartz can handle all this itself if you want it too. It gets its information from a properties files on startup that you can define or use the default one that comes with quartz. I have been using the default because it works for my purposes.
As far as defining jobs, you create your job classes and call your ejbs from there. It is rather very simple.
For your reading pleasure:
All Quartz documentation
Quartz JavaDoc
Cookbook containing lots of code snippets
Hope that's enough to get you started!
Great news! JBoss has a built-in scheduler already.
Since the EJB 2.0 specification included running stateless session beans and MDBs at scheduled intervals, all application servers have included this capability for some time now.
Here is an example of configuring JBoss to run a class using its built-in scheduler:
http://www.jboss.org/community/wiki/Scheduler
The best part about JBoss' implementation is that it is based on the MBean specification, which means that you can create/update/delete scheduled tasks at runtime.
Ok, i am sorry, i found in the sources of Jboss Seam just what i needed :
QuartzDispatcher to create QuartzTriggerHandle wich fires seam event at specified time and date and is manually pausable, resumable and stoppable. I use an #observer on the method i wanted to execute.
It's simple, and it works so far.
As pointed out by Poindexter, the Quartz documentation has nice starting points: Tutorial for Developing with Quartz, Examples of Usage, Cook Book (Quick How-Tos in the form of code examples), etc.
The What Is Quartz article is really good too (even if a bit old now).
For integration with JBoss, maybe have a look at How to configure a Quartz service on JBoss Wiki.

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