Friday, May 02, 2008

Multiple versions of Java on Debian

Goal: To install both Java6 and Java7 from Sun and configure a simple way to change which one is used as system default.

Procedure:

I. Install Java6.

After Sun went GPL with Java, Debian started to include it in the repos, but it usually seriously lags behind, so we will install Java from Sun binary packages which can be downloaded from Sun's website. For this we will need two packages: fakeroot and java-package. The whole process is described here and in short looks like:

1) as a non-root user copy *.bin file to the directory where you have write permission
2) still as a non-root:
$ fakeroot make-jpkg $name_of_java_binary_package
3) accept licence, wait a while when .deb builds
4) as a root install .deb created in pt.3

Remember though that there are some packages that depend explicitly on 'sun-jre-1.6' (package provided by java from Debian repositories), while java created with java-package provides more general 'j2re1.6'. There are also packages that depend specifically on GNU Java (scala for example) so installing those will pull whole new Java stacks. Did anyone say 'dependency mess'?
 

II. Install java7.

Above works like charm for java6, but will fail with java7 because java-package knows nothing about java7 yet. We will have to prepare the configuration ourselves. Basing on info found here that's what we're going to do:

1) use the configuration for java6 as the basis:
$ cp -a /usr/share/java-package/sun-j2sdk1.6 /usr/share/java-package/sun-j2sdk1.7

2) Edit 'install' and 'remove' scripts:
a) update line starting with 'suffix': suffix=j2sdk1.7-sun
b) as of beta26 java7 constains the same list of binaries as java6, so we can leave 'update-alternatives' configuration unchanged

3) update 'sun-j2sdk.sh', add the following to the case statement responsible for handling your architecture:

#jdk-7-ea-bin-b26-linux-i586-24_apr_2008.bin
# WARNING: change following when beta numbers > 99
  "jdk-7-ea-bin-b"[0-9][0-9]"-linux-i586"*)
  j2se_version=1.7+beta${archive_name:14:2}${revision}
  j2se_expected_min_size=130
  found=true
  ;;


Now .deb should build without problems, just like with java6. Install it using your package management software of choice (wajig in my case):

banshee:/usr/src/java# wajig install sun-j2sdk1.7_1.7+beta26_i386.deb

At this point, basically everything is configured, you may use update-alternatives to set which java will be used across the system:

banshee:/etc/alternatives# update-alternatives --config java

There are 4 alternatives which provide `java'.
Selection Alternative
-----------------------------------------------
+ 1 /usr/lib/jvm/java-gcj/jre/bin/java
* 2 /usr/lib/j2sdk1.6-sun/bin/java
  3 /usr/lib/j2sdk1.7-sun/bin/java
  4 /usr/bin/gij-4.3

Press enter to keep the default[*], or type selection number: 3
Using '/usr/lib/j2sdk1.7-sun/bin/java' to provide 'java'.


III. A bit more fun with update-alternatives

To avoid having to manually switch all binaries that come with Java (like javac, javap etc) you can write two simple scripts which will automate the process:

banshee:/etc/alternatives# cat /usr/bin/switch_to_java6
#! /bin/sh
for i in $(ls /usr/lib/j2sdk1.6-sun/bin/); do
  update-alternatives --set $i /usr/lib/j2sdk1.6-sun/bin/$i;
done;

banshee:/etc/alternatives# cat /usr/bin/switch_to_java7
#! /bin/sh
for i in $(ls /usr/lib/j2sdk1.7-sun/bin/); do
  update-alternatives --set $i /usr/lib/j2sdk1.7-sun/bin/$i;
done;


You will see some warnings like:

Using '/usr/lib/j2sdk1.7-sun/bin/jconsole' to provide 'jconsole'.
update-alternatives: Cannot find alternative `/usr/lib/j2sdk1.7-sun/bin/jcontrol'.

That's because not everything contained in jdk's bin/ directory is provided as an alternative. Those warnings are harmless.

No comments: