User Tasks and Forms with JSF and CDI

691 views
Skip to first unread message

Harald Wellmann

unread,
Sep 18, 2013, 4:42:06 AM9/18/13
to camunda-...@googlegroups.com
I can't figure out how to start and finish a user task with a custom form.

My context is JBoss, JSF, CDI, and all the forms are hand-crafted JSF
forms of my application, I'm _not_ talking about Camunda task list.

Scenario:

1) start.jsf

Click button to start process instance, redirect to userTask.jsf

2) userTask.jsf

Form with fields to set some process variables, click button to complete task.



Things I don't understand from looking at docs and examples:

- I can use a @StartProcess annotation on the action method for
start.jsf, but then how do I get hold of the processInstanceId which
somehow needs to be passed to the userTask.jsf?

- Do I need to start the user task explicitly, and if so, how? Should I use

#{businessProcess.startTask(taskId, true)}

or

#{businessProcess.resumeProcessById(processId)}

in userTask.jsf or maybe both?

The User Task is the first task in my process, so I'd expect the task
to be started automatically after firing the start event - true or
false?

- How does the Form Key in the BPMN model enter the picture? Or is it
required for the Camunda Tasklist only? What's the difference between
"embedded:app:myForm", "app:myForm" and "myForm"?

Any help or pointers to working examples much appreciated!

Best regards,
Harald

Bernd Rücker (camunda)

unread,
Sep 18, 2013, 11:54:46 AM9/18/13
to Harald Wellmann, camunda-...@googlegroups.com
Hi Harald.

Just today I started to migrate the JSF Task Form Guide - it is available
as temporary version here:
http://stage.docs.camunda.org/real-life/how-tos/#process-engine-jsf-task-f
orms. Does that help?

A working example uses JSF task form can be found here:
https://github.com/camunda/camunda-bpm-examples/tree/master/bestellprozess
-java-ee6.

Cheers
Bernd

-----Urspr�ngliche Nachricht-----
Von: camunda-...@googlegroups.com
[mailto:camunda-...@googlegroups.com] Im Auftrag von Harald Wellmann
Gesendet: Mittwoch, 18. September 2013 10:42
An: camunda-...@googlegroups.com
Betreff: User Tasks and Forms with JSF and CDI
--
You received this message because you are subscribed to the Google Groups
"camunda BPM users & process application developers" group.
To unsubscribe from this group and stop receiving emails from it, send an
email to camunda-bpm-us...@googlegroups.com.
To post to this group, send email to camunda-...@googlegroups.com.

Nico Rehwaldt

unread,
Sep 19, 2013, 4:22:22 AM9/19/13
to camunda-...@googlegroups.com
Hi Harald, 

please have a look at the quickstart Bernd pointed you at and see if it solves some of your issues.

To start a process you can use the processEngine.getRuntimeService().startProcessInstanceBy...() the resulting ProcessInstance will have the correct instance id. 

In the task list, we use query parameters to pass the task id to a task form. You are however open to follow other approaches. 

In general, to work with tasks you can use the helper org.camunda.bpm.engine.cdi.jsf.TaskForm. It allowy you to start and complete tasks.

Hope this helps!

Cheers, 

Nico

Harald Wellmann

unread,
Sep 19, 2013, 11:53:44 AM9/19/13
to camunda-...@googlegroups.com
Hi Bernd,

thanks for the JSF Task Form Guide, that answers most of my JSF
related questions, but I'm still unsure about the CDI part.

I've been looking at bestellprozess-java-ee6 demo before, but I don't
find it very helpful. I can't relate the process model to what I see
in the UI; when I click a button, I don't see what I expect, and I
don't know if my expectation is wrong, or my setup or the demo itself.
Besides, the @StartProcess and @CompleteTask annotations I was
interested in don't occur in this demo.

Just to give you an idea how things that may seem trivial to you are a
massive obstacle to new users, let's look at this expression:

#{camunda.taskForm.startTask(taskId, callbackUrl)}

1) I expect to find a bean with EL name "camunda".

Wrong! There is no such bean. The TaskForm bean is named
"camunda.taskForm". I didn't know that EL names are allowed to contain
dots, and I would have expected an EL exception.

2) I expect startTask() to start a task.

Wrong. By enabling the global CDI process event listener and logging
all events, I can see that the user task is started when the
predecessor task is completed. TaskForm.startTask() has no Javadoc, it
delegates to BusinessProcess.startTask(), and somewhere in the Javadoc
of that class, I see "@return the resumed task", which appears to be
more accurate: An executing task is resumed by attaching the current
conversation to it. If the task weren't started, we couldn't attach to
it (and we wouldn't even have a taskId, I presume).

3) I expect taskId to be the Task ID.

Wrong!!! The User Task has an id attribute (<userTask
id="kunde-umberaten" ...>), corresponding to the ID property in the
Modeller UI. So anyone would expect Task.getId() to return this ID,
and the same goes for all sorts of TaskFoo.doSomethingWithId() methods
(e.g. TaskQuery.taskId()). It took me several hours of debugging to
find out that the XML "id" correspond to "key" on the Java API, and
that "id" on the Java API is an autogenerated UUID. Same problem with
Process ID vs. Key.

Now this is utterly and fatally confusing. I don't think I want to
know how this name clash came to be, and I fear it's too late to be
changed, but then please do include a big red letter warning in the
User Guide to spare other newbies discomfort and frustration....

4) I'm not sure what a callbackUrl is supposed to be in this context.

If you mean a redirect URL, then why not call it "redirectUrl"? But in
JSF, wouldn't it be more natural to use an outcome here, to hook into
JSF navigation?

In my own demo, I'd been trying hard to "start" a task from my
controller bean by businessProcess.startTask("MyUserTask"), until I
realized that I really needed an interface like startTaskByKey() which
does not exist.

So I replaced BusinessProcess by ExtendedBusinessProcess, adding the
missing API:

public class ExtendedBusinessProcess {

@Inject
private BusinessProcess process;

@Inject
private TaskService taskService;

public void attachToTaskByDefinitionKey(String taskName) {

String instanceId = process.getProcessInstanceId();
Task task =
taskService.createTaskQuery().processInstanceId(instanceId).taskDefinitionKey(taskName).singleResult();
process.setTask(task);
process.startTask(task.getId());
}
}



My demo is working now, but I'm still unsure in which layer to
start/resume or complete user tasks:

- in the JSF view
- in the (JSF) controller bean
- in the service bean/EJB

You seem to favour the JSF view, I currently do it in the controller,
and I feel it really should be in the service bean. Imagine an
application with alternative UIs, e.g. a JSF web UI and an Eclipse RCP
UI. All process logic is business logic and should be located in the
service layer and not in the UI layer(s), or what do you think?

Cheers,
Harald

Bernd Rücker (camunda)

unread,
Sep 19, 2013, 12:20:32 PM9/19/13
to Harald Wellmann, camunda-...@googlegroups.com

Hi Harald.


Just a quick answer as I am in a hurry. By the way: Did you already think of maybe attending an training? I think a couple of things could get clearer there (see www.camunda.com/fox/training/camunda-bpm-basics/).

 

However - quick answers inline - hope that helps.

 

-----Ursprüngliche Nachricht-----


Von: camunda-...@googlegroups.com [mailto:camunda-...@googlegroups.com] Im Auftrag von Harald Wellmann

Gesendet: Donnerstag, 19. September 2013 17:54
An: camunda-...@googlegroups.com
Betreff: Fwd: [camunda-bpm-users] AW: User Tasks and Forms with JSF and CDI

 

Hi Bernd,

 

thanks for the JSF Task Form Guide, that answers most of my JSF related questions, but I'm still unsure about the CDI part.

 

I've been looking at bestellprozess-java-ee6 demo before, but I don't find it very helpful. I can't relate the process model to what I see in the UI; when I click a button, I don't see what I expect, and I don't know if my expectation is wrong, or my setup or the demo itself.

Besides, the @StartProcess and @CompleteTask annotations I was interested in don't occur in this demo.

 

I actually think it is more understandable code not using these annotations but the CDI beans directly.

 

Just to give you an idea how things that may seem trivial to you are a massive obstacle to new users, let's look at this expression:

 

#{camunda.taskForm.startTask(taskId, callbackUrl)}

 

1) I expect to find a bean with EL name "camunda".

 

Wrong! There is no such bean. The TaskForm bean is named "camunda.taskForm". I didn't know that EL names are allowed to contain dots, and I would have expected an EL exception.

 

Now you know :-)

 

2) I expect startTask() to start a task.

 

Wrong. By enabling the global CDI process event listener and logging all events, I can see that the user task is started when the predecessor task is completed. TaskForm.startTask() has no Javadoc, it delegates to BusinessProcess.startTask(), and somewhere in the Javadoc of that class, I see "@return the resumed task", which appears to be more accurate: An executing task is resumed by attaching the current conversation to it. If the task weren't started, we couldn't attach to it (and we wouldn't even have a taskId, I presume).

 

startTask starts a conversation and binds the task instance to it (to read/change process variables in that conversation - maybe in a wizzard with multiple pages) before the task is completed and this changes are written to the process engine. See http://stage.docs.camunda.org/real-life/how-to/#user-interface-jsf-task-forms-how-does-this-work

 

3) I expect taskId to be the Task ID.

 

Wrong!!! The User Task has an id attribute (<userTask id="kunde-umberaten" ...>), corresponding to the ID property in the Modeller UI. So anyone would expect Task.getId() to return this ID, and the same goes for all sorts of TaskFoo.doSomethingWithId() methods (e.g. TaskQuery.taskId()). It took me several hours of debugging to find out that the XML "id" correspond to "key" on the Java API, and that "id" on the Java API is an autogenerated UUID. Same problem with Process ID vs. Key.

 

Now this is utterly and fatally confusing. I don't think I want to know how this name clash came to be, and I fear it's too late to be changed, but then please do include a big red letter warning in the User Guide to spare other newbies discomfort and frustration....

 

the id in the BPMN XML is the "task key". the task id is the primary key of the task instance.

 

4) I'm not sure what a callbackUrl is supposed to be in this context.

 

If you mean a redirect URL, then why not call it "redirectUrl"? But in JSF, wouldn't it be more natural to use an outcome here, to hook into JSF navigation?

 

It simply redirects - true. Maybe redirectUrl might have been better.

 

In my own demo, I'd been trying hard to "start" a task from my controller bean by businessProcess.startTask("MyUserTask"), until I realized that I really needed an interface like startTaskByKey() which does not exist.

 

So I replaced BusinessProcess by ExtendedBusinessProcess, adding the missing API:

 

public class ExtendedBusinessProcess {

 

    @Inject

    private BusinessProcess process;

 

    @Inject

    private TaskService taskService;

 

    public void attachToTaskByDefinitionKey(String taskName) {

 

        String instanceId = process.getProcessInstanceId();

        Task task =

taskService.createTaskQuery().processInstanceId(instanceId).taskDefinitionKey(taskName).singleResult();

        process.setTask(task);

        process.startTask(task.getId());

    }

}

 

 

 

My demo is working now, but I'm still unsure in which layer to start/resume or complete user tasks:

 

- in the JSF view

- in the (JSF) controller bean

- in the service bean/EJB

 

You seem to favour the JSF view, I currently do it in the controller, and I feel it really should be in the service bean. Imagine an application with alternative UIs, e.g. a JSF web UI and an Eclipse RCP UI. All process logic is business logic and should be located in the service layer and not in the UI layer(s), or what do you think?

 

Controller is fine from my feeling. The view is more ashortcut to not be forced to have any controller for simple forms. If you have a controller - best do it there.


If you move logic to a service bean I would not use BusinessProcess - as I see conversations part of the UI - not the Service/Business Logic Layer.

 

Cheers,

Daniel Meyer

unread,
Sep 19, 2013, 12:49:47 PM9/19/13
to Harald Wellmann, camunda-...@googlegroups.com

Hi Harald,

 

thanks for taking the time and pointing out where you had trouble understanding how the CDI / JSF integration works. This kind of feedback can really help us improving things.

 

Cheers,

Daniel Meyer

Project Lead

www.camunda.org/community/team.html

Reply all
Reply to author
Forward
0 new messages