Configuring Work Manager for J2EE Container
J2EE container providers that support the Work Manager API normally provide a UI-based tool for defining Work Manager. WebLogic 9.0, for example, provides such a tool for configuring Work Manager (
Figure 3 shows a WebLogic 9.0 administrative console showing a Work Manager configuration). The user needs to provide a work manager name and point Work Manager to a target server or cluster. As an example, I have created TestWorkManager.
 | |
| Figure 3: WebLogic Administrative Console Showing TestWorkManager |
An implementation also can provide features that are not part of a specification. For example, WebLogic allows users to configure Work Manager with the following optional parameters:
- Minimum thread constraint: The minimum number of threads allocated to resolve deadlock
- Maximum thread constraint: The maximum number of threads that can be allocated to execute requests
- Capacity constraint: Total number of requests that can queue or execute before WebLogic starts rejecting requests
Implementation of Work Manager-Based Application
Take the following steps to implement an application for parallel processing with WebLogic 9.0:
- Implement the Work interface and define your business logic in the run() method. The current version of WebLogic 9.0 does not support execution of work in remote JVMs, but it may in the future. So it's a good practice to implement java.io.Serializable as well for future enhancements to Work Manager.
- Implement the WorkListener interface for listening to work lifecycle events. Although not necessary, this step is a good practice.
- JNDI lookup is the primary way of accessing Work Manager. Servlets and EJB can access Work Manager via JNDI lookup within the local JVM. You can associate the Work Manager resource to an application by defining resource-ref in the appropriate deployment descriptor. For a servlet to access Work Manager, you define the resource-ref in web.xml. For EJB, you can define the resource-ref in ejb-jar.xml:
<resource-ref>
<res-ref-name>wm/TestWorkManager</res-ref-name>
<res-type>commonj.work.WorkManager</res-type>
<res-auth>Container</res-auth>
<res-sharing-scope>Shareable</res-sharing-scope>
</resource-ref>
- Now, look at a code snippet that invokes Work Manager and schedules work for execution on a container-managed thread. The following snippet shows the code for using the Work Manager API:
//#1. Get Work Manager from local JNDI
WorkManager workManager;
InitialContext ctx = new InitialContext();
this.workManager = (WorkManager)ctx.lookup("java:comp/env/wm/TestWorkManager");
//#2. Create instance of Work and WorkListener implementation
Work work = new WorkImpl("HelloWorld");
WorkListener workListener=new WorkListenerImpl();
//#3. Schedule work for execution, which would start in parallel to current thread
WorkItem workItem = workManager.schedule(work, workListener);
//#4. Create list of WorkItem you want to wait for completion
List workItemList=new ArrayList();
workItemList.add(workItem);
//#5. Wait for completion of work
this.workManager.waitForAll(workItemList, WorkManager.INDEFINITE);
//#6. You can get results from Work implementation
WorkImpl workImpl= (WorkImpl)workItem.getResult();
In this implementation, you assume WorkImpl and WorkListenerImpl are implementations of the Work and WorkListener interfaces.
The Takeaway
This article discussed a simple and powerful API for parallel execution of tasks within a managed environment. It explained the high-level design of the Work Manager API and explored WebLogic 9.0's working implementation of the Work Manager API.
With the Work Manager API, developers can design robust applications for executing tasks in parallel, listen to work lifecycle events, and add the dependency of task completion to other tasks. Work Manager implementations also could be highly scalable if app server providers implemented a work manager capable of executing work on remote JVMs.