Why ApplicationException thrown from server-side interceptor is wrapped by JBoss AS/EJB container?
ybxiang.china Oct 17, 2012 10:57 PMDear 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.