Activiti: используйте activiti:expression для определения повторно используемого сценария ScriptTaskListener.

Я хочу где-то определить исходный код скрипта и повторно использовать его из нескольких ScriptTaskListeners в Activiti 5.12 или более поздней версии.

Предполагая, что я определил переменную процесса taskScript в предыдущей задаче скрипта groovy, которая содержит исходный код groovy:

execution.setVariable("taskScript", 
    'def log = org.slf4j.LoggerFactory.getLogger("my.Logger");log.info("works")')

Теперь я хочу, чтобы org.activiti.engine.impl.bpmn.listener.ScriptTaskListener использовал этот код, передав его как activiti:expression:

<activiti:taskListener event="complete" class="org.activiti.engine.impl.bpmn.listener.ScriptTaskListener" >
  <activiti:field name="script">
     <activiti:expression><![CDATA[${taskScript}]]></activiti:expression>
  </activiti:field>
  <activiti:field name="language" stringValue="groovy" />
</activiti:taskListener>

Я получаю исключение ниже:

javax.script.ScriptException: groovy.lang.MissingMethodException: 
No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.$() 
is applicable for argument types: (Script657$_run_closure1)

Похоже, что выражение ${taskScript} не оценивается до того, как Activiti передаст его свойству script ScriptTaskListener, а движок groovy пытается оценить ${taskScript} как groovy script.

Однако это отлично работает:

<activiti:taskListener event="complete" class="org.activiti.engine.impl.bpmn.listener.ScriptTaskListener" >
  <activiti:field name="script">
    <activiti:string>
      def log = org.slf4j.LoggerFactory.getLogger("my.Logger");
      log.info("works")
    </activiti:string>
  </activiti:field>
  <activiti:field name="language" stringValue="groovy" />
</activiti:taskListener>

Я очень смущен, почему я не могу этого сделать. Разве activiti:expression не следует всегда оценивать перед применением к activiti:field?

Есть ли другой способ повторного использования кода скрипта в ScriptTaskListeners?


person dschulten    schedule 19.06.2020    source источник
comment
Никогда не пользовался активити, но работает ли <activiti:field name="script"><activiti:string><activiti:expression><![CDATA[${taskScript}]]></activiti:expression></activiti:string></activiti:field>? А может <activiti:field name="script"><activiti:string><![CDATA[${taskScript}]]></activiti:string></activiti:field>? ????   -  person tim_yates    schedule 19.06.2020


Ответы (1)


Ключ в том, как ScriptTaskListener оценивает выражение. Он не оценивает выражение UEL и передает его в Groovy, а позволяет только механизму Groovy вычислить выражение. Нам нужно передать отличный скрипт как выражение вместо выражения ${taskScript} UEL.

Оказывается, это работает:

<activiti:expression><![CDATA[
try {
  evaluate(task.getVariable("taskScript"));
} catch (ex) {
  def log = org.slf4j.LoggerFactory.getLogger("my.Logger");
  log.warn("failed to invoke taskScript", ex)
}
]]>
</activiti:expression>

Вызов оценки должен быть вложенным в try..catch, потому что исключение в прослушивателе препятствует обработке события, так что ваши процессы будут постоянно остановлены.

person dschulten    schedule 19.06.2020