I've built and deployed the app on WAS 6.0 and the happy path work fine. The problem occurs when an exception occurs.
A checked exception is thrown from the application, i.e. object not found. The exception is caught and a rollback is called (sessionContext.setRollbackOnly()) - the exception is thrown on and is caught again by my RoutingSession EJB converted to a String and passed back to my servlet. This works fine in WAS 5.0. in WAS 6.0 it works fine upto somewhere in the _Stub class of my routing bean - a remote exception is thrown from here. See stacktrace:
javax.transaction.TransactionRolledbackException: CORBA TRANSACTION_ROLLEDBACK 0x0 No; nested exception is:
org.omg.CORBA.TRANSACTION_ROLLEDBACK: javax.transaction.TransactionRolledbackException: ; nested exception is:
com.ibm.websphere.csi.CSITransactionRolledbackException: Transaction marked rollbackonly vmcid: 0x0 minor code: 0 completed: No
at com.ibm.CORBA.iiop.UtilDelegateImpl.mapSystemException(UtilDelegateImpl.java:216)
at com.ibm.CORBA.iiop.UtilDelegateImpl.wrapException(UtilDelegateImpl.java:700)
at javax.rmi.CORBA.Util.wrapException(Util.java:296)
at com.services.requestrouter._RequestRouter_Stub.processDataPackets(_RequestRouter_Stub.java:320)
at com.services.requestrouter.RequestRouterUtils.processDataPackets(RequestRouterUtils.java:106)
at com.ei.channel.server.ServerUtils.processDataPackets(ServerUtils.java:38)
at com.ei.channel.server.HttpServer.processDataPackets(HttpServer.java:195)
at com.ei.channel.server.HttpServer.doPost(HttpServer.java:141)
at com.ei.channel.server.HttpServer.service(HttpServer.java:252)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1282)
at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:673)
at com.ibm.ws.webcontainer.servlet.CacheServletWrapper.handleRequest(CacheServletWrapper.java:80)
at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:1804)
at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:84)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:469)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewInformation(HttpInboundLink.java:408)
at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:286)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.sendToDiscriminaters(NewConnectionInitialReadCallback.java:201)
at com.ibm.ws.tcp.channel.impl.NewConnectionInitialReadCallback.complete(NewConnectionInitialReadCallback.java:103)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.requestComplete(WorkQueueManager.java:566)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.attemptIO(WorkQueueManager.java:619)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager.workerRun(WorkQueueManager.java:952)
at com.ibm.ws.tcp.channel.impl.WorkQueueManager$Worker.run(WorkQueueManager.java:1039)
at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1455)
Caused by: org.omg.CORBA.TRANSACTION_ROLLEDBACK: javax.transaction.TransactionRolledbackException: ; nested exception is:
com.ibm.websphere.csi.CSITransactionRolledbackException: Transaction marked rollbackonly vmcid: 0x0 minor code: 0 completed: No
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:80)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:44)
at java.lang.reflect.Constructor.newInstance(Constructor.java:315)
at com.ibm.rmi.util.ProxyUtil.copyObject(ProxyUtil.java:341)
at com.ibm.CORBA.iiop.UtilDelegateImpl.copyObject(UtilDelegateImpl.java:805)
at javax.rmi.CORBA.Util.copyObject(Util.java:333)
at com.services.requestrouter._RequestRouter_Stub.processDataPackets(_RequestRouter_Stub.java:316)
... 21 more
The container is throwing a CSITransactionRolledbackException when I don't expect it to - I've dealt with it already.
steps:
1) servlet receives http request
2) servlet makes call to RoutingSessionEJB
3) RoutingSessionEJB looks up BusinessServiceSessionEJB
4) RoutingSessionEJB makes call to the BusinessServiceSessionEJB
5) Exception thrown and caught by BusinessServiceSessionEJB
6) BusinessServiceSessionEJB calls sessionContext.setRollbackOnly()
7) BusinessServiceSessionEJB throws Exception
8) Exception caught by RoutingSessionEJB
9) Exception converted to Vector
10) RoutingSessionEJB makes call to Audit service (***I wonder has it a problem with this because it expects the txn to have finished - although there is no ejb call in the service**)
11) Vector returned from method on RoutingSessionEJB
stepping threw this code it all executes as expected
12) somewhere in the Stub processRequest method for the RoutingSessionEJB a RemoteException is thrown
//Servlet
try {
RouterHome home = (RouterHome) lookup...
Router router = home.create();
2) return router.processRequest(obj);
} catch (RemoteException re) {
exception is CSITransactionRolledbackException
}
//RouterBean
public Vector processRequest(Vector request) {
Vector response = null;
try {
3) CustomerSearchHome home = (CustomerSearchHome) Server.lookup...
CustomerSearch customerSearch = home.create();
4) return customerSearch.processRequest(obj);
} catch (ApplicationException ae) {
//exception is caught here
//log it and convert to vector
8 & 9)response = //converted exception
} finally {
10) AuditUtils.audit(request, response);
}
11) return response;
}
//CustomerSearchSessionEJB
public Vector processRequest(Request obj) throws ApplicationException {
Vector response = null;
try {
process.....
5) }catch (ApplicationException eex) {
6) sessionContext.setRollbackOnly();
7) throw new ApplicationException(eex)
}
return response;
}
If RoutingSessionEJB doesn't want the container to throw a
RemoteException even if the transaction that bean started is rolled
back, it must explicitly call sessionContext.setRollbackOnly() before
returning -- even if setRollbackOnly() was already called by a different
EJB somewhere up in the callpath. (The container only knows that the
transaction was rolled back for some reason, not necessarily that it was
rolled back because of a setRollbackOnly() call.)
The requirement for the starter of the tran to call setRollbackOnly() in
order to suppress the throwing of a TransactionRolledbackException is
defined in the EJB standard specs. The change between 5.1.1 and 6.0.2
was made to better comply with the official specs.