EJB 3.1 会话 Bean:
import javax.ejb.*;
public class FooException extends EJBException {
}
@Stateless @Local
public class Foo {
public void bar() throws FooException {
if (/* something wrong */) {
throw new FooException();
}
}
}
现在测试:
import org.junit.*;
public class FooTest {
@Test(expected = FooException.class)
public void testException() {
new InitialContext().lookup("Foo").bar();
}
}
问题是EJBException
被困在测试中,而不是FooException
。看起来 EJB 容器丢失了有关我的自定义异常类型的信息并抛出基本类型(EJBException
)。这里有什么问题吗? (这是 OpenEJB 3.1)
首先,这里不需要使用@Local注解。这将接口指定为本地接口,或者在 bean 上使用时(在您的情况下)可用于指向本地接口(通过 value 属性)。这两种情况都不适用于此。您给出的代码也将无法编译。 Lookup("Foo") 将返回一个需要转换的对象。
不管怎样,EJB 容器不会丢失任何信息,而是将异常包装在 EJBException 中。这是因为 FooException 最终继承自 RuntimeException。容器将任何此类异常视为nonapplication exception
对于这些,EJB 规范定义它们应该被包装。
在您的情况下,您已经从 EJBException 扩展,因此这似乎是一个极端情况。例如,JBoss AS 6 在这种情况下不会进行额外的包装,但显然 OpenEJB 会这样做。
您可以通过不让 FooException 继承 EJBException 或通过在测试中捕获异常、解开它并重新抛出解开的异常来解决此问题。
由于您的 bar 方法声明它抛出 FooException,所以我的猜测是您没有意识到 EJBException 是 RuntimeException,因此是非应用程序异常。为什么要让FooException继承EJBException呢?您认为这是出于某种需要,还是需要满足某些特殊目的?
(作为额外提示,请确保您了解应用程序异常和非应用程序异常在回滚任何事务和销毁池 bean 方面的区别)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)