[jboss-user] [JBoss jBPM] - Action ; Token.signal( ... ) ; Exception: locked tokens

JimKnopf do-not-reply at jboss.com
Wed Nov 29 05:03:38 EST 2006


Hi again,
I am calling an action and in this action i am fire a Rule from JRules. Based on the result of this rule i want to use a transition ( token.signal( "xxx" ) ).
But when i do this, i get an Exception. Is it not possible to use use token.signal in an action? And then, how should i realise actions in which i want to move to a next token? Is it only Possible with DecicionHandlers?

The Exception:
anonymous wrote : 
  | org.jbpm.JbpmException: can't continue execution on locked tokens.  signalling the same token that executes an action is not allowed
  | 	at org.jbpm.graph.exe.Token.signal(Token.java:164)
  | 	at org.jbpm.graph.exe.Token.signal(Token.java:137)
  | 


  |   </decision>
  |    <decision name="SGA">
  |       <event type="node-enter">
  | 			<action name="checkSGA" class="actions.DefaultRuleAction">
  | 				<ruleFile>etr2.drl</ruleFile>
  | 				<transitionName>t_sga a</transitionName>
  | 				<transitionName_False>t_sga c</transitionName_False>
  | 			</action>
  |       </event>
  |       <transition name="t_sga a" to="SGA A"></transition>
  |       <transition name="t_sga b" to="SGA B"></transition>
  |       <transition name="t_sga c" to="SGA C"></transition>
  |    </decision>
  |    <state name="SGA A">
  | 

Action:

  | public class DefaultRuleAction extends RuleAction {
  | 	private static final long serialVersionUID = 8459834862286126414L;
  | 	
  | 	//Name der Variablen die in der Action beruecksichtigt werden.
  | 	public List objectNames = null;
  | 	public String transitionName = null;
  | 	public String transitionName_False = null;
  | 	
  | 	public void execute( ExecutionContext executionContext) throws Exception {		
  | 		// TODO Auto-generated method stub
  | 		System.err.println("My Timer-Rule-Action!");
  | 		
  | 		if (this.ruleFile == null) {
  | 			System.err.println("Es wurde kein Rule-File angegeben.");
  | 			// TODO String aus einer Property laden.
  | 			return;
  | 		}
  | 		
  | 		// load up the RuleBase
  | 		WorkingMemory workingMemory = null;
  | 		try {
  | 			RuleBase ruleBase = readRule(this.ruleFile);
  | 			
  | 			workingMemory = this.generateWorkingMemory( ruleBase );
  | 			
  | 			this.assertObjectsIn( workingMemory, executionContext );
  | 			workingMemory.fireAllRules();
  | 
  | 			if( RuleAction.getResultFrom( workingMemory ) == true ){
  | 				if(this.transitionName != null){
  | 					executionContext.getToken().signal( transitionName );
  | 				}
  | 			}else{
  | 				if(this.transitionName_False != null){
  | 					executionContext.getToken().signal( transitionName_False );
  | 				}
  | 			}
  | 				
  | 		} catch (FileNotFoundException fnfe) {
  | 			System.err.println("Es wurde ein falsches Rule-File angegeben.");
  | 			fnfe.printStackTrace();
  | //			 TODO String aus einer Property laden.
  | 		} catch (MissingRuleResultException mrre){
  | 			System.err.println("Es wurde kein RuleResult-Object im WorkingMemory der Regel gefunden.");
  | 			mrre.printStackTrace();
  | //			TODO String aus einer Property laden.
  | 		} catch (Exception e){
  | 			System.err.println("Rule-Base konnte nicht angelegt werden.");
  | 			e.printStackTrace();
  | //			TODO String aus einer Property laden.
  | 		} finally{
  | 			if(workingMemory != null)
  | 				workingMemory.dispose();
  | 		}
  | 		
  | 		//ArcaViaController.getInstance().cancelTimer( executionContext.getTimer() );
  | 		
  | 	}
  | 
  | 


  | public abstract class RuleAction implements ActionHandler{
  | 	/* Name der Variablen des Workflows welche in das WorkingMemory
  | 	   der Regel eingepflegt werden sollen.*/
  | 	protected List objectNames = null;
  | 	
  | 	protected String ruleFile = null;
  | 	private RuleResult ruleResult = new RuleResult();
  | 	
  | 	/**
  |      * Please note that this is the "low level" rule assembly API.
  | 	 * @throws Exception 
  |      */
  | 	protected static RuleBase readRule(String ruleFileLocation) throws Exception{
  | //		ruleFileLocation = "src" +
  | //        		System.getProperty("file.separator") +
  | //        		"rules" +
  | //        		System.getProperty("file.separator") +
  | //        		ruleFileLocation;
  | 		
  | 		System.err.println( ruleFileLocation );
  | 		
  | 		//read in the source
  | 		Reader source = null;
  | 		try{
  | 			source = new InputStreamReader( RuleAction.class.getResourceAsStream( "/"+ruleFileLocation ) );
  | //			source = new InputStreamReader( new FileInputStream( new File(ruleFileLocation) ) );
  | 			
  | 		}catch( Exception e ){
  | 			throw new FileNotFoundException();
  | 		}
  | 		
  | 		//optionally read in the DSL (if you are using it).
  | 		//Reader dsl = new InputStreamReader( DroolsTest.class.getResourceAsStream( "/mylang.dsl" ) );
  | 
  | 		//Use package builder to build up a rule package.
  | 		//An alternative lower level class called "DrlParser" can also be used...
  | 		
  | 		DrlParser parser = new DrlParser();
  | 		PackageDescr packageDescr = parser.parse( source);
  | 		
  | 		/*
  | 		 * Wenn der default PackageBuilder eine Exception erzeugt (was er tat),
  | 		 * soll man ihn dann durch diese Code-Zeilen ersetzen laut der JBoss wiki Seite
  | 		 */
  | 		PackageBuilderConfiguration pkgBuilderCfg = new PackageBuilderConfiguration();
  | 		pkgBuilderCfg.setCompiler(PackageBuilderConfiguration.JANINO);
  | 		PackageBuilder builder = new PackageBuilder(pkgBuilderCfg);
  | 
  | 				
  | 		//default PackageBuilder
  | 		//PackageBuilder builder = new PackageBuilder();
  | 
  | 		//this wil parse and compile in one step
  | 		//NOTE: There are 2 methods here, the one argument one is for normal DRL.
  | 		//builder.addPackageFromDrl( source );
  | 		builder.addPackage(packageDescr);
  | 		
  | 		//Use the following instead of above if you are using a DSL:
  | 		//builder.addPackageFromDrl( source, dsl );
  | 		
  | 		//get the compiled package (which is serializable)
  | 		Package pkg = builder.getPackage();
  | 		
  | 		//add the package to a rulebase (deploy the rule package).
  | 		RuleBase ruleBase = RuleBaseFactory.newRuleBase();
  | 		ruleBase.addPackage( pkg );
  | 		return ruleBase;
  | 	}
  | 	
  | 	/**
  | 	 * Lädt aus dem uebergebenen WorkingMemory ein RuleResult-Object und
  | 	 * liefert den Result-Wert von diesem Object zurueck.
  | 	 * Dieser Result-Wert kann in einer Regel dazu verwendet werden,
  | 	 * ein Ergebniss zurueck zu liefern (zur Zeit nur true oder false).
  | 	 *   
  | 	 * @param wm WorkingMemory aus welchem das RuleResult-Object geprueft werden soll.
  | 	 * @return Den Result-Wert des RuleResult-Objectes in dem uebergeben WorkingMemory.
  | 	 * @throws MissingRuleResultException Es gibt kein RuleResult-Object im uebergebenen WorkingMemory.
  | 	 */
  | 	protected static boolean getResultFrom( WorkingMemory wm ) throws MissingRuleResultException{
  | //		if( wm == null )
  | //			throw new NullPointerException();
  | 		
  | 		List ruleResults = wm.getObjects( RuleResult.class );
  | 		
  | 		if( ruleResults.size() < 1 )
  | 			throw new MissingRuleResultException();
  | 		
  | 		RuleResult rs = (RuleResult)ruleResults.get(0);
  | 		return rs.getResult();
  | 		
  | 	}
  | 	
  | 	/**
  | 	 * Lädt das RuleResult Object in den WorkingMemory
  | 	 * so das man Ihn später in der Rule verwenden kann und
  | 	 * das in Ihm stehende Ergebniss der Regel mit der Methode
  | 	 * <code>getResultFrom(WorkingMemory wm)</code> auslesen kann.
  | 	 * 
  | 	 * @param wm WorkingMemory welches mit einem RuleResult Object vorbereitet werden soll.
  | 	 */
  | 	protected void prepareWorkingMemory( WorkingMemory wm ){
  | //		if( wm == null )
  | //			throw new NullPointerException();
  | 		wm.assertObject( this.ruleResult );
  | 	}
  | 	
  | 	/**
  | 	 * Erzeugt einen neuen WorkingMemory in der uebergebenen RuleBase und
  | 	 * ruft fuer diesen dann <code>prepareWorkingMemory( WorkingMemory wm )</code>
  | 	 * auf um den WorkingMemory mit dem RuleResult-Object zu beladen.
  | 	 * 
  | 	 * @param ruleBase RuleBase in welchem das neue WorkingMemory erzeugt werden soll.
  | 	 * @return Das Erzeugte WorkingMemory.
  | 	 */
  | 	protected WorkingMemory generateWorkingMemory( RuleBase ruleBase){
  | 		WorkingMemory wm = ruleBase.newWorkingMemory();
  | 		this.prepareWorkingMemory( wm );
  | 		
  | 		return wm;
  | 	}
  | 	
  | 	/**
  | 	 * Lädt die Variablen des Workflows welche der Action bei Ihrem Aufruf
  | 	 * durch den Workflow uebergeben wurden in den WorkingMemory der Regel.
  | 	 *  
  | 	 * @param wm WorkingMemory welcher mit den Objecten beladen werden soll.
  | 	 * @param executionContext Context mittels welcher die Variablen enthaelt.
  | 	 */
  | 	protected void assertObjectsIn( WorkingMemory wm, ExecutionContext executionContext ){
  | 
  | 		if (objectNames != null) {
  | 			// Ausgewählte Variablen einladen
  | 			ContextInstance ci = executionContext.getContextInstance();
  | 			Iterator it = objectNames.iterator();
  | 			while (it.hasNext()) {
  | 				String objectName = (String) it.next();
  | 				wm.assertObject(ci.getVariable(objectName));
  | 			}
  | 		}/*
  | 			 * Zu gefährlich in der Handhabung daher deaktiviert else{ //
  | 			 * Alle Variablen einladen wenn keine uebergeben wurden
  | 			 * ContextInstance ci = executionContext.getContextInstance();
  | 			 * Iterator it = ci.getVariables().entrySet().iterator();
  | 			 * while(it.hasNext()){ workingMemory.assertObject( it.next() ); } }
  | 			 */
  | 		
  | 	}
  | 
  | }
  | 

View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=3989613#3989613

Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=3989613




More information about the jboss-user mailing list