Activiti: используйте activiti: expression для определения многоразового скрипта ScriptTaskListener - PullRequest
0 голосов
/ 19 июня 2020

Я хочу где-то определить исходный код скрипта и повторно использовать его из нескольких 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 передаст его в свойство ScriptTaskListener script, скорее механизм groovy пытается оценить ${taskScript} как сценарий groovy.

Это, однако, работает нормально:

<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?

1 Ответ

0 голосов
/ 19 июня 2020

Ключ в том, как ScriptTaskListener оценивает выражение. Он не оценивает выражение UEL и передает его в Groovy, а позволяет вычислять выражение только механизму 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, потому что исключение в прослушивателе предотвращает обработку события, так что ваши процессы будут постоянно останавливаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...