[jbpm-commits] JBoss JBPM SVN: r7057 - in jbpm3/branches/jbpm-3.2-soa/core/src: test/java/org/jbpm and 1 other directories.

do-not-reply at jboss.org do-not-reply at jboss.org
Tue Feb 21 21:04:57 EST 2012


Author: marco.rietveld
Date: 2012-02-21 21:04:57 -0500 (Tue, 21 Feb 2012)
New Revision: 7057

Added:
   jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3423/
   jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3423/JBPM3423Test.java
Modified:
   jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/GraphElement.java
   jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/Node.java
Log:
JBPM-3423 stack overflow/error message when deploying proc defs that contain nodes with same name

Modified: jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/GraphElement.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/GraphElement.java	2012-02-22 02:03:22 UTC (rev 7056)
+++ jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/GraphElement.java	2012-02-22 02:04:57 UTC (rev 7057)
@@ -457,7 +457,18 @@
     }
     else if (parent instanceof NodeCollection && otherParent instanceof NodeCollection) {
       NodeCollection nodeCollection = (NodeCollection) parent;
-      int index = nodeCollection.getNodes().indexOf(this);
+      
+      // JBPM-3423: equals calls itself recursively via ArrayList.indexOf(this)
+      // hashCode's in Java are not 100% reliable (i.e. NOT always unique)
+      //   but reliable enough for this situation
+      Iterator iter = nodeCollection.getNodes().iterator();
+      int index = -1;
+      for( int i = 0; iter.hasNext(); ++i ) { 
+        int elemHashCode = System.identityHashCode(iter.next());
+        if( elemHashCode == System.identityHashCode(this) ) { 
+          index = i;
+        }
+      }
       assert index != -1 : nodeCollection.getNodes();
 
       NodeCollection otherNodeCollection = (NodeCollection) otherParent;

Modified: jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/Node.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/Node.java	2012-02-22 02:03:22 UTC (rev 7056)
+++ jbpm3/branches/jbpm-3.2-soa/core/src/main/java/org/jbpm/graph/def/Node.java	2012-02-22 02:04:57 UTC (rev 7057)
@@ -469,8 +469,7 @@
       String oldName = this.name;
       if (superState != null) {
         if (superState.hasNode(name)) {
-          throw new IllegalArgumentException("cannot rename " + this + " because " + superState
-            + " already has a node named " + name);
+          throw new IllegalArgumentException("Super state '" + superState + "' already has a node named " + name);
         }
         Map nodes = superState.getNodesMap();
         nodes.remove(oldName);
@@ -478,8 +477,7 @@
       }
       else if (processDefinition != null) {
         if (processDefinition.hasNode(name)) {
-          throw new IllegalArgumentException("cannot rename " + this + " because "
-            + processDefinition + " already has a node named " + name);
+          throw new IllegalArgumentException("Process definition '" + processDefinition + "' contains two nodes with name " + name);
         }
         Map nodeMap = processDefinition.getNodesMap();
         nodeMap.remove(oldName);

Added: jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3423/JBPM3423Test.java
===================================================================
--- jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3423/JBPM3423Test.java	                        (rev 0)
+++ jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3423/JBPM3423Test.java	2012-02-22 02:04:57 UTC (rev 7057)
@@ -0,0 +1,82 @@
+package org.jbpm.jbpm3423;
+
+import java.util.Timer;
+import java.util.TimerTask;
+
+import org.jbpm.db.AbstractDbTestCase;
+import org.jbpm.graph.def.ProcessDefinition;
+
+public class JBPM3423Test extends AbstractDbTestCase {
+
+  private static final String PROCESS_DEFINITION_MULTI_NODE = 
+      "<process-definition  xmlns=''  name='SimpleProcess'>" + 
+      "  <start-state name='start-state1'>" + 
+      "    <transition to='SAME'></transition>" + 
+      "  </start-state>" + 
+      "  <node name='SAME'>" + 
+      "    <action class='com.sample.action.MessageActionHandler' name='Node1Action'>" + 
+      "      <message>NODE-1</message>" + 
+      "    </action>" + 
+      "    <transition to='node'></transition>" + 
+      "  </node>" + 
+      "    <!--  Because this is ALSO 'SAME', it can cause recursion in the GraphElement.equals(...) method  -->" + 
+      "  <node name='SAME'>" + 
+      "    <action class='com.sample.action.MessageActionHandler' name='Node2Action'>" + 
+      "      <message>NODE-2</message>" + 
+      "    </action>" + 
+      "    <transition to='end-state1'></transition>" + 
+      "  </node>" + 
+      "  <end-state name='end-state1'></end-state>" + 
+      "</process-definition>";
+      
+
+  private boolean stackOverflow = false;
+  private boolean exceptionWasThrown = false;
+  private boolean threadHadToBeKilled = false;
+  
+  public void testNoRecursivenessInParsingNodesWithDuplicateNames() throws Exception { 
+    // Thread to deploy process that might stack overflow
+    final Thread deployThread = new Thread() { 
+      public void run() { 
+        try { 
+          ProcessDefinition.parseXmlString(PROCESS_DEFINITION_MULTI_NODE);
+        }
+        catch( Throwable t ) { 
+          if( t instanceof StackOverflowError ) { 
+            stackOverflow = true;
+          }
+          if( t.getMessage() != null && t.getMessage().contains("contains two nodes") ) { 
+            exceptionWasThrown = true;
+          }
+        }
+      }
+    };
+    
+    // Timer task to stop above thread if necessary.
+    TimerTask stopThreadTask = new TimerTask() {
+      private Thread threadToStop = deployThread;
+      public void run() {
+        if( threadToStop.isAlive() ) { 
+          threadToStop.stop();
+        }
+      }
+    };
+    
+    // Setup
+    Timer stopThreadTimer = new Timer();
+    long delay = 2*1000;
+    
+    // Start deploy
+    deployThread.start();
+    
+    // Kill thread if necessary after delay
+    stopThreadTimer.schedule(stopThreadTask, delay);
+    Thread.sleep(delay + 100);
+    
+    assertFalse("Stack overflow occurred!", stackOverflow);
+    assertFalse("Deploy thread had to be killed!", threadHadToBeKilled);
+    assertTrue("No exception was thrown during deployment.", exceptionWasThrown);
+  }
+  
+  
+}


Property changes on: jbpm3/branches/jbpm-3.2-soa/core/src/test/java/org/jbpm/jbpm3423/JBPM3423Test.java
___________________________________________________________________
Added: svn:mime-type
   + text/plain
Added: svn:eol-style
   + native



More information about the jbpm-commits mailing list