I’m on this project where we develop a component. This is a J2EE component, it has its own database and it does some mainframe communication. This component is to be deployed on a WebSphere application server, version 6.1 (WAS).
The component is to be used by a specific J2EE application. This application is to be deployed on an Oracle Application Server (OC4J) – possibly version 10.1.3.1. The application also has its own database…
Transactions are really important to this component. The “local” database has to be “in sync” with the mainframe, and we are taking care to have 2-phase commit (2PC) between the component, the database and the mainframe. Note that the mainframe is allowed to rollback a transaction during transaction completion.
Transactions are really important to the entire application; the application database, the “component local” database and the mainframe has to be “in sync”. Basically the global transactions are started in the application, propagated over the component into the mainframe and back…
Now, everything except the mainframe is Java and J2EE so the question about how to have the different subsystems participate in global distributed transactions should have an obvious answer: use session beans and RMI/IIOP.
OC4J 10.1.3.1 versus WebSphere 220.127.116.11
At least in theory, the use of (stateless) session beans should enable different application servers to participate in global distributed transactions. And using CORBA/IIOP should somehow ensure this in a standardized manner.
So, we naively assumed that by using session beans and RMI/IIOP we could have the application and the component participate in global distributed transactions without having to write any non-standard glue code (except for the mainframe integration 🙂 )
When reality came closer, we started a small proof-of-concept (PoC) project that could demonstrate global transaction participation between different application servers. The initial outcome was that between two application servers from the same vendor (OC4J – OC4J, WAS – WAS), distributed transaction was no problem.
When “the application” was OC4J and “the component” WAS, either there was no transaction propagation. Or, WAS would throw an exception with a message like “interoperable global transaction required” (from memory). Not good…
We tried to look for alternative solutions, but no straightforward short term solution came to mind. There is no way the application could be deployed on anything but OC4J. And for non-obvious technical reasons, the component could not easily be reimplemented on OC4J.
For reasons I no longer recall, we silently assumed the problem was related to WebSphere. Maybe because we could find (Google) documents describing what WebSphere specific settings are necessary to have different versions of WebSphere participate in distributed global transactions…
It would be possible and would make good sense if we ported the component to run in a more modern application server. So we looked at Glassfish (v1 ur1 p01) – the open source Sun reference implementation of JEE 5.
So I reimplemented the PoC to run on OC4J and Glassfish… Still no luck – Glassfish threw a TransactionRequiredException. Interesting, as the stateless session bean deployed in Glassfish is TX-required, so Glassfish should start a transaction if none is already present. The TransactionRequiredException must then be a signal that a transaction is present, but it is not possible for Glassfish to participate – almost like the “interoperable global transaction required” error from WebSphere…
When calling Glassfish from a non-transactional client, Glassfish behaves as expected and creates the transaction when entering the EJB container.
I tried deploying the “application end” of the PoC in WAS and have it call Glassfish. This is actually working all right. Not perfectly. Commit and rollback done in the WAS end is propagated into Glassfish as it should, but an exception is logged in “both ends” on transaction “after-completion”. But the exception does not interfere with the application or component and the transaction propagation seems to be working as expected.
OC4J 11 preview edition
Reading a lot of specs, it appears that CORBA OTS (Object Transaction Services) should be the common standard that makes the magic happen. It also appears that JTS 1.0 requires OTS 1.1…
Now, the feature matrix for OC4J 10.1.3 does not mention JTS at all, but the feature matrix for the upcoming OC4J 11 (currently available as a preview download) actually mentions JTS 1.0.
So, maybe we can have transaction propagation between OC4J 11 and WAS!
I downloaded the preview edition, installed it and deployed the “application end” of the PoC in this application server… After having spent some hours struggling with a “missing common wide CodeSet” CORBA error, that I initially assumed should be solved in the OC4J end, I was back with the interesting WebSphere exception: “interoperable global transaction required”.
BEA WebLogic 10
BEA is known to always be trying hard to be “on the beat”. Having the latest specs implemented “production ready” in new releases not too soon after the specs are finalized.
BEA being a “middleware only” shop has also always been known to focus on interoperability – being able to interoperate with any other major vendor in the market, if possible.
BEA’s latest WebLogic version (WLS 10) is no exception, and it would be possible for us to port the component to run on WLS 10. And maybe OC4J and WLS 10 would get along…
So I rewrote the PoC to run on OC4J and WLS. New problem – OC4J gets a CORBA MARSHAL exception when calling the remote home “create” method! I tried lots of different strategies but never got past the MARSHAL exception. Strange…
Just for sanity checking, I deployed the “application end” on WAS and I was back in business. Transaction propagation from WAS to WLS 10 was working like a charm. No strange exceptions or other errors in any log files and commit and rollback done in the WAS end was nicely propagated into WLS 10!
According to lots of fine papers and specs, J2EE/JEE application servers are able to participate in global distributed transactions. These specs are not new, most are based on CORBA specs that are almost decades old! One should assume that today, in 2007 when recent finalized Web-Service transaction specs are being implemented by the major players in the market that application servers based on “old specs” should be able to participate in distributed transactions, even between different application server vendors.
This is definitely not the case! Do we think matters are better with Web-Services??
Here are the conclusions we have drawn from trying to integrate between different J2EE/JEE application servers, using stateless session beans communicating with RMI/IIOP:
- Don’t assume that transaction propagation works between application servers from different vendors.
- Don’t assume that nice standards mentioned in a feature matrix (e.g. JTS, OTS, JTA) actually ensures some kind of interoperability.
- BEA and IBM seems to have the most mature products regarding transaction interoperability; perhaps because BEA and IBM has been on the OTS working group since way back in the nineties.
Update 2007-06-25: I just found an Oracle document (Oracle Containers for J2EE – Services Guide), reading section 18.104.22.168 it clearly states: “The current release of OC4J is transactionally noninteroperable, so when a transaction spans EJB containers, OC4J raises a specified exception.”
Notes and links
Read this BEA blog entry on why we should not take Oracle seriously as a middleware vendor – I tend to still agree on most of the content, event though it is rather old: http://dev2dev.bea.com/blog/estahl/archive/2005/07/13_reasons_to_t.html
Others have tried to have OC4J interoperate with WebSphere according to this post on Oracle Technology Network discussion forums: http://forums.oracle.com/forums/thread.jspa?messageID=1902636
But it appears that Oracle have no answer when the OC4J is to interoperate with anything but… OC4J. The last comment on this thread is from me trying to provoke a reaction.