当前位置: 首页 > 知识库问答 >
问题:

是否从JBPM WorkItemHandlers引发异常?

颛孙英才
2023-03-14

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

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

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

我还找到了这个名为Magnolia的第三方留档页面,它展示了一种不同的技术。您定义一个错误消息类型,其中错误代码值是异常类的完全限定名称。然后您将错误边界事件附加到调用处理程序的活动。如果处理程序抛出该异常,它将被错误事件捕获。我测试了这个方法,它运行良好;它甚至将异常对象捕获到一个过程变量中。

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

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

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

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

共有2个答案

夏俊人
2023-03-14

在jBPM 6.2中,可以使用可以“附加”到特定任务的错误边界事件。例如,如果在您的评估任务中,您抛出了一个java。lang.ArithmeticException,您可以使用此边界事件捕获异常,并将其转到另一个任务来处理该异常。

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

沈琛
2023-03-14

从本质上讲,您提出了两个问题,我们可以分别解决这两个问题,看看我们是否可以解决您的担忧:

  1. 处理工作项处理程序引发的异常的最佳实践方法是什么

这里没有银弹。这取决于许多不同的因素,例如:

>

  • 您可以从异常中恢复吗?例如,如果jBPM和您在WorkItemHandler中访问的资源尊重相同的XA事务,并且有问题的异常将事务标记为回滚,则您的选项是有限的,因为持久状态不会被存储。

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

    根据您想做的事情,最好在哪里做?Java还是BPMN?BPMN有利于补偿,但WorkItemHandler或Decorator可能更适合重试。也许它是两者的组合,您将Java异常转换为BPMN信号/错误,向调用者指示它应该重试。

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

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

  •  类似资料:
    • 问题内容: 我想知道只有Integer.parseInt(无论如何)都不会失败的情况下才能做些什么。 更具体地说,我有一个jTextArea用户指定值,由换行符分隔。 我想检查每一行,看看是否可以转换为整数。 想出了类似的东西,但是不起作用: 任何帮助表示赞赏。 问题答案:

    • 问题内容: 有谁知道是否存在可以测试被测代码中是否抛出异常的或类似东西? 问题答案:

    • 问题内容: (下面的示例代码是独立且可运行的,您可以尝试一下,它不会使系统崩溃:) Tom Hawtin在这里评论了这个问题:为什么人们在事件队列上运行JavaGUI 那: EDT不太可能崩溃。 EDT调度中抛出的未经检查的异常将被捕获,转储并且线程继续运行。 有人可以解释一下这是怎么回事(每次您单击 “引发未经检查的异常” 按钮时,都会有意除以零): 我收到以下消息(这是我期望的): 对我来说,

    • 问题内容: 在其中引发异常是否被认为是不好的形式?如果是这样,那么当某些类变量初始化为错误类型或类型错误时,可以接受的引发错误的方法是什么? 问题答案: 在内部引发异常是绝对可以的。在构造函数中没有其他好的方法来指示错误情况,并且标准库中有数百个示例,在这些示例中构建对象会引发异常。 当然,要提高的错误级别取决于您。如果向构造函数传递了无效的参数,则最好。

    • 我在写一个apk分析程序。我不能深入细节,因为这是研究材料。然而,重点在于,当我执行分析例程时,不时会得到以下消息: 这只是主要代码。我必须执行三个主要操作。为了不泄露特定信息,我把它们重新命名为A、B、C 我将这个问题标记为multithread,因为在多线程版本中也会发生同样的情况,为了调试错误,我使用此代码对该版本进行了序列化。请注意,NullPointerException位于线程主线程中

    • 现在我想测试我的扩展是否按预期工作。 如何编写测试来验证执行第二个方法的尝试是否会引发带有特定消息的RuntimeException?