Skip to main content

OpenJDK is a very good thing - but you have to test for it

Posted by fabriziogiudici on July 29, 2008 at 2:18 PM PDT

When one month ago it has been announced that OpenJDK had been freed by the last encumbrances, I said I was happy: it was really great news, an important milestone in the opensourcing of Java. A proof of the important benefits of that milestone has been given by the inclusion of OpenJDK in more and more Linux distributions.

But I also said another thing: that even though OpenJDK is guaranteed to be Java, in the sense that it passes the Test Compatibility Kit, if you wish to deploy an application with no Java embedded and you imagine that it could be run with either Sun's JDK/JRE or OpenJDK you have to esplicitly test for both. From my point of view, it is an obvious thing: the two things are different bits, and when you have different bits you have to test for all, even if both are certified in the same way. There's no such a thing as a perfect certification. Looking at comments to my post and other related blogs, not everybody agreed with me.

Unfortunately, I was right, as I've just discovered I'm a first victim of the thing. One of the milestones that I hoped to achieve with blueMarine 0.9.RC3 was the compability with OpenJDK, but now that I managed in testing it, I discovered a showstopper.

In a few words, I made a big mistake in jrawio, which is a ImageI/O provider. I registered some services by means of the META-INF/services facility, and I put them under META-INF/services/javax.imageio.spi.ImageReaderSpi, while two of them are indeed implementations of another interface, ImageInputStreamSpi.

Now, since this code exists since two years and is inside all the versions of blueMarine that have been released in the meantime, it appears that Sun's JDK is forgiving; while OpenJDK throws a ClassCastException:

[exec] java.lang.ClassCastException: Cannot cast it.tidalwave.imageio.io.FileImageInputStream2Spi to javax.imageio.spi.ImageReaderSpi
[exec] at java.lang.Class.cast(Class.java:3007)
[exec] at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:362)
[exec] Caused: java.util.ServiceConfigurationError: javax.imageio.spi.ImageReaderSpi: Provider it.tidalwave.imageio.io.FileImageInputStream2Spi could not be instantiated
[exec] at java.util.ServiceLoader.fail(ServiceLoader.java:224)
[exec] at java.util.ServiceLoader.access$100(ServiceLoader.java:181)
[exec] at java.util.ServiceLoader$LazyIterator.next(ServiceLoader.java:370)
[exec] at java.util.ServiceLoader$1.next(ServiceLoader.java:438)
[exec] at javax.imageio.spi.IIORegistry.registerApplicationClasspathSpis(IIORegistry.java:210)
[exec] at javax.imageio.ImageIO.scanForPlugins(ImageIO.java:109)

Now, I'd like to point out two things:

  1. the behaviour of OpenJDK seems to be more correct than the one of Sun's JDK, but it's a gray area AFAIK (it's exactly the kind of gray area I feared);
  2. it's a fault of mine, and is probably related to lack of tests in jrawio (I still didn't understand what happens to the mistakenly registered services: they are just ignored or they are instantiated? In the latter case, something should be broken in blueMarine, but I didn't realize. To tell the truth this involves the support for a specific Canon file format, which I could have test badly).

Nevertheless, the point is that I have an application which runs quite well on Linux boxes with Sun's JDK; doesn't at all with OpenJDK. I specifically tested it, so I discovered the problem. If I had only announced that blueMarine is automatically fine with OpenJDK I would have faced with shame and disgrace ;-)

So, the morale is that whenever there's a single bit different from a tested configuration, you have to test again. It's the basic rule and you should stick with it.

Technorati Tags: , , ,

Comments

openjdk6 is based on jdk7 bits (it was forked off around jdk7's b23), so it may have some fixes which Sun's 6u* train doesn't (not all fixes are backported to 7). This is likely the reason for the difference in behavior. Dmitri

"Its hasNext and next methods can therefore throw a ServiceConfigurationError if a provider-configuration file violates the specified format, or if it names a provider class that cannot be found and instantiated, or *** if the result of instantiating the class is not assignable to the service type,*** or if any other kind of exception or error is thrown as the next provider is located and instantiated"

BTW, no, I can't see your email address. You can write me at fabrizio dot giudici at tidalwave dot it

Rest assured, I have special interest for Linux and I wish to support the broader range of distros. Given the availability of OpenJDK I want to make it the official supported platform for the Linux world. I'll post more info to the list you cited. I'm sorry for my late responsivity in the last weeks, but I'm also working hard to move all the websites and the forum to a new server - as you can see I'm experiencing high downtimes with the current one, due to a number of reasons. Thanks for your patience.

Thanks a lot -- it is nice to see that the hope that I will have working blueMarine on Fedora is not lost. Is this the problem which causes the problems described here http://thread.gmane.org/gmane.linux.redhat.fedora.java/2657 ? (if yes, could you comment there, please?) If you want somebody to test blueMarine on Fedora with OpenJDK, let me know (I hope this thing shows you my email).