+

Search Tips   |   Advanced Search

Develop applications that use work areas

Applications interact with the work area service by implementing the UserWorkArea interface. This interface defines all of the methods used to create, manipulate, and terminate work areas.

package com.ibm.websphere.workarea;

public interface UserWorkArea {
   void begin(String name);
   void complete() throws NoWorkArea, NotOriginator;

   String getName();
   String[] retrieveAllKeys();
   void set(String key, java.io.Serializable value)
      throws NoWorkArea, NotOriginator, PropertyReadOnly;
   void set(String key, java.io.Serializable value, PropertyModeType mode)
      throws NoWorkArea, NotOriginator, PropertyReadOnly;
   java.io.Serializable get(String key);
   PropertyModeType getMode(String key);
   void remove(String key)
      throws NoWorkArea, NotOriginator, PropertyFixed;
}

EJB applications can use the UserWorkArea interface only within the implementation of methods in either the remote or local interface, or both; likewise, servlets can use the interface only within the service method of the HTTPServlet class. Use of work areas within any life cycle method of a servlet or enterprise bean is considered a deviation from the work area programming model and is not supported.

The work area service defines the following exceptions for use with the UserWorkArea interface:

NoWorkArea

Raised when a request requires an associated work area but none is present.

NotOriginator

Raised when a request attempts to manipulate the contents of an imported work area.

PropertyReadOnly

Raised when a request attempts to modify a read-only or fixed read-only property.

PropertyFixed

Raised by the remove method when the designated property has one of the fixed modes.


Tasks

  1. Access a partition by either:

    • Accessing the UserWorkArea partition, to access the UserWorkArea partition.
    • Accessing a user-defined work area partition, to access a user-defined work area.

    The following steps use the UserWorkArea partition as an example; however, we can use a user-defined partition in the same way.

  2. Begin a new work area.

    Use the begin method to create a new work area and associate it with the calling thread. A work area is scoped to the thread that began the work area and is not accessible by multiple threads. The begin method takes a string as an argument; the string is used to name the work area. The argument must not be null, which causes the java.lang.NullPointer exception to be raised. In the following code example, the application begins a new work area with the name SimpleSampleServlet:

    public class SimpleSampleServlet {
    ...
       try {
          ...
          userWorkArea = (UserWorkArea)jndi.lookup(
             "java:comp/websphere/UserWorkArea");
       }
       ...
    
       userWorkArea.begin("SimpleSampleServlet");
       ...
    }
    

    The begin method is also used to create nested work areas; if a work area is associated with a thread when the begin method is called, the method creates a new work area nested within the existing work area.

    The work area service makes no use of the names associated with work areas; We can name work areas in any way chosen. Names are not required to be unique, but the usefulness of the names for debugging is enhanced if the names are distinct and meaningful within the application. Applications can use the getName method to return the name associated with a work area by the begin method.

  3. Set properties in the work area.

    An application with a current work area can insert properties into the work area and retrieve the properties from the work area. The UserWorkArea interface provides two set methods for setting properties and a get method for retrieving properties. The two-argument set method inserts the property with the property mode of normal. The three-argument set method takes a property mode as the third argument. Both set methods take the key and the value as arguments. The key is a String; the value is an object of the type java.io.Serializable. None of the arguments can be null, which causes the java.lang.NullPointer exception to be raised.

    The following SimpleSample application uses objects of two classes, the SimpleSampleCompany class and the SimpleSampleProperty class, as values for properties. The SimpleSampleCompany class is used for the site identifier, and the SimpleSamplePriority class is used for the priority.

    public class SimpleSampleServlet {
       ...
       userWorkArea.begin("SimpleSampleServlet");
    
       try {
          // Set the site-identifier (default is Main).
          userWorkArea.set("company",
             SimpleSampleCompany.Main, PropertyModeType.read_only);
    
          // Set the priority.
          userWorkArea.set("priority", SimpleSamplePriority.Silver);
       }
    
       catch (PropertyReadOnly e) {
         // The company was previously set with the read-only or
         // fixed read-only mode.
         ...
       }
    
        catch (NotOriginator e) {
         // The work area originated in another process,
         // so it can't be modified here.
         ...
       }
    
       catch (NoWorkArea e) {
          // There is no work area begun on this thread.
          ...
       }
    
       // Do application work.
       ...
    }
    

    The get method takes the key as an argument and returns a Java Serializable object as the value associated with the key. For example, to retrieve the value of the company key from the work area, the previous code example uses the get method on the work area to retrieve the value.

    Setting property modes. The two-argument set method on the UserWorkArea interface takes a key and a value as arguments and inserts the property with the default property mode of normal. To set a property with a different mode, applications must use the three-argument set method, which takes a property mode as the third argument. The values used to request the property modes are as follows:

    • Normal: PropertyModeType.normal
    • Fixed normal: PropertyModeType.fixed_normal
    • Read-only: PropertyModeType.read_only
    • Fixed read-only: PropertyModeType.fixed_readonly

  4. Manage local work with a work area.
  5. Complete the work area.

    After an application has finished using a work area, it must complete the work area by calling the complete method on the UserWorkArea interface. This terminates the association with the calling thread and destroys the work area. If the complete method is called on a nested work area, the nested work area is terminated and the parent work area becomes the current work area. If there is no work area associated with the calling thread, a NoWorkArea exception is created. Every work area must be completed, and work areas can be completed only by the originating process. For example, if a server attempts to call the complete method on a work area that originated in a client, a NotOriginator exception is created. Work areas created in a server process are never propagated back to an invoking client process.

    The work area service claims full local-remote transparency. Even if two beans happen to be deployed in the same server, and therefore the same JVM and process, a work area begun on an invocation from another is completed and the bean in which the request originated is always in the same state after any remote call.

    The following code example shows the completion of the work area created in the client application.

    public class SimpleSampleServlet {
       ...
       userWorkArea.begin("SimpleSampleServlet");
       userWorkArea.set("company",
           SimpleSampleCompany.Main, PropertyModeType.read_only);
       userWorkArea.set("priority", SimpleSamplePriority.Silver);
       ...
    
       // Do application work.
       ...
    
       // Terminate the work area.
       try {
          userWorkArea.complete();
       }
    
       catch (NoWorkArea e) {
          // There is no work area associated with this thread.
          ...
       }
    
       catch (NotOriginator e) {
          // The work area was imported into this process.
          ...
       }
      ...
    }
    

    The following code example shows the sample application completing the nested work area that it created earlier in the remote invocation.

    public class SimpleSampleBeanImpl implements SessionBean {
    
        public String [] test() {
          ...
    
          // Begin a nested work area.
          userWorkArea.begin("SimpleSampleBean");
          try {
            userWorkArea.set("company",
                             SimpleSampleCompany.London_Development);
          }
          catch (NotOriginator e) {
          }
    
          SimpleSampleCompany company =
             (SimpleSampleCompany) userWorkArea.get("company");
          SimpleSamplePriority priority =
             (SimpleSamplePriority) userWorkArea.get("priority");
    
          // Complete all nested work areas before returning.
          try {
            userWorkArea.complete();
          }
          catch (NoWorkArea e) {
          }
          catch (NotOriginator e) {
          }
       }
    }
    
    


Example

Work area object types. In the following example, the client creates a work area and inserts two properties into the work area: a site identifier and a priority. The site-identifier is set as a read-only property; the client does not allow recipients of the work area to override the site identifier. This property consists of the key company and a static instance of a SimpleSampleCompany object. The priority property consists of the key priority and a static instance of a SimpleSamplePriority object. The object types are defined as shown in the following code example:

public static final class SimpleSampleCompany {
   public static final SimpleSampleCompany Main;
   public static final SimpleSampleCompany NewYork_Sales;
   public static final SimpleSampleCompany NewYork_Development;
   public static final SimpleSampleCompany London_Sales;
   public static final SimpleSampleCompany London_Development;
}

public static final class SimpleSamplePriority {
   public static final SimpleSamplePriority Platinum;
   public static final SimpleSamplePriority Gold;
   public static final SimpleSamplePriority Silver;
   public static final SimpleSamplePriority Bronze;
   public static final SimpleSamplePriority Tin;
}

The client then makes an invocation on a remote object. The work area is automatically propagated; none of the methods on the remote object take a work area argument. On the remote side, the request is first handled by the SimpleSampleBean; the bean first reads the site identifier and priority properties from the work area. The bean then intentionally attempts, and fails, both to write directly into the imported work area and to override the read-only site-identifier property.

The SimpleSampleBean successfully begins a nested work area, in which it overrides the client's priority, then calls another bean, the SimpleSampleBackendBean. The SimpleSampleBackendBean reads the properties from the work area, which contains the site identifier set in the client and priority set in the SimpleSampleBean. Finally, the SimpleSampleBean completes its nested work area, writes out a message based on the site-identifier property, and returns.

Use the work area partition manager. The following code example illustrates the use of the work area partition manager interface. The sample illustrates how to create and retrieve a work area partition programmatically`. Please note that programmatically creating a work area partition is only available on the Java Platform, Enterprise Edition (Java EE) client. To create a work area partition on the server one must use the administrative console. Refer to the Work area partition service article for configuration parameters available to configure a partition.

import com.ibm.websphere.workarea.WorkAreaPartitionManager;
import com.ibm.websphere.workarea.UserWorkArea;
import com.ibm.websphere.workarea.PartitionAlreadyExistsException;
import com.ibm.websphere.workarea.NoSuchPartitionException;
import java.lang.IllegalAccessError;
import java.util.Properties;
import javax.naming.InitialContext;

//This sample demonstrates how to retrieve an instance of the 
//WorkAreaPartitionManager implementation and how to use that
//instance to create a WorkArea partition and retrieve a partition.  
//NOTE: Creating a partition in the way listed is only available 
//on a J2EE client.  To create a partition on the server use the 
//WebSphere administrative console.  Retrieving a WorkArea
//partition is performed in the same way on both client and server.

public class Example {

     //The name of the partition to create/retrieve
     String partitionName = "myPartitionName";
     //The name in java naming the WorkAreaPartitionManager instance is bound to
     String jndiName = "java:comp/websphere/WorkAreaPartitionManager";

     //On a J2EE client a user would create a partition as follows:
     public UserWorkArea myCreate(){
         //Variable to hold our WorkAreaPartitionManager reference
         WorkAreaPartitionManager partitionManager = null;
         //Get an instance of the WorkAreaPartitionManager implementation
         try {
             InitialContext initialContext = new InitialContext();
             partitionManager = (WorkAreaPartitionManager) initialContext.lookup(jndiName);
         } catch (Exception e) {  }

         //Set the properties to configure our WorkArea partition
         Properties props = new Properties();
         props.put("maxSendSize","12345");
         props.put("maxReceiveSize","54321");
         props.put("Bidirectional","true");
  			 props.put("DeferredAttributeSerialization","true");

         //Variable used to hold the newly created WorkArea Partition
         UserWorkArea myPartition = null;

         try{
             //This is the way to create a partition on the J2EE client.  Use the
             //WebSphere Administrative Console to create a WorkArea Partition
             //on the server.
             myPartition = partitionManager.createWorkAreaPartition(partitionName,props);
         }
         catch (PartitionAlreadyExistsException e){  }
         catch (IllegalAccessException e){  }

         return myPartition;
     }

     //. . . .

     //In order to retrieve a WorkArea partition at some time later or 
     //from some other class, do the following (from client or server):
     public UserWorkArea myGet(){
         //Variable to hold our WorkAreaPartitionManager reference
         WorkAreaPartitionManager partitionManager = null;
         //Get an instance of the WorkAreaPartitionManager implementation
         try {
             InitialContext initialContext = new InitialContext();
             partitionManager = (WorkAreaPartitionManager) initialContext.lookup(jndiName);
         } catch (Exception e) {  }

         //Variable used to hold the retrieved WorkArea partition
         UserWorkArea myPartition = null;
         try{
             myPartition = partitionManager.getWorkAreaPartition(partitionName);
         }catch(NoSuchPartitionException e){  }

         return myPartition;
     }
}


What to do next

For additional information about work area, see the com.ibm.websphere.workarea package in the API. The generated API documentation is available in the information center table of contents from the path Reference > APIs - Application programming interfaces.


Related:

  • Overview of work area service
  • Work area partition service
  • Manage local work with a work areas
  • Manage the UserWorkArea partition
  • Accessing the UserWorkArea partition
  • Additional Application Programming Interfaces (APIs)
  • Accessing a user defined work area partition