This package defines the application invocation interface used by the workflow package to invoke tool agents that control applications.


Interface Summary
ContextRequester This interface marks a ToolAgent as a requester of a ToolAgentContext.
ExceptionMappingProvider This interface must be implemented by ToolAgents that want the workflow engine to map the causes of CannotExecuteExceptions to process exceptions that cause the current activity to be abandoned.
ExecutionModeProvider Deprecated. As of version 1.2, there are no different execution modes any more.
ResultProvider This interface marks a ToolAgent as provider of a result during invoke.
ToolAgent This interface is used to control applications that execute work items.
ToolAgentContext This interface defines methods of the workflow engine that are available to a tool agent.
XMLArgumentTypeProvider This interface can be implemented by ToolAgents that provide information about the accepted coding of arguments that describe XML data.

Class Summary
ExceptionMappingProvider.ExceptionMapping Define a single exception mapping.
ResultProvider.ExceptionResult A special kind of result that may be returned by result.

Exception Summary
ApplicationNotStoppedException This exception is thrown by a ToolAgent if it cannot terminate the execution of a running application.
CannotExecuteException This exception is thrown by a ToolAgent if it cannot execute a given activity.

Package Description

This package defines the application invocation interface used by the workflow package to invoke tool agents that control applications.

Java classes that are to be used as tool agents must implement the interface ToolAgent. Tool agents are declared in a workflow using the application tag in the XPDL. This declaration is associated with the implementation class of ToolAgent using an extension. The extension syntax supported allows to specify the Java class to use and additional properties of the tool agent (see the User Manual for details).

Note that a tool agent can be implemented with full functionallity based on the tool agent interface only. The remainder of this package description explains how tool agent implementation may be simplified and how the performance of tool agent invocations may be improved. As with the client API, we have tried to keep this extended interface as independant of the implementation framework (J2EE) as possible. However, this attempt is limited by requirements imposed by transaction handling. While the interfaces could be kept clean of dependencies on J2EE interfaces or classes, their usage pattern is partially motivated by EJB transaction semantics.

From the workflow engine's point of view, tool agent invocation is asynchronous, i.e. it does not expect a result from the invoke method. The invoked application must at some point in time call WfActivity.setResult and WfActivity.complete to signal completion of its work. Although the tool agent model assumes that this is done "later" (e.g. by the application process), these calls may also be made in the implementation of the invoke method, thus effectively combining the tool agent with the application that it controls (making the tool agent a tool).

If you try to call setResult and complete in the invoke method of your tool implementation, you'll sooner or later notice that these methods (being remote calls) may throw RemoteExceptions, indicating some temporary failure. If you do not handle these exceptions, they will be handled by the workflow engine and your tool will simply be re-invoked. If, however, your invoke method is "expensive" or has side effects, you may not want it to be re-executed because of a temporary failure during setResult or complete.

Consequently, you put a while loop around these calls, repeating them until they run without a RemoteException. Regrettably, this is where EJB semantics come in. While the repeat pattern works in a stand-alone EJB client, it won't work here because invoke is called in the context of an EJB method and the RemoteException from setResult or complete is noticed by the EJB container, and the complete tool agent invocation transaction will be rolled back. So you have to execute the calls to setResult and complete in a new transaction. This is what ToolAgentContext.finishActivity has been defined for. This method calls setResult and complete in a new transaction (and repeats the calls until no RemoteException is thrown). If you want to use this method (or another method from the tool agent context), your tool agent must implement ContextRequester in order to receive the context before invoke is called.

Having a closer look at transactions, there is a drawback to the solution described above. If we look at open transactions, we find that there is one transaction handling the tool invocation; this has been suspended for a new transaction that executes the actual tool agent invocation (this must be done in its own transaction, else the workflow engine cannot terminate an activity if an exception is thrown by the tool agent as, again, the invoking transaction would be marked for rollback by the application server). By calling finishActivity during invoke, the transaction executing the tool invocation will also be suspended in favour of the transaction that finishes the activity. This situation may, under certain circumstances lead to deadlocks.

To avoid these "excessive" nested transaction suspends, the calls to setResult and complete should better be done after tool invocation by the the same transaction that has invoked the tool. Tools (i.e. tool agents that want to return a result and complete the activity during invoke) should therefore implement ResultProvider. This allows the tool to simply leave the result evaluated during invoke in an attribute from where it will be retrieved after invoke by the workflow engine. The workflow engine then calls setResult and complete on the activity. Besides avoiding transaction problems, usage of ResultProvider actually simplifies the tool implementation.