1 Reply Latest reply on Oct 18, 2012 12:06 AM by jaikiran

    Why ApplicationException thrown from server-side interceptor is wrapped by JBoss AS/EJB container?

    ybxiang.china

      Dear guys,

       

       

      I defined an application exception and an Intercepter in server side:

       

      import javax.ejb.ApplicationException;

      @ApplicationException(rollback=true)

      public class NotExistingSessionTokenException extends Exception {   

          private static final long serialVersionUID = 1L;

       

          public static final NotExistingSessionTokenException INSTANCE;

          static {

              INSTANCE = new NotExistingSessionTokenException();

          }

       

          private static final String MSG = "Fake Session Exception";

       

          private NotExistingSessionTokenException() {

              super(MSG);

          }

      }

       

       

       

      public class SessionTokenInterceptor {

          Logger log = Logger.getLogger(SessionTokenInterceptor.class);

       

          @PersistenceContext

          protected EntityManager em;

       

          @Resource

          private EJBContext ejbContext;

       

          @AroundInvoke

          public Object processSessionToken(final InvocationContext invocationContext) throws Exception{

              //1. session token

              //log.info("retrieve SESSION TOKEN from invocation context instead of ejbContext");

              String sessionToken = (String)invocationContext.getContextData().get(ServerClientSharedConstants.SESSION_TOKEN_KEY);

              //log.debug("SESSION_TOKEN:"+sessionToken);//good!

       

              //2. JAAS username

              //log.info("retrieve JAAS username");

              String username = ejbContext.getCallerPrincipal().getName();//JAAS username

       

              //3. check

              if(sessionToken==null){

                  log.error("User["+username+"] has no SESSION TOKEN, so is NOT allowed to do more in this system.");

                  throw NullSessionTokenException.INSTANCE;

              }

              if(! isSessionTokenExisting(sessionToken)){

                  log.error("User["+username+"] is using invalid SESSION TOKEN, so is NOT allowed to do more in this system.");

                  throw NotExistingSessionTokenException.INSTANCE;

              }

       

              //4. call original method and return its result so that other interceptor can continue

              try{

                   return invocationContext.proceed();

              }finally{

              }

          }

      }

       

       

      I used the interceptor on my session bean:

      @Interceptors({SessionTokenInterceptor.class})

      public class SecuredRemoteSession implements ISecuredRemoteSession{

      ...

      }

       

       

       

       

       

      On client side, I catch this exception in an interceptor, but I got a wrapped Exception: javax.ejb.EJBException

       

       

      import java.lang.reflect.UndeclaredThrowableException;

       

      import org.apache.log4j.Logger;

      import org.eclipse.swt.widgets.Display;

      import org.jboss.ejb.client.EJBClientInterceptor;

      import org.jboss.ejb.client.EJBClientInvocationContext;

       

      import com.ybxiang.nms.common.exception.NotExistingSessionTokenException;

       

      public class ClientExceptionInterceptor implements EJBClientInterceptor{

          private final static Logger log = Logger.getLogger(ClientExceptionInterceptor.class);

       

          @Override

          public void handleInvocation(EJBClientInvocationContext context)

                  throws Exception {

              context.sendRequest();

          }

       

          @Override

          public Object handleInvocationResult(EJBClientInvocationContext context)

                  throws Exception {

              String methodName = context.getInvokedMethod().getName();

       

              for(int i=0;i<ignoredMehtods_handleInvocationResult.length;i++){

                  if(methodName.equals(ignoredMehtods_handleInvocationResult[i])){

                      return context.getResult();

                  }

              }

       

              Object result = null;

              try{

                  result = context.getResult();

              }catch(NotExistingSessionTokenException e){

                 log.error("NotExistingSessionTokenException is NOT catched!");//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ What I want!

              }catch(javax.ejb.EJBException e){           

                  if(e.getCause() instanceof java.lang.reflect.UndeclaredThrowableException){

                      UndeclaredThrowableException cause = (UndeclaredThrowableException)e.getCause();

                      Throwable t = cause.getUndeclaredThrowable();

       

                      if(t instanceof NotExistingSessionTokenException){

                          log.error("NotExistingSessionTokenException is catched!");//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ What I NOT want!

                      }else{

                          log.error("bla bla...);

                      }

                  }

                  else{

                  }

                  throw e;

              }catch(Exception e){

                  log.error("UNknown Exceptoin:",e);

       

                  throw e;

              }finally{

              }       

       

              return result;

          }

      }

       

       

       

       

      Why Application Exception thrown in server-side interceptor is wrapped by EJB container?

       

      Thanks in advance.