未捕获自定义 RuntimeException
Custom RuntimeException not caught
我有自己的 ApplicationException extends 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.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)
这里的问题是您抛出 RuntimeException
而不是某种已检查的异常。
在这种情况下,当 RuntimeException
发生时,EJBContainer 将回滚事务并抛出 EJBException
(这也是 RuntimeException
)结果是,您的客户端不会直接看到您的自定义异常,而是看到容器抛出的 EJBException
。
您可能会抛出一个已检查的异常(只是不要扩展 RuntimeException
而是 Exception
),但是您必须在必要时自行回滚事务。
另一方面,您可以展开由 EJBContainer 抛出的 EJBException 以找出原因,如果这对您来说真的很有趣的话。
有关 EJB 中异常处理的更多详细信息,另请参阅此博客文章:
http://palkonyves.blogspot.de/2013/04/exceptions-and-transactions-in-ejb.html
请务必检查 @ApplicationException
的语义,EJB 规范从中指出异常,因此带注释的将被解包发送到客户端。本质上,如果您抛出任何其他未注释 @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;
}
}
我有自己的 ApplicationException extends 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.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)
这里的问题是您抛出 RuntimeException
而不是某种已检查的异常。
在这种情况下,当 RuntimeException
发生时,EJBContainer 将回滚事务并抛出 EJBException
(这也是 RuntimeException
)结果是,您的客户端不会直接看到您的自定义异常,而是看到容器抛出的 EJBException
。
您可能会抛出一个已检查的异常(只是不要扩展 RuntimeException
而是 Exception
),但是您必须在必要时自行回滚事务。
另一方面,您可以展开由 EJBContainer 抛出的 EJBException 以找出原因,如果这对您来说真的很有趣的话。
有关 EJB 中异常处理的更多详细信息,另请参阅此博客文章: http://palkonyves.blogspot.de/2013/04/exceptions-and-transactions-in-ejb.html
请务必检查 @ApplicationException
的语义,EJB 规范从中指出异常,因此带注释的将被解包发送到客户端。本质上,如果您抛出任何其他未注释 @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;
}
}