Saturday, 29 May 2010

Oracle Sun JDK vs OpenJDK

These days Ubuntu comes with Open JDK installed as standard. Many Java programmers replace this immediately with the Oracle Sun JDK.

So what's the difference? Well, the OpenJDK is a 100% open-source implementation of the Java language specification. The Oracle Sun JDK is largely open-source but still contains some precompiled binaries that Sun didn't have copyright to release under an open-source license.

You can read more here:

Oracle - Free and Open Source Java

I've always tended to replace the OpenJDK with Sun Java, but since installing Ubuntu 10.04 Lucid Lynx, I've been seeing how I get on with the OpenJDK. To date, developing straightforward Java, JSP and servlets with Spring, Struts2, Hibernate and Maven deployed on Tomcat, has worked perfectly well. I've also been using the IcedTea plugin in Firefox with no issues.

But yesterday, I hit my first snag. If you read my previous post you'll know that I've been looking into the new annotations in the Servlet 3.0 specification: @WebServlet, @WebFilter and @WebListener. To get examples to run I had to install Glassfish v3. All was well until I tried to run the Admin Console and I got this error:

java.lang.UnsupportedOperationException: Cannot create XMLStreamReader or XMLEventReader from a
javax.xml.transform.stream.StreamSource
        at com.sun.xml.internal.stream.XMLInputFactoryImpl.jaxpSourcetoXMLInputSource(XMLInputFactoryImpl.java:283)
        at com.sun.xml.internal.stream.XMLInputFactoryImpl.createXMLStreamReader(XMLInputFactoryImpl.java:143)
        at org.jvnet.hk2.config.ConfigParser.parse(ConfigParser.java:109)
        at org.jvnet.hk2.config.ConfigParser.parse(ConfigParser.java:104)
        at org.jvnet.hk2.config.ConfigParser.parse(ConfigParser.java:100)
        at org.glassfish.admingui.plugin.ConsolePluginService.init(ConsolePluginService.java:121)
        at org.glassfish.admingui.plugin.ConsolePluginService.getIntegrationPoints(ConsolePluginService.java:423)
        at org.glassfish.admingui.common.handlers.PluginHandlers.getIntegrationPoints(PluginHandlers.java:160)
        at org.glassfish.admingui.handlers.ThemeHandlers.getThemeFromIntegrationPoints(ThemeHandlers.java:98)
        ... 47 more

That didn't worry me too much at the time, but I was also getting some odd behaviour with Java Server Faces (JSF) applications that I hadn't seen on Tomcat. Most of the time I'm able to switch freely between one and the other with web applications.

So, based on a forum post about the problems with the Glassfish admin console, I installed all the Sun Java 6 components. My problems with the admin console disappeared and my JSF application started behaving normally again. So, on that basis, there seem to be glitches with JSF using the current version of the OpenJDK. The Glassfish admin console is based on JSF.

If you need to replace your OpenJDK installation on Ubuntu 10.04, these are the steps:

  1. Enable the partner repositories: System -> Administration -> Software Sources and check the box for http://archive.canonical.com/ubuntu lucid partner in the Other Sources tab. You might also want the sources checked too.
  2. Install the Sun Java6 packages: sun-java6-jdk, sun-java6-jre, sun-java6-source, sun-java6-fonts, sun-java6-bin and possibly sun-java6-plugin.

You'll then need to switch your default Java to the Oracle Sun version:

$ sudo update-java-alternatives -v -s java-6-sun

Do also check that you haven't hard-coded OpenJDK into any JAVA_HOME variables or application settings.

3 comments:

tiede said...

Hi - thanks a lot.. That helped me with my glassfish/openjdk problem :-)

Anonymous said...

Hi
Thanks very much for this.
As a Linux newb and an experienced (tho self-taught) java programmer, can I ask you to just clarify sthg:
- your command "update-java-alternatives" means I have switched to the Sun java JRE, right?
- but is it not the javac binary belonging to the Sun JDK which I need to specify when compiling code? Presumably there are two such files, one belonging to OpenJDK, the other to Sun JDK...?
- so how does the system know which one to use (and where are they kept, by the way)?

Hope you can find time to answer: my email is cscupost@hotmail.com.

Richard Senior said...

If you run "which javac", you will see that the javac in your path is a symbolic link to /etc/alternatives/javac. This is the Java compiler that you will run when you compile code.

When you run update-java-alternatives -s java-6-sun, it creates symbolic links for each component in /etc/alternatives. If you look at /etc/alternatives/javac, you will find it points to /usr/lib/jvm/java-6-sun/bin/javac, which in turn is a symbolic link to the latest Sun JDK at /usr/lib/jvm/java-6-sun-1.6.0.22.

Run update-java-alternatives for the OpenJDK implementation and symbolic links will be created to the binaries under /usr/lib/jvm/java-6-openjdk.

The update-java-alternatives command uses metadata files for each Java implementation. You can find them in /usr/lib/jvm/.*.jinfo on Ubuntu. These files specify locations of various components provided by the implementation, e.g. javac, and are used to create appropriate symbolic links for javac, java, jar, javadoc and other utilities.

For more information:

$ man update-java-alternatives

It's not "my" command by the way. I believe it's Ubuntu, originating in Debian.

If you are in doubt as to which versions are actually active after all these layers of symbolic links:

$ java -version
java version "1.6.0_22"
Java(TM) SE Runtime Environment (build 1.6.0_22-b04)
Java HotSpot(TM) 64-Bit Server VM (build 17.1-b03, mixed mode)

That's the Oracle (Sun) virtual machine, as opposed to the Open JDK:

$ java -version
java version "1.6.0_20"
OpenJDK Runtime Environment (IcedTea6 1.9.1) (6b20-1.9.1-1ubuntu3)
OpenJDK 64-Bit Server VM (build 17.0-b16, mixed mode)

Followers