Time for genuine 'write-once, run-anywhere' Java

One of the big selling points of Java has been its "write once, run anywhere" capabilities. Of course, in practice, this has always been "write once, test everywhere" you intend to deploy your chosen application.

With the planned purchase of BEA Systems by Oracle, I got to thinking about what this meant for the "write once, run anywhere" mantra in relation to application servers.

My thoughts were partly spurred by my need to port a large server application to IBM's WebSphere and Oracle's Application Server from BEA's WebLogic. This left me thinking about the practicalities involved in porting Java, and looking for areas where an ironing out of inconsistencies between Java containers would have a beneficial effect.

As I looked deeper at the challenges the companies would face, it became clear that in many cases the problem with Java portability springs from a combination of developer ignorance and specification omissions - or at least limitations.

When it comes to Java across different Virtual Machines, there are at least two gotchas you should be wary of. The first relates to the type of JVM available. For example, we had an application running on one hardware platform using a 64-bit JVM and all was fine. In moving to a new platform, there was only a 32-bit JVM available. On this platform the application suddenly started experiencing out of memory exceptions. In a similar vain, I know of a colleague who had a working system on a 32-bit JVM but when moving to a 64-bit JVM found that it required more memory.

The second gotcha relates to non-Java standard classes. For example, a little while ago I encountered a developer who had directly referenced the sun.security.provider.X509Factory class; this was only found when the code was run on an IBM JVM and this class was, of course, missing. Perhaps the developer should not have used this class - but nothing actually stopped him from doing so.

Next, there are application-server specific issues. I refer, of course, to those parts of a server-side system that are not specified by Java EE but are needed to correctly deploy an application to the application server. These are application-server specific deployment descriptors (such as weblogic.xml or orion.xml). Each of these files has its own format, which may vary widely (for example WebSphere uses an .XMI format). However, it goes further than that, as in some cases defaults can be assumed and on other application servers no default is provided - or an alternative default is used.

Even in areas you'd expect the Java EE specification to cover have incompatibilities or inconsistencies. As an example, in an ejb-jar.xml file if an unused <resource-ref> is included then some versions of WebLogic ignore the entry while some versions of WebSphere generate misleading error messages.

Transaction management is another minefield, with different application servers having differing defaults - resulting in strange error messages from applications that might work on WebLogic but throw exceptions relating to nested transactions on WebSphere. There are other examples, such as shared connections, where - depending upon the application server - a connection sharing scheme may be emulated or actually shared. The end result may be that a working application on one server may result in unpredictable behavior on another.

Application servers may also implement the Java specification in differing ways. For example, on WebLogic it is possible to have an interface hierarchy in which the remove (Object primaryKey) method occurs both in an application interface and in the EJBHome interface, both of which are used in the same EJB implementation class. While this is fine in WebLogic, errors are generated by the EJB compiler at deployment time in WebSphere.

So there is considerable variability between different application servers for those aspects of an application that sit outside or on the fringe of the specification. Oracle's purchase of BEA at least raises the possibility of the companies working together either on a consolidated application server or on making the two application servers more consistent. If they do this, it will be a considerable step towards establishing an implicit standard in these areas. This may mean greater consensus around how some of these fringe items should work or be defined.

I suspect IBM is unlikely to follow Oracle in ironing out its differences with BEA. However, others in the field - possibly in the open-source camp - might be able to agree a common model and this may become accepted as an implicit standard over time. This can only be a good thing for those of us tasked with the niggling difficulties in working with different Java containers.®