# Getting \*\*defined\*\* process user tasks and task attributes

**URL:** <https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494>\
**Category:** Flowable Engine\
**Created:** [September 10, 2019, 9:59am UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494 "2019-09-10T09:59:09Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![DarkStar1](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/darkstar1/32/394_2.png) [@DarkStar1](https://forum.flowable.org/u/DarkStar1)\
**Post date:** [September 10, 2019, 9:59am UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/1 "2019-09-10T09:59:09Z")

</div>

I was wondering if it is possible to retrieve the user tasks defined in a deployed process (not and instantiated one).  
Currently, the only solution I can think of is to:

- Add a category to user tasks
- Retrieve the process definition model (extremely huge object)
- Filter objects in the `mainProcess.flowElements` array for objects that have a category matching the required category.

It’s all to aid in dynamically creating a menu of possible user tasks defined for a process.

The other question is that I notice that the flow elements has an **attributes** property but is always empty in my instances. I’ve looked in the modeler and I’ve searched in the documents but don’t know the why of this property or how it can be populated.

---

<div class="post-metadata">

**Author:** ![joram](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/joram/32/26_2.png) [@joram](https://forum.flowable.org/u/joram)\
**Post date:** [September 10, 2019, 11:40am UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/2 "2019-09-10T11:40:47Z")

</div>

> [@DarkStar1](#):
>
> It’s all to aid in dynamically creating a menu of possible user tasks defined for a process.

The approach you describe sounds like the way to go: you need to mark the user tasks somehow, if you can’t show them all on the screen. Note that the BpmnModel is always cached in-memory and that the filtering also will happen in-memory. Even if it’s a big process definition, this is very fast.

> [@DarkStar1](#):
>
> The other question is that I notice that the flow elements has an **attributes** property

Not sure which one you’re referring to. Do you have an example?

---

<div class="post-metadata">

**Author:** ![DarkStar1](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/darkstar1/32/394_2.png) [@DarkStar1](https://forum.flowable.org/u/DarkStar1)\
**Post date:** [September 10, 2019, 1:23pm UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/3 "2019-09-10T13:23:17Z")

</div>

> [@joram](#):
>
> Not sure which one you’re referring to. Do you have an example?

```auto
{
....,
 "flowElements": [
            {
                "id": "centralStartEvent",
                "xmlRowNumber": 5,
                "xmlColumnNumber": 5,
                "extensionElements": {},
                "attributes": {}, <--------------- This one
                "name": null,
                "documentation": null,
                "executionListeners": [],
                "asynchronous": false,
                "notExclusive": false,
                "incomingFlows": [],
                "outgoingFlows": [
                    { ... }
                ],
                "eventDefinitions": [],
                "initiator": "initiator",
                "formKey": null,
                "validateFormFields": null,
                "formProperties": [],
                "interrupting": true,
                "exclusive": true
            },
....
}

```

---

<div class="post-metadata">

**Author:** ![joram](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/joram/32/26_2.png) [@joram](https://forum.flowable.org/u/joram)\
**Post date:** [September 13, 2019, 7:07am UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/4 "2019-09-13T07:07:57Z")

</div>

Looking at the code, they seem to be extension attributes. Meaning, if you have custom attributes (different xml namespace) in your xml, they’ll end up there. But there’s no possibility to set these in the Modeler, only programmatically or in XML.

---

<div class="post-metadata">

**Author:** ![AdrienAllemand](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/adrienallemand/32/1830_2.png) [@AdrienAllemand](https://forum.flowable.org/u/AdrienAllemand)\
**Post date:** [June 11, 2020, 2:35pm UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/5 "2020-06-11T14:35:14Z")

</div>

Do you have a simple way to pass a custom attribute from XML ? I mean write something like  
`<humanTask id="HumanTask_0d65dvu" name="define schedule" avalia:apiKey="DefineScheduleApiKey"/> `  
in the cmmn so it is retrievable from

```auto
 "attributes": {}, <--------------- This one

```

---

<div class="post-metadata">

**Author:** ![joram](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/joram/32/26_2.png) [@joram](https://forum.flowable.org/u/joram)\
**Post date:** [June 11, 2020, 6:00pm UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/6 "2020-06-11T18:00:51Z")

</div>

Not on that level, but only on the extensionElements which is possible on each element.  
Once there, it can be retrieved in any custom behavior class.

---

<div class="post-metadata">

**Author:** ![DarkStar1](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/darkstar1/32/394_2.png) [@DarkStar1](https://forum.flowable.org/u/DarkStar1)\
**Post date:** [June 12, 2020, 7:13am UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/7 "2020-06-12T07:13:31Z")

</div>

> Do you have a simple way to pass a custom attribute from XML ? I mean write something like  
> `<humanTask id="HumanTask_0d65dvu" name="define schedule" avalia:apiKey="DefineScheduleApiKey"/> `  
> in the cmmn so it is retrievable from

I know that for workflow BPMN.xml consumed by the process engine, you have something like this for example:

```
<userTask id="a3" name="Some Taske" flowable:formFieldValidation="true" flowable:formKey="a3"
                  flowable:candidateGroups="GROUP_someGroup"
                  flowable:listColumns='[{"type":"text","key":"applicationId","sortable":true}"}]'>

```

with **flowable:listColumns** being a custome attribute; but be aware that if you were to import the BPMN.xml into the modeler, the Flowable modeler will literally strip away any custom unrecognised attributes.

---

<div class="post-metadata">

**Author:** ![AdrienAllemand](https://yyz1.discourse-cdn.com/flex035/user_avatar/forum.flowable.org/adrienallemand/32/1830_2.png) [@AdrienAllemand](https://forum.flowable.org/u/AdrienAllemand)\
**Post date:** [June 12, 2020, 7:28am UTC](https://forum.flowable.org/t/getting-defined-process-user-tasks-and-task-attributes/4494/8 "2020-06-12T07:28:04Z")

</div>

Thank you for your answers ! I managed to access my custom attribute as an extensionElement thought it’s a bit a pain to extract afterward :  
My CMMN :

```auto
        <humanTask id="HumanTask_06epgwk" name="write proposal">
          <extensionElements>
            <avalia:taskType>APITask</avalia:taskType>
            <avalia:apiKey>WriteProposalKey</avalia:formKey>
          </extensionElements>
        </humanTask>

```

My TaskCreationInterceptor uses reflexion to extract the task type’s class and instantiate it in the correct way (AbstractTask is a “mirror” of a Flowable Task stored on our side, containing logic and data to establish a bridge with the existing system)

```auto
    public void notify(CreateHumanTaskAfterContext delegateTask) {

        AbstractTask abstractTask;
        // extracting the task type
        if(delegateTask.getHumanTask().getExtensionElements().containsKey("taskType") &&
            delegateTask.getHumanTask().getExtensionElements().get("taskType").size() == 1) {
            String taskType = delegateTask
                    .getHumanTask()
                    .getExtensionElements()
                    .get("taskType")
                    .get(0)
                    .getElementText();

            try {
                abstractTask = (AbstractTask) Class.forName(classPath + taskType).getConstructor().newInstance();
            } catch(ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
                // handle class not found
                abstractTask = new DefaultTask();
            }
        }
}

```
