我想在某个地方定义脚本源码,并在Activiti5.12或更高版本中从多个ScriptTaskListeners中重用它。
假设我在前面的groovy脚本任务中定义了一个包含groovy源代码的processVariable taskScript:
execution.setVariable("taskScript",
'def log = org.slf4j.LoggerFactory.getLogger("my.Logger");log.info("works")')现在,我希望通过将代码作为activiti:expression传递,让org.activiti.engine.impl.bpmn.listener.ScriptTaskListener使用该代码
<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)在Activiti将表达式${taskScript}传递给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中有没有不同的方式重用脚本代码?
发布于 2020-06-19 23:05:31
关键是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>evaluate调用必须与try..catch嵌套,因为侦听器中的异常会阻止事件被处理,因此您的进程将永久停止。
https://stackoverflow.com/questions/62466678
复制相似问题