Java JDK の導入と Hello World!

# Java JDK の導入と Hello World!

## 目的

Java のプログラムをビルド・実行するシンプルな開発環境を構築します。  

## 実現すること

ローカル環境 (Ubuntu) に Java の開発環境をインストールします。  

## 技術背景

### Java JDK とは？  

<details>
<summary>こちらを展開してご覧いただけます。</summary>

### Java JDK

Java JDK とは、Java プログラミング言語で開発されたアプリケーションを作成するためのソフトウェアパッケージです。JDK には、Java 言語で書かれたコードをコンパイルして実行可能なバイナリファイルを生成するための Java コンパイラや、Java アプリケーションを実行するための Java ランタイムが含まれています。

JDK には、Java アプリケーションを開発するために必要な様々なツールやライブラリが含まれているため、Java アプリケーションを開発するためには、JDK のインストールが必要です。

JDK には、Oracle や OpenJDK などの複数の実装があります。ただし、Oracle JDK は商用利用に対してライセンス費用が必要となる(※なった)ため、一般的には OpenJDK (※その系列) が好まれます。

</details>

## 開発環境

+ Windows 11 Home 22H2 を使用しています。  
+ [WSL](https://learn.microsoft.com/ja-jp/windows/wsl/about) の Ubuntu を操作していきますので macOS の方も参考にして頂けます。  

<details>

WSL (Microsoft Store アプリ版)

```sh
> wsl --version
WSL バージョン: 1.0.3.0
カーネル バージョン: 5.15.79.1
WSLg バージョン: 1.0.47
```

Ubuntu

```sh
$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 22.04.1 LTS
Release:        22.04
```

</details>

※ この記事では基本的に Ubuntu のターミナルで操作を行います。

## JDK インストール

存在確認

```sh
$ java -version
コマンド 'java' が見つかりません。次の方法でインストールできます:
※ 以下省略
```

OpenJDK のリストを表示  
※ openjdk-17-jdk があることを確認します。

```sh
$ apt-cache search openjdk
openjdk-17-jdk - OpenJDK Development Kit (JDK)
```

インストール

```sh
$ sudo apt update
$ sudo apt install openjdk-17-jdk
```

バージョン確認

```sh
$ java -version
openjdk version "17.0.5" 2022-10-18
OpenJDK Runtime Environment (build 17.0.5+8-Ubuntu-2ubuntu120.04)
OpenJDK 64-Bit Server VM (build 17.0.5+8-Ubuntu-2ubuntu120.04, mixed mode, sharing)
```

Java JDK (開発環境) を Ubuntu にインストールすることが出来ました。

## JAVA_HOME を設定

JAVA_HOME 設定を追記

```sh
$ vim ~/.bashrc
```

一番下へ次の4行を追加

```sh
# JDK
JAVA_HOME=$(readlink -f /usr/bin/javac | sed "s:/bin/javac::")
export JAVA_HOME
PATH=$PATH:$JAVA_HOME/bin
export PATH
```

設定の反映

```sh
$ source ~/.bashrc
```

パスを確認

```sh
$ echo $JAVA_HOME
/usr/lib/jvm/java-17-openjdk-amd64
$ echo $PATH
```

Java JDK の PATH を設定することが出来ました。

## "Hello World" を表示する手順

プロジェクトフォルダの作成
※ ~/tmp/hello-java をプロジェクトフォルダとします。

```sh
$ cd ~
$ mkdir -p tmp/hello-java
$ cd tmp/hello-java
```

ファイルの作成

```sh
$ vim HelloWorld.java
```

ファイルの内容

```java
public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello World!");
    }
}
```

コンパイル

```sh
$ javac HelloWorld.java
```

実行

```sh
$ java HelloWorld
```

出力

```sh
Hello World!
```

ファイル構成

```sh
$ sudo apt update
$ sudo apt install tree
$ tree
.
├── HelloWorld.class
└── HelloWorld.java
```

ターミナルに "Hello World!" と表示することが出来ました。

## Java のバージョン切り替えについて

※ Ubuntu に異なるバージョンの Java JDK をインストールして、それらを適時切り替えて使用することが出来ます。  

Java 8 LTS と、Java 11 LTS をインストールする  

```sh
$ sudo apt update
$ sudo apt install openjdk-8-jdk
$ sudo apt install openjdk-11-jdk
```

コンパイラのバージョンを切り替え  
※ 1で Java 11 を選択  
※ ここでは update-alternatives を使用します。  

```sh
$ sudo update-alternatives --config javac
alternative javac (/usr/bin/javac を提供) には 3 個の選択肢があります。

  選択肢    パス                                        優先度  状態
------------------------------------------------------------
* 0            /usr/lib/jvm/java-17-openjdk-amd64/bin/javac   1711      自動モード
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/javac   1111      手動モード
  2            /usr/lib/jvm/java-17-openjdk-amd64/bin/javac   1711      手動モード
  3            /usr/lib/jvm/java-8-openjdk-amd64/bin/javac    1081      手動モード
```

ランタイムのバージョンの切り替え  
※ 1で Java 11 を選択  

```sh
$ sudo update-alternatives --config java
alternative java (/usr/bin/java を提供) には 3 個の選択肢があります。

  選択肢    パス                                          優先度  状態
------------------------------------------------------------
* 0            /usr/lib/jvm/java-17-openjdk-amd64/bin/java      1711      自動モード
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      手動モード
  2            /usr/lib/jvm/java-17-openjdk-amd64/bin/java      1711      手動モード
  3            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      手動モード
```

バージョン確認

```sh
$ java -version
openjdk version "11.0.17" 2022-10-18
OpenJDK Runtime Environment (build 11.0.17+8-post-Ubuntu-1ubuntu222.04)
OpenJDK 64-Bit Server VM (build 11.0.17+8-post-Ubuntu-1ubuntu222.04, mixed mode, sharing)
```

$JAVA_HOME を確認

+ WSL Ubuntu再起動  
※ Windows 11 のコマンドプロンプト  

```sh
> wsl -t Ubuntu-22.04
```

Ubuntu のターミナルで確認

```sh
$ echo $JAVA_HOME
/usr/lib/jvm/java-11-openjdk-amd64
```

※ 環境変数も Java 11 に変更されているのが確認出来ます。  

このように Java JDK のバージョンをプロジェクトにあわせ手軽に切り替えることが出来ます。  

## GraalVM ビルド環境

<details>
<summary>こちらを展開してご覧いただけます。</summary>

### GraalVM とは？

GraalVM は、Oracle によって開発された Java 仮想マシンの1つで、Java や Kotlin、Scala などの様々な言語の実行や、ネイティブバイナリへの変換が可能なマルチ言語ランタイム環境です。GraalVM は、通常の Java 仮想マシンよりも高速に実行することができ、また、Java コードをネイティブバイナリに変換することによって、より高速で軽量なアプリケーションを実行できるようになります。また、JavaScript エンジンである Node.js をホストすることもでき、複数の言語の統合において優れた柔軟性を持っています。

### GraalVM インストール

Ubuntu で Native Image ビルドを行うためには以下の手順が必要です。  
※ この記事では手動でインストールする方法で行いました。  

GraalVM を手動で **/usr/lib/jvm/** にインストール

```sh
$ cd ~
$ wget https://github.com/graalvm/graalvm-ce-builds/releases/download/vm-22.3.1/graalvm-ce-java17-linux-amd64-22.3.1.tar.gz
$ sudo mkdir -p /usr/lib/jvm/graalvm-ce-java17-linux-amd64
$ sudo tar zxvf graalvm-ce-java17-linux-amd64-22.3.1.tar.gz -C /usr/lib/jvm/graalvm-ce-java17-linux-amd64 --strip-components=1
```

インストールされた GraalVM のパスを確認

```sh
$ ls -la  /usr/lib/jvm/
graalvm-ce-java17-linux-amd64
```

現在インストールされた JVM を確認  
※ そのまま Enter します。

```sh
$ sudo update-alternatives --config java
  選択肢    パス                                          優先度  状態
------------------------------------------------------------
  0            /usr/lib/jvm/java-17-openjdk-amd64/bin/java      1711      自動モード
  1            /usr/lib/jvm/java-11-openjdk-amd64/bin/java      1111      手動モード
* 2            /usr/lib/jvm/java-17-openjdk-amd64/bin/java      1711      手動モード
  3            /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java   1081      手動モード
```

GraalVM を update-alternatives に設定  
※ 優先順位の数値を 1017 (※任意) に設定しています。  
※ GraalVM の優先順位を下げる意図があります。  

```sh
$ sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/graalvm-ce-java17-linux-amd64/bin/java 1017
$ sudo update-alternatives --install /usr/bin/javac javac /usr/lib/jvm/graalvm-ce-java17-linux-amd64/bin/javac 1017
```

GraalVM に切り替え  
※ GraalVM の番号を選択します。  

```sh
$ sudo update-alternatives --config java
$ sudo update-alternatives --config javac
```

<details>
<summary>削除する場合と自動モードに戻す場合</summary>

※ 削除する場合

```sh
$ sudo update-alternatives --remove java /usr/lib/jvm/graalvm-ce-java17-linux-amd64/bin/java
$ sudo update-alternatives --remove javac /usr/lib/jvm/graalvm-ce-java17-linux-amd64/bin/javac
```

※ 自動モードに戻す場合

```sh
$ sudo update-alternatives --auto java
$ sudo update-alternatives --auto javac
```

</details>

JAVA_HOME を動的に設定しているので Ubuntu を再起動します。  
※ (WSL の場合ターミナルを閉じる)  

バージョン確認  

```sh
$ java -version
openjdk version "17.0.6" 2023-01-17
OpenJDK Runtime Environment GraalVM CE 22.3.1 (build 17.0.6+10-jvmci-22.3-b13)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.1 (build 17.0.6+10-jvmci-22.3-b13, mixed mode, sharing)
```

JVM に GraalVM を設定することが出来ています。  

バージョン確認  

```sh
$ gu --version
GraalVM Updater 22.3.1
```

Native Image コマンドをインストール

```
$ sudo $(which gu) install native-image
Downloading: Component catalog from www.graalvm.org
Processing Component: Native Image
Downloading: Component native-image: Native Image from github.com
Installing new component: Native Image (org.graalvm.native-image, version 22.3.1)
```

バージョン確認

```sh
$ native-image --version
GraalVM 22.3.1 Java 17 CE (Java Version 17.0.6+10-jvmci-22.3-b13)
```

ネイティブバイナリへのビルドに必要なライブラリをインストール

```sh
$ sudo apt update
$ sudo apt install build-essential libz-dev zlib1g-dev
```

</details>

## まとめ

+ Ubuntu に Java JDK をインストールして、最小構成の開発環境を構築することが出来ました。
+ 実際の開発では javac コマンドでコンパイルすることや、java コマンドでクラスファイルを実行することは少ないと思いますが、 Java 開発環境の理解につながると思います。
+ より実践的な Java 開発環境構築 [Maven の導入と Hello World!](https://qiita.com/hiroxpepe/items/40f7f199b9be7f9e3b5b) に続きます。