在使用开源 Camunda 流程引擎框架做二次开发,肯定会遇上报错,这是正常的事件。先不说Camunda ,就算用Spring、 FastJson等等框架都会遇上各种各样的报错,报错不要紧,解决就行了,做程序员不就是这样嘛。解决一个BUG,又产生另外2个BUG。
OK,现在回到报错上来。程序报错大多数情况下就这么几种:
-
空指针
-
未识别参数
-
数组越界
在本次的这个报错就属于未识别参数。既然知道了是什么原因,那再进一步乱想,是不是程序某个地方需要这个参数,而又在某个方法里校验的时候又找不到这个参数,所以就抛异常出错了。
为了验证猜想,来进一步跟踪代码! 报这个异常是在点完成任务的时候报的,那继续跟踪即可!
在跟踪代码之前猜想一下需要做什么事情:
-
完成当前任务
-
完成任务后,根据流程图判断此任务节点后面是否还有用户任务节点。如果有就产生下一个用户任务节点的任务;如果没有,就走到结束ab节点,更新流程结束
带着猜想下面来看看代码是怎么走的
这里的 completeTask方法 才是真正的做事。
protected void completeTask(TaskEntity task) {
// 添加操作日志
task.logUserOperation(UserOperationLogEntry.OPERATION_TYPE_COMPLETE);
// 开始真真的做完成任务的事
task.complete();
}
public void complete() {
if (TaskState.STATE_COMPLETED.equals(this.lifecycleState) // 任务状态判断
|| TaskListener.EVENTNAME_COMPLETE.equals(this.eventName)
|| TaskListener.EVENTNAME_DELETE.equals(this.eventName)) {
throw LOG.invokeTaskListenerException(new IllegalStateException("invalid task state"));
}
// if the task is associated with a case
// execution then call complete on the
// associated case execution. The case
// execution handles the completion of
// the task.
if (caseExecutionId != null) {
getCaseExecution().manualComplete();
return;
}
// in the other case:
// ensure the the Task is not suspended 继续判断
ensureTaskActive();
// trigger TaskListener.complete event
// 起一个事件监听
final boolean shouldDeleteTask = transitionTo(TaskState.STATE_COMPLETED);
// shouldn't attempt to delete the task if the COMPLETE Task listener failed,
// or managed to cancel the Process or Task Instance
if (shouldDeleteTask)
{
// delete the task
// this method call doesn't invoke additional task listeners
// 删除任务
Context
.getCommandContext()
.getTaskManager()
.deleteTask(this, TaskEntity.DELETE_REASON_COMPLETED, false, skipCustomListeners);
// if the task is associated with a
// execution (and not a case execution)
// and it's still in the same activity
// then call signal an the associated
// execution.
if (executionId !=null) {
ExecutionEntity execution = getExecution();
// execution 表删除任务
execution.removeTask(this);
// 执行器发送信号
execution.signal(null, null);
}
}
}
最后跟踪到 执行 activityBehavior.signal(this, signalName, signalData) 这句代码报异常。
这行代码的功能是来干嘛呢?发送信号,执行任务
最后是在给任务绑定执行人的时候,在参数 VariableScope variableScope 对象没有找到画流程图时定义的 ${assignee},在执行 getValue方法的时候就报异常了。