How to use custom Exception in Session Beans?
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();
}
}
开发者_如何学JAVA
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)
精彩评论