やまものブログ

メモ書きブログです (^_^;A

ubuntu 14.04 に Java Platform (JDK) 8u20 をインストールする

前回の作業では下記のようなコアダンプに頻繁に遭遇しました。

#
# A fatal error has been detected by the Java Runtime Environment:
#
# SIGSEGV (0xb) at pc=0x00007f708af4c2a1, pid=3097, tid=140124088477440
#
# JRE version: OpenJDK Runtime Environment (7.0_55-b14) (build 1.7.0_55-b14)
# Java VM: OpenJDK 64-Bit Server VM (24.51-b03 mixed mode linux-amd64 compressed oops)
# Problematic frame:
# C [libsoup-2.4.so.1+0x6c2a1] soup_session_feature_detach+0x11
#
# Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again

Java を最新にしたら何か変わるのではないかと期待して、これまで使ってきた 1.7.0_55-b14ORACLE のサイトにある 1.8.0_20-b26 に入れかえました。今回は、Javaを入れ替える作業手順についてのメモです。ADT(Android Developer Tools)とは直接関係ありません。

なお、コアダンプについて言及すると、Java1.8.0_20-b26 にアップしても状況は変わりませんでした。コアダンプを再現できる操作手順としては、Run をクリックした後、すぐにもう一度 Run をクリックすると高い確率でコアダンプします。Eclipse とか ADT の内部構造は無知なので憶測ですが、何らかの処理が実行されている最中に別の処理を開始するとコアダンプしやすいような気がしました。Java のバージョンを上げても状況が変わらないということは、旧バージョン 1.7.0_55-b14 自体に問題があるわけではないのでしょう。

以降では、私が行った Java のインストール手順をまとめます。なお、この手順があるべき正しい手順かどうかは分かりません。かなり悩んで憶測で進めたところもありますので。

1. ダウンロード

Get the Android SDK からたどっていくと、最終的には、Java SE Development Kit 8 Downloads に行き着きました。

Oracle Binary Code License Agreement for Java SE to download this software.
で Accept をチェックして、
Linux x64    135.6 MB      jdk-8u20-linux-x64.rpm
をダウンロードしました。

deb ファイルが無かったので、tar.gz  と rpm は迷うところでしたが、Ubunturpm をインストールするには alien というアプリが使えるらしいので rpm にしました。

その alien のインストールから作業です。
$ sudo apt-get -yV install alien
$ alien --version
alien version 8.90

.rpm ファイルを .deb ファイルに変換します。
$ sudo alien --scripts -d jdk-8u20-linux-x64.rpm
jdk1.8.0-20_1.8.020-1_amd64.deb generated

待たされること5分くらい。何か失敗したのではないかと不安にもなりましたが、無事に終了しました。
$ ls -l jdk1.8.0-20_1.8.020-1_amd64.deb
-rw-r--r-- 1 root root 128531854 9月 13 21:28 jdk1.8.0-20_1.8.020-1_amd64.deb

alien に "--scripts" オプションをつけましたが、これが無いと下記のエラーが出ます。この内容は理解していませんが、単純に回避するためにオプションをつけています。
Warning: Skipping conversion of scripts in package jdk1.8.0_20: postinst postrm prerm
Warning: Use the --scripts parameter to include the scripts.

インストールです。
$ sudo dpkg -i jdk1.8.0-20_1.8.020-1_amd64.deb

とくにエラーも無く無事に終了するものの、プロンプトから "java -version" で確認してもバージョンは変わらず 1.7.0_55-b14 のままです

そこで、パッケージ情報を確認します。
$ dpkg --info jdk1.8.0-20_1.8.020-1_amd64.deb
<中略>
Package: jdk1.8.0-20
Version: 1.8.020-1
<以降、省略>

パッケージ名が jdk1.8.0-20 だと分かったので、パッケージに含まれるファイルを確認
$ dpkg -L jdk1.8.0-20 | less
<中略>
/usr/java/jdk1.8.0_20/bin/javac
<以降、省略>

新しい Java/usr/java/jdk1.8.0_20 にインストールされていることが判明しました。
ここで単純に、.profile にて PATH 環境変数/usr/java/jdk1.8.0_20/bin を追加してしまえば、java/javac を切り替えられます。しかし、今まで apt-get や dpkg で PATH を触ったことが無いので、他にあるべき手段があるのではという疑問があったのと、今後の最新版へアップデート作業が間違いなくマニュアルになるのも気持ち悪かったので、調べてみるとありました。それが以降の作業です。

2. update-alternatives

プロンプトから java と入力して実行されるのはリンクのリンクで、下記のとおり /usr/lib/jvm/java-7-openjdk-amd64 に実体があります。

$ which java
/usr/bin/java
$ ls -l /usr/bin/java
lrwxrwxrwx 1 root root 22 12月 21 2013 /usr/bin/java -> /etc/alternatives/java
$ ls -l /etc/alternatives/java
lrwxrwxrwx 1 root root 46 12月 21 2013 /etc/alternatives/java -> /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
$ ls -l /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java
-rwxr-xr-x 1 root root 6368 4月 18 10:04 /usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java

このリンクの管理は update-alternatives というコマンドでできるようです。下記はヘルプです。
$ update-alternatives --help
使い方: update-alternatives [<オプション> ...] <コマンド>

コマンド:
--install <リンク> <名前> <パス> <優先度>
[--slave <リンク> <名前> <パス>] ...
システムに alternatives のグループを追加する
--remove <名前> <パス> <名前> のグループ alternative から <パス> を削除する
--remove-all <名前> alternatives システムから <名前> のグループを削除する
--auto <名前> マスターリンク <名前> を、自動モードに切り替える
--display <名前> <名前> グループについての情報を表示する
--query <名前> --display <名前> の機械解析向けバージョン
--list <名前> <名前> グループのすべてのターゲットを表示する
--get-selections マスター alternative 名およびその状態を一覧する
--set-selections 標準入力から alternative 状態を読み込む
--config <名前> <名前> グループの alternatives を表示し、ユーザに
使用したいものを尋ねる
--set <名前> <パス> <名前> の alternative として <パス> を設定する
--all すべての alternatives に対して --config を呼び出す

<リンク> は /etc/alternatives/<名前> を指すシンボリックリンクです。
(例: /usr/bin/pager)
<名前> はこのリンクグループのマスター名です。
(例: pager)
<パス> は alternative ターゲットファイルのうちの 1 つの場所です。
(例: /usr/bin/less)
<優先度> は整数です; より大きな数を持つ選択肢は、自動モードにおいてより高い
優先度を持ちます。

オプション:
--altdir <ディレクトリ> alternatives ディレクトリを変更する
--admindir <ディレクトリ> 管理ディレクトリを変更する
--log <ファイル> ログファイルを変更する
--force alternative リンク付きのファイルの置換を許容する
--skip-auto 自動モードにおいて、正しく設定された alternatives
のプロンプトをスキップする (--config にのみ関連)
--verbose 冗長操作として、多く出力する
--quiet 静かな操作として、最小限の出力にする
--help このヘルプを表示する
--version バージョン番号を表示する

ここで、java グループのターゲットを確認すると、新たにインストールした jdk1.8.0-20 が見当たりません。
$ update-alternatives --list java
/usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java

さらに、update-alternatives が管理するマスター名の一覧を確認します。
$ update-alternatives --get-selections

これの出力は長いので掲載しませんが、javagrep すると 39 個も該当します。

jdk1.8.0-20 を追加するには、java 関連マスター 39個を一つ一つ --install で登録していくことになります。そのためのスクリプトを以下のように作って実行しました。
sudo update-alternatives --install /usr/bin/java java /usr/java/jdk1.8.0_20/jre/bin/java 1072
sudo update-alternatives --install /usr/bin/keytool keytool /usr/java/jdk1.8.0_20/jre/bin/keytool 1072
sudo update-alternatives --install /usr/bin/pack200 pack200 /usr/java/jdk1.8.0_20/jre/bin/pack200 1072
sudo update-alternatives --install /usr/bin/rmid rmid /usr/java/jdk1.8.0_20/jre/bin/rmid 1072
sudo update-alternatives --install /usr/bin/rmiregistry rmiregistry /usr/java/jdk1.8.0_20/jre/bin/rmiregistry 1072
sudo update-alternatives --install /usr/bin/unpack200 unpack200 /usr/java/jdk1.8.0_20/jre/bin/unpack200 1072
sudo update-alternatives --install /usr/bin/orbd orbd /usr/java/jdk1.8.0_20/jre/bin/orbd 1072
sudo update-alternatives --install /usr/bin/servertool servertool /usr/java/jdk1.8.0_20/jre/bin/servertool 1072
sudo update-alternatives --install /usr/bin/tnameserv tnameserv /usr/java/jdk1.8.0_20/jre/bin/tnameserv 1072
sudo update-alternatives --install /usr/bin/jexec jexec /usr/java/jdk1.8.0_20/jre/lib/jexec 1072
sudo update-alternatives --install /usr/bin/policytool policytool /usr/java/jdk1.8.0_20/jre/bin/policytool 1072
sudo update-alternatives --install /usr/bin/appletviewer appletviewer /usr/java/jdk1.8.0_20/bin/appletviewer 1072
sudo update-alternatives --install /usr/bin/extcheck extcheck /usr/java/jdk1.8.0_20/bin/extcheck 1072
sudo update-alternatives --install /usr/bin/idlj idlj /usr/java/jdk1.8.0_20/bin/idlj 1072
sudo update-alternatives --install /usr/bin/jar jar /usr/java/jdk1.8.0_20/bin/jar 1072
sudo update-alternatives --install /usr/bin/jarsigner jarsigner /usr/java/jdk1.8.0_20/bin/jarsigner 1072
sudo update-alternatives --install /usr/bin/javac javac /usr/java/jdk1.8.0_20/bin/javac 1072
sudo update-alternatives --install /usr/bin/javadoc javadoc /usr/java/jdk1.8.0_20/bin/javadoc 1072
sudo update-alternatives --install /usr/bin/javah javah /usr/java/jdk1.8.0_20/bin/javah 1072
sudo update-alternatives --install /usr/bin/javap javap /usr/java/jdk1.8.0_20/bin/javap 1072
sudo update-alternatives --install /usr/bin/jcmd jcmd /usr/java/jdk1.8.0_20/bin/jcmd 1072
sudo update-alternatives --install /usr/bin/jconsole jconsole /usr/java/jdk1.8.0_20/bin/jconsole 1072
sudo update-alternatives --install /usr/bin/jdb jdb /usr/java/jdk1.8.0_20/bin/jdb 1072
sudo update-alternatives --install /usr/bin/jhat jhat /usr/java/jdk1.8.0_20/bin/jhat 1072
sudo update-alternatives --install /usr/bin/jinfo jinfo /usr/java/jdk1.8.0_20/bin/jinfo 1072
sudo update-alternatives --install /usr/bin/jmap jmap /usr/java/jdk1.8.0_20/bin/jmap 1072
sudo update-alternatives --install /usr/bin/jps jps /usr/java/jdk1.8.0_20/bin/jps 1072
sudo update-alternatives --install /usr/bin/jrunscript jrunscript /usr/java/jdk1.8.0_20/bin/jrunscript 1072
sudo update-alternatives --install /usr/bin/jsadebugd jsadebugd /usr/java/jdk1.8.0_20/bin/jsadebugd 1072
sudo update-alternatives --install /usr/bin/jstack jstack /usr/java/jdk1.8.0_20/bin/jstack 1072
sudo update-alternatives --install /usr/bin/jstat jstat /usr/java/jdk1.8.0_20/bin/jstat 1072
sudo update-alternatives --install /usr/bin/jstatd jstatd /usr/java/jdk1.8.0_20/bin/jstatd 1072
sudo update-alternatives --install /usr/bin/native2ascii native2ascii /usr/java/jdk1.8.0_20/bin/native2ascii 1072
sudo update-alternatives --install /usr/bin/rmic rmic /usr/java/jdk1.8.0_20/bin/rmic 1072
sudo update-alternatives --install /usr/bin/schemagen schemagen /usr/java/jdk1.8.0_20/bin/schemagen 1072
sudo update-alternatives --install /usr/bin/serialver serialver /usr/java/jdk1.8.0_20/bin/serialver 1072
sudo update-alternatives --install /usr/bin/wsgen wsgen /usr/java/jdk1.8.0_20/bin/wsgen 1072
sudo update-alternatives --install /usr/bin/wsimport wsimport /usr/java/jdk1.8.0_20/bin/wsimport 1072
sudo update-alternatives --install /usr/bin/xjc xjc /usr/java/jdk1.8.0_20/bin/xjc 1072
#sudo update-alternatives --install /usr/bin/mozilla-javaplugin.so mozilla-javaplugin.so /usr/java/jdk1.8.0_20/jre/lib/amd64/IcedTeaPlugin.so 1072
なお、上記の各コマンドの末尾にある<優先度>1072 を指定したのは、1.7.0_55-b141071 だったので +1 してみただけで、これがいいのかどうかは不明です。

上記のコマンドを実行することで、java グループのターゲットに新たにインストールした jdk1.8.0-20 があらわれます。
$ update-alternatives --list java
/usr/java/jdk1.8.0_20/jre/bin/java
/usr/lib/jvm/java-7-openjdk-amd64/jre/bin/java

3. update-java-alternatives

切り替える対象が java 1つだけなら update-alternatives の "--set" オプションで設定するだけで充分ですが、39個もあると大変です。これを便利に一括切り替えしてくれるのが、update-java-alternatives で、コマンドのヘルプは以下のとおりです。

$ update-java-alternatives --help
usage: update-java-alternatives [--jre-headless] [--jre] [--plugin] [ -t|--test|-v|--verbose]
-l|--list [<jname>]
-s|--set <jname>
-a|--auto
-h|-?|--help

update-java-alternatives を使うには、/usr/lib/jvm/ の下に .jinfo なるファイルが必要です。
この時点では 1.7.0_55-b14.jinfo しか存在しません。alien/dpkg を上手く使えていれば、生成されたのかもしれませんが。。。

$ ls -la /usr/lib/jvm/.*.jinfo
-rw-r--r-- 1 root root 2439 4月 18 10:03 /usr/lib/jvm/.java-1.7.0-openjdk-amd64.jinfo

そこで、1.7.0_55-b14.jinfo を見よう見真似で jdk1.8.0_20 のものを作りました。

-rw-rw-r-- 1 root root 1959  9月 15 00:26 /usr/lib/jvm/.jdk1.8.0_20.jinfo
name=jdk1.8.0_20
alias=jdk1.8.0_20
priority=1072
section=main

hl java /usr/java/jdk1.8.0_20/jre/bin/java
hl keytool /usr/java/jdk1.8.0_20/jre/bin/keytool
hl pack200 /usr/java/jdk1.8.0_20/jre/bin/pack200
hl rmid /usr/java/jdk1.8.0_20/jre/bin/rmid
hl rmiregistry /usr/java/jdk1.8.0_20/jre/bin/rmiregistry
hl unpack200 /usr/java/jdk1.8.0_20/jre/bin/unpack200
hl orbd /usr/java/jdk1.8.0_20/jre/bin/orbd
hl servertool /usr/java/jdk1.8.0_20/jre/bin/servertool
hl tnameserv /usr/java/jdk1.8.0_20/jre/bin/tnameserv
hl jexec /usr/java/jdk1.8.0_20/jre/lib/jexec
jre policytool /usr/java/jdk1.8.0_20/jre/bin/policytool
jdk appletviewer /usr/java/jdk1.8.0_20/bin/appletviewer
jdk extcheck /usr/java/jdk1.8.0_20/bin/extcheck
jdk idlj /usr/java/jdk1.8.0_20/bin/idlj
jdk jar /usr/java/jdk1.8.0_20/bin/jar
jdk jarsigner /usr/java/jdk1.8.0_20/bin/jarsigner
jdk javac /usr/java/jdk1.8.0_20/bin/javac
jdk javadoc /usr/java/jdk1.8.0_20/bin/javadoc
jdk javah /usr/java/jdk1.8.0_20/bin/javah
jdk javap /usr/java/jdk1.8.0_20/bin/javap
jdk jcmd /usr/java/jdk1.8.0_20/bin/jcmd
jdk jconsole /usr/java/jdk1.8.0_20/bin/jconsole
jdk jdb /usr/java/jdk1.8.0_20/bin/jdb
jdk jhat /usr/java/jdk1.8.0_20/bin/jhat
jdk jinfo /usr/java/jdk1.8.0_20/bin/jinfo
jdk jmap /usr/java/jdk1.8.0_20/bin/jmap
jdk jps /usr/java/jdk1.8.0_20/bin/jps
jdk jrunscript /usr/java/jdk1.8.0_20/bin/jrunscript
jdk jsadebugd /usr/java/jdk1.8.0_20/bin/jsadebugd
jdk jstack /usr/java/jdk1.8.0_20/bin/jstack
jdk jstat /usr/java/jdk1.8.0_20/bin/jstat
jdk jstatd /usr/java/jdk1.8.0_20/bin/jstatd
jdk native2ascii /usr/java/jdk1.8.0_20/bin/native2ascii
jdk rmic /usr/java/jdk1.8.0_20/bin/rmic
jdk schemagen /usr/java/jdk1.8.0_20/bin/schemagen
jdk serialver /usr/java/jdk1.8.0_20/bin/serialver
jdk wsgen /usr/java/jdk1.8.0_20/bin/wsgen
jdk wsimport /usr/java/jdk1.8.0_20/bin/wsimport
jdk xjc /usr/java/jdk1.8.0_20/bin/xjc
plugin mozilla-javaplugin.so /usr/java/jdk1.8.0_20/jre/lib/amd64/IcedTeaPlugin.so

さらに、/usr/lib/jvm/ に実体のインストールパスへのリンクを作成します。
$ cd /usr/lib/jvm/
$ sudo ln -s /usr/java/jdk1.8.0_20 .

これで、ようやく、Java を切り替えられます。
$ sudo update-java-alternatives -s jdk1.8.0_20
update-alternatives: エラー: mozilla-javaplugin.so の alternatives がありません
update-java-alternatives: plugin alternative does not exist: /usr/java/jdk1.8.0_20/jre/lib/amd64/IcedTeaPlugin.so

エラーは mozillaプラグインが無いという内容です。これはもともと 1.7.0_55-b14 でもインストールされておらず、現在使用中の Firefoxプラグインの一覧にもそれらしきものが無いため、無視しました。
なお、IcedTea に関する情報は Wiki サイト IcedTea にありましたが、軽く読んだだけではよく理解できませんでした。とりあえず、 Firefoxプラグインとしては、
IcedTea NPR Web BRowser Plugin (...
と表示されるようです。

以上で、めでたく、java のバージョンは切り替わったようです。
$ java -version
java version "1.8.0_20"
Java(TM) SE Runtime Environment (build 1.8.0_20-b26)
Java HotSpot(TM) 64-Bit Server VM (build 25.20-b23, mixed mode)
$ javac -version
javac 1.8.0_20

冒頭で述べたとおり、これで ADT でのコアダンプが減ったわけではありません
次回からまた ADT の Training に戻りたいと思っています