4 Replies Latest reply on Oct 20, 2009 10:15 AM by Brian Westrich

    Catching invalid transition names in jBPM4

    Brian Westrich Newbie

      In jBPM4.x, is there a way to tell whether an invalid transition is passed to the executionService.signalExecutionById method?

      In 3.2.3, when an invalid transition was passed into ProcessInstance.signal, an exception was thrown. In the above mentioned 4.1 method, no exception is thrown and the state-transition does not occur.

        • 1. Re: Catching invalid transition names in jBPM4
          Sebastian Schneider Master

          As far as I know a signal name does not need to be a valid transition name.

          • 2. Re: Catching invalid transition names in jBPM4
            Brian Westrich Newbie

            Interesting to know that signal names have such flexibility. And I can imagine situations where that might be useful.

            However, the way I've used jBPM 3.2.3, if I send a process instance a signal, I expect the signal to cause a transition (even if the transition is to the same state). So I add validation code between the client and the executing business process that notifies the client if they pass in a signal which is not a valid transition (and thus will not cause a transition).

            I think I just figured out a way of doing such a validation using 4.x: Cast the Execution (interface) to an ExecutionImpl, call getActivity() to get the ActivityImpl, then call findOutgoingTransition(String name). If findOutgoingTransition returns a null, the transition is not valid. The below code shows this approach, as well as a way to list all valid transitions.


            public class FirstEnterHandler implements ExternalActivityBehaviour {
             public void execute(ActivityExecution execution) throws Exception {
             String transitionName = "byListener?";
             ExecutionImpl executionImpl = (ExecutionImpl) execution;
             ActivityImpl activity = executionImpl.getActivity();
             TransitionImpl transition = activity.findOutgoingTransition(transitionName);
             if (transition == null) {
             String validTrans = activity.getOutgoingTransitions().toString();
             throw new RuntimeException("invalid transition " + transitionName
             + ", valid transitions are : " + validTrans);
             }
             execution.take(transitionName);
             }
             }


            Even if this code works, it seems like a lot of use of internal implementation classes. Is this approach an ok way to validate signal names?



            • 3. Re: Catching invalid transition names in jBPM4
              Sebastian Schneider Master

              Honestly I can't answer your last question. But what about just trying to call execution.take(transitionName) and catching the exception in case of an invalid name?


              void take(java.lang.String transitionName)

              takes the outgoing transition with the given name.

              This method can only be called from inside ExternalActivityBehaviour implementations.

              Transitions will be looked up recursively starting from the current activity and then up the activity-parent-hierarchy

              Parameters:
              transitionName - is the name of the transition to take. A null value will match the first unnamed transition.
              Throws:
              JbpmException - in case no such transition is found in the current activity or in case this method is called from inside an ActivityBehaviour.




              • 4. Re: Catching invalid transition names in jBPM4
                Brian Westrich Newbie

                You're absolutely right, I could just call take() and see if it throws an exception. That approach would be simpler than the one I suggested. Thanks for pointing it out.

                So to summarize, it looks like the Execution interface does provide a way to see if a transition is valid (i.e. call take and see if it throws an exception). On the other hand, to get the list of valid transitions one must use the underlying implementation classes (ExecutionImpl, etc.).