未捕获自定义RuntimeException

时间:2015-05-20 07:55:31

标签: java java-ee exception-handling runtimeexception

我有自己的ApplicationException,扩展了RuntimeException:

package com.haslerrail.aura.common.exception;

public class ApplicationException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private final ErrorCode errorCode;

    private final Object[] arguments;

    public ApplicationException(final ErrorCode errorCode, final Object... arguments) {
        super();
        this.errorCode = errorCode;
        this.arguments = arguments;
    }

    public ErrorCode getErrorCode() {
        return errorCode;
    }

    public Object[] getArguments() {
        return arguments;
    }

}

这个异常将被抛出是我的无状态bean的函数:

public void doSomething()
        throws IOException, ApplicationException, InternalException {
    if (true) {
        throw new ApplicationException(ErrorCode.FILE_TYPE_NOT_SUPPORTED, "test");
    }
}

我想通过我的sessionScoped bean捕获这个runtimeException:

public void doXXX(final FileUploadEvent event) throws SystemException {
    try {

        myStatelessbean.doSomething();  // Throw my ApplicationExcetion

    } catch (final ApplicationException e) {
        System.out.println("catch ApplicationException");
    } catch (final Exception e) {
        System.out.println("catch Exception");
    }

}

我的问题是,异常是由Exception捕获的,而不是我自己的ApplicationException!我不知道我做错了什么......

e.printStackTrace()给出了异常文本:

javax.ejb.EJBException: com.haslerrail.aura.common.exception.ApplicationException
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleExceptionInOurTx(CMTTxInterceptor.java:166)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:230)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:76)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ee.component.NamespaceContextInterceptor.processInvocation(NamespaceContextInterceptor.java:50)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ejb3.component.interceptors.AdditionalSetupInterceptor.processInvocation(AdditionalSetupInterceptor.java:32)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.as.ee.component.TCCLInterceptor.processInvocation(TCCLInterceptor.java:45)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ViewService$View.invoke(ViewService.java:165)
    at org.jboss.as.ee.component.ViewDescription$1.processInvocation(ViewDescription.java:173)
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288)
    at org.jboss.invocation.ChainedInterceptor.processInvocation(ChainedInterceptor.java:61)
    at org.jboss.as.ee.component.ProxyInvocationHandler.invoke(ProxyInvocationHandler.java:72)
    at XXXX.myStatelessbean.$$$view353.doSomething(Unknown Source)  

2 个答案:

答案 0 :(得分:4)

这里的问题是你正在抛出RuntimeException而不是某种经过检查的异常。

在这种情况下,当RuntimeException发生时,EJBContainer将回滚事务并抛出EJBException(也是RuntimeException)结果是,您的客户端没有直接查看您的自定义Exception,但是容器抛出的EJBException

您可以抛出已检查的Exception(只是不要扩展RuntimeException而是Exception),但是必须在必要时自行回滚事务。 另一方面,你可以展开EJBContainer抛出的EJBException来获取原因,如果你真的对它感兴趣的话。

有关EJB中异常处理的更多详细信息,请参阅此博客文章: http://palkonyves.blogspot.de/2013/04/exceptions-and-transactions-in-ejb.html

答案 1 :(得分:4)

请检查{规范}说明该异常的@ApplicationException的语义,因此注释将被发送到客户端解包。本质上,如果你抛出任何未注释@ApplicationException的其他异常,ejb容器会将抛出的异常包装到EJBException中并将其抛给客户端。因此,您将永远无法在客户端捕获您的实际例外。

//I always set rollback, cause its needless in most circumstances to commit transaction when an exception occurs.
@ApplicationException(rollback = true, inherit=true)
public class MyApplicationException extends RuntimeException {

    private static final long serialVersionUID = 1L;

    private final ErrorCode errorCode;

    private final Object[] arguments;

    public MyApplicationException(final ErrorCode errorCode, final Object... arguments) {
        super();
        this.errorCode = errorCode;
        this.arguments = arguments;
    }

    public ErrorCode getErrorCode() {
        return errorCode;
    }

    public Object[] getArguments() {
        return arguments;
    }

}