首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Activiti:使用activiti:expression定义可重用的ScriptTaskListener脚本

Activiti:使用activiti:expression定义可重用的ScriptTaskListener脚本
EN

Stack Overflow用户
提问于 2020-06-19 16:52:27
回答 1查看 96关注 0票数 0

我想在某个地方定义脚本源码,并在Activiti5.12或更高版本中从多个ScriptTaskListeners中重用它。

假设我在前面的groovy脚本任务中定义了一个包含groovy源代码的processVariable taskScript

代码语言:javascript
复制
execution.setVariable("taskScript", 
    'def log = org.slf4j.LoggerFactory.getLogger("my.Logger");log.info("works")')

现在,我希望通过将代码作为activiti:expression传递,让org.activiti.engine.impl.bpmn.listener.ScriptTaskListener使用该代码

代码语言:javascript
复制
<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>

我得到的异常如下:

代码语言:javascript
复制
javax.script.ScriptException: groovy.lang.MissingMethodException: 
No signature of method: org.codehaus.groovy.jsr223.GroovyScriptEngineImpl.$() 
is applicable for argument types: (Script657$_run_closure1)

在Activiti将表达式${taskScript}传递给ScriptTaskListener script属性之前,似乎不会对其求值,而是groovy引擎尝试将${taskScript}作为groovy脚本进行求值。

但是,这可以很好地工作:

代码语言:javascript
复制
<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中有没有不同的方式重用脚本代码?

EN

回答 1

Stack Overflow用户

发布于 2020-06-19 23:05:31

关键是ScriptTaskListener如何计算表达式。它不计算UEL表达式并将其传递给Groovy,而是只让Groovy引擎计算该表达式。我们需要传递一个groovy脚本作为表达式,而不是${taskScript}的UEL表达式。

事实证明,这是可行的:

代码语言:javascript
复制
<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>

evaluate调用必须与try..catch嵌套,因为侦听器中的异常会阻止事件被处理,因此您的进程将永久停止。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62466678

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档