[maven-release-plugin]  copy for tag uima-ducc-2.2.1

git-svn-id: https://svn.apache.org/repos/asf/uima/uima-ducc/tags/uima-ducc-2.2.1@1805087 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/RELEASE_NOTES.html b/RELEASE_NOTES.html
index 77ecce7..bfec715 100755
--- a/RELEASE_NOTES.html
+++ b/RELEASE_NOTES.html
@@ -77,6 +77,13 @@
 enabled there should be "swap" property defined. If it's missing, you need to add a kernel parameter 
 swapaccount=1. Details of how to do this can be found <a href="http://unix.stackexchange.com/questions/147158/how-to-enable-swap-accounting-for-memory-cgroup-in-archlinux">here</a>.
 
+Due to a bug in uima sdk, the uima AnalysisEngineProcessException cannot be serialized as a Java object. If your
+analysis engine throws an exception in process(), the ducc framework will stringify it and wrapt it in
+java RuntimeException. If you have a custom error handler plugged in into a job driver you will not be
+able to test for AnalysisEngineProcessException in a stack trace with a code like this:
+
+   if ( error instanceof AnalysisEngineProcessException ) ...
+
 
 </body>
 </html>
diff --git a/src/main/assembly/bin.xml b/src/main/assembly/bin.xml
index b11f5a5..549b06c 100644
--- a/src/main/assembly/bin.xml
+++ b/src/main/assembly/bin.xml
@@ -509,6 +509,7 @@
         <include>1.dd.job</include>
         <include>1.dd.sync.job</include>
         <include>1.job</include>
+        <include>1-error.job</include>
         <include>1.inputs</include>
         <include>1.service</include>
       </includes>
diff --git a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java
index a883250..c977d4a 100644
--- a/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java
+++ b/uima-ducc-agent/src/main/java/org/apache/uima/ducc/agent/launcher/DuccCommandExecutor.java
@@ -563,6 +563,11 @@
 
 			throw ex;
 		} finally {
+			if ( isKillCmd ) {
+				// the kill command process has been launched. Nothing else to do. 
+				// We now wait for the process to die.
+				return; 
+			}
 		    if ( !failed ) {
 			// associate exit code
 			((ManagedProcess) managedProcess).getDuccProcess()
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java
index e5270bd..1dde288 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/AServicePing.java
@@ -105,21 +105,18 @@
      *
      * @param endpoint This is the name of the service endpoint, as passed in
      *                 at service registration.
+     *                 
+     * @throws Exception If initialization fails
      */
     public abstract void init(String arguments, String endpoint) throws Exception;
 
     /**
-     * <p>
      * Called by the ping driver to initialize static information about the service and
      * pinger.  This method calls the public init() method and is not intended for public
      * consumption.
-     * </p>
      *
-     * <p>
      * This method initializes the following state prior to invoking init(String, String):
-     * </p>
      *
-     * <xmp>
      * VAR NAME               TYPE         MEANING
      * ------------------     --------     ---------------------------------------------
      * monitor_rate           int          Ping period, in minutes.
@@ -133,7 +130,6 @@
      * last_use               long         When was the last known use of this service
      *                                     before it was (re)started?
      *
-     * </xmp>
      *
      * @param arguments This is passed in from the service specification's
      *                  service_ping_arguments string.
@@ -143,6 +139,8 @@
      *
      * @param initState Properties file with static data about the service and 
      *                  pinger.
+     *                  
+     * @throws Exception If initialization fails
      */
     public void init(String arguments, String endpoint, Map<String, Object> initState)
         throws Exception
@@ -180,7 +178,7 @@
      */
     public abstract IServiceStatistics getStatistics();
 
-    /**
+    /*
      * Current state of the monitored service is passed in here.
      * NOTE: Used for SM to Ping/Monitor communicaiton only.
      */    
@@ -190,21 +188,18 @@
     }
 
     /**
-     * <p>
      * Getter of the service state;  Implementors may just access it directly if they want.
      * Access the state passed to the ping/monitor from SM:
-     * </p>
-     * <xmp>
+     * 
      * KEY                  Object Type       MEANING
      * ----------------     -------------     ------------------------------------------------------------------
-     * all-instances        Long[]            DUCC Ids of all running instances (may not all be in Runing state)
+     * all-instances        Long[]            DUCC Ids of all running instances (may not all be in Running state)
      * active-instances     Long[]            DUCC Ids of all instances that are Running
      * autostart-enabled    Boolean           Current state of service autostart
      * references           Long[]            DUCC Ids of all jobs referencing this service
      * run-failures         Integer           Total run failures since the service was started
-     * </xmp>
      *
-     * @return A Map<String, Object> of string-key to Object containing dynamic information from the SM.  Callers
+     * @return A String to Object Map containing dynamic information from the SM.  Callers
      *        must cast the value to the correct type as shown below.
      */
     public Map<String, Object> getSmState() 
@@ -310,7 +305,7 @@
         return String.format(sb.toString(), vals);
     }
 
-    /**
+    /*
      * <p>
      * This is used by the SM for running pingers internally as SM threads, to direct
      * the ping log into the SM log.
@@ -377,32 +372,23 @@
     }
 
     /**
-     * <p>
      * This determines if there have been excessive service instance failures by tracking the 
      * number of failures, not consecutive, but rather within a window of time.  It may be
      * overridden by extending monitors.
-     * </p>
      *
-     * <p>
      * This default implementation uses a time window to determine if exessive failures
      * have occurred in a short period of time.  It operates off the two failure parameters
      * from the service registration:
-     * <xmp>
      *     instance_failure_window  [time-in-minutes]
      *     instance_failure_limit   [number of failures]
-     * </xmp>
-     * </p>
-     * <p>
+     *     
      * If more than 'instance_failure_limit' failures occure within the preceding 
      * 'time-in-minutes' this method returns 'true' and the SM disables automatic
      * restart of instances.  Restart may be resumed by manually issuing a CLI start
      * to the service one the problem is resolved.
-     * </p>
      *
-     * <p>
      * Implementing ping/monitors may override this with custom logic to determine if a
      * service has had excessive failures.
-     * </p>
      *
      * @return true if too many failures have been observed, false otherwise.  If 'true'
      * is returned, the SM no longer restarts failed instances.
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java
index 2dd101f..c1dd4f2 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/CliBase.java
@@ -217,7 +217,7 @@
         }
     }
 
-    /**
+    /*
      * Standard init for all except the Service calls that are sent to the SM
      */
 
@@ -240,7 +240,7 @@
    * @param cli_props    (Initially) empty properties file to be filled in
    * @param consoleCb    Console callback object (optional)
    * @param servlet      The name of the http servlet that will serve this request
-   * @throws Exception
+   * @throws Exception   If initialization fails, e.g. invalid arguments or properties
    */
     protected synchronized void init(String myClassName, IUiOption[] uiOpts, String[] args, Properties props,
                     DuccProperties cli_props, IDuccCallback consoleCb, String servlet)
@@ -517,6 +517,8 @@
      * structures for the API, and extracts the numeric id of the [job, ducclet, reservation, service]
      * returned by the Orchestrator.
      *
+     * @param reply - an Orchestrator reply event
+     *   
      * @return true if the action succeeded and false otherwise.  The action in this case, is whatever
      *               the Orchestrator was asked to do: submit something, cancel something, etc.
      */
@@ -595,7 +597,7 @@
         return consoleCb;
     }
 
-    /**
+    /*
      * NOTE: We do NOT want to be intentionally throwing from the CLI.  Pls pass e.getMessage() or
      *       e.toString() to this instead of throwing.
      */
@@ -690,7 +692,7 @@
         mlt.start();
     }
 
-    /**
+    /*
      * Needs to be done before submitting the job because the job needs the ports.  We'll
      * just define the listener, but not start it until the job monitor starts, in case the
      * submission fails.
@@ -721,7 +723,7 @@
         cli_props.setProperty(key, env);
     }
 
-    /**
+    /*
      * Be sure to call this BEFORE submission, to insure the callback address is set in properties.
      */
     protected synchronized void startConsoleListener(boolean start_stdin)
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java
index bc122d6..7401737 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobCancel.java
@@ -51,8 +51,11 @@
 
 	
     /**
-     * @param args Array of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_CANCEL">DUCC CLI reference.</a>
+     * Cancel a job
+     * 
+     * @param args Array of string arguments as described in the
+     *             Command Line Interface section of the DuccBook 
+     * @throws Exception if request fails
      */
 	public DuccJobCancel(String [] args) 
         throws Exception
@@ -61,8 +64,11 @@
 	}
 
     /**
+     * Cancel a job
+     * 
      * @param args List of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_CANCEL">DUCC CLI reference.</a>
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
 	public DuccJobCancel(List<String> args) 
         throws Exception
@@ -72,8 +78,11 @@
 	}
 
     /**
-     * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_CANCEL">DUCC CLI reference.</a>
+     * Cancel a job
+     * 
+     * @param props Properties file of arguments as described in the
+     *              Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
 	public DuccJobCancel(Properties props) 
         throws Exception
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java
index 3beed83..e657e4e 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccJobSubmit.java
@@ -92,8 +92,11 @@
     private AllInOneLauncher allInOneLauncher = null;
 
     /**
+     * Submit a job
+     * 
      * @param args Array of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SUBMIT">DUCC CLI reference.</a>
+     * Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
     public DuccJobSubmit(String[] args)
         throws Exception
@@ -102,8 +105,11 @@
     }
 
     /**
+     * Submit a job
+     * 
      * @param args List of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SUBMIT">DUCC CLI reference.</a>
+     * Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
     public DuccJobSubmit(ArrayList<String> args)
         throws Exception
@@ -113,8 +119,11 @@
 
 
     /**
+     * Submit a job
+     * 
      * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SUBMIT">DUCC CLI reference.</a>
+     * Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
     public DuccJobSubmit(Properties props)
         throws Exception
@@ -130,6 +139,7 @@
      *      <a href="/doc/duccbook.html#DUCC_CLI_SUBMIT">DUCC CLI reference.</a>
      * @param consoleCb If provided, messages are directed to it instead of
      *        stdout.
+     * @throws Exception if request fails
      */
     public DuccJobSubmit(ArrayList<String> args, IDuccCallback consoleCb)
         throws Exception
@@ -145,6 +155,7 @@
      *      <a href="/doc/duccbook.html#DUCC_CLI_SUBMIT">DUCC CLI reference.</a>
      * @param consoleCb If provided, messages are directed to it instead of
      *        stdout.
+     * @throws Exception if request fails
      */
     public DuccJobSubmit(String[] args, IDuccCallback consoleCb)
         throws Exception
@@ -164,6 +175,7 @@
      *      <a href="/doc/duccbook.html#DUCC_CLI_SUBMIT">DUCC CLI reference.</a>
      * @param consoleCb If provided, messages are directed to it instead of
      *        stdout.
+     * @throws Exception if request fails
      */
     public DuccJobSubmit(Properties props, IDuccCallback consoleCb)
         throws Exception
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationCancel.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationCancel.java
index c91c531..168acce 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationCancel.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationCancel.java
@@ -47,8 +47,9 @@
     };
 
     /**
-     * @param args Array of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_CANCEL">DUCC CLI reference.</a>
+     * @param args Array of string arguments as described in the
+     * Command Line Interface section of the DuccBook 
+     * @throws Exception if request fails
      */
 	public DuccManagedReservationCancel(String [] args) 
         throws Exception
@@ -57,8 +58,9 @@
 	}
 
     /**
-     * @param args List of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_CANCEL">DUCC CLI reference.</a>
+     * @param args List of string arguments as described in the
+     * Command Line Interface section of the DuccBook 
+     * @throws Exception if request fails
      */
 	public DuccManagedReservationCancel(List<String> args) 
         throws Exception
@@ -69,7 +71,8 @@
 
     /**
      * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_CANCEL">DUCC CLI reference.</a>
+     * Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
 	public DuccManagedReservationCancel(Properties props) 
         throws Exception
@@ -92,6 +95,7 @@
      * to effect the cancellation.
      *
      * @return True if the orchestrator accepts the job cancellation.
+     * @throws Exception if request fails
      */
 	public boolean execute() 
         throws Exception 
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java
index 39f3331..3add95c 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccManagedReservationSubmit.java
@@ -63,7 +63,8 @@
 
     /**
      * @param args List of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_SUBMIT">DUCC CLI reference.</a>
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
     public DuccManagedReservationSubmit(String[] args)
         throws Exception
@@ -73,7 +74,8 @@
 
     /**
      * @param args Array of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_SUBMIT">DUCC CLI reference.</a>
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if request fails            
      */
     public DuccManagedReservationSubmit(ArrayList<String> args)
         throws Exception
@@ -83,7 +85,8 @@
 
     /**
      * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_SUBMIT">DUCC CLI reference.</a>
+     *              Command Line Interface section of the DuccBook
+     * @throws Exception if request fails             
      */
    public DuccManagedReservationSubmit(Properties props)
         throws Exception
@@ -96,9 +99,9 @@
      * messages, rather than directing them to stdout.
      *
      * @param args Array of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_SUBMIT">DUCC CLI reference.</a>
-     * @param consoleCb If provided, messages are directed to it instead of
-     *        stdout.
+     *             Command Line Interface section of the DuccBook
+     * @param consoleCb If provided, messages are directed to it instead of stdout.
+     * @throws Exception if request fails
      */
     public DuccManagedReservationSubmit(String[] args, IDuccCallback consoleCb)
         throws Exception
@@ -112,9 +115,9 @@
      * messages, rather than directing them to stdout.
      *
      * @param args List of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_SUBMIT">DUCC CLI reference.</a>
-     * @param consoleCb If provided, messages are directed to it instead of
-     *        stdout.
+     *             Command Line Interface section of the DuccBook
+     * @param consoleCb If provided, messages are directed to it instead of stdout.
+     * @throws Exception if request fails
      */
     public DuccManagedReservationSubmit(ArrayList<String> args, IDuccCallback consoleCb)
         throws Exception
@@ -129,9 +132,9 @@
      * messages, rather than directing them to stdout.
      *
      * @param props Properties file contianing string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_PROCESS_SUBMIT">DUCC CLI reference.</a>
-     * @param consoleCb If provided, messages are directed to it instead of
-     *        stdout.
+     *              Command Line Interface section of the DuccBook
+     * @param consoleCb If provided, messages are directed to it instead of stdout.
+     * @throws Exception if request fails
      */
     public DuccManagedReservationSubmit(Properties props, IDuccCallback consoleCb)
         throws Exception
@@ -146,6 +149,7 @@
      * the job properties to the DUCC orchestrator for execution.
      *
      * @return True if the orchestrator accepts the job; false otherwise.
+     * @throws Exception if request fails
      */
     public boolean execute() throws Exception
     {
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationCancel.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationCancel.java
index 0ec0597..1bea200 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationCancel.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationCancel.java
@@ -49,8 +49,8 @@
     };
 
     /**
-     * @param args Array of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_UNRESERVE">DUCC CLI reference.</a>
+     * @param args Array of string arguments as described in the
+     * @throws Exception if request fails 
      */	
 	public DuccReservationCancel(String [] args) 
         throws Exception
@@ -59,8 +59,9 @@
 	}
 
     /**
-     * @param args List of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_UNRESERVE">DUCC CLI reference.</a>
+     * @param args List of string arguments as described in the
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if request fails 
      */
 	public DuccReservationCancel(List<String> args) 
         throws Exception
@@ -71,7 +72,8 @@
 
     /**
      * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_UNRESERVE">DUCC CLI reference.</a>
+     *              Command Line Interface section of the DuccBook
+     * @throws Exception if request fails             
      */
 	public DuccReservationCancel(Properties props) 
         throws Exception
@@ -80,9 +82,9 @@
 	}
 
     /**
-     * Return the DUCC Orchestrator message, if any, pertaining to the cancelation.
+     * Return the DUCC Orchestrator message, if any, pertaining to the cancellation.
      *
-     * @return Return any message associated with the cancelation.
+     * @return Return any message associated with the cancellation.
      */
 	public String getResponseMessage()
 	{
@@ -90,10 +92,11 @@
 	}
 
     /**
-     * Execute collects the parameters for reservation cancelation and sends them to the DUCC Orchestrator
-     * to effect the cancelation.
+     * Execute collects the parameters for reservation cancellation and sends them to the DUCC Orchestrator
+     * to effect the cancellation.
      *
-     * @return True if the orchestrator accepts the reservation cancelation.
+     * @return True if the orchestrator accepts the reservation cancellation.
+     * @throws Exception if request fails
      */
 	public boolean execute() 
         throws Exception 
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java
index 5bf55ee..228953f 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccReservationSubmit.java
@@ -44,7 +44,8 @@
 	
     /**
      * @param args Array of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_RESERVE">DUCC CLI reference.</a>
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
 	public DuccReservationSubmit(String[] args)
         throws Exception
@@ -54,7 +55,8 @@
 
     /**
      * @param args List of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_RESERVE">DUCC CLI reference.</a>
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
 	public DuccReservationSubmit(ArrayList<String> args)
         throws Exception
@@ -65,7 +67,8 @@
 
     /**
      * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_RESERVE">DUCC CLI reference.</a>
+     *              Command Line Interface section of the DuccBook
+     * @throws Exception if request fails
      */
 	public DuccReservationSubmit(Properties props)
         throws Exception
@@ -94,7 +97,7 @@
      * Reservations must be from one of the 'reserve' classes i.e for a whole machine.
      *
      * @return True if the DUCC grants the reservation. 
-     * @throws Exception 
+     * @throws Exception if request fails
      */
 	public boolean execute() throws Exception
     {		
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
index ea8fda6..d837f2f 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceApi.java
@@ -363,8 +363,10 @@
     /**
      * The register API is used to register a service with the service manager.
      *
-     * @param args String rray of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @param args String array of arguments as described in the
+     *             Command Line Interface section of the DuccBook
      * @return {@link IServiceReply IServiceReply} object with register status.
+     * @throws Exception if the request is invalid
      */
     public IServiceReply register(String[] args)
         throws Exception
@@ -492,8 +494,10 @@
      * The unregister API is used to unregister a service.  The service manager will stop all instances and
      * remove the service registration.
      *
-     * @param args String array of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @param args String array of arguments as described in the
+     *             Command Line Interface section of the DuccBook
      * @return {@link IServiceReply IServiceReply} object with unregister reply status.
+     * @throws Exception if the request is invalid
      */
     public IServiceReply unregister(String[] args)
         throws Exception
@@ -521,8 +525,10 @@
     /**
      * The start API is used to start one or more instances of a registered service.
      *
-     * @param args String array of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @param args String array of arguments as described in the
+     *             Command Line Interface section of the DuccBook
      * @return {@link IServiceReply IServiceReply} object with start reply status.
+     * @throws Exception if the request is invalid
      */
     public IServiceReply start(String[] args)
         throws Exception
@@ -555,8 +561,10 @@
     /**
      * The stop API is used to stop one or more service instances.
      *
-     * @param args String array of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @param args String array of arguments as described in the
+     *             Command Line Interface section of the DuccBook
      * @return {@link IServiceReply IServiceReply} object with stop status.
+     * @throws Exception if the request is invalid
      */
     public IServiceReply stop(String[] args)
         throws Exception
@@ -589,8 +597,10 @@
      * The service 'modify' command is used to change various aspects of a registered service
      * without the need to reregister it.
      *
-     * @param args String array of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @param args String array of arguments as described in the
+     *             Command Line Interface section of the DuccBook
      * @return {@link IServiceReply IServiceReply} object with modify status.
+     * @throws Exception if the request is invalid
      */
     public IServiceReply modify(String[] args)
         throws Exception
@@ -622,8 +632,10 @@
      * The service 'modify' command is used to change various aspects of a registered service
      * without the need to reregister it.
      *
-     * @param args String array of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @param args String array of arguments as described in the
+     *             Command Line Interface section of the DuccBook
      * @return {@link IServiceReply IServiceReply} object with modify status.
+     * @throws Exception if the request is invalid
      */
     public IServiceReply modifyX(String[] args)
         throws Exception
@@ -678,8 +690,10 @@
     /**
      * The query API is used to query the status of services known to the service manager.
      *
-     * @param args String array of arguments as described in the <a href="/doc/duccbook.html#DUCC_CLI_SERVICES">DUCC CLI reference.</a>
+     * @param args String array of arguments as described in the
+     *             Command Line Interface section of the DuccBook
      * @return {@link IServiceReply IServiceReply} object with query results status.
+     * @throws Exception if the request is invalid
      */
     public IServiceReply query(String[] args)
         throws Exception
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceCancel.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceCancel.java
index 5cb24c3..61c7fa4 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceCancel.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceCancel.java
@@ -50,8 +50,9 @@
 
 	
     /**
-     * @param args Array of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SERVICE_CANCEL">DUCC CLI reference.</a>
+     * @param args Array of string arguments as described in the
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if the request is invalid 
      */
 	public DuccServiceCancel(String [] args) 
         throws Exception
@@ -60,8 +61,9 @@
 	}
 
     /**
-     * @param args List of string arguments as described in the 
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SERVICE_CANCEL">DUCC CLI reference.</a>
+     * @param args List of string arguments as described in the
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if the request is invalid 
      */
 	public DuccServiceCancel(List<String> args) 
         throws Exception
@@ -72,7 +74,8 @@
 
     /**
      * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SERVICE_CANCEL">DUCC CLI reference.</a>
+     *              Command Line Interface section of the DuccBook
+     * @throws Exception if the request is invalid
      */
 	public DuccServiceCancel(Properties props) 
         throws Exception
@@ -83,7 +86,7 @@
     /**
      * Return the DUCC Orchestrator message, if any, pertaining to the cancelation.
      *
-     * @return Return any message associated with the cancelation.
+     * @return Return any message associated with the cancellation.
      */
 	public String getResponseMessage()
 	{
@@ -91,10 +94,11 @@
 	}
 
     /**
-     * Execute collects the parameters for job cancelation and sends them to the DUCC Orchestrator
-     * to effect the cancelation.
+     * Execute collects the parameters for job cancellation and sends them to the DUCC Orchestrator
+     * to effect the cancellation.
      *
-     * @return True if the orchestrator accepts the job cancelation.
+     * @return True if the orchestrator accepts the job cancellation.
+     * @throws Exception if the request is invalid
      */
 	public boolean execute() 
         throws Exception 
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java
index 21b7fb9..039de4d 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/DuccServiceSubmit.java
@@ -83,7 +83,8 @@
 
     /**
      * @param args Array of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SERVICE_SUBMIT">DUCC CLI reference.</a>
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if the request is invalid
      */
     public DuccServiceSubmit(String[] args)
         throws Exception
@@ -93,7 +94,8 @@
 
     /**
      * @param args List of string arguments as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SERVICE_SUBMIT">DUCC CLI reference.</a>
+     *             Command Line Interface section of the DuccBook
+     * @throws Exception if the request is invalid
      */
     public DuccServiceSubmit(ArrayList<String> args)
         throws Exception
@@ -103,7 +105,8 @@
 
     /**
      * @param props Properties file of arguments, as described in the
-     *      <a href="/doc/duccbook.html#DUCC_CLI_SERVICE_SUBMIT">DUCC CLI reference.</a>
+     *              Command Line Interface section of the DuccBook
+     * @throws Exception if the request is invalid
      */
     public DuccServiceSubmit(Properties props)
         throws Exception
diff --git a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOption.java b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOption.java
index 5eef1de..ddfa960 100644
--- a/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOption.java
+++ b/uima-ducc-cli/src/main/java/org/apache/uima/ducc/cli/IUiOption.java
@@ -42,7 +42,7 @@
  *           public String description() { return "Run driver and pipeline in single process."; } 
  *           public String example()     { return null; }
  *       },
- *       public boolean multiargs() { return false; } // the option can have >1 arg
+ *       public boolean multiargs() { return false; } // the option can have multiple arguments
  *       public boolean required()  { return false; } // this option is required
  *       public String  deflt()     { return null; }  // default, or ""
  *       public String  sname()     { return null; }  // short name of option
diff --git a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/DuccAdminEvent.java b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/DuccAdminEvent.java
index b5061d3..5245bb1 100644
--- a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/DuccAdminEvent.java
+++ b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/DuccAdminEvent.java
@@ -52,7 +52,8 @@
     }
 
     /**
-     * Return the id of the user making the request. 
+     * 
+     * @return -  the id of the user making the request. 
      */
     public String getUser()
     {
@@ -60,7 +61,7 @@
     }
 
     /**
-     * Return the authentication block for the request.
+     * @return the authentication block for the request.
      */
     public byte[] getAuthBlock()
     {
diff --git a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/RmAdminQLoadReply.java b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/RmAdminQLoadReply.java
index e8186c6..b81ade7 100644
--- a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/RmAdminQLoadReply.java
+++ b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/admin/event/RmAdminQLoadReply.java
@@ -40,15 +40,15 @@
     }
 
 
-    /** RM only, other use produces incorrect results. */
+    /* RM only, other use produces incorrect results. */
     public void setShareQuantum(long q)               { this.shareQuantum = q / ( 1024*1024); }
-    /** RM only, other use produces incorrect results. */
+    /* RM only, other use produces incorrect results. */
     public void addNodepool    (RmQueriedNodepool np) { nodepools.add(np); }
-    /** RM only, other use produces incorrect results. */
+    /* RM only, other use produces incorrect results. */
     public void addClass       (RmQueriedClass    cl) { classes.add(cl); }
 
     /**
-     * Return the share quantum currently being used by RM.
+     * @return the share quantum currently being used by RM.
      */
     public long getShareQuantum()                 { return shareQuantum; }
 
@@ -62,7 +62,7 @@
      */
     public List<RmQueriedClass>    getClasses()   { return classes; }
 
-    /** RM only, other use produces incorrect results. */
+    /* RM only, other use produces incorrect results. */
     public void    notReady()                     { this.ready = false; }
 
     /**
diff --git a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccRmAdmin.java b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccRmAdmin.java
index dde1021..d264026 100644
--- a/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccRmAdmin.java
+++ b/uima-ducc-common/src/main/java/org/apache/uima/ducc/common/main/DuccRmAdmin.java
@@ -186,12 +186,11 @@
     /**
      * Marshall and transmit the request to RM, waiting for the response.
      * 
-     * @param A DuccAdminEvent appropriate to the desired function.
+     * @param duccEvent A DuccAdminEvent appropriate to the desired function.
      *
      * @return An {@link RmAdminReply RmAdminReply} appropriate to the response.  See the specific replies
      *         for details.
-
-	 * @throws Exception if anything goes wrong in transmission or receipt of the request.
+  	 * @throws Exception if anything goes wrong in transmission or receipt of the request.
      */
     public RmAdminReply dispatchAndWaitForReply(DuccAdminEvent duccEvent) 
         throws Exception 
@@ -295,27 +294,27 @@
 
 	/**
 	 * This queries details on each host the RM is scheduling to.
-     *
-     * @return A {@link RmAdminQOccupancyReply RmAdminQOccupancyReply} containing data regarding the current
-     *         hosts.
+   *
+   * @return A {@link RmAdminQOccupancyReply RmAdminQOccupancyReply} containing data regarding the current
+   *         hosts.
 	 * 
 	 * @throws Exception if anything goes wrong in transmission or receipt of the request.
 	 */
 	public RmAdminQOccupancyReply qoccupancy()
 		throws Exception 
     {
-        RmAdminQOccupancy qo = new RmAdminQOccupancy(user, cypheredMessage);
+	  RmAdminQOccupancy qo = new RmAdminQOccupancy(user, cypheredMessage);
 		return (RmAdminQOccupancyReply) dispatchAndWaitForReply(qo);
 	}
     
     // UIMA-4142
 	/**
 	 * Send a reconfigure event to RM.  RM rereads all its configuration data an possibly reconfigures
-     * the schedule if needed.  
-     *
-     * @return {@link RmAdminReply RmAdminReply}.  The message must be <code>Reconfiguration complete.</code>;
-     *         any other response indicates failure.  Failure occurs when the new configuration is invalid.  If this
-     *         occurs use <code>check_ducc -cv </code> to read and validate the current configuration.
+   * the schedule if needed.  
+   *
+   * @return {@link RmAdminReply RmAdminReply}.  The message must be <code>Reconfiguration complete.</code>;
+   *         any other response indicates failure.  Failure occurs when the new configuration is invalid.  If this
+   *         occurs use <code>check_ducc -cv </code> to read and validate the current configuration.
 	 * 
 	 * @throws Exception if anything goes wrong in transmission or receipt of the request.
 	 */
@@ -330,8 +329,9 @@
      * This is called from <code>main</code> in response to a CLI request.
      *
      * @param args the command line arguments. See the usage method below for details.
+     * @return 0 if succeeds, 1 if fails
      *
-	 * @throws Exception if anything goes wrong in transmission or receipt of the request.
+	   * @throws Exception if anything goes wrong in transmission or receipt of the request.
      */    
     public int run(String[] args)
     	throws Exception
@@ -396,7 +396,7 @@
         System.exit(1);
     }
 
-    /**
+    /*
      * This is provided for use by the CLI, to invoke the various RM administrative commands.
      */
 	public static void main(String[] args) 
diff --git a/uima-ducc-examples/src/main/resources/sleepjobs/1-error.job b/uima-ducc-examples/src/main/resources/sleepjobs/1-error.job
new file mode 100644
index 0000000..da77c2a
--- /dev/null
+++ b/uima-ducc-examples/src/main/resources/sleepjobs/1-error.job
@@ -0,0 +1,34 @@
+# 
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+# 
+#   http://www.apache.org/licenses/LICENSE-2.0
+# 
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+# 
+description                    Test job 1
+
+driver_descriptor_CR           org.apache.uima.ducc.test.randomsleep.FixedSleepCR
+driver_descriptor_CR_overrides jobfile=${DUCC_HOME}/examples/simple/1.inputs compression=10 error_rate=50
+driver_jvm_args                -Xmx500M
+
+process_descriptor_AE          org.apache.uima.ducc.test.randomsleep.FixedSleepAE
+process_memory_size            2
+classpath                      ${DUCC_HOME}/lib/uima-ducc/examples/*:${DUCC_HOME}/apache-uima/lib/*
+process_jvm_args               -Xmx100M 
+process_thread_count           1
+process_per_item_time_max      5
+environment                    AE_INIT_TIME=5 AE_INIT_RANGE=5 AE_INIT_ERROR=0 AE_RUNTIME_ERROR=50 LD_LIBRARY_PATH=/yet/a/nother/dumb/path
+process_deployments_max        999
+
+scheduling_class               normal
diff --git a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/HttpWorkerThread.java b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/HttpWorkerThread.java
index 3e9b111..49a54c9 100644
--- a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/HttpWorkerThread.java
+++ b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/configuration/jp/HttpWorkerThread.java
@@ -32,12 +32,10 @@
 import java.util.concurrent.atomic.AtomicInteger;
 
 import org.apache.http.client.methods.HttpPost;
-import org.apache.http.conn.HttpHostConnectException;
 import org.apache.uima.ducc.common.utils.DuccLogger;
 import org.apache.uima.ducc.container.net.iface.IMetaCas;
 import org.apache.uima.ducc.container.net.iface.IMetaCasTransaction;
 import org.apache.uima.ducc.container.net.iface.IMetaCasTransaction.Type;
-import org.apache.uima.ducc.container.net.iface.IPerformanceMetrics;
 import org.apache.uima.ducc.container.net.impl.MetaCasTransaction;
 import org.apache.uima.ducc.container.net.impl.PerformanceMetrics;
 import org.apache.uima.ducc.container.net.impl.TransactionId;
@@ -230,17 +228,16 @@
 						// the JD says there are no more WIs. Sleep awhile
 						// do a GET in case JD changes its mind. The JP will
 						// eventually be stopped by the agent
-
+    			  // Retry at the start of this block as another thread may have just exited with work
+    				// so the TAS (or JD) may now have a lot of work.	
  						synchronized (HttpWorkerThread.class) {
 							while(duccComponent.isRunning() ) {
+							  transaction = getWork(postMethod, major, ++minor);
+							  if ( transaction.getMetaCas() != null && transaction.getMetaCas().getUserSpaceCas() != null ) {
+							    logger.info("run", null,"Thread:"+Thread.currentThread().getId()+" work flow has restarted");
+							    break;
+							  }
 								waitAwhile(duccComponent.getThreadSleepTime());
-								// just awoken, check if the JP is still in Running state
-								if ( duccComponent.isRunning()) {
-									transaction = getWork(postMethod, major, ++minor);
-									if ( transaction.getMetaCas() != null && transaction.getMetaCas().getUserSpaceCas() != null ) {
-										break;
-									}
-								}
 							}
 						}
 						
@@ -308,11 +305,31 @@
 								break;
 							}
 							IMetaCas mc = transaction.getMetaCas();
-							
-							// Fetch serialized exception as a blob
+							//byte[] serializedException = null;
 							Method getLastSerializedErrorMethod = processorInstance.getClass().getDeclaredMethod("getLastSerializedError");
 							byte[] serializedException =
 							    (byte[])getLastSerializedErrorMethod.invoke(processorInstance);
+			
+//							if ( ee.getCause() instanceof DuccUimaProcessException ) {
+//								// The process() exception had been serialized on the user side of the JP since
+//								// only there the Classloader has all the classes to serialize the exception.
+//								serializedException = ((DuccUimaProcessException)ee.getCause()).getSerializedException();
+//							} else {
+//								// strip InvocationTargetException
+//								serializedException = serializeException(ee.getCause());
+//							}
+							/*
+							ByteArrayOutputStream baos = new ByteArrayOutputStream();
+						    ObjectOutputStream oos = new ObjectOutputStream(baos);
+						    try {
+						       oos.writeObject(ee.getCause());
+						       serializedException = baos.toByteArray();
+					        } catch (Exception e) {
+					        	Exception e2 = new RuntimeException("Ducc Service Failed to Serialize the Cause of Process Failure. Check Service Log for Details");
+					        	oos.writeObject(e2);
+					        	serializedException = baos.toByteArray();
+					        }
+					        */
 							mc.setUserSpaceException(serializedException);								
 
 							logger.info("run", null, "Work item processing failed - returning serialized exception to the JD");
@@ -325,12 +342,16 @@
 								break;
 							}
 							// Serialize exception for the JD.
+							byte[] serializedException = serializeException(ee);
+							/*
 							ByteArrayOutputStream baos = new ByteArrayOutputStream();
 						    ObjectOutputStream oos = new ObjectOutputStream( baos );
 						    oos.writeObject( ee);
 						    oos.close();
 							transaction.getMetaCas().setUserSpaceException(baos.toByteArray());
+						    */
 							logger.error("run", null, ee);
+							transaction.getMetaCas().setUserSpaceException(serializedException);								
 						}
 						// Dont return serialized CAS to reduce the msg size
 						transaction.getMetaCas().setUserSpaceCas(null);
@@ -455,5 +476,30 @@
 		}
 
 	}
+	private byte[] serializeException(Throwable t) {
+		byte[] serializedException;
+		ByteArrayOutputStream baos = new ByteArrayOutputStream();
+	    ObjectOutputStream oos = null;
+	    try {
+	       oos = new ObjectOutputStream(baos);
+	       oos.writeObject(t);
+	       serializedException = baos.toByteArray();
+        } catch (Exception ee) {
+        	Exception e2 = new RuntimeException("Ducc Service Failed to Serialize the Cause of Process Failure. Check Service Log for Details");
+        	try {
+        		oos.writeObject(e2);
+    		} catch( Exception ex ) {}
+        	
+        	serializedException = baos.toByteArray();
+        } finally {
+        	if ( oos != null ) {
+        		try {
+        			oos.close();
+        		} catch( Exception ex ) {}
+        	
+        	}
+        }
+	    return serializedException;
+	}
 
 }
diff --git a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java
index 9f7f043..712f6d9 100644
--- a/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java
+++ b/uima-ducc-transport/src/main/java/org/apache/uima/ducc/transport/event/sm/IServiceDescription.java
@@ -37,19 +37,19 @@
 {
 
     /**
-     * This returns the Unique ID of the service as assigned by DUCC.
+     * @return the Unique ID of the service as assigned by DUCC.
      */
 	public Long getId();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setId(Long id);
 
     /**
-     * Get the owner of the service
+     * @return the owner of the service
      */
     public String getUser();
-    /**
+    /*
      * Set the owner of the service
      */
     public void   setUser(String u);
@@ -70,67 +70,67 @@
      */
 	public Integer[] getInstanceIds();
 
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setImplementors(ArrayList<Long> implementors, ArrayList<Integer> instancids);
 
 	public Long[] getReferences();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setReferences(ArrayList<Long> references);
 
 	public ServiceType getType();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setType(ServiceType type);
 
 	public ServiceClass getSubclass();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setSubclass(ServiceClass subclass);
 
 	public String getEndpoint();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setEndpoint(String endpoint);
 
 	public String getBroker();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setBroker(String broker);
 
 	public ServiceState getServiceState();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setServiceState(ServiceState serviceState);
 
 	public JobState getJobState();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setJobState(JobState jobState);
 
 	public boolean isActive();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setActive(boolean active);
 
 	public void setDeregistered(boolean d);	
-    /**
+    /*
      * Internal to DUCC.
      */
     public void setQueueStatistics(IServiceStatistics qstats);    
 
     public IServiceStatistics getQueueStatistics();
-    /**
+    /*
      * Internal to DUCC.
      */
     public void setAutostart(boolean autostart);
@@ -163,13 +163,13 @@
     public String getErrorString();
     public void   setErrorString(String s);
 
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setEnabled(boolean enable);
 
 	public IServiceStatistics getQstats();
-    /**
+    /*
      * Internal to DUCC.
      */
 	public void setQstats(IServiceStatistics qstats);
@@ -177,18 +177,18 @@
 	public boolean isDeregistered();
 
 	public void setInstances(int instances);
-    /**
+    /*
      * Internal to DUCC.
      */
     public int getInstances();
 
     public void setLinger(long linger);    
-    /**
+    /*
      * Internal to DUCC.
      */
     public long getLinger();    
 
-    /**
+    /*
      * Internal to DUCC.
      */
     public void addDependency(String endpoint, String msg);
diff --git a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java
index 410577a..e774674 100644
--- a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java
+++ b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/DuccAbstractProcessContainer.java
@@ -21,6 +21,8 @@
 import java.io.ByteArrayOutputStream;
 import java.io.DataOutputStream;
 import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.net.InetAddress;
 import java.net.Socket;
 import java.util.HashMap;
@@ -41,6 +43,8 @@
 import org.apache.uima.resource.metadata.TypePriorities;
 import org.apache.uima.resource.metadata.TypeSystemDescription;
 import org.apache.uima.util.CasCreationUtils;
+import org.apache.uima.util.Level;
+import org.apache.uima.util.Logger;
 
 public abstract class DuccAbstractProcessContainer implements IProcessContainer{
 	// Container implementation must implement the following methods
@@ -49,8 +53,9 @@
     protected abstract void doStop() throws Exception;
     protected abstract List<Properties>  doProcess(Object subject) throws Exception;
     protected 	AnalysisEngineMetaData analysisEngineMetadata;
-
-	protected Throwable lastError = null;
+    // Stores errors caught in doProcess() with key= current thread id. Each thread
+    // clears previous error in process() below before calling doProcess()
+    protected Map<Long, Throwable> errorMap = new HashMap<Long, Throwable>();
     protected int scaleout=1;
     // Map to store DuccUimaSerializer instances. Each has affinity to a thread
 	protected static Map<Long, DuccUimaSerializer> serializerMap =
@@ -133,7 +138,10 @@
  		// a context cl before calling user code. 
  		ClassLoader savedCL = Thread.currentThread().getContextClassLoader();
  		Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
-         try {
+        // Clear previous error this thread may have added in doProcess()
+ 		errorMap.remove(Thread.currentThread().getId());
+        
+ 		try {
      		return doProcess(xmi);
          }finally {
  			Thread.currentThread().setContextClassLoader(savedCL);
@@ -155,7 +163,25 @@
          }
      }
 
-    
+    protected String serializeAsString(Throwable t) throws Exception {
+        StringWriter sw = new StringWriter();
+        String serializedCause = "";
+        try {
+ 
+            t.printStackTrace(new PrintWriter(sw));
+            serializedCause =  sw.toString();
+        } catch (Throwable e) {
+			try {
+				Logger logger = UIMAFramework.getLogger(DuccAbstractProcessContainer.class);
+				logger.log(Level.WARNING, "Unable to Stringfiy "+t.getClass().getName());
+				
+			} catch( Exception ee) {}
+			// Unable to serialize user Exception (not Serializable?)
+			// Just send a simple msg telling user to check service log
+			serializedCause = "Unable to Stringifiy Exception "+t.getClass().getName()+" - Please Check JP Log File For More Details";
+		}
+        return serializedCause;
+    }
     protected byte[] serialize(Throwable t) throws Exception {
 		ByteArrayOutputStream baos = new ByteArrayOutputStream();
 		ObjectOutputStream oos = new ObjectOutputStream(baos);
@@ -163,16 +189,47 @@
 		try {
 			oos.writeObject(t);
 		} catch (Exception e) {
-			e.printStackTrace();
-			// Unable to serialize user Exception (not Serializable?)
-			// Create a new Exception and serialize it
-			RuntimeException re 
- 			   = new RuntimeException("Unable to Serialize User Exception - Please Check JP Log File For More Details");
-			oos.writeObject(re);
+			try {
+				Logger logger = UIMAFramework.getLogger(DuccAbstractProcessContainer.class);
+				logger.log(Level.WARNING, "Unable to Serialize "+t.getClass().getName()+" - Will Stringify It Instead");
+				
+			} catch( Exception ee) {}
+			throw e;
+		} finally {
+			oos.close();
 		}
-		oos.close();
+		
 		return baos.toByteArray();
 	}
+	protected byte[] getLastSerializedError() throws Exception {
+		byte[] result = null;
+		if (errorMap.containsKey(Thread.currentThread().getId())) {
+			Throwable lastError = 
+					errorMap.get(Thread.currentThread().getId());
+			if ( System.getProperty("SendExceptionAsString")!= null ) {
+				// the client of this JP/Service does not have user classpath
+				// to be able to deserialize this exception. Instead of serializing
+				// the exception as a java object, stringify it first and wrap it.
+				// The client process might want to log this error.
+				result = serialize(new RuntimeException(serializeAsString(lastError)));
+			} else {
+				try {
+					// try to serialize Throwable as a java Object
+					result = serialize(lastError);
+				} catch( Exception e) {
+					// Fallback is to stringify the exception and wrap it
+					result = serialize(new RuntimeException(serializeAsString(lastError)));
+				}
+			}
+		} else {  // Throwable not found for this thread id in errorMap
+			// this is not normal that we are here. This method was 
+			// called since the process() failed. An exception should have
+			// been added to the errorMap with a key=thread id
+			result = serialize(new RuntimeException("AE.process( )failed - check service log"));
+		}
+		return result;
+	}
+
     private Socket connectWithAgent() throws Exception {
     	InetAddress host = null;
         int statusUpdatePort = -1;
diff --git a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaASProcessContainer.java b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaASProcessContainer.java
index cae1892..a1be0e2 100644
--- a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaASProcessContainer.java
+++ b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaASProcessContainer.java
@@ -41,7 +41,6 @@
 import org.apache.uima.aae.client.UimaAsynchronousEngine;
 import org.apache.uima.aae.monitor.statistics.AnalysisEnginePerformanceMetrics;
 import org.apache.uima.adapter.jms.client.BaseUIMAAsynchronousEngine_impl;
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.collection.EntityProcessStatus;
 import org.apache.uima.ducc.IUser;
@@ -115,14 +114,7 @@
 			return scaleout;
 		}
 	}
-	public byte[] getLastSerializedError() throws Exception {
 
-		if (lastError != null) {
-			return serialize(lastError);
-		}
-		return null;
-
-	}
 	/**
 	 * This method is called by each worker thread before entering
 	 * process loop in run(). Each work thread shares instance of
@@ -306,8 +298,7 @@
 	public List<Properties> doProcess(Object xmi) throws Exception {
 		CAS cas = uimaASClient.getCAS();   // fetch a new CAS from the client's Cas Pool
 		try {
-			// reset last error
-			lastError = null;
+
 			// Use thread dedicated UimaSerializer to de-serialize the CAS
 			getUimaSerializer().deserializeCasFromXmi((String)xmi, cas);
 
@@ -322,7 +313,19 @@
 			if ( enablePerformanceBreakdownReporting ) {
 				List<AnalysisEnginePerformanceMetrics> perfMetrics =
 						new ArrayList<AnalysisEnginePerformanceMetrics>();
-				uimaASClient.sendAndReceiveCAS(cas, perfMetrics);
+				
+				try {
+					uimaASClient.sendAndReceiveCAS(cas, perfMetrics);
+				} catch( Throwable t) {
+					// save the error
+					errorMap.put(Thread.currentThread().getId(), t);
+					// AE failed, throw an exception. The HttpWorketThread will 
+					// subsequently call getLastSerializedException() on this class
+					// to fetch serialized exception saved in 'lastError' above.
+					// The 'lastError' is reset each time super.process() is called.
+					throw new RuntimeException(); 
+				}
+				
 				for( AnalysisEnginePerformanceMetrics metrics : perfMetrics ) {
 					Properties p = new Properties();
 					p.setProperty("name", metrics.getName());
@@ -341,7 +344,19 @@
 				}
 			} else {
 				// delegate processing to the UIMA-AS service and wait for a reply
-				uimaASClient.sendAndReceiveCAS(cas);//, perfMetrics);
+				try {
+					uimaASClient.sendAndReceiveCAS(cas);
+				} catch( Throwable t) {
+					// save the error
+					errorMap.put(Thread.currentThread().getId(), t);
+					// AE failed, throw an exception. The HttpWorketThread will 
+					// subsequently call getLastSerializedException() on this class
+					// to fetch serialized exception saved in errorMap above.
+					// The map entry for each thread is reset in super.process().
+
+					throw new RuntimeException();  
+				}
+				
 				// convert UIMA-AS metrics into properties so that we can return this
 				// data in a format which doesnt require UIMA-AS to digest
 				Properties p = new Properties();
@@ -353,18 +368,17 @@
 			}
 
 			return metricsList;
-		} catch( Throwable e ) {
-			lastError = e;
-			Logger logger = UIMAFramework.getLogger();
-			logger.log(Level.WARNING, "UimaProcessContainer", e);
-			e.printStackTrace();
-			throw new AnalysisEngineProcessException();
+		} catch( Throwable t ) {
+			throw t;
 		} finally {
 			if ( cas != null) {
 				cas.release();
 			}
 		}
 	}
+	public byte[] getLastSerializedError() throws Exception {
+       return super.getLastSerializedError();
+	}
 	private String getPID(final String fallback) {
 		// the following code returns '<pid>@<hostname>'
 		String name = ManagementFactory.getRuntimeMXBean().getName();
diff --git a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaProcessContainer.java b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaProcessContainer.java
index 4ad02c0..c152559 100644
--- a/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaProcessContainer.java
+++ b/uima-ducc-user/src/main/java/org/apache/uima/ducc/user/jp/UimaProcessContainer.java
@@ -33,7 +33,6 @@
 import org.apache.uima.UIMAFramework;
 import org.apache.uima.analysis_engine.AnalysisEngine;
 import org.apache.uima.analysis_engine.AnalysisEngineManagement;
-import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.ducc.user.common.UimaUtils;
 import org.apache.uima.ducc.user.jp.uima.UimaAnalysisEngineInstancePoolWithThreadAffinity;
@@ -105,14 +104,7 @@
 	    scaleout = threadCount==null ? 1 : Integer.valueOf(threadCount);   // Default to 1
 	    return scaleout;		  
 	}
-	public byte[] getLastSerializedError() throws Exception {
 
-		if (lastError != null) {
-			return serialize(lastError);
-		}
-		return null;
-
-	}
 
 	public int doInitialize(Properties props, String[] args) throws Exception {
 			return configureAndGetScaleout(args);
@@ -187,15 +179,28 @@
 		latch.await();
 		CAS cas = casPool.getCas();
 		try {
-			// reset last error
-			lastError = null;
 			// deserialize the CAS
 			getUimaSerializer().deserializeCasFromXmi((String)xmi, cas);
 
 			// the following checks out AE instance pinned to this thread
 			ae = instanceMap.checkout();
 			List<AnalysisEnginePerformanceMetrics> beforeAnalysis = getMetrics(ae);
-			ae.process(cas);
+			
+			// Handle AnalysisEngineProcessException
+			try {
+				ae.process(cas);
+			} catch( Throwable t) {
+				// save the error
+				errorMap.put(Thread.currentThread().getId(), t);
+				// AE failed, throw an exception. The HttpWorketThread will 
+				// subsequently call getLastSerializedException() on this class
+				// to fetch serialized exception saved in errorMap above.
+				// The map entry for each thread is reset in super.process().
+				throw new RuntimeException(); 
+			}
+			// *****************************************************
+			// No exception in process() , return metrics as a List
+			// *****************************************************
 			List<AnalysisEnginePerformanceMetrics> afterAnalysis = getMetrics(ae);
 
 			// get the delta
@@ -218,15 +223,10 @@
 						String.valueOf(metrics.getNumProcessed()));
 				metricsList.add(p);
 			}
-			
 			return metricsList;
-		} catch( Throwable e ) {
-			lastError = e;
-			Logger logger = UIMAFramework.getLogger();
-			logger.log(Level.WARNING, "UimaProcessContainer", e);
-			e.printStackTrace();
-			throw new AnalysisEngineProcessException();
-		}
+		} catch( Throwable tt ) {
+			throw tt;
+ 		}
 		finally {
 			if (ae != null) {
 				instanceMap.checkin(ae);
@@ -236,6 +236,9 @@
 			}
 		}
 	}
+	public byte[] getLastSerializedError() throws Exception {
+	       return super.getLastSerializedError();
+	}
 	   private List<AnalysisEnginePerformanceMetrics> getMetrics(AnalysisEngine ae)
 			throws Exception {
 		List<AnalysisEnginePerformanceMetrics> analysisManagementObjects = new ArrayList<AnalysisEnginePerformanceMetrics>();