Posted by: kukeltje | 2 October, 2008

Other products using jBPM

More often than people think, jBPM is used in other products. One of the reasons is that by itself jBPM is, besides a product, also an embedable framework/engine. Therefore it lends itself perfectly for being embedded. One of the nicer applications which already uses jBPM for a long time is Alfresco (which maybe by accident did not give me admission to their new ‘Labs‘ product presentation in ‘Utrecht’ (guys, if you read this, you can still send an invitation to ronald (at) jbpm (dot) org ;-)). They also use one of my other favourite framework called Chiba, a W3C XForms engine, which I hope they will not ditch instead of developing their own since more complex forms need it. Believe me, we’ve tried developing our own forms framework and it worked fine for simple forms, but extending it for more complex forms continuously fails misarably. In the end you have nearly implemented the XForms spec, functionality wise, but in a completely different way.

The reason for this post is that I think jBPM deserves the exposure of being used in different products, which again are used in big companies (like financial institutions, just not sure that is good publicity these days).  So every so often I will post references here to products that use jBPM embedded if I come across them and think it is interesting enough to mention.

The company I did not expect to use jBPM (but hoped they once would) is SUN. My google alert on jBPM (in fact the query is “jbpm -sys-con” otherwise I get spammed by those #$%$%^@) contained a post on portals by Cambridge Technology Partners and mentioned WebSynergy today. A quote from their site:

WebSynergy is  the next-generation Web aggregation and presentation platform from Sun™ Microsystems. This platform includes developer tools and an enterprise-grade presentation runtime based on Liferay Portal Server, GlassFish™ version 3, and MySQL™ software.

Nice to see they are using jBPM albeit via the SAW, the Simple API for Workflow ‘framework’. ‘Standardizing’ an api which reminds me of some other effort 😉

If anyone comes across interesting other products that use jBPM, let me know

Posted by: kukeltje | 1 October, 2008

Implementing ‘milestones’ in jBPM

Very intelligent people have made it their daytime job to study Workflow Patterns. One of the patterns Workflow Control Pattern 18 (WCP-18) is about so called milestones. Since I do not want to completely redefine, what a milestone is, I’ll take their definition of a milestone as a startingpoint.

A task is only enabled when the process instance (of which it is part) is in a specific state (typically a parallel branch). The state is assumed to be a specific execution point (also known as a milestone) in the process model. When this execution point is reached the nominated task can be enabled. If the process instance has progressed beyond this state, then the task cannot be enabled now or at any future time (i.e. the deadline has expired). Note that the execution does not influence the state itself, i.e. unlike normal control-flow dependencies it is a test rather than a trigger.

First of all, the definition of a task is important. Their definition which in the Data Control Patterns btw, so not very logical since it is also part of control patterns (but hey, they are scientists, who’d expect logic from them)

A task corresponds to a single unit of work. Four distinct types of task are denoted: atomic, block, multi-instance and multi-instance block. We use the generic term components of a workflow to refer to all of the tasks that comprise a given workflow model. An atomic task is one which has a simple, self-contained definition (i.e. one that is not described in terms of other workflow tasks) and only one instance of the task executes when it is initiated. A block task is a complex action which has its implementation described in terms of a sub-workflow. When a block task is started, it passes control to the first task(s) in its corresponding sub-workflow. This sub-workflow executes to completion and at its conclusion, it passes control back to the block task . E.g. block task C is defined in terms of the sub-workflow comprising tasks, X, Y and Z.

What I get from this is that it comprises jBPM tasks, states, nodes, even subprocesses, which in fact is no problem for jBPM at all.

Secondly and that surprises me a little is that they state “is in a specific state”, so not in or after a specific state. Again, no problem at all for jBPM, since it can handle both, but rather limiting from a real world point of view since I had to implement this twice. Maybe it’s the terminology or maybe it is just me or maybe they just missed this? 😉

What is nice about this site, is that for each of these WCP, they have a flash example, but keep in mind that this is just one example. There does not need to be a loop back e.g (imo). You can start it by clicking on the ‘start’ button in the lower left-hand corner if it does not start automatically. After that, you can click on each of the individual tokens to see the behaviour and play with different scenarios.

You can enable ‘task E’ by putting the upper token in the dotted circle. If you play with it some more you’ll see that ‘E’ is no (wait-)state as opposed to the other ‘tasks’ (so is it a task at all??? hmmm, scientists)

A deffered choice is nothing more than providing an option to choose one path of execution from a variable number. jBPM has two options for this. A default decisionnode jBPM or the user selecting one ‘transition’ when executing a task. So to me it is fairly easy to see that this can be modelled in jBPM with all basic constructs available. Having the possibility to go to E or F is nothing more than implementing either a ‘guards’ in the form of conditions on transitions on a decision node that checks what state a specific (other) token is in, or even guards directly on transitions on a task node.

<task-node name='D'>
    <task name='Task D'/>
    <transition name='to E' condition='[check if a token is between B and C]' />
    <transition name='to F' />
</task-node>

Now I have to admit that this is something that has only been possible since jBPM 3.2. So that the scientists say this is not possible in jBPM 3.1, I have to agree. Besides that, it is kind of a combination of a task with one transition and exclusive choice pattern. So it is not possible in this way in jBPM 3.1, but what if we try to move a little closer to the real pattern

If you take another look at their example, you’ll see that between ‘task D’ and ‘task E’/’task F’ there is a deferred choice. To me, only in this deferred choice knowledge exists of whether task E can be chosen or not. So it seems this is not available in ‘task D’. So the crux is how to present this to the user (assuming there is a user). I’ve not been able to find (nor did I search very thoroughly, e.g. in YAWL) how they solve this.

Ok, lets go  a step further. In the milestone pattern figure it states explicitly that A can only be started if there is a token between B and C. Where C is the state that Task C is started. In my opinion is it therefor allowed to be in a task-node C (which has a task c). There is one issue. Task A may only be created if the token has left task-node B and task C is not started. Now look at this basic model

	<fork name='fork'>
		<transition to='task-node a' name='to task-node a' />
		<transition to='task-node b' name='to task-node b' />
	</fork>
	<task-node name='task-node a'>
		<task name='task a' swimlane='users' />
		<transition name='to join' to='join' />
	</task-node>
	<task-node name='task-node b'>
		<task name='task b' swimlane='users' />
		<transition name='to task-node c' to='task-node c' />
	</task-node>
	<task-node name='task-node c'>
		<task name='task c' swimlane='users' />
		<transition name='to join' to='join' />
	</task-node>
	<join name='join'>
		<transition name='to end' to='end' />
	</join>

What is missing here is that task A is directly created, which it should not be. This can be very easily changed in jBPM by adding a ‘create-tasks=”false”‘ attribute on task-node A, so this becomes

	<task-node name='task-node a' create-tasks='false'>
		<task name='task a' swimlane='users' />
		<transition name='to join' to='join' />
	</task-node>

Now we should create a ‘task a’ the moment task-node b is ‘left’. This is very simple in jBPM and can either be done on a transition, or on an event, with java and javascript. In this example I use a java class.

	<task-node name='task-node b'>
		<task name='task b' swimlane='users' />
		<event type='node-leave'>
			<action class='net.vankuijk.jbpm.utils.CreateTask'>
				<taskNodeName>task-node a</taskNodeName>
			</action>
		</event>
		<transition name='to task-node c' to='task-node c' />
	</task-node>

	<task-node name='task-node b'>
		<task name='task b' swimlane='users' />

		<transition name='to task-node c' to='task-node c'>
            	<action class='net.vankuijk.jbpm.utils.CreateTask'>
				<taskNodeName>task-node a</taskNodeName>
			</action>
            </transition>
	</task-node>

Both are valid and I made the class a little generic (since I use it more and more) so I can pass it parameters. Now how does this class look like

public class CreateTask implements ActionHandler {

	String taskNodeName;

	public void execute(ExecutionContext executionContext) throws Exception {

		TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance();
		Node node = executionContext.getProcessDefinition().getNode(
				taskNodeName);

		TaskNode taskNode = (TaskNode) node;

		Token parentToken = (Token) executionContext.getToken().getParent();

		Task task = (Task) taskNode.getTasksMap().values()
				.iterator().next();
		Token childToken = new Token(parentToken, taskNode.getName());
		childToken.setNode(taskNode);
		tmi.createTaskInstance(task, childToken);

	}
}

As you can see, a very simple class.

Now how do we end this task when task C starts? Remember that jBPM creates tasks but not automatically starts them. Starting them is calling a method on the api that actually does this and due the the flexible nature of jBPM, there is an event fired in this case, called ‘task-start’.

	<task-node name='task-node c'>
		<task name='task c' swimlane='users' />
		<transition name='to join' to='join' />
		<event type='task-start'>
			<action class='net.vankuijk.jbpm.utils.CancelTask'>
				<taskNodeName>task-node a</taskNodeName>
			</action>
		</event>
	</task-node>

We should just not forget to test whether task a was not started yet since it has to be left alone once it is.

public class CancelTask implements ActionHandler{

	String taskNodeName;

	public void execute(ExecutionContext executionContext) throws Exception {

		// Assuming max one active childToken and max one unfinished task in
		// this childtoken

		Node node = executionContext.getProcessDefinition().getNode(
				taskNodeName);

		TaskNode taskNode = (TaskNode) node;

		Token token = (Token) executionContext.getToken().getParent()
				.getChildrenAtNode(taskNode).get(0);

		Iterator unfinishedTasks = executionContext.getTaskMgmtInstance()
				.getUnfinishedTasks(token).iterator();
		if (unfinishedTasks.hasNext()) {
			TaskInstance ti = (TaskInstance) unfinishedTasks.next();
			if (ti.isOpen() && ti.getStart() == null) {
				ti.cancel();
			}
		}
	}
}

Of course some more nullpointer checking, logging etc should be in there. This example will become part of the jBPM distribution and it will all be in there. Maybe this is a good starting point to initiate a community effort to create these kinds of utility classes, maybe also for TDD

I hope that I demonstrated with this that jBPM, with some small extensions, supports one of the many milestones patterns, albeit a simple one. And that even jBPM 3.1 should have gotten a + in the product evaluation, you just have to know the capabilities of a product/framework/… and not expect it to contain everything but the kitchensink out of the box.

Ronald

p.s. I’ve split this post into 2 parts since it became to long. The second part of this post, a more complex ‘milestone/trigger/…’ example with a slightly different approach from B2 International will be posted next week

Posted by: salaboy | 19 September, 2008

I was thinking..

This is my first post here, I hope I can contribute with something.

But the real reason of this post is to talk about an idea that I have in mind for weeks.

I was thinking (like the title said) in do some research in jBPM User, Design Forum and some wikis and do a kind of top ten hot topics asked by the starters in jBPM. Another top ten with the most advanced things in jBPM.

And three really important posts about:

  1. How to improve the initial relationship with the new developers
  2. How and why  become jBPM contributor (May be Tom can help with this)
  3. The future of jBPM and the main actual goals (extracted from Design jBPM forum, i think Tom have the last words on this)

Probably for time reasons, i will do this in my blog in spanish.. but i’m sure that i can make some reviews here.

Let me know if you have some comments about this ideas.

PS: please correct my english if something is not clear enough.

Salaboy!

Posted by: planetjbpm | 18 September, 2008

First post, expect more

There have been people posting blog entries about jBPM. Mostly interesting articles like the performance showdown by Joram Barrez. Recently, I noticed that one of the active jBPM community members, Mauricio Salatino (Salaboy21), put a wordpress url in his signature when posting on the jBPM users forum. Curious as I am, I followed the url and to my great frustration (ok I exaggerate a little) it was in Spanish. French, German, English and of course Dutch would have been ‘easy’. Spanish… hmm.. I tried reading it, succeded unexpectedly wel, but in the end used the translation plugin in my browser to translate it.

I was impressed… in two ways. First of all, the translation (from google) was great. Secondly, and in fact this impressed me more,  was that Salaboy wrote 14 articles on jBPM the last month. Basic things, conceptual things, more advanced things, a great mixture. When I posted a reference on the jBPM user forum, I got a response from Salaboy that he proposed this blog to JBoss to be included as a community member feed, they turned it down… The reasons were that they only wanted blogs written in the English language and they did not want to use google translation services. Now I’m lost…

Well… creative as I am (my day job contains the word architect in the job description) I thought that a kind of syndicated blog with articles of my own, references to external blogs, with English introductions to e.g. spanish articles and a link via google translation services to these articles would get trough.

Now you know why I started this blog, you are probably curious what will come next. People sometimes ask things like: “Why is x,y,z not possible in jBPM, it is a common requirement”. Most of the time people expect things to work out of the box the way they expect it to. The control-flow workflowpatterns (nice but kind of hyped) are another example. The initial scientific study in 2002 yielded 20 patterns (jBPM can do them all, look in the testcases in the source if you do not believe me) and a revised view 4 years later resulted in 43 patterns… wow… over a 100% increase in 4 years. There has been some discussion on whether jBPM supports them or not. I dare to say jBPM can support most of them.

In the more advanced areas, there is no single way to do things and that is one of the reasons some language constructs are not in JPDL, but are achievable with a combination of JPDL and the usage of the jBPM core api. This is not how the theoretical scientists look at it, but it gives the flexibility to achieve almost everything you want. The first two articles are on some more advanced jBPM usage where this is shown.

The first one will be about milestones. Something that is partly supported directly in the core, just not with persitable JPDL node type. But with some simple reusable java code it is possible without using this milestone node type. A short real live ‘problem solving’ with the people from B2 International resulted in a testcase written by them, which I slightly adapted. This will show how simple it is to achieve milestone functionality

After that, I will post an example on how to achieve ‘escalation’ of tasks. Also something that is not supported out of the box since it (in my opinion) should be something that is modeled into the process and can very easily be.

I hope I’ve made you all curious, so stay tuned

« Newer Posts

Categories