[jbpm-commits] JBoss JBPM SVN: r5137 - in jbpm3/branches/jbpm-3.2-soa/modules/core/src: main/java/org/jbpm/graph/node and 5 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Sat Jun 27 08:56:00 EDT 2009


Author: alex.guizar at jboss.com
Date: 2009-06-27 08:56:00 -0400 (Sat, 27 Jun 2009)
New Revision: 5137

Modified:
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java
   jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java
Log:
JBPM-2115: jBPM testsuite hangs when executed with DB2 (CODING IN PROGRESS)
Prevent JobExecutorThread from waiting 5 sec after LockAcquisitionException
Start job executor after starting processes in SimplePerformanceTest to avoid concurrency and allow measurements with HSQL

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/context/exe/ContextInstance.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -31,391 +31,341 @@
 import org.jbpm.module.exe.ModuleInstance;
 
 /**
- * maintains all the key-variable pairs for a process instance. You can obtain a
- * ContextInstance from a processInstance from a process instance like this :
+ * maintains all the key-variable pairs for a process instance. You can obtain a ContextInstance
+ * from a processInstance from a process instance like this :
+ * 
  * <pre>
  * ProcessInstance processInstance = ...;
  * ContextInstance contextInstance = processInstance.getContextInstance();
  * </pre>
- * More information on context and process variableInstances can be found in 
- * <a href="../../../../../userguide/en/html/reference.html#context">the userguide, section context</a>
+ * 
+ * More information on context and process variableInstances can be found in <a
+ * href="../../../../../userguide/en/html/reference.html#context">the userguide, section context</a>
  */
-public class ContextInstance extends ModuleInstance
-{
+public class ContextInstance extends ModuleInstance {
 
   private static final long serialVersionUID = 1L;
 
-  // maps Token's to TokenVariableMap's
+  // maps Tokens to TokenVariableMaps
   protected Map tokenVariableMaps = null;
-  // maps variablenames (String) to values (Object)
+  // maps variable names (String) to values (Object)
   protected transient Map transientVariables = null;
   protected transient List updatedVariableContainers = null;
 
-  public ContextInstance()
-  {
+  public ContextInstance() {
   }
 
   // normal variableInstances (persistent) ////////////////////////////////////
 
-  /*
-   * creates a variable on the root-token (= process-instance scope) and calculates the actual VariableInstance-type from the value.
+  /**
+   * creates a variable on the root-token (= process-instance scope) and calculates the actual
+   * VariableInstance-type from the value.
    */
-  public void createVariable(String name, Object value)
-  {
+  public void createVariable(String name, Object value) {
     setVariableLocally(name, value, getRootToken());
   }
 
-  /*
-   * sets the variable on the root token, creates the variable if necessary and calculates the actual VariableInstance-type from the value.
+  /**
+   * sets the variable on the root token, creates the variable if necessary and calculates the
+   * actual VariableInstance-type from the value.
    */
-  public void setVariableLocally(String name, Object value)
-  {
+  public void setVariableLocally(String name, Object value) {
     setVariableLocally(name, value, getRootToken());
   }
 
-  /*
-   * creates a variable in the scope of the given token and calculates the actual VariableInstance-type from the value.
+  /**
+   * creates a variable in the scope of the given token and calculates the actual
+   * VariableInstance-type from the value.
    */
-  public void createVariable(String name, Object value, Token token)
-  {
+  public void createVariable(String name, Object value, Token token) {
     setVariableLocally(name, value, token);
   }
 
-  /*
-   * creates a variable in the scope of the given token and calculates the actual VariableInstance-type from the value.
+  /**
+   * creates a variable in the scope of the given token and calculates the actual
+   * VariableInstance-type from the value.
    */
-  public void setVariableLocally(String name, Object value, Token token)
-  {
+  public void setVariableLocally(String name, Object value, Token token) {
     TokenVariableMap tokenVariableMap = createTokenVariableMap(token);
     tokenVariableMap.setVariableLocally(name, value);
   }
 
-  /*
+  /**
    * gets all the variableInstances on the root-token (= process-instance scope).
    */
-  public Map getVariables()
-  {
+  public Map getVariables() {
     return getVariables(getRootToken());
   }
 
-  /*
+  /**
    * retrieves all the variableInstances in scope of the given token.
    */
-  public Map getVariables(Token token)
-  {
-    Map variables = null;
-
+  public Map getVariables(Token token) {
     TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
-    if (tokenVariableMap != null)
-    {
-      variables = tokenVariableMap.getVariables();
-    }
-
-    return variables;
+    return tokenVariableMap != null ? tokenVariableMap.getVariables() : null;
   }
 
-  /*
+  /**
    * adds all the variableInstances on the root-token (= process-instance scope).
    */
-  public void addVariables(Map variables)
-  {
+  public void addVariables(Map variables) {
     setVariables(variables, getRootToken());
   }
 
-  /*
-   * The method setVariables is the same as the {@link #addVariables(Map, Token)}, but it was added for more consistency.
+  /**
+   * The method setVariables is the same as the {@link #addVariables(Map, Token)}, but it was added
+   * for more consistency.
    */
-  public void setVariables(Map variables)
-  {
+  public void setVariables(Map variables) {
     setVariables(variables, getRootToken());
   }
 
-  /*
-   * adds all the variableInstances to the scope of the given token. This method delegates to {@link #setVariables(Map, Token)}. The method setVariables was added for
-   * more consistency.
+  /**
+   * adds all the variableInstances to the scope of the given token. This method delegates to
+   * {@link #setVariables(Map, Token)}. The method setVariables was added for more consistency.
    */
-  public void addVariables(Map variables, Token token)
-  {
+  public void addVariables(Map variables, Token token) {
     setVariables(variables, token);
   }
 
-  /*
-   * adds all the variableInstances to the scope of the given token. The method setVariables is the same as the {@link #addVariables(Map, Token)}, but it was added for
-   * more consistency.
+  /**
+   * adds all the variableInstances to the scope of the given token. The method setVariables is the
+   * same as the {@link #addVariables(Map, Token)}, but it was added for more consistency.
    */
-  public void setVariables(Map variables, Token token)
-  {
+  public void setVariables(Map variables, Token token) {
     // [JBPM-1778] Empty map variables on process creation is set as null
     TokenVariableMap tokenVariableMap = getOrCreateTokenVariableMap(token);
     Iterator iter = variables.entrySet().iterator();
-    while (iter.hasNext())
-    {
-      Map.Entry entry = (Map.Entry)iter.next();
-      String name = (String)entry.getKey();
+    while (iter.hasNext()) {
+      Map.Entry entry = (Map.Entry) iter.next();
+      String name = (String) entry.getKey();
       Object value = entry.getValue();
       tokenVariableMap.setVariable(name, value);
     }
   }
 
-  /*
+  /**
    * gets the variable with the given name on the root-token (= process-instance scope).
    */
-  public Object getVariable(String name)
-  {
+  public Object getVariable(String name) {
     return getVariable(name, getRootToken());
   }
 
-  /*
-   * retrieves a variable in the scope of the token. If the given token does not have a variable for the given name, the variable is searched for up the token
-   * hierarchy.
+  /**
+   * retrieves a variable in the scope of the token. If the given token does not have a variable for
+   * the given name, the variable is searched for up the token hierarchy.
    */
-  public Object getVariable(String name, Token token)
-  {
+  public Object getVariable(String name, Token token) {
     Object variable = null;
     TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
-    if (tokenVariableMap != null)
-    {
+    if (tokenVariableMap != null) {
       variable = tokenVariableMap.getVariable(name);
     }
     return variable;
   }
 
-  /*
-   * retrieves a variable which is local to the token. Method {@link #getVariableLocally(String, Token)} is the same as this method and it was added for naming
-   * consistency.
+  /**
+   * retrieves a variable which is local to the token. Method
+   * {@link #getVariableLocally(String, Token)} is the same as this method and it was added for
+   * naming consistency.
    */
-  public Object getLocalVariable(String name, Token token)
-  {
+  public Object getLocalVariable(String name, Token token) {
     return getVariableLocally(name, token);
   }
 
-  /*
-   * retrieves a variable which is local to the token. this method was added for naming consistency. it is the same as {@link #getLocalVariable(String, Token)}.
+  /**
+   * retrieves a variable which is local to the token. this method was added for naming consistency.
+   * it is the same as {@link #getLocalVariable(String, Token)}.
    */
-  public Object getVariableLocally(String name, Token token)
-  {
+  public Object getVariableLocally(String name, Token token) {
     Object variable = null;
-    if (tokenVariableMaps != null && tokenVariableMaps.containsKey(token))
-    {
-      TokenVariableMap tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
-      if (tokenVariableMap != null)
-      {
+    if (tokenVariableMaps != null && tokenVariableMaps.containsKey(token)) {
+      TokenVariableMap tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
+      if (tokenVariableMap != null) {
         variable = tokenVariableMap.getVariableLocally(name);
       }
     }
     return variable;
   }
 
-  /*
+  /**
    * sets a variable on the process instance scope.
    */
-  public void setVariable(String name, Object value)
-  {
+  public void setVariable(String name, Object value) {
     setVariable(name, value, getRootToken());
   }
 
-  /*
-   * sets a variable. If a variable exists in the scope given by the token, that variable is updated. Otherwise, the variable is created on the root token (=process
-   * instance scope).
+  /**
+   * sets a variable. If a variable exists in the scope given by the token, that variable is
+   * updated. Otherwise, the variable is created on the root token (=process instance scope).
    */
-  public void setVariable(String name, Object value, Token token)
-  {
+  public void setVariable(String name, Object value, Token token) {
     TokenVariableMap tokenVariableMap = getOrCreateTokenVariableMap(token);
     tokenVariableMap.setVariable(name, value);
   }
 
-  /*
-   * checks if a variable is present with the given name on the root-token (= process-instance scope).
+  /**
+   * checks if a variable is present with the given name on the root-token (= process-instance
+   * scope).
    */
-  public boolean hasVariable(String name)
-  {
+  public boolean hasVariable(String name) {
     return hasVariable(name, getRootToken());
   }
 
-  /*
+  /**
    * checks if a variable is present with the given name in the scope of the token.
    */
-  public boolean hasVariable(String name, Token token)
-  {
+  public boolean hasVariable(String name, Token token) {
     boolean hasVariable = false;
     TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
-    if (tokenVariableMap != null)
-    {
+    if (tokenVariableMap != null) {
       hasVariable = tokenVariableMap.hasVariable(name);
     }
     return hasVariable;
   }
 
-  /*
+  /**
    * deletes the given variable on the root-token (=process-instance scope).
    */
-  public void deleteVariable(String name)
-  {
+  public void deleteVariable(String name) {
     deleteVariable(name, getRootToken());
   }
 
-  /*
-   * deletes a variable from the given token. For safety reasons, this method does not propagate the deletion to parent tokens in case the given token does not contain
-   * the variable.
+  /**
+   * deletes a variable from the given token. For safety reasons, this method does not propagate the
+   * deletion to parent tokens in case the given token does not contain the variable.
    */
-  public void deleteVariable(String name, Token token)
-  {
+  public void deleteVariable(String name, Token token) {
     TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
-    if (tokenVariableMap != null)
-    {
+    if (tokenVariableMap != null) {
       tokenVariableMap.deleteVariable(name);
     }
   }
 
   // transient variableInstances //////////////////////////////////////////////
 
-  /*
+  /**
    * retrieves the transient variable for the given name.
    */
-  public Object getTransientVariable(String name)
-  {
+  public Object getTransientVariable(String name) {
     Object transientVariable = null;
-    if (transientVariables != null)
-    {
+    if (transientVariables != null) {
       transientVariable = transientVariables.get(name);
     }
     return transientVariable;
   }
 
-  /*
+  /**
    * sets the transient variable for the given name to the given value.
    */
-  public void setTransientVariable(String name, Object value)
-  {
-    if (transientVariables == null)
-    {
+  public void setTransientVariable(String name, Object value) {
+    if (transientVariables == null) {
       transientVariables = new HashMap();
     }
     transientVariables.put(name, value);
   }
 
-  /*
+  /**
    * tells if a transient variable with the given name is present.
    */
-  public boolean hasTransientVariable(String name)
-  {
-    if (transientVariables == null)
-    {
+  public boolean hasTransientVariable(String name) {
+    if (transientVariables == null) {
       return false;
     }
     return transientVariables.containsKey(name);
   }
 
-  /*
-   * retrieves all the transient variableInstances map. note that no deep copy is performed, changing the map leads to changes in the transient variableInstances of
-   * this context instance.
+  /**
+   * retrieves all the transient variableInstances map. note that no deep copy is performed,
+   * changing the map leads to changes in the transient variableInstances of this context instance.
    */
-  public Map getTransientVariables()
-  {
+  public Map getTransientVariables() {
     return transientVariables;
   }
 
-  /*
+  /**
    * replaces the transient variableInstances with the given map.
    */
-  public void setTransientVariables(Map transientVariables)
-  {
+  public void setTransientVariables(Map transientVariables) {
     this.transientVariables = transientVariables;
   }
 
-  /*
+  /**
    * removes the transient variable.
    */
-  public void deleteTransientVariable(String name)
-  {
-    if (transientVariables == null)
-      return;
+  public void deleteTransientVariable(String name) {
+    if (transientVariables == null) return;
     transientVariables.remove(name);
   }
 
-  Token getRootToken()
-  {
+  Token getRootToken() {
     return processInstance.getRootToken();
   }
 
-  /*
-   * searches for the first token-variable-map for the given token and creates it on the root token if it doesn't exist.
+  /**
+   * searches for the first token-variable-map for the given token and creates it on the root token
+   * if it doesn't exist.
    */
-  public TokenVariableMap getOrCreateTokenVariableMap(Token token)
-  {
-    if (token == null)
-    {
+  public TokenVariableMap getOrCreateTokenVariableMap(Token token) {
+    if (token == null) {
       throw new JbpmException("can't get variables for token 'null'");
     }
 
     // if the given token has a variable map
     TokenVariableMap tokenVariableMap = null;
-    if ((tokenVariableMaps != null) && (tokenVariableMaps.containsKey(token)))
-    {
-      tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
+    if ((tokenVariableMaps != null) && (tokenVariableMaps.containsKey(token))) {
+      tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
 
     }
-    else if (!token.isRoot())
-    {
+    else if (!token.isRoot()) {
       tokenVariableMap = getOrCreateTokenVariableMap(token.getParent());
 
     }
-    else
-    {
+    else {
       tokenVariableMap = createTokenVariableMap(token);
     }
 
     return tokenVariableMap;
   }
 
-  TokenVariableMap createTokenVariableMap(Token token)
-  {
-    if (tokenVariableMaps == null)
-    {
+  TokenVariableMap createTokenVariableMap(Token token) {
+    if (tokenVariableMaps == null) {
       tokenVariableMaps = new HashMap();
     }
-    TokenVariableMap tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
-    if (tokenVariableMap == null)
-    {
+    TokenVariableMap tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
+    if (tokenVariableMap == null) {
       tokenVariableMap = new TokenVariableMap(token, this);
       tokenVariableMaps.put(token, tokenVariableMap);
     }
     return tokenVariableMap;
   }
 
-  /*
-   * looks for the first token-variable-map that is found up the token-parent hirarchy.
+  /**
+   * looks for the first token-variable-map that is found up the token-parent hierarchy.
    */
-  public TokenVariableMap getTokenVariableMap(Token token)
-  {
+  public TokenVariableMap getTokenVariableMap(Token token) {
     TokenVariableMap tokenVariableMap = null;
-    if (tokenVariableMaps != null)
-    {
-      if (tokenVariableMaps.containsKey(token))
-      {
-        tokenVariableMap = (TokenVariableMap)tokenVariableMaps.get(token);
+    if (tokenVariableMaps != null) {
+      if (tokenVariableMaps.containsKey(token)) {
+        tokenVariableMap = (TokenVariableMap) tokenVariableMaps.get(token);
       }
-      else if (!token.isRoot())
-      {
+      else if (!token.isRoot()) {
         tokenVariableMap = getTokenVariableMap(token.getParent());
       }
     }
     return tokenVariableMap;
   }
 
-  public VariableInstance getVariableInstance(String name, Token token)
-  {
+  public VariableInstance getVariableInstance(String name, Token token) {
     VariableInstance variableInstance = null;
     TokenVariableMap tokenVariableMap = getTokenVariableMap(token);
-    if (tokenVariableMap != null)
-    {
+    if (tokenVariableMap != null) {
       tokenVariableMap.getVariableInstances();
     }
     return variableInstance;
   }
 
-  public Map getTokenVariableMaps()
-  {
+  public Map getTokenVariableMaps() {
     return tokenVariableMaps;
   }
 }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/graph/node/Join.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -95,28 +95,24 @@
 
   public void execute(ExecutionContext executionContext) {
     Token token = executionContext.getToken();
-
     boolean isAbleToReactivateParent = token.isAbleToReactivateParent();
 
     if (!token.hasEnded()) {
       token.end(false);
     }
 
-    // if this token is not able to reactivate the parent, 
+    // if this token is not able to reactivate the parent,
     // we don't need to check anything
     if (isAbleToReactivateParent) {
-
-      // the token arrived in the join and can only reactivate 
+      // the token arrived in the join and can only reactivate
       // the parent once
       token.setAbleToReactivateParent(false);
 
       Token parentToken = token.getParent();
-
       if (parentToken != null) {
-
         JbpmContext jbpmContext = executionContext.getJbpmContext();
-        Session session = (jbpmContext != null ? jbpmContext.getSession() : null);
-        if (session != null) {
+        Session session;
+        if (jbpmContext != null && (session = jbpmContext.getSession()) != null) {
           // obtain update lock by default (LockMode.UPGRADE)
           LockMode lockMode = parentLockMode != null ? LockMode.parse(parentLockMode)
               : LockMode.UPGRADE;
@@ -125,7 +121,7 @@
           session.lock(parentToken, lockMode);
         }
 
-        boolean reactivateParent = true;
+        boolean reactivateParent;
 
         // if this is a discriminator
         if (isDiscriminator) {
@@ -133,57 +129,50 @@
           // this must be the first token arriving, otherwise isAbleToReactivateParent()
           // should have been false above.
           reactivateParent = true;
-
-          // if a fixed set of tokenNames is specified at design time...
         }
+        // if a fixed set of tokenNames is specified at design time...
         else if (tokenNames != null) {
           // check reactivation on the basis of those tokenNames
           reactivateParent = mustParentBeReactivated(parentToken, tokenNames.iterator());
-
-          // if a script is specified
         }
+        // if a script is specified
         else if (script != null) {
-
           // check if the script returns a collection or a boolean
           Object result = null;
           try {
             result = script.eval(token);
           }
           catch (Exception e) {
-            this.raiseException(e, executionContext);
+            raiseException(e, executionContext);
           }
-          // if the result is a collection 
+          // if the result is a collection
           if (result instanceof Collection) {
-            // it must be a collection of tokenNames 
+            // it must be a collection of tokenNames
             Collection runtimeTokenNames = (Collection) result;
             reactivateParent = mustParentBeReactivated(parentToken, runtimeTokenNames.iterator());
-
-            // if it's a boolean... 
           }
+          // if it's a boolean...
           else if (result instanceof Boolean) {
             // the boolean specifies if the parent needs to be reactivated
             reactivateParent = ((Boolean) result).booleanValue();
           }
-
-          // if a nOutOfM is specified
+          // otherwise
+          else {
+            // non-null result means the parent needs to be reactivated
+            reactivateParent = result != null;
+          }
         }
+        // if a nOutOfM is specified
         else if (nOutOfM != -1) {
-
           int n = 0;
-          // wheck how many tokens already arrived in the join
-          Iterator iter = parentToken.getChildren().values().iterator();
-          while (iter.hasNext()) {
+          // check how many tokens already arrived in the join
+          for (Iterator iter = parentToken.getChildren().values().iterator(); iter.hasNext();) {
             Token concurrentToken = (Token) iter.next();
-            if (this.equals(concurrentToken.getNode())) {
-              n++;
-            }
+            if (equals(concurrentToken.getNode())) n++;
           }
-          if (n < nOutOfM) {
-            reactivateParent = false;
-          }
-
-          // if no configuration is specified..
+          reactivateParent = n >= nOutOfM;
         }
+        // if no configuration is specified..
         else {
           // the default behaviour is to check all concurrent tokens and reactivate
           // the parent if the last token arrives in the join
@@ -194,13 +183,11 @@
 
         // if the parent token needs to be reactivated from this join node
         if (reactivateParent) {
-
           // write to all child tokens that the parent is already reactivated
-          Iterator iter = parentToken.getChildren().values().iterator();
-          while (iter.hasNext()) {
-            ((Token) iter.next()).setAbleToReactivateParent(false);
+          for (Iterator iter = parentToken.getChildren().values().iterator(); iter.hasNext();) {
+            Token concurrentToken = (Token) iter.next();
+            concurrentToken.setAbleToReactivateParent(false);
           }
-
           // write to all child tokens that the parent is already reactivated
           ExecutionContext parentContext = new ExecutionContext(parentToken);
           leave(parentContext);
@@ -209,21 +196,16 @@
     }
   }
 
-  public boolean mustParentBeReactivated(Token parentToken, Iterator childTokenNameIterator) {
-    boolean reactivateParent = true;
-    while ((childTokenNameIterator.hasNext()) && (reactivateParent)) {
-      String concurrentTokenName = (String) childTokenNameIterator.next();
-
+  public boolean mustParentBeReactivated(Token parentToken, Iterator concurrentTokenNames) {
+    while (concurrentTokenNames.hasNext()) {
+      String concurrentTokenName = (String) concurrentTokenNames.next();
       Token concurrentToken = parentToken.getChild(concurrentTokenName);
-
       if (concurrentToken.isAbleToReactivateParent()) {
-        log.debug("join will not yet reactivate parent: found concurrent token '"
-            + concurrentToken
-            + "'");
-        reactivateParent = false;
+        log.debug("join will not reactivate parent yet, found concurrent " + concurrentToken);
+        return false;
       }
     }
-    return reactivateParent;
+    return true;
   }
 
   public String getParentLockMode() {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/JobExecutorThread.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -16,7 +16,6 @@
 import org.jbpm.db.JobSession;
 import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.job.Job;
-import org.jbpm.persistence.JbpmPersistenceException;
 import org.jbpm.persistence.db.DbPersistenceService;
 import org.jbpm.persistence.db.StaleObjectLogConfigurer;
 
@@ -151,16 +150,12 @@
           acquiredJobs = jobsToLock;
           log.debug("acquired lock on jobs: " + acquiredJobs);
         }
-        catch (JbpmPersistenceException e) {
-          // if this is a stale state exception, keep it quiet
-          if (DbPersistenceService.isStaleStateException(e)) {
-            StaleObjectLogConfigurer.getStaleObjectExceptionsLog()
-                .error("failed to acquire lock on jobs " + jobsToLock);
-            acquiredJobs = Collections.EMPTY_LIST;
-          }
-          else {
-            throw e;
-          }
+        catch (RuntimeException e) {
+          if (!DbPersistenceService.isLockingException(e)) throw e;
+          // if this is a locking exception, keep it quiet
+          StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+              "failed to acquire lock on jobs " + jobsToLock);
+          acquiredJobs = Collections.EMPTY_LIST;
         }
       }
     }
@@ -207,15 +202,11 @@
       try {
         jbpmContext.close();
       }
-      catch (JbpmPersistenceException e) {
-        // if this is a stale state exception, keep it quiet
-        if (DbPersistenceService.isStaleStateException(e)) {
-          StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error("failed to complete job " +
-              job);
-        }
-        else {
-          throw e;
-        }
+      catch (RuntimeException e) {
+        if (!DbPersistenceService.isLockingException(e)) throw e;
+        // if this is a locking exception, keep it quiet
+        StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+            "failed to complete job " + job);
       }
     }
   }
@@ -241,16 +232,12 @@
       try {
         jbpmContext.close();
       }
-      catch (JbpmPersistenceException e) {
-        // if this is a stale state exception, keep it quiet
-        if (DbPersistenceService.isStaleStateException(e)) {
-          StaleObjectLogConfigurer.getStaleObjectExceptionsLog()
-              .error("failed to determine next due date for job executor thread " + threadName);
-          nextDueDate = null;
-        }
-        else {
-          throw e;
-        }
+      catch (RuntimeException e) {
+        if (!DbPersistenceService.isLockingException(e)) throw e;
+        // if this is a locking exception, keep it quiet
+        StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+            "failed to determine next due date for job executor thread " + threadName);
+        nextDueDate = null;
       }
     }
     return nextDueDate;

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/job/executor/LockMonitorThread.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -11,7 +11,6 @@
 import org.jbpm.JbpmContext;
 import org.jbpm.db.JobSession;
 import org.jbpm.job.Job;
-import org.jbpm.persistence.JbpmPersistenceException;
 import org.jbpm.persistence.db.DbPersistenceService;
 import org.jbpm.persistence.db.StaleObjectLogConfigurer;
 
@@ -47,16 +46,16 @@
         currentLockMonitorInterval = lockMonitorInterval;
       }
       catch (RuntimeException e) {
-        log.error("exception in lock monitor thread. waiting "
-            + currentLockMonitorInterval
-            + " milliseconds", e);
+        log.error("exception in lock monitor thread. waiting " +
+            currentLockMonitorInterval +
+            " milliseconds", e);
         try {
           sleep(currentLockMonitorInterval);
         }
         catch (InterruptedException ie) {
           log.debug("delay after exception got interrupted", ie);
         }
-        // after an exception, double the current lock monitor interval to prevent 
+        // after an exception, double the current lock monitor interval to prevent
         // continuous exception generation when e.g. the db is unreachable
         currentLockMonitorInterval <<= 1;
         if (currentLockMonitorInterval > maxLockMonitorInterval || currentLockMonitorInterval < 0) {
@@ -92,15 +91,11 @@
       try {
         jbpmContext.close();
       }
-      catch (JbpmPersistenceException e) {
-        // if this is a stale state exception, keep it quiet
-        if (DbPersistenceService.isStaleStateException(e)) {
-          StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
-              "optimistic locking failed, could not unlock overdue jobs: " + overdueJobs);
-        }
-        else {
-          throw e;
-        }
+      catch (RuntimeException e) {
+        if (!DbPersistenceService.isLockingException(e)) throw e;
+        // if this is a locking exception, keep it quiet
+        StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+            "could not unlock overdue jobs: " + overdueJobs);
       }
     }
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/db/DbPersistenceService.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -22,6 +22,7 @@
 package org.jbpm.persistence.db;
 
 import java.sql.Connection;
+import java.sql.SQLException;
 
 import javax.sql.DataSource;
 
@@ -32,6 +33,8 @@
 import org.hibernate.SessionFactory;
 import org.hibernate.StaleStateException;
 import org.hibernate.Transaction;
+import org.hibernate.exception.LockAcquisitionException;
+
 import org.jbpm.JbpmContext;
 import org.jbpm.JbpmException;
 import org.jbpm.db.ContextSession;
@@ -78,8 +81,8 @@
   }
 
   public SessionFactory getSessionFactory() {
-    return session != null ? session.getSessionFactory() : persistenceServiceFactory
-        .getSessionFactory();
+    return session != null ? session.getSessionFactory()
+        : persistenceServiceFactory.getSessionFactory();
   }
 
   public Session getSession() {
@@ -155,14 +158,14 @@
     if (connection == null) {
       if (persistenceServiceFactory.getDataSource() != null) {
         try {
-          log.debug("fetching jdbc connection from datasource");
+          log.debug("establishing connneciton to data source");
           connection = persistenceServiceFactory.getDataSource().getConnection();
           mustConnectionBeClosed = true;
         }
-        catch (Exception e) {
+        catch (SQLException e) {
           // NOTE that Errors are not caught because that might halt the JVM
           // and mask the original Error.
-          throw new JbpmException("could not obtain connection from datasource", e);
+          throw new JbpmPersistenceException("connection to data source failed", e);
         }
       }
       else {
@@ -172,9 +175,9 @@
         }
         if (session != null) {
           connection = session.connection();
-          log.debug("fetched "
-              + connection
-              + " from hibernate session, client is responsible for closing it!");
+          log.debug("fetched " +
+              connection +
+              " from hibernate session, client is responsible for closing it!");
           mustConnectionBeClosed = false;
         }
       }
@@ -226,15 +229,8 @@
       mustSessionBeFlushed = false; // commit does a flush anyway
       transaction.commit();
     }
-    catch (Exception e) {
-      if (isStaleStateException(e)) {
-        log.info("problem committing transaction: optimistic locking failed");
-        StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
-            "optimistic locking failed while committing " + transaction, e);
-      }
-      else {
-        log.error("transaction commit failed", e);
-      }
+    catch (HibernateException e) {
+      // avoid log and throw antipattern
       return e;
     }
     return null;
@@ -247,8 +243,8 @@
       mustSessionBeFlushed = false;
       transaction.rollback();
     }
-    catch (Exception e) {
-      log.error("transaction rollback failed", e);
+    catch (HibernateException e) {
+      // avoid log and throw antipattern
       return e;
     }
     return null;
@@ -260,15 +256,8 @@
         log.debug("flushing " + session);
         session.flush();
       }
-      catch (Exception e) {
-        if (isStaleStateException(e)) {
-          log.info("problem flushing session: optimistic locking failed");
-          StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
-              "optimistic locking failed while flushing " + session, e);
-        }
-        else {
-          log.error("hibernate flush failed", e);
-        }
+      catch (HibernateException e) {
+        // avoid log and throw antipatternf
         return e;
       }
     }
@@ -277,17 +266,18 @@
 
   private Exception closeSession() {
     if (mustSessionBeClosed) {
-      try {
-        if (session.isOpen()) {
+      if (session.isOpen()) {
+        try {
           log.debug("closing hibernate session");
           session.close();
         }
-        else {
-          log.warn("hibernate session was already closed");
+        catch (HibernateException e) {
+          // avoid log and throw antipattern
+          return e;
         }
       }
-      catch (Exception e) {
-        return e;
+      else {
+        log.warn("hibernate session was already closed");
       }
     }
     return null;
@@ -295,18 +285,18 @@
 
   private Exception closeConnection() {
     if (mustConnectionBeClosed) {
-      try {
-        if (connection != null) {
+      if (connection != null) {
+        try {
           log.debug("closing jdbc connection");
           connection.close();
         }
-        else {
-          log.warn("jdbc connection was already closed");
+        catch (SQLException e) {
+          // avoid log and throw antipattern
+          return e;
         }
       }
-      catch (Exception e) {
-        log.error("hibernate session close failed", e);
-        return e;
+      else {
+        log.warn("jdbc connection was already closed");
       }
     }
     return null;
@@ -316,7 +306,7 @@
     try {
       getSession().save(object);
     }
-    catch (Exception e) {
+    catch (HibernateException e) {
       // NOTE that Errors are not caught because that might halt the JVM
       // and mask the original Error.
       throw new JbpmPersistenceException("couldn't assign id to " + object, e);
@@ -514,9 +504,9 @@
     return false;
   }
 
-  public static boolean isStaleStateException(Exception exception) {
+  public static boolean isLockingException(Exception exception) {
     for (Throwable t = exception; t != null; t = t.getCause()) {
-      if (t instanceof StaleStateException) return true;
+      if (t instanceof StaleStateException || t instanceof LockAcquisitionException) return true;
     }
     return false;
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/persistence/jta/JtaDbPersistenceService.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -21,6 +21,10 @@
  */
 package org.jbpm.persistence.jta;
 
+import javax.transaction.HeuristicMixedException;
+import javax.transaction.HeuristicRollbackException;
+import javax.transaction.NotSupportedException;
+import javax.transaction.RollbackException;
 import javax.transaction.Status;
 import javax.transaction.SystemException;
 import javax.transaction.UserTransaction;
@@ -29,9 +33,9 @@
 import org.apache.commons.logging.LogFactory;
 import org.hibernate.engine.SessionFactoryImplementor;
 import org.hibernate.util.JTAHelper;
+
 import org.jbpm.JbpmException;
 import org.jbpm.persistence.db.DbPersistenceService;
-import org.jbpm.persistence.db.StaleObjectLogConfigurer;
 
 public class JtaDbPersistenceService extends DbPersistenceService {
 
@@ -59,8 +63,8 @@
   }
 
   protected boolean isTransactionRollbackOnly() {
-    return super.isTransactionRollbackOnly()
-        || JTAHelper.isMarkedForRollback(getTransactionStatus());
+    return super.isTransactionRollbackOnly() ||
+        JTAHelper.isMarkedForRollback(getTransactionStatus());
   }
 
   public void beginTransaction() {
@@ -70,7 +74,10 @@
       transaction = jtaFactory.getUserTransaction();
       transaction.begin();
     }
-    catch (Exception e) {
+    catch (NotSupportedException e) {
+      throw new JbpmException("transaction is already in course", e);
+    }
+    catch (SystemException e) {
       throw new JbpmException("transaction begin failed", e);
     }
   }
@@ -91,21 +98,19 @@
       transaction.commit();
       return null;
     }
-    catch (Exception e) {
-      if (isStaleStateException(e)) {
-        log.debug("optimistic locking failed, could not commit " + transaction);
-        StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
-            "optimistic locking failed, could not commit " + transaction, e);
-      }
-      else {
-        // Switched to debug because either handle OR log 
-        // an exception is best practice, not both!
-        // Example: Clustered JobExecutor may have
-        // Exceptions which should be kept quiet
-        log.debug("transaction commit failed", e);
-      }
+    // avoid log and throw antipattern
+    catch (RollbackException e) {
       return e;
     }
+    catch (HeuristicMixedException e) {
+      return e;
+    }
+    catch (HeuristicRollbackException e) {
+      return e;
+    }
+    catch (SystemException e) {
+      return e;
+    }
   }
 
   protected Exception rollback() {
@@ -114,12 +119,8 @@
       transaction.rollback();
       return null;
     }
-    catch (Exception e) {
-      // Switched to debug because either handle OR log 
-      // an exception is best practice, not both!
-      // Example: Clustered JobExecutor may have
-      // Exceptions which should be kept quiet
-      log.debug("transaction rollback failed", e);
+    catch (SystemException e) {
+      // avoid log and throw antipattern
       return e;
     }
   }

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/main/java/org/jbpm/svc/Services.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -33,11 +33,9 @@
 import org.apache.commons.logging.LogFactory;
 
 import org.jbpm.JbpmContext;
-import org.jbpm.JbpmException;
 import org.jbpm.graph.exe.ProcessInstance;
 import org.jbpm.logging.LoggingService;
 import org.jbpm.msg.MessageService;
-import org.jbpm.persistence.JbpmPersistenceException;
 import org.jbpm.persistence.PersistenceService;
 import org.jbpm.persistence.db.DbPersistenceService;
 import org.jbpm.persistence.db.StaleObjectLogConfigurer;
@@ -236,45 +234,36 @@
   }
 
   public void close() {
-    if (services != null) {
-      Exception firstException = null;
-      for (Iterator iter = serviceNames.iterator(); iter.hasNext();) {
-        String serviceName = (String) iter.next();
-        Service service = (Service) services.get(serviceName);
-        if (service != null) {
-          try {
-            log.debug("closing service '" + serviceName + "': " + service);
-            service.close();
+    if (services == null) return;
+
+    RuntimeException firstException = null;
+    for (Iterator iter = serviceNames.iterator(); iter.hasNext();) {
+      String serviceName = (String) iter.next();
+      Service service = (Service) services.get(serviceName);
+      if (service == null) continue;
+
+      try {
+        log.debug("closing '" + serviceName + "' service");
+        service.close();
+      }
+      catch (RuntimeException e) {
+        if (firstException == null) {
+          firstException = e;
+        }
+        else {
+          // if this is a locking exception, keep it quiet
+          if (DbPersistenceService.isLockingException(e)) {
+            StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
+                "problem closing '" + serviceName + "' service", e);
           }
-          catch (JbpmPersistenceException e) {
-            // if this is a stale state exception, keep it quiet
-            if (DbPersistenceService.isStaleStateException(e)) {
-              log.info("optimistic locking failed, could not close service: " + serviceName);
-              StaleObjectLogConfigurer.getStaleObjectExceptionsLog().error(
-                  "optimistic locking failed, could not close service: " + serviceName, e);
-            }
-            else {
-              log.error("problem closing service '" + serviceName + "'", e);
-            }
-            if (firstException == null) {
-              firstException = e;
-            }
+          else {
+            log.error("problem closing '" + serviceName + "' service", e);
           }
-          catch (Exception e) {
-            // NOTE that Error's are not caught because that might halt the JVM
-            // and mask the original Error.
-            log.error("problem closing service '" + serviceName + "'", e);
-            if (firstException == null) {
-              firstException = e;
-            }
-          }
         }
       }
-      if (firstException != null) {
-        throw firstException instanceof JbpmException ? (JbpmException) firstException
-            : new JbpmException("problem closing services", firstException);
-      }
     }
+
+    if (firstException != null) throw firstException;
   }
 
   public static void assignId(Object object) {

Modified: jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java	2009-06-27 12:19:46 UTC (rev 5136)
+++ jbpm3/branches/jbpm-3.2-soa/modules/core/src/test/java/org/jbpm/perf/SimplePerformanceTest.java	2009-06-27 12:56:00 UTC (rev 5137)
@@ -22,11 +22,8 @@
 package org.jbpm.perf;
 
 import org.jbpm.db.AbstractDbTestCase;
-import org.jbpm.graph.def.ActionHandler;
 import org.jbpm.graph.def.ProcessDefinition;
-import org.jbpm.graph.exe.ExecutionContext;
 import org.jbpm.graph.exe.ProcessInstance;
-import org.jbpm.util.Semaphore;
 
 /**
  * This test creates a number of process instances. Every instance has a call to an ActionHandler.
@@ -41,86 +38,52 @@
 
   private static final int WARMUP_INSTANCES = 100;
   private static final int MEASUREMENT_INSTANCES = 1000;
+  private static final long TIMEOUT = 5 * 60 * 1000;
 
-  private static final Semaphore signalLight = new Semaphore(0);
-
   private ProcessDefinition processDefinition;
 
   protected void setUp() throws Exception {
     super.setUp();
 
     processDefinition = ProcessDefinition.parseXmlString("<process-definition name='perf'>"
-        + "  <event type='process-start'>"
-        + "    <action class='"
-        + AsyncSignalAction.class.getName()
-        + "' async='true'/>"
-        + "  </event>"
         + "  <start-state name='start'>"
         + "    <transition to='end'/>"
         + "  </start-state>"
-        + "  <end-state name='end'/>"
+        + "  <end-state async='true' name='end'/>"
         + "</process-definition>");
     jbpmContext.deployProcessDefinition(processDefinition);
-
-    newTransaction();
-    startJobExecutor();
   }
 
   protected void tearDown() throws Exception {
-    stopJobExecutor();
-
-    newTransaction();
     jbpmContext.getGraphSession().deleteProcessDefinition(processDefinition.getId());
-
     super.tearDown();
   }
 
   public void testAsyncCall() {
-    // Won't Fix [JBPM-2043] Performance test coverage
-    if (getHibernateDialect().indexOf("HSQL") != -1) return;
-
     launchProcessInstances(WARMUP_INSTANCES);
 
     long startTime = System.currentTimeMillis();
     launchProcessInstances(MEASUREMENT_INSTANCES);
     long duration = (System.currentTimeMillis() - startTime) / 1000;
 
-    System.out.println("=== Test finished processing "
-        + MEASUREMENT_INSTANCES
-        + " instances in "
-        + duration
-        + " seconds ===");
-    System.out.println("=== This is "
-        + (MEASUREMENT_INSTANCES / duration)
-        + " instances per second ===");
+    System.out.println("=== Test finished processing " +
+        MEASUREMENT_INSTANCES +
+        " instances in " +
+        duration +
+        " seconds ===");
+    System.out.println("=== This is " +
+        (MEASUREMENT_INSTANCES / duration) +
+        " instances per second ===");
   }
 
   private void launchProcessInstances(int count) {
     for (int i = 0; i < count; i++) {
-      ProcessInstance pi = new ProcessInstance(processDefinition);
-      jbpmContext.save(pi);
       newTransaction();
+      ProcessInstance processInstance = new ProcessInstance(processDefinition);
+      processInstance.signal();
+      jbpmContext.save(processInstance);
     }
 
-    commitAndCloseSession();
-    try {
-      signalLight.acquire(count);
-    }
-    catch (InterruptedException e) {
-      fail(getName() + " got interrupted while waiting for process instances to end");
-    }
-    finally {
-      beginSessionTransaction();
-    }
+    processJobs(TIMEOUT);
   }
-
-  public static class AsyncSignalAction implements ActionHandler {
-
-    private static final long serialVersionUID = -8617329370138396271L;
-
-    public void execute(final ExecutionContext executionContext) throws Exception {
-      executionContext.leaveNode();
-      signalLight.release();
-    }
-  }
 }




More information about the jbpm-commits mailing list