【Java】複数バージョンのJavaを切り替えて使う方法

# はじめに

複数バージョンのJavaをJavaを切り替えて使う方法には、[jenvを使った方法](https://qiita.com/ryotaro76/items/0413ac967d7b4cf30370)などもありますが、ここではオーソドックスなalternativesを使った方法を紹介します。

例えば、以下のようなシーンで役立てられると思うので、alternativesというコマンド名だけでも覚えておくと役に立つかもしれません。

* 古いJavaがインストールされている本番環境に新しいJavaをインストールしたいけれども、不具合が発生した場合に古いJavaへ切り戻したい時。
* テスト環境で複数バージョンのJavaを利用したい時。
* OracleJDKからOpenJDKにサッと切り替えたい時。

# alternativesコマンドとは

alternativesはCentOSに標準で入っているコマンドです。

alternativesをmanコマンドで調べると、"maintain symbolic links determining default commands"と書かれています。
英語だと分かりづらいですが、「シンボリックリンクを活用して、同様の機能を持つソフトウェアや、バージョン違いのソフトを切り替えられる」という優れもののコマンドです。

つまり、 **Javaだけに限らず、様々なコマンドで応用することが可能** です。

# テスト環境

* OS：CentOS 6.10
* インストール済みのJava：Java12（Oracle JDK）
 * RPMでインストールしています。

```
[root@akagi ~]# java -version
java version "12.0.1" 2019-04-16
Java(TM) SE Runtime Environment (build 12.0.1+12)
Java HotSpot(TM) 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)
```

# 事前準備

## 新しいJava（OpenJDK）のインストール

1. [OpenJDKのサイト](https://jdk.java.net/12/)から、Java12のtar.gzをダウンロードします。
2. tar.gzを適当なディレクトリ（※ここでは/usr/local）以下に配置・展開してインストールを完了します。
 * インストールは完了していますが、パスが通っていない状態です。

```
[root@akagi ~]# cd /usr/local/
[root@akagi local]# tar zxvf openjdk-12.0.1_linux-x64_bin.tar.gz 
[root@akagi local]# ls | grep jdk
jdk-12.0.1
openjdk-12.0.1_linux-x64_bin.tar.gz
```

# alternativesコマンドによるJavaの切り替え

## 現在の状態を確認する

* `alternatives --config {総称名(generic name)}`で、現在の状態を対話モードで確認できます。
 * 総称名は"java"や"perl"など、実際に利用しているコマンドを指定します。
* ここでは"java"に対応するコマンドが1つしかないので、[Enter]を押して現在の設定を維持したまま対話モードを抜けます。

```
[root@akagi local]# alternatives --config java

1 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/java/jdk-12.0.1/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:
```

## コマンドの登録～利用するJVMの切り替え

* `alternatives --install {リンク} {総称名(generic name)} {パス} {優先度}`と入力することで、選択肢となるコマンドを登録できます。
 * 存在しない"総称名"を指定した場合、"総称名"のグループが新たに作成されます。
 * 既に存在する"総称名"を指定した場合、同じ"総称名"のグループ内に登録されます。
 * リンクは、総称名のコマンドを実行した際に呼ばれるシンボリックリンクで、"/usr/bin/java"や"/usr/local/bin/perl"などを指定します。
 * パスは、総称名のコマンドを実行した際に実際に実行されるコマンドです。
* 再び`alternatives --config java`と入力して、呼び出されるJVMを切り替えます。
 * [＋]は現在選択されているもので、この時点ではOracleJDKが選択状態となっています。
 * そこで、最後に要求される「選択番号」で2（2番）を入力して、OpenJDKに切り替えます。

```
[root@akagi local]# alternatives --install /usr/bin/java java /usr/local/jdk-12.0.1/bin/java 2
[root@akagi local]# alternatives --config java

2 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*+ 1           /usr/java/jdk-12.0.1/bin/java
   2           /usr/local/jdk-12.0.1/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:2
```

## 設定後の状態を確認する

* 設定完了後に`alternatives --config java`と入力して、現在選択されているJVMを確認します。
 * この時点では2番（OpenJDK）が選択されています。

```
[root@akagi local]# alternatives --config java

2 プログラムがあり 'java' を提供します。

  選択       コマンド
-----------------------------------------------
*  1           /usr/java/jdk-12.0.1/bin/java
 + 2           /usr/local/jdk-12.0.1/bin/java

Enter を押して現在の選択 [+] を保持するか、選択番号を入力します:
```

* 最後にJavaのバージョンを表示して、実際に動作しているのがOpenJDKであることを確認します。

```
[root@akagi local]# java -version
openjdk version "12.0.1" 2019-04-16
OpenJDK Runtime Environment (build 12.0.1+12)
OpenJDK 64-Bit Server VM (build 12.0.1+12, mixed mode, sharing)
```

### その他

* 以下の記事によると、CentOS7系でもalternativesコマンドでJavaのバージョンを切り替えられるようです。
 * [CentOS7系+JDK-9.0.1+JDK1.8.0+alternativesで切り替え](https://qiita.com/edward999th/items/ffec0ff3209797c43da7)

### 参考URL

* [CentOSで「alternatives」コマンドを使用してJavaのバージョンを切り替える](https://necoyama3.hatenablog.com/entry/20110505/1304587888)