2011年12月22日木曜日

(続報) Ubuntu 11.10 "Oneiric Ocelot" での sun-java6-jdk パッケージについて

全くもって面倒なことになりました。

何がというと Japanese Team からもアナウンスと解説が ML にポストされた Oracle(Sun) 由来の JDK に関する問題です。

sun-java6-jdk に関する話題はこの Blog でも Oneiric Ocelot (11.10) にからめて取り上げましたけれども、過去の Ubuntu においても直面することになりました。さらに悪いことに partner レポジトリや LffL Java PPA で配布されてきた最終版はセキュリティ上の問題があるということで、本格的に対処する必要が出てきました。

ML での解説では OpenJDK もしくは Oracle JDK を本家からダウンロードしたものを導入するという 2つの選択肢が示されていますが、Oracle JDK を前提とした開発を行わなければならないシーンがまだまだ存在するのも事実です。

そういったわけで、前回の記事の続きという位置づけで、Oracle JDK の導入方法について書いてみたいと思います。

Oracle JDK 配布ファイルの入手


まずは Oracle のサイトから JDK を入手します。Java SE Downloads のサイトから Java SE 6 Update 30 ( Update バージョンは今後も更新される可能性があるので適宜読み替えてください ) の JDK Download リンクとたどります。

そして、 Oracle Binary Code License Agreement for Java SE に同意した上でファイルをダウンロードします。 Ubuntu の場合パッケージ管理は .deb 形式ですので、 i386 アーキテクチャでは jdk-6u30-linux-i586.bin 、amd64 アーキテクチャでは  jdk-6u30-linux-x64.bin をダウンロードすることとなります(バージョンが変わるとファイル名も変わりますが適宜読み替えてください)。

JDK の展開


次にダウンロードしたものを展開します。従来であれば /usr/lib/jvm/ 以下に展開すべきところなのですが、このようなひどい仕打ちをするものを /usr 以下に入れるのはちょっとはばかられるので、/opt 行きにしたいと思います。 /opt 以下は /opt/(パッケージ名) もしくは /opt/(LANANAプロバイダ名) といった風にディレクトリを作成することになっていますが、LANANAプロバイダのリストには Sun は登録されていますが、Oracle は登録されていないという状況なので、/opt/jvm を使うことにしたいと思います。とりあえずディレクトリを作成しておきます。

# mkdir -p /opt/jvm

そして、先ほどダウンロードした配布ファイルを展開します。配布ファイルは自己展開することを前提に作られているようなので、chmod +x で実行できるようにして -noregister オプションをつけて実行します。

余談ですが、 -noregister をつけずに実行すると現状では Oracle にこういった情報が登録されるようです。この辺のポリシーについては今後も変更されうることを念頭に入れながら、 -noregister オプションをつけ忘れることも考えて一旦展開は一般ユーザで実施し、その後しかるべき場所にコピーするくらいの慎重さがあっても良いような気がします。

i386アーキテクチャの場合:
$ cd /path/to/download (ダウンロードしたディレクトリに移動)
$ chmod +x jdk-6u30-linux-i586.bin

$ ./jdk-6u30-linux-i586.bin -noregister

Unpacking...
Checksumming...
Extracting...
UnZipSFX 5.50 of 17 February 2002, by Info-ZIP (Zip-Bugs@lists.wku.edu).
   creating: jdk1.6.0_30/
   creating: jdk1.6.0_30/jre/
   creating: jdk1.6.0_30/jre/bin/
  inflating: jdk1.6.0_30/jre/bin/java

... (途中略) ...

Creating jdk1.6.0_30/lib/tools.jar
Creating jdk1.6.0_30/jre/lib/ext/localedata.jar
Creating jdk1.6.0_30/jre/lib/plugin.jar
Creating jdk1.6.0_30/jre/lib/javaws.jar
Creating jdk1.6.0_30/jre/lib/deploy.jar
Done.

$

amd64アーキテクチャの場合:
$ cd /path/to/download (ダウンロードしたディレクトリに移動)
$ chmod +x jdk-6u30-linux-x64.bin

$ ./jdk-6u30-linux-x64.bin
... (以下メッセージ省略) ...

展開が終わったら /opt/jvm に JDK のファイル群をコピーします。また、コピー元のファイルは不要なので消しておきます。

# cp -r /path/to/download/jdk1.6.0_30 /opt/jvm/
$ rm -r /path/to/download/jdk1.6.0_30
i386アーキテクチャの場合:
$ rm /path/to/jdk-6u30-linux-i586.bin
amd64アーキテクチャの場合:
$ rm /path/to/jdk-6u30-linux-x64.bin

なお、展開されるディレクトリはアーキテクチャによらず jdk.1.6.0_30 となっているようです。また、間違ったアーキテクチャの配布ファイルを展開しようとするとエラーになります。

インストールした JDK を使えるようにする


従来は update-alternative コマンドで使用する各種コマンドを切り替えるということをやってきたわけで、その気になれば Oracle JDK についても同じように設定することが可能ではあるのですが、もはや「Ubuntuの外のモノ」として扱わざるをえない状況になりましたので、使いたいユーザがそれぞれ設定をするということにとどめることにしたいと思います。

基本的に JAVA_HOME 環境変数と PATH を適切に設定すれば使えることになっているので、ホームディレクトリの .profile に

11 # if running bash
12 if [ -n "$BASH_VERSION" ]; then
13     # include .bashrc if it exists
14     if [ -f "$HOME/.bashrc" ]; then
15         . "$HOME/.bashrc"
16     fi
17 fi
18
19 JAVA_HOME=/opt/jvm/jdk1.6.0_30
20 for binpath in jre/bin bin ; do
21     if [ -d "$JAVA_HOME/$binpath" ] ; then
22         PATH="$JAVA_HOME/$binpath:$PATH"
23     fi
24 done
25
26 # set PATH so it includes user's private bin if it exists
27 if [ -d "$HOME/bin" ] ; then
28     PATH="$HOME/bin:$PATH"
29 fi

といった具合に書いておくとよいかと思います(この例では19~24行目に記述を挿入しました)。
ログインしなおすか

$ . ~/.profile

として設定を再読み込みさせた上で

$ which java
/opt/jvm/jdk1.6.0_30/bin/java
$ java -version
java version "1.6.0_30"
Java(TM) SE Runtime Environment (build 1.6.0_30-b12)
Java HotSpot(TM) Client VM (build 20.5-b03, mixed mode)

と表示されるようになれば作業完了です。

あとは必要に応じてOracle JDK を必要とするユーザに同じような設定を行います。

古い sun-java6 パッケージの削除


最新の Oracle JDK への移行が一段落ついた段階で、古い(そしてセキュリティ上問題のある)sun-java6 パッケージ群を削除します。MLでの解説にもありますがパッケージは

$ dpkg -l '*sun-java6*'

コマンドで調べることができますので、それぞれ

# apt-get purge sun-java-6-jdk

などといったようにして削除します。また、前回紹介しました LffL Java PPA でインストールした場合には、

# add-apt-repository --remove ppa:ferramroberto/java

でレポジトリを削除することができます(がちょっとバグがあって deb-src ラインが削除されなかったりもしますがその辺は現状で必要に応じて対応して下さい)。

ちょっと苦言言わせてください


開発元が買収され方針が変わったということは理解できるのですが、このように各方面に大きな影響を与えうるビジネスやライセンス上の変更を予告などをすることなしに実施してしまうという体質は正直ほめられたものではないと思います。

ベンダーにはベンダーの考え方というものがあるのでしょうけれども将来自分たちの首をしめることにならないように自制の効いた運用をして欲しいと切に願います。Java に限った話ではないのですが、エンジニアの反感を買うようなことは何も生み出さないと思います。