如何在会话Bean中使用自定义异常? [英] How to use custom Exception in Session Beans?

查看:134
本文介绍了如何在会话Bean中使用自定义异常?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

EJB 3.1会话Bean:

  import javax.ejb。*; 
public class FooException extends EJBException {
}
@Stateless @Local
public class Foo {
public void bar()throws FooException {
if(/ *有错误* /){
throw new FooException();
}
}
}

现在测试: p>

  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)


EJB 3.1 Session 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();
    }
  }
}

Now the test:

import org.junit.*;
public class FooTest {
  @Test(expected = FooException.class)
  public void testException() {
    new InitialContext().lookup("Foo").bar();
  }
}

The problem is that EJBException is caught in the test, not FooException. Looks like EJB container looses information about my custom exception type and throws a basic type (EJBException). What is wrong here? (it's OpenEJB 3.1)

解决方案

First of all, you don't need to use the @Local annotation here. This designates an interface as a local interface or when used at a bean (in your case) can be used to point to a local interface (via the value attribute). Neither case is applicable here. Your code as given will also not compile. lookup("Foo") will return an Object that needs to be casted.

Anyway about the problem, the EJB container doesn't loose any information but wraps your exception in an EJBException. This is because FooException ultimately inherits from RuntimeException. Any such exception is treated by the container as a nonapplication exception and for those the EJB spec defines that they should be wrapped.

In your situation you already extend from EJBException, so it seems like this is a corner case. JBoss AS 6 for instance doesn't do the extra wrapping in this situation, but apparently OpenEJB does.

You can solve this problem by either not letting FooException inherit from EJBException, or by catching the exception in your test, unwrapping it and rethrowing the unwrapped exception.

Since your bar method is declaring that it throws FooException, my guess is that you didn't realize that EJBException is a RuntimeException and thus a nonapplication exception. Why did you let FooException inherrit from EJBException? Did you think this was somehow required, or does this need to server some special purpose?

(as an extra hint, make sure you understand the difference between application and nonapplicaton exceptions with respect to rolling back any transaction and destroying the pooled bean)

这篇关于如何在会话Bean中使用自定义异常?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆