Alfresco recently launched the Activiti project, which will be implementing a BPMN 2.0 process engine on Tom Baeyens’ Process Virtual Machine (PVM). The idea of the process virtual machine is simple and appealing, but beware the siren song of software abstraction elegance. The idea is that all of the hard work of developing a process engine can be put into a layer that is more general and abstract than any process definition language. Then, when anyone wants to create a process engine based on a new language, it is a simple matter to map the concepts of the new language onto the constructs of the PVM and voila: a new process engine!
I think there are a number of problems with this idyllic picture, but before I talk about those, I have to admit that I’m reminded of an old debate in the operating system world. For a number of years in the 90’s all the talk in operating system research was about how operating systems based on microkernels were going to make operating systems with traditional kernels obsolete. The arguments were similar to the argument for process virtual machines and everyone was waiting expectantly for one of the microkernel-based operating systems (e.g. Minix or Hurd) to take over the world. Linux would be obsolete. There was just the matter of waiting… and waiting…
It was never going to happen. Linus Torvalds, writer of the Linux kernel, also made it clear that he had no interest in moving to a microkernel-based architecture. There was a long debate, but I especially liked what Linus said in 2006:
“Microkernels are much harder to write and maintain…And I’m not just saying that. This is a fact. It’s a fact that has been shown in practice over and over again, not just in kernels. But it’s been shown in operating systems too – and not just once. The whole “microkernels are simpler” argument is just bull, and it is clearly shown to be bull by the fact that whenever you compare the speed of development of a microkernel and a traditional kernel, the traditional kernel wins. By a huge amount, too.”
The analogy isn’t perfect – no analogy ever is – but the shared characteristic is the fact that some attempts to force the internal implementation of a software development platform into multiple seemingly elegant layers of abstraction may ultimately fail. The user of the operating system, or developer of the process, won’t care. They want an application platform on which it is easy to develop, test, debug, monitor, administer, secure, etc.
A BPMS is already several levels of abstraction up from an operating system, even without a process virtual machine. A traditionally developed BPMS will be on top of an application server and a database. The application server is on a JVM, which is on an operating system, which often is on top of a virtual machine. Every layer adds value but it also adds cost – primarily do to the fact that each new layer of abstraction can’t be completely hidden. Is the cost/benefit tradeoff right for a PVM layer?
I’d say no. For a BPMS it certainly isn’t possible to completely hide the presence of this new layer while still providing useful services. Here are few examples:
Logging. Clearly if the PVM is going to be performing any complex logic, especially anything involving integration with external systems, it is critical that each step of consequence be loggable (if that level of logging is turned on). The PVM doesn’t fail there. The problem is: how can the PVM write a log message that makes any sense to the user? It can’t talk about a problem in the user’s inclusive gateway (a BPMN concept) because it has no understanding of that level. Its understanding is at the level of an abstract state machine, so that is all it can log about. This means that making sense of the log requires understanding how the language you wrote your process in was mapped into a PVM state machine.
Persistence and reporting. The PVM state machine is a persistent state machine. This is one of its great values: you don’t have to worry about saving the state and reconstituting it when the next event comes in. With a BPMS, the fact that processes are persistent also make it possible to generate very valuable custom reports that provide visibility into what is going on in the business. The custom reports are based on queries against the database that persists the processes. This means that the report writer has to be able to make sense of the database schemas used to store the process. Process variables, data objects, sub-process variables – these are the concepts that the process writer knows about. But the PVM has no knowledge of these constructs. Whatever persistent representation it has will be completely foreign. It is another place where the abstraction seeps through.
Faults and debugging. Sometimes the process developer will make mistakes and the resulting process will fail – possibly somewhere deep within a transformation inside three layers of sub-process. How will the exception be reported? Will there be an error message that describes the BPMN context where the problem occurred, or will there be a Java traceback that shows multiple layers of the PVM? I suspect the latter.
Other capabilities provided by the PVM just aren’t that difficult to implement. A loop? How hard is that to write? In fact any control flow construct is pretty trivial to implement. We are, after all, implementing in Java. The language is already a pretty productive development environment.
So, all this is to say: be careful. Not all pretty-looking abstractions are good for you.