cancel
Showing results for 
Search instead for 
Did you mean: 

How to create a custom activity

sascha1
Champ in-the-making
Champ in-the-making
Hello,

is there any document or example how to create custom Activities?

I think i have to implement an ActivityBehavior.

First of all I would like to implement an Activity that is waiting for an JMSMessage. I began to implement a class that extends AbstractBpmnActivityBehavior and implements javax.jms.MessageListener at the moment if a message arrives simply leave() is called. The implementation should be improved later but now I need to know how to make Activiti use my custom Activity?  Can someone please sketch how to do this.

Sascha
18 REPLIES 18

jbarrez
Star Contributor
Star Contributor
Implement ActivityBehaviour (not JavaDelegate, since you want 'wait behavior'), implement whatever interface you need for catching the JMS listener, and probably registyer your bean with the queueu.

frederikherema1
Star Contributor
Star Contributor
You should also add your activity to the parsing-mechanism, so it can be instantiated by activiti.

@See BPMNParse

sascha1
Champ in-the-making
Champ in-the-making
Thank you both for your replies!

What do you mean with:

Implement ActivityBehaviour (not JavaDelegate, …
I am implementing AbstractBpmnActivityBehavior and of course JMS interface for catching a Message.

Do I really need to change the Activiti Parser (BPMNParse), do I really need to recompile Activiti-Engine isn't there any mechanism to plugin-in my implementation?

Sascha

frederikherema1
Star Contributor
Star Contributor
You can hook in a BPMNParser I guess, which alters the activityBehaviour in the ActivityImpl when for example, parsing a servicetask which has a special attribute on it:

void parseServiceTask(Element serviceTaskElement, ScopeImpl scope, ActivityImpl activity);

You can just plug the parseListener in in the config (search the forum, I've explained the process before here)

jbarrez
Star Contributor
Star Contributor
It depends on your use case. I assume you just want to do:

<serviceTask activiti:class="MyImplementation' …

Then it is enough to do what you do, no changes to the engine are required.

sascha1
Champ in-the-making
Champ in-the-making
Hello,

at least for now  ServiceTask seem to suffice. It works except that if I call leave(ActivityExecution execution) in my onMessage-implementation (implementation of javax.jms.MessageListener) i get a NullPointerException. At the moment I am creating a reference (instance-variable) to the ActivityExecution-Parameter of execute-Method and call leave with this reference as parameter.

In ExecutionEntity the method performOperation(AtomicOperation operation) looks like this:

public void performOperation(AtomicOperation executionOperation) {
    Context
      .getCommandContext()
      .performOperation(executionOperation, this);
  }

Context.getCommandContext() is null and this causes the NullPointerException.
Maybe I am in a wrong context or something like this. At the moment I did not start to further analyze the activiti-engine-code. Any ideas how to leave properly after receiving a message?

jbarrez
Star Contributor
Star Contributor
How do you call your class? Now that I think of it: you have to make sure you call it through the Activiti interfaces (ie runtimeService.signal) since otherwise you will indeed have exceptions because the context doesnt exist.

So you'll probably have to put your JMS listener 'in front of the process', and not being part of the process itself. So when you receive a JMS message, you will need to call runtimeService.signal() to continue the process.

sascha1
Champ in-the-making
Champ in-the-making
Hello,

I did have a similar idea.

I tried to call runtimeService.signal(executionID) inside the onMessage-implementation. But I don't know how to acquire the correct RuntimeService.

I tried this:

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

  RuntimeService runtimeService = processEngine.getRuntimeService();

  runtimeService.signal(this.executionID);

and overrode signal(…)-method of FlowNodeActivityBehavior with:

public void signal(ActivityExecution execution, String signalName,
   Object signalData) throws Exception {
  leave(execution);
}

But it seems to me that a new ProcessEngine is created and i get

org.activiti.engine.ActivitiException: this activity doesn't accept signals

though I had overriden signal-method of org.activiti.engine.impl.bpmn.behavior.FlowNodeActivityBehavior.

Edited:

I added my class like this


<serviceTask id="servicetask1" name="WaitOnEvent" activiti:class="de.uni_stuttgart.informatik.eventum.activiti.activities.JmsCatchMsgBehavior" />

onMessage correctly receives Messages.

sascha1
Champ in-the-making
Champ in-the-making
I observed that if I override the method

public void signal(ActivityExecution execution, String signalName, Object signalData) throws Exception;

of FlowNodeActivityBehavior my overriding implementation is never called. Always the implementation of FlowNodeActivityBehavior which only throws an ActivitiException("this activity doesn't accept signals") is called. This is maybe a bug.
Getting started

Tags


Find what you came for

We want to make your experience in Hyland Connect as valuable as possible, so we put together some helpful links.