java - EJB3.1 系统异常与 javax.ejb.EJBException

标签 java jakarta-ee exception java-ee-6 ejb-3.1

在提出我的问题之前,先了解一下 EJB3.1 异常的背景知识 -

应用程序异常包括

  • 用户定义的已检查或未检查异常
    @ApplicationException 注解
  • 所有检查的异常

    java.lang.Exception & 它的子类异常
    除了 java.rmi.RemoteException 和它的子类异常

  • 系统异常包括
  • java.rmi.RemoteException 及其子类异常
  • 所有未经检查的异常

    java.lang.RuntimeException 及其子类异常
    java.lang.Error 及其子类异常

  • 以下是我在此 book 中读到的声明

    In EJB System exceptions are not excepted by the client, when encountered such exceptions are not passed to the client as is but are wrapaped in a javax.ejb.EJBException.



    我的问题——
  • 上面描述的所有应用程序异常都应该由 EJB 直接抛出给客户端吗?
  • 如果系统异常在抛出到客户端之前被包裹在 javax.ejb.EJBException 中,那么 javax.ejb.EJBException 是否被视为系统异常?
  • 最佳答案

    IndoKnight,你对如何做的完美总结Exception Java EE 框架内的语义.. 工作。

    这是“bean提供者”的唯一两行,即你和我,需要了解Java EE中的异常:

    相对于 bean 可能受到的其他约束,您的 bean 可以完全自由地从您认为合适的任何类型的异常或错误中恢复。如果您从异常中恢复过来,那么恭喜 - 没有问题了 =)

    例如,一个相关的约束可能是“使用容器管理事务划分的企业 bean 不得使用任何干扰容器事务划分边界的事务管理方法”引用 Java EE 7 tutorial第 48-2 页(您想以编程方式设置容器管理事务的回滚,使用 EJBContext.setRollbackOnly())。

    与任何类型的 Java 应用程序一样,您也不鼓励处理 ThrowableError从一个非常低的水平抛出。 RuntimeException理论上算在这一类中,因为它非常著名地表示“开发人员错误”,就像“完全出乎意料”一样 - 但我们都知道事实并非如此。

    基本上,一个意外的异常(运行时异常+我们假设源自其他人的其他东西)被认为是您的代码无法处理的,而应该由服务器处理。服务器需要通过在日志中打印一些关于它的内容来处理“无法处理的”异常(请参阅 EJB 3.2 specification ,第 204 页)(稍后我将详细介绍!)。

    进一步来说..

    你问(这是我相信或坚持的):

    Are all application exceptions described above supposed to be thrown directly by EJB to client?



    是的。 除非您使用 ApplicationException 的回滚属性明确声明它应该回滚,否则事务(如果一个是 Activity 的)不应回滚。 . Java 代码抛出异常是很自然的事情。 Java EE 无意拆除这种编程模型。所以继续吧,抛出你喜欢的已检查异常,强制客户端 try catch 这些异常或将运行时异常标记为应用程序异常并抛出它们。投球快乐!

    If System Exceptions are wrapped inside javax.ejb.EJBException before throwing to the client, then is javax.ejb.EJBException considered as System Exception?



    ,但不是因为您提供的原因。需要明确的是,没有称为 SystemException 的类型。描述大多数 bean 没有想到可能发生的那种异常只是花哨的措辞,而且很可能,它们源自 EJB 容器。您的代码绝对不应该抛出 EJBException。这样做可能只会阻碍服务器的思想。您也不能将异常注释为 @ApplicationException,因为您不拥有代码,它由 Java EE API 提供。您可以扩展 EJBException,但将您的代码伪装成服务器代码库的一部分是没有任何意义的。最重要的是,因为 EJBException 扩展了 RuntimeException ,我认为将 EJBException 归类为“系统级异常”是安全的。

    小心恶魔

    一些 远程 客户将收到 RemoteException而不是 EJBException。

    拦截器 在大型企业项目中,您甚至可能没有意识到,即使您从未计划让他这样做,也可能会吞下从您的方法中抛出的异常,从而使 Activity 事务提交。

    我敢打赌你认为 抑制异常 始终可以使用 Throwable.getCause() 检索.请注意 EJB 3.2 specification并不是说容器必须或应该保留对被抑制原因的引用。事实上,容器唯一要做的就是记录异常。然后,如果 bean 不是单例,则必须丢弃 bean 实例并且不再使用。此外,如果 bean 是消息驱动 bean,那么只有原始异常才需要“包装”。未指定如何“包装”异常。 super 便携的酷代码应该看看 Throwable.getCause() 方法和 Throwable.getSuppressed()也。不要盲目地期望在您的处理代码中总能找到原始异常。

    异步 返回 void 的方法(注释为 @Asynchronous 的公共(public) session bean 方法)无法将异常传播到他的客户端。因此,它们不得声明或抛出应用程序异常(请参阅 EJB 3.2 specification 第 82 页)。请注意,当您调用异步方法时,服务器可能无法提供线程资源来为您的请求提供服务,如果是,则需要抛出一个.. EJBException(第 48 页)!

    关于java - EJB3.1 系统异常与 javax.ejb.EJBException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21766729/

    相关文章:

    java - 除了模板特定从搜索中排除页面之外,还有其他替代方法吗

    java - 当用户确认保持在线时刷新 session 时间

    java - 共享内存(int)与java线程的同步

    java - 为什么java会为吉他和弦提供不同的结果

    Java - 如何创建可查询但不可更新的 JTextfield?

    java - java EE 应用程序的 SMS 身份验证

    java - 当文件格式不正确/为空时抛出什么异常

    django:当 debug = False 时显示数据库错误

    java - 处理一个不存在的 servlet 异常

    java - 使用 Spring Data JPA 和 postgresql 在 @Query 中将字符串转换为时间戳