Reputation: 1537
I have my own ApplicationException witch 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;
}
}
This exception will be thrown be a function of my stateless bean:
public void doSomething()
throws IOException, ApplicationException, InternalException {
if (true) {
throw new ApplicationException(ErrorCode.FILE_TYPE_NOT_SUPPORTED, "test");
}
}
I would like to catch this runtimeException by my sessionScoped bean like this:
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");
}
}
My problem is, the exception is caught by the Exception and never by my own ApplicationException! I have no idea what i'm doing wrong....
e.printStackTrace() gives the exception text:
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)
Upvotes: 5
Views: 3562
Reputation: 3533
Please do check the semantics of @ApplicationException
from which the EJB specs says that the exception, so annotated will be sent to the client unwrapped. In essence, if you throw any other exception, which is not annotated @ApplicationException
, the ejb container wraps the thrown exception into an EJBException
and throws it to the client. Hence, you will never be able to catch your actual exception on your client side.
//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;
}
}
Upvotes: 6
Reputation: 2797
The Problem here is that you are throwing a RuntimeException
instead of some kind of checked Exception.
In this case, when a RuntimeException
occurs, the EJBContainer will rollback the Transaction and throw a EJBException
(which is also a RuntimeException
) The result is, that your client does not directly see your custom Exception but the EJBException
which is thrown by the container.
You may throw a checked Exception instead (just do not extend RuntimeException
but Exception
), but then you have to rollback the transaction on your own, when neccessary.
On the other hand you could unroll the EJBException which is thrown by the EJBContainer to get the cause, if this is really interesting for you.
For more details about Exception Handling in EJBs see also this blog article: http://palkonyves.blogspot.de/2013/04/exceptions-and-transactions-in-ejb.html
Upvotes: 6