Professional Documents
Culture Documents
JBOSS jBPM
Control de versiones
Fecha Autor Observaciones
10/08/09 Jorge Roldán Barrio Versión inicial del documento
Manual de introducción a JBoss jBPM
1. Introducción
La lógica de negocio se puede definir en forma de una serie de tareas relacionadas que se deben
ejecutar de forma secuencial, paralela o en función de alguna condición. Al conjunto de estas tareas
se le conoce como proceso de negocio. La gestión de procesos de negocio (BPM – Business Process
Management) se encarga del modelado de los procesos de negocio, y define el flujo de trabajo
(workflow) que rige su funcionamiento. Un workflow modela de forma gráfica las relaciones entre
las distintas tareas.
Existen varios sistemas de gestión de procesos de negocio, y uno de ellos es JBoss jBPM, cuya
principal ventaja para aquellos que quieren aprender esta tecnología es que es open-source. En el
presente manual se pretende introducir al lector en el uso de esta herramienta.
3 de 22
Manual de introducción a JBoss jBPM
2. Instalación
Antes de empezar a trabajar con jBPM, se va a proceder a la instalación de dicha herramienta y de
un conjunto de utilidades que facilitan el desarrollo jBPM en Eclipse llamadas jBoss Tools.
Se ejecuta el instalador de jBPM. Lo primero que pide es la ruta de instalación, que en este caso va
a ser C:\java\jbpm. A continuación pregunta por los paquetes a instalar, pero lo dejaremos tal y
como está y pulsaremos “Next”. Ahora se debe elegir la versión del servidor en la que estamos
realizando la instalación, después la base de datos y finalmente la ruta del servidor. Tras esto ya se
pasa a realizar la instalación.
4 de 22
Manual de introducción a JBoss jBPM
Ahora habría que crear el esquema de base de datos que usa jBPM. Por sencillez, se va a mantener
la configuración por defecto para la fuente de datos que utiliza jBPM. Para hacer que funcione, se
debe ir al MySQL Administrator y crear un nuevo catálogo llamado jbpmtest y un nuevo usuario de
nombre jbpmtest y sin password. Se asigna a este usuario todos los permisos de la tabla jbpmtest.
En la ruta de instalación de jbpm (C:\java\jbpm) hay, entre otras cosas, scripts de creación del
esquema usado por jBPM. Si se va al MySQL Query Browser y se realiza la conexión al esquema
jbpmtest, a través de File → Open Script se puede seleccionar el script para la creación de las tablas
en MySQL, C:\java\jbpm\database\jbpm.jpdl.mysql.sql.
Con la ejecución de este script, se habrá finalizado la instalación de jBPM con MySQL.
Con esto se debería haber creado un proyecto de ejemplo que tiene una definición de un proceso
simple en el archivo processdefinition.xml del paquete simple de la carpeta src/main/jpdl. Si el
paquete simple estuviese vacío, se pueden recuperar los archivos que se encuentran en la carpeta
C:\java\jbpm\examples\src\test\resources\simple y dejarlos en el paquete simple.
5 de 22
Manual de introducción a JBoss jBPM
Si se hace doble clic sobre el archivo processdefinition.xml se abrirá el jBPM Graphical Process
Designer con la descripción gráfica del proceso de ejemplo.
El siguiente paso a dar es desplegar esta definición de proceso en el servidor jBPM para poder
trabajar con ella. Para ello hay que ir a la pestaña deployment y revisar los datos en el apartado
Deployment Server Settings para que coincidan con los del servidor de aplicaciones, que deberá
estar arrancado. Pulsando en Deploy Process Archive se realizará el despliegue, se puede
comprobar verificando que esta definición se ha guardado en la tabla
JBPM_PROCESSDEFINITION de la base de datos.
6 de 22
Manual de introducción a JBoss jBPM
3.1 Nodos
Definen los pasos que que se tienen que seguir durante la ejecución de un proceso, y pueden ser de
los siguientes tipos:
− Nodos de inicio y fin
− Nodo de tarea
− Nodo de estado
− Nodo de decisión
− Nodos fork y join
− Nodos node
Los nodos de fin delimitan el final de la ejecución de un proceso. Un proceso puede tener varios
nodos de fin, a los que puede llegar en función de las condiciones de ejecución del proceso. Al
llegar a cualquiera de ellos finaliza la ejecución de este flujo.
Si es el propio proceso quien debe tomar la decisión se debe usar un nodo de decisión. Los criterios
de la decisión se pueden especificar:
7 de 22
Manual de introducción a JBoss jBPM
Si es una entidad externa quien debe tomar la decisión se deberían usar varias transiciones que
salgan de un estado de espera. A este estado de espera se le indicará cual es la transición a seguir
cuando se relance la ejecución del proceso.
3.2 Transiciones
Indican el camino a seguir desde un nodo a otro dentro del proceso. Pueden tener condiciones de
guarda las restringen.
3.3 Acciones
Una acción se ejecuta cuando ocurren determinados eventos en la ejecución de un proceso.
Principalmente cuando se entra o se sale de un nodo y cuando se toma una transición. Estas
acciones no tienen influencia sobre el flujo de control del proceso.
8 de 22
Manual de introducción a JBoss jBPM
En primer lugar hay que ir a la definición de dicho proceso, que se encuentra en el archivo
processdefinition.xml del paquete simple del directorio src/main/jpdl. Al hacer doble clic sobre este
archivo se puede ver este proceso modelado de forma gráfica en el jBPM Graphical Process
Designer:
Las dos transiciones tienen asociadas una acción definida a través del manejador
MessageActionHandler:
package com.sample.action;
import org.jbpm.graph.def.ActionHandler;
import org.jbpm.graph.exe.ExecutionContext;
/**
* The message member gets its value from the configuration in the
9 de 22
Manual de introducción a JBoss jBPM
/**
* A message process variable is assigned the value of the message
* member. The process variable is created if it doesn't exist yet.
*/
public void execute(ExecutionContext context) throws Exception {
context.getContextInstance().setVariable("message", message);
}
}
Esta acción guarda en el contexto de la instancia de proceso la variable 'message', cuyo valor está
definido dentro de las propiedades de la acción.
import junit.framework.TestCase;
import org.jbpm.graph.def.ProcessDefinition;
import org.jbpm.graph.exe.ProcessInstance;
// Move the process instance from its start state to the first state.
// The configured action should execute and the appropriate message
// should appear in the message process variable.
instance.signal();
assertEquals(
"Instance is in first state",
instance.getRootToken().getNode().getName(),
"first");
assertEquals(
10 de 22
Manual de introducción a JBoss jBPM
// Move the process instance to the end state. The configured action
// should execute again. The message variable contains a new value.
instance.signal();
assertEquals(
"Instance is in end state",
instance.getRootToken().getNode().getName(),
"end");
assertTrue("Instance has ended", instance.hasEnded());
assertEquals(
"Message variable is changed",
instance.getContextInstance().getVariable("message"),
"About to finish!");
}
}
Lo primero que hace este método de prueba es leer la definición del proceso del archivo
simple/processdefinition.xml. A continuación crea un nueva instancia del proceso simple y
después manda una señal a la instancia creada para que pase al primer estado. Por último, se envía
otra señal a la instancia para que vaya al estado final y termine la ejecución del proceso.
En este ejemplo se ha visto cómo crear instancias de un proceso a partir de un archivo de definición
de proceso, que puede ser creado de forma gráfica. También se ha visto cómo se realiza la ejecución
de un proceso.
11 de 22
Manual de introducción a JBoss jBPM
5. Persistencia de procesos
En el apartado anterior se ha visto cómo ir recorriendo el flujo de ejecución de una instancia de un
proceso de forma local. El estado de esta ejecución se guarda en memoria y cuando esta termina no
queda rastro de ella.
Sin embargo, lo normal es que un proceso no se ejecute de esta forma, sino que haya ocasiones en
que se mantenga a la espera de que ocurra algún evento o de que algún actor realice una tarea antes
de reanudar la ejecución. Por ello, toda la información relativa a la ejecución del proceso debe
persistir en una base de datos de la que poder recuperar cuando sea preciso.
Para la persistencia en bases de datos, jBPM utiliza Hibernate. Por tanto, lo primero que hay que
hacer es realizar la configuración adecuada para la base de datos en el archivo hibernate.config.xml.
Dentro del proyecto que hemos creado, en la carpeta src/main/config se pueden encontrar varios
ejemplos de configuración para las distintas bases de datos soportadas. Hay que sustituir el
contenido del archivo hibernate.config.xml por el de hibernate.config.mysql.xml y hacer un cambio
para que no se vuelva a crear el esquema de la base de datos cada vez que se cargue la
configuración, que va a ser comentar la línea:
<property name="hibernate.hbm2ddl.auto">create</property>
También hay que añadir la librería del conector de MySQL que contiene el driver JDBC a la base de
datos.
Una vez hecho esto, se va a ver cómo se maneja la persistencia en jBPM. Lo primero es cargar la
configuración de jBPM, que se guarda en el archivo jbpm.cfg.xml, de la siguiente manera:
// Se carga la configuración de jBPM
Una vez creado este contexto, se pueden realizar operaciones de persistencia. Cuando se hayan
finalizado estas operaciones, se debe cerrar el contexto:
// Se cierra el contexto jBPM
jbpmContext.close();
12 de 22
Manual de introducción a JBoss jBPM
ProcessDefinition processDefinition =
graphSession.findLatestProcessDefinition("simple");
// Se crea una nueva instancia del proceso simple
List processInstances =
graphSession.findProcessInstances(processDefinition.getId());
for (Object object : processInstances) {
processInstance = (ProcessInstance)object;
Ahora se puede revisar la base de datos y comprobar la creación de esta instancia en la tabla
JBPM_PROCESSINSTANCE. También se puede ver en la tabla JBPM_TOKEN el token de
ejecucion de esta instancia. En el campo NODE de esta tabla se indica en que nodo del flujo se
encuentra la ejecución de este proceso.
De esta manera, se ha creado una instancia del proceso simple que está preparada para su ejecución.
Para ello, un usuario debería recuperar esta instancia del contexto de la siguiente forma:
// Se carga la configuración de jBPM
ProcessDefinition processDefinition =
graphSession.findLatestProcessDefinition("simple");
13 de 22
Manual de introducción a JBoss jBPM
List processInstances =
graphSession.findProcessInstances(processDefinition.getId());
for (Object object : processInstances) {
ProcessInstance processInstance = (ProcessInstance)object;
if(!processInstance.hasEnded()) {
System.out.println(
"Se va a enviar una señal a la instancia: "
+ processInstance.getId());
// Se arranca la ejecución de esta instancia
processInstance.signal();
System.out.println(
"Se ha enviado una señal a la instancia: "
+ processInstance.getId());
} else {
System.out.println(
"Ya ha terminado la instancia: "
+ processInstance.getId());
}
}
Con esto se ha visto cómo usar la persistencia de jBPM para crear una instancia de un proceso y
posteriormente recuperar esta instancia y continuar con su ejecución.
14 de 22
Manual de introducción a JBoss jBPM
6. Asignación de tareas
A continuación se va a exponer cómo crear tareas en jBPM y asignar qué actor o actores las deben
realizar. Esto permite a los actores responsables de su realización recoger las tareas pendientes que
existan en un determinado momento para completar su ejecución.
En primer lugar vamos a crear una definición de proceso llamada tarea formada por un nodo inicial,
un nodo de tarea y un nodo final:
Como ya se ha mencionado anteriormente, un nodo de tarea representa una o varias tareas que
deben ser ejecutadas por una persona. Cuando la ejecución del proceso llega a un nodo de tarea, se
crea una instancia de una tarea (task) en la lista de los miembros del workflow. El nodo se quedará
en estado de espera hasta que el usuario informe de la realización de la tarea.
Para crear una tarea en un nodo de tarea, vamos a las propiedades de este nodo. En la tabla de tareas
pulsamos el botón derecho del ratón y seleccionamos New Task. Le damos nombre a esta tarea, en
este caso algoquehacer y descripción si queremos. En el apartado Assignment, vemos que hay
varias formas de asignar un tarea:
− Pooled Actor: Se le indica una secuencia de actorId separados por comas. Esta tarea al ser
creada no es asignada a la lista de ningún actor. Un actor la debe recuperar de la lista de
tareas pendientes para el pool de actores y asignarsela para que forme parte de su lista de
tareas.
− Swimlane: Un swimlane o carril sirve para definir una asignación que es la misma para
varias tareas de un proceso.
15 de 22
Manual de introducción a JBoss jBPM
identidad de jBPM. Permite realizar asignaciones en función del usuario, grupo o rol.
− Handler: Se le indica una clase manejadora, que será la que realice la asignación de la tarea.
Para mantener el ejemplo sencillo vamos a realizar la asignación de la tarea a un actor, al que vamos
a llamar user1:
Después de desplegar este proceso en el servidor, vamos a realizar una prueba en dos pasos. En el
primer paso vamos a crear una instancia de este proceso tarea y a iniciar su ejecución. Esto es algo
que ya hemos visto:
// Se carga la configuración de jBPM
ProcessDefinition processDefinition =
graphSession.findLatestProcessDefinition("tarea");
// Se crea una nueva instancia del proceso simple
processInstance.signal();
16 de 22
Manual de introducción a JBoss jBPM
jbpmContext.close();
taskInstance.end();
}
jbpmContext.close();
Se ha visto como asignar una tarea a un actor y de como recuperar las tareas pendientes de un actor
en un proceso posterior para llevar a cabo su ejecución.
17 de 22
Manual de introducción a JBoss jBPM
− Añadiendo condiciones a las transiciones o beanshell scripts que devuelven un boolean. Los
nodos recorreran sus transiciones examinando las condiciones hasta encontrar la primera
transición que cumpla las condiciones.
A continuación se va a crear como ejemplo un proceso que contiene un nodo de decisión que utiliza
una subclase de DecissionHandler para conocer la transición a seguir.
Este proceso empieza en un nodo de inicio del que se sale mediante la transición comenzar. Esta
transición tiene una acción crearvalor manejada por la clase ValorAction, que se encarga de
introducir en el contexto de ejecución una variable valor:
public class ValorAction implements ActionHandler {
public String valor;
@Override
public void execute(ExecutionContext executionContext) throws Exception {
executionContext.getContextInstance().setVariable("valor", valor);
}
}
18 de 22
Manual de introducción a JBoss jBPM
A continuación se llega a un nodo de decision manejado por una clase Decisor, que comprueba si en
el contexto de ejecución existe una variable valor con un valor asignado. Si existe esta variable se
abandona el nodo por la transición terminar1 y si no, por la transición terminar2:
public class Decisor implements DecisionHandler {
public Decisor(String info) {
super();
}
@Override
public String decide(ExecutionContext executionContext) throws Exception {
String valor =
(String)executionContext.getContextInstance().getVariable("valor");
if(valor != null) {
return "terminar1";
} else {
return "terminar2";
}
}
}
Por último, al llegar a cualquiera de los nodos finales se lanza una acción que muestra en que nodo
está terminando la ejecución del flujo, manejada por la clase MostrarMensajeAction:
public class MostrarMensajeAction implements ActionHandler {
public MostrarMensajeAction(String info) {
super();
}
@Override
public void execute(ExecutionContext executionContext) throws Exception {
System.out.println(
"Se sale del flujo por el nodo: "
+ executionContext.getNode().getName());
}
}
19 de 22
Manual de introducción a JBoss jBPM
Se puede ejecutar este proceso mediante una clase de test como esta:
public void testSimpleProcess() throws Exception {
// Extraer la definicion de proceso del archivo processdefinition.xml.
ProcessDefinition processDefinition =
ProcessDefinition.parseXmlResource("decision/processdefinition.xml");
assertNotNull("La definicion debe no ser nula", processDefinition);
// Create an instance of the process definition.
instance.signal();
}
20 de 22
Manual de introducción a JBoss jBPM
Conclusiones
El presente manual está siendo realizado durante el aprendizaje de la herramienta jBPM. No es más
que la compilación de los pequeños artículos que estoy escribiendo en mi blog
(http://tratandodeentenderlo.blogspot.com). Estoy tratando de plasmar en ellos la experiencia
adquirida durante el aprendizaje de jBPM, aunque mi intención es escribir sobre otros temas de
interés, también relacionados con el mundo Java.
Aunque este manual contiene suficiente información para ayudar a los usuarios inexpertos en su
introducción a jBPM, es mi intención seguir ampliándolo. Para ello agradecería que todo aquel
lector que tenga alguna duda o sugerencia sobre el material presentado en este documento me la
hiciese llegar por correo electrónico (jorge.roldan@gmail.com) o como comentarios a través de mi
blog.
21 de 22
Manual de introducción a JBoss jBPM
Referencias
− jBPM jPDL User Guide 3.2.3
− Bussines Process Management with Jboss jBPM (Matt Cumberlidge, Packt Publishing)
22 de 22