Gatschet
Gatschet

Reputation: 1537

Custom RuntimeException not caught

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

Answers (2)

maress
maress

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

stg
stg

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

Related Questions