cancel
Showing results for 
Search instead for 
Did you mean: 

JavaDelegates, custom nodes, configuration and use

msandoz
Champ in-the-making
Champ in-the-making
I read this:

Since the Java class instance is reused, the injection only happens once, when the serviceTask is called the first time. When the fields are altered by your code, the values won't be re-injected so you should treat them as immutable and don't make any changes to them.

I defined several custom designer nodes, and it seems they create bpml like:

    <serviceTask id="servicetask2" name="Excel" activiti:class="org.nexusbpm.activiti.ExcelNexusJavaDelegation">
      <extensionElements>
        <activiti:field name="skipHeader">
          <activiti:string>true</activiti:string>
        </activiti:field>
        <activiti:field name="columnLimit">
          <activiti:string>${'hello'}</activiti:string>
        </activiti:field>

if I have two such tasks, which I need to behave differently in the flow, does this mean I cannot create a custom node to do so? For example, my two service tasks (both of same class) might each need different column limits.

Also, I was concerned that even when I put a variable into the value in the properties tab, such as ${'hello'} - it still seems to render as a string instead of an expression. If it was an expression, I could change the value of the expression and it would make the first problem I am having easier.

Also, is there any way to configure these tasks (for example with spring) when they are instantiated? I may need complicated objects injected at create time. Right now, I am trying to wrap several of my spring beans in java delegate wrappers. These allow my to keep my code built in a separate module, and just adapt it to interface with activiti. If custom nodes in the editor could generate references to spring beans instead of classes, that would be very useful. Is it planned?

I see in the user guide where this is supported in the xml:

 <serviceTask id="serviceTask" activiti:delegateExpression="${delegateExpressionBean}" />

<serviceTask id="javaService"
             name="My Java Service Task"
             activiti:expression="#{printer.printMessage()}" />

sorry to put so many questions in one post - they are all related i think? Smiley Happy
3 REPLIES 3

msandoz
Champ in-the-making
Champ in-the-making
I've been testing the behavior on 5.8 over the weekend and there seem to be some interesting changes in the delegate behavior.

The delegates now do appear to be instance-specific and can be configured differently, even multiple times within a process.

They now also seem to handle expressions, which can be declared via member properties, and can be evaluated at execution time, even referring to spring variables.

This is very nice!

I was wondering though - I'd like the code I'm actually delegating to - the business logic - to be a spring bean, which is invoked by the delegate. What's the best way from the delegate to get to the engine to be able to resolve beans? I could pass the business logic spring bean in the expressions, but this seems to be counter-intuitive to a user. Is there some way to request an arbitrary bean from what I have available - the DelegateExecution - or should I use some other means?

Also, on the topic of the generation of the bpm20 xmls, it is strange that this code:

FieldExtensionsExport.java

      for (FieldExtension fieldExtension : fieldExtensionList) {
        if(fieldExtension.getFieldname() != null && fieldExtension.getFieldname().length() > 0 &&
                fieldExtension.getExpression() != null && fieldExtension.getExpression().length() > 0) {
         
          xtw.writeStartElement(ACTIVITI_EXTENSIONS_PREFIX, "field", ACTIVITI_EXTENSIONS_NAMESPACE);
          xtw.writeAttribute("name", fieldExtension.getFieldname());
          if (fieldExtension.getExpression().contains("${")) {
            xtw.writeStartElement(ACTIVITI_EXTENSIONS_PREFIX, "expression", ACTIVITI_EXTENSIONS_NAMESPACE);
          } else {
            xtw.writeStartElement(ACTIVITI_EXTENSIONS_PREFIX, "string", ACTIVITI_EXTENSIONS_NAMESPACE);
          }
          xtw.writeCharacters(fieldExtension.getExpression());
          xtw.writeEndElement();
          xtw.writeEndElement();
        }
      }

is not called from ServiceTaskExport, which has the rather less powerful:

    if (serviceTask.getResultVariableName() != null && serviceTask.getResultVariableName().length() > 0) {
      xtw.writeAttribute(ACTIVITI_EXTENSIONS_PREFIX, ACTIVITI_EXTENSIONS_NAMESPACE, "resultVariableName", serviceTask.getResultVariableName());
    }

The difference is that since the custom node editor always creates a servicetask, there is no way to generate variable expressions using the custom nodes. Would it be reasonable for me to add a Jira for an enhancement for this?

tiesebarrell
Champ in-the-making
Champ in-the-making
There might be a specific reason for that, but you should certainly file an issue so we can look into it. If you do, please reference this thread so we can lookup the details.

msandoz
Champ in-the-making
Champ in-the-making
ACT-1033 - ServiceTaskExport does not take advantage of expressions

for the export issues.

I will start a new thread on the other issue.