从 JBPM WorkItemHandlers 抛出异常?

Throwing exceptions from JBPM WorkItemHandlers?

我对从 JBPM 工作项处理程序抛出异常以及在业务流程的其他地方处理异常这一主题感到有点困惑。我们在 Jboss EAP 6.1 中使用 JBPM 6.0.3 运行。

JBPM User Guide 意味着永远不要从 WorkItemHandler 中抛出异常。相反,处理程序应该捕获它们并以某种方式处理它们,或者将它们转换为错误消息、信号或类似信息。 JBPM 甚至提供工作项处理程序包装器,它可以捕获信号并将它们转换为消息。用户指南中没有讨论任何其他方式处理异常。

然后我们有 jbpm-workitems 包,其中包含许多专门编码以抛出异常的处理程序。例如,该包中继承自 AbstractLogOrThrowWorkItemHandler 的任何内容都可能引发 WorkItemHandlerRuntimeException。也许这些处理程序只能通过包装它们来使用,但这似乎是一个奇怪的设计选择。

我还发现了 this third-party documentation page 一种叫做 Magnolia 的东西,它展示了一种不同的技术。您定义错误消息类型,其中错误代码值是异常的完全限定名称 class。然后将错误边界事件附加到调用处理程序的 activity。如果处理程序抛出该异常,它将被错误事件捕获。我已经测试了这个方法,它工作正常;它甚至将异常对象捕获到流程变量中。

我很困惑,因为 Magnolia 页面上显示的方法与 JBPM 用户指南中的方法完全不同,而且 JBPM 指南中没有任何内容甚至暗示 Magnolia 方法会起作用。 Magnolia 方法似乎更容易使用,但我担心它可能不受支持。

处理工作项处理程序抛出的异常的最佳做法是什么? Magnolia 方法是否已被弃用,或者只是偶然起作用?还是我可以指望继续工作的东西?

编辑:提出这个问题的原因是我们的团队想使用来自 jbpm-workitems 的 RESTWorkItemHandler。此处理程序将在某些非常普通的情况下抛出异常。 JBPM 文档基本上说不要让您的工作项处理程序抛出异常;在处理程序中捕获它们,或将处理程序包装在捕获异常的装饰器中。这会使像 REST 处理程序这样的处理程序难以正确构造和注册。我觉得很奇怪,JBPM 会维护一堆标准的工作项处理程序,如果不将它们包装在另一个处理程序中就无法使用。

然后我找到了 Magnolia 文档中描述的方法,它避免了必须将处理程序包装在装饰器中。但是JBPM文档中没有描述Magnolia文档中的方法。

在 jBPM 6.2 中,您可以使用 Error 边界事件,您可以 "attach" 执行特定任务。因此,例如,如果在 Evaluation 任务中抛出 java.lang.ArithmeticException,则可以使用此边界事件捕获异常并让它转到另一个任务来处理异常。

如果这不正确请纠正我,但我认为边界异常处理与引发错误的任务的执行是异步的。

您可以尝试如下操作:

基本上你问的是两个我们可以单独解决的问题,让我们看看我们是否可以解决你的问题:

  1. 处理工作项处理程序抛出的异常的最佳做法是什么?

这里没有灵丹妙药。这取决于许多不同的因素,例如:

  • 你能从异常中恢复吗?例如,如果 jBPM 和您在 WorkItemHandler 中访问的资源遵循相同的 XA 事务并且所讨论的异常将事务标记为回滚,则您的选项将受到限制,因为不会存储持久状态。

  • 如果可以康复,你想做什么?重试、手动干预、中止流程并记录失败,或反转补偿流程中的先前活动?

  • 根据你想做的事情,最好的地方是哪里? Java 还是 BPMN? BPMN 有利于补偿,但 WorkItemHandler 或装饰器可能更适合重试。也许这是两者的结合,您将 Java 异常转换为 BPMN Signal/Error,向调用者指示它应该重试。

这里没有单一的答案,许多不同的方法可能都是有效的。

  1. Magnolia 方法是否已弃用或有效 只是偶然?还是我可以指望继续 上班?

不,没有弃用,查看代码我会说它是设计使然。请记住,在他们的示例中,您使用的是 Magnolia 的装饰器,在这种情况下,您应该询问 Magnolia 人员他们将来是否会支持它。但是有很多装饰器的例子,你可以自由地自己写一些来实现你选择的异常处理技术。