views:

90

answers:

3

I'm running two glassfish v2 domains containing stateless session EJBs. In a few cases, an EJB in one domain has to call one in the other.

My problem is that when the called EJB aborts with an exception, the caller does not receive the message of the exception and instead reports an internal error that is not helpful at all in diagnosing the problem. What happens seems to be this:

  • At the transport layer, a org.omg.CORBA.portable.ApplicationException is created,which already loses all detail information about the exception except its class.
  • Inside com.sun.jts.CosTransactions.TopCoordinator.get_txcontext(), the status of the transaction ass rolled back causes a org.omg.CosTransactions.Unavailable to be thrown, which gets wrapped and passed around a few times and eventually results into this error being displayed to the user:

    org.omg.CORBA.INVALID_TRANSACTION:   vmcid: 0x0  minor code: 0  completed: No
    at com.sun.jts.CosTransactions.CurrentTransaction.sendingRequest(CurrentTransaction.java:807)
    at com.sun.jts.CosTransactions.SenderReceiver.sending_request(SenderReceiver.java:139)
    at com.sun.jts.pi.InterceptorImpl.send_request(InterceptorImpl.java:344)
    at com.sun.corba.ee.impl.interceptors.InterceptorInvoker.invokeClientInterceptorStartingPoint(InterceptorInvoker.java:271)
    at com.sun.corba.ee.impl.interceptors.PIHandlerImpl.invokeClientPIStartingPoint(PIHandlerImpl.java:348)
    at com.sun.corba.ee.impl.protocol.CorbaClientRequestDispatcherImpl.beginRequest(CorbaClientRequestDispatcherImpl.java:284)
    at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.request(CorbaClientDelegateImpl.java:184)
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:186)
    at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)
    at com.sun.corba.ee.impl.presentation.rmi.bcel.BCELStubBase.invoke(BCELStubBase.java:225)
    

Is there anything I can do here to preserve information about the actual cause of the problem?

+1  A: 

The cause of the problem should be available in the server log of the domains hosting the EJB that had a problem.

It sounds like getting more info back from the other end may be difficult... I do not know which issue tracker would be the right one for the info lost when the ApplicationException is created/thrown.

A total hack would be to create a set of custom exception classes in the project that has the ejb that has failed. You would make them very fine grained to cover the likely causes of the problem and provide enough detail in their name to identify the actual location of the problem, too. Yucky... but that may be the only choice until an issue gets filed and the fix is distributed.

vkraemer
+1  A: 

Is there anything I can do here to preserve information about the actual cause of the problem?

Unfortunately, no. The ORB does not use normal object serialization for system exceptions (i.e., org.omg.CORBA.*), which means that causes are lost. As @vkraemer said, you'll need to rely on server logs.

bkail
A: 

I finally got to the bottom of this: actually, Glassfish transmits exceptions through IIOP quite correctly and everything works as it should... unless you do something idiotic like this:

try{
    ejb.getFoo();
}catch (Exception e){
    // try again
    ejb.getFoo();
}

Yeah, it was our own damn code that swallowed the exception and tried to call a transaction-requiring EJB method within a distributed transaction that's been rolled back due to the exception.

Michael Borgwardt