UbuntuにOpenJDK21をインストール

目次

Ubuntuを 20.04.3 から 22.04.5 にアップグレードしたらJavaが動作しなくなりました。 動かなくなったOpen JDK16の変わりにOpen JDK21をインストールします。

環境は Ubuntu 22.04.5 LTS です。

javacによるコンパイルができなくなった

ubuntuのアップグレード後javaのソースファイルをコンパイルしようとしたところjavacが見つからないと表示されるようになりました。 使用していたOpen JDK16は長期サポートではなかったので新しいバージョンを使用することにします。

ubuntu wiki - OpenJDK アップデート

長期サポートは11, 17, 21が対象のようですので新しい21をインストールすることにしました。

$ java -version
openjdk version "16.0.1" 2021-04-20
OpenJDK Runtime Environment (build 16.0.1+9-Ubuntu-120.04)
OpenJDK 64-Bit Server VM (build 16.0.1+9-Ubuntu-120.04, mixed mode, sharing)
$ javac -version
コマンド 'javac' が見つかりません。次の方法でインストールできます:
sudo apt install openjdk-11-jdk-headless  # version 11.0.24+8-1ubuntu3~22.04, or
sudo apt install default-jdk              # version 2:1.11-72build2
sudo apt install openjdk-17-jdk-headless  # version 17.0.12+7-1ubuntu2~22.04
sudo apt install openjdk-18-jdk-headless  # version 18.0.2+9-2~22.04
sudo apt install openjdk-19-jdk-headless  # version 19.0.2+7-0ubuntu3~22.04
sudo apt install openjdk-21-jdk-headless  # version 21.0.4+7-1ubuntu2~22.04
sudo apt install openjdk-8-jdk-headless   # version 8u422-b05-1~22.04
sudo apt install ecj                      # version 3.16.0-1

インストールするパッケージの確認

aptをアップデートして"openjdk-21"で検索してみると以下のパッケージが見つかりました。

$ sudo apt update
$ apt --names-only search 'openjdk-21'
ソート中... 完了
全文検索... 完了  
openjdk-21-dbg/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  Java runtime based on OpenJDK (debugging symbols)

openjdk-21-demo/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  Java runtime based on OpenJDK (demos and examples)

openjdk-21-doc/jammy-updates,jammy-updates,jammy-security,jammy-security 21.0.5+11-1ubuntu1~22.04 all
  OpenJDK Development Kit (JDK) documentation

openjdk-21-jdk/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  OpenJDK Development Kit (JDK)

openjdk-21-jdk-headless/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  OpenJDK Development Kit (JDK) (headless)

openjdk-21-jre/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  OpenJDK Java runtime, using Hotspot JIT

openjdk-21-jre-headless/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  OpenJDK Java runtime, using Hotspot JIT (headless)

openjdk-21-jre-zero/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  Alternative JVM for OpenJDK, using Zero

openjdk-21-source/jammy-updates,jammy-updates,jammy-security,jammy-security 21.0.5+11-1ubuntu1~22.04 all
  OpenJDK Development Kit (JDK) source files

openjdk-21-testsupport/jammy-updates,jammy-security 21.0.5+11-1ubuntu1~22.04 amd64
  Java runtime based on OpenJDK (regression test support)

headlessとついているパッケージはサーバー向けでユーザーインターフェイスに関するサポートをしないバージョンなのでopenjdk-21-jdkを使用します。

openjdk-21-jdkの情報は次の通りです。

$ apt show openjdk-21-jdk
Package: openjdk-21-jdk
Version: 21.0.5+11-1ubuntu1~22.04
Priority: optional
Section: universe/java
Source: openjdk-21
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: OpenJDK Team <openjdk-21@packages.debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 3,626 kB
Provides: java-compiler, java-sdk (= 21), java10-sdk, java11-sdk, java12-sdk, java13-sdk, java14-sdk, java15-sdk, java16-sdk, java17-sdk, java18-sdk, java19-sdk, java2-sdk, java20-sdk, java21-sdk, java5-sdk, java6-sdk, java7-sdk, java8-sdk, java9-sdk
Depends: openjdk-21-jre (= 21.0.5+11-1ubuntu1~22.04), openjdk-21-jdk-headless (= 21.0.5+11-1ubuntu1~22.04), libc6 (>= 2.34), zlib1g (>= 1:1.1.4)
Recommends: libxt-dev
Suggests: openjdk-21-demo, openjdk-21-source, visualvm
Homepage: https://openjdk.java.net/
Download-Size: 3,424 kB
APT-Sources: http://jp.archive.ubuntu.com/ubuntu jammy-updates/universe amd64 Packages
Description: OpenJDK Development Kit (JDK)
 OpenJDK is a development environment for building applications,
 applets, and components using the Java programming language.

Open JDK21のインストール

aptコマンドでインストールします。

$ sudo apt install openjdk-21-jdk

インストールが終わったのでjava実行環境のバージョンを確認します。

$ java -version
openjdk version "21.0.5" 2024-10-15
OpenJDK Runtime Environment (build 21.0.5+11-Ubuntu-1ubuntu122.04)
OpenJDK 64-Bit Server VM (build 21.0.5+11-Ubuntu-1ubuntu122.04, mixed mode, sharing)

javaコンパイラのバージョンを確認します。

$ javac -version
javac 21.0.5

環境変数を設定

Javaアプリケーションによって使われる環境変数を設定します。

JAVA_HOMEはJDKをインストールしたフォルダを設定します。 update-alternativesコマンドで確認します。

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

  選択肢    パス                                       優先度  状態
------------------------------------------------------------
* 0            /usr/lib/jvm/java-21-openjdk-amd64/bin/java   2111      自動モード
  1            /usr/lib/jvm/java-16-openjdk-amd64/bin/java   1611      手動モード
  2            /usr/lib/jvm/java-21-openjdk-amd64/bin/java   2111      手動モード

現在の選択 [*] を保持するには <Enter>、さもなければ選択肢の番号のキーを押してください: 

環境変数を設定するファイルは、共通して定義する場合は"/etc/environment"に、ユーザーごとに定義する場合は"~/.bashrc"に定義します。 パスの"/bin/java"は含めずにファイルに保存します。

今回は"/etc/environment"ファイルに設定しました。

JAVA_HOME="/usr/lib/jvm/java-21-openjdk-amd64"

現在のセッションに変更を反映させます。

$ source /etc/environment

設定を確認します。

$ echo $JAVA_HOME
/usr/lib/jvm/java-21-openjdk-amd64

Javaファイルをコンパイルする

確認用に"HELLO WORLD!“と表示するJavaソースファイルをコンパイルして実行してみます。

“HelloWorld.java”

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

// Hello World! と表示するプログラム
public class HelloWorld extends JFrame implements ActionListener {
    // 文字を表示するラベル
    JLabel label;

    HelloWorld() {
        setTitle("Hello World!");
        setSize(800, 200);
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 文字を表示するラベル
        label = new JLabel("");
        label.setHorizontalAlignment(JLabel.CENTER);
        // 文字表示実行ボタン
        JButton printButton = new JButton("Hello World!");
        printButton.addActionListener(this);
        printButton.setActionCommand("Button Print");
        // 終了ボタン
        JButton endButton = new JButton("終わりだよ〜(o・∇・o)");
        endButton.addActionListener(this);
        endButton.setActionCommand("Button End");

        JPanel p = new JPanel();
        p.setBorder(BorderFactory.createEmptyBorder(30, 0, 0, 0));
        p.add(printButton);
        p.add(endButton);

        getContentPane().add(label, BorderLayout.PAGE_START);
        getContentPane().add(p, BorderLayout.CENTER);
        getContentPane().validate();
    }
    // ボタンを押したときに実行する処理
    public void actionPerformed(ActionEvent e) {
        String command = e.getActionCommand();
        if (command.equals("Button Print")) {
            label.setText(hello());
        } else if (command.equals("Button End")) {
            System.exit(0);
        }
    }
    // 表示する文字列を返す
    private String hello() {
        String[] data = {
            "121141141524111112223214332",
            "12111414141213111111121112111412122",
            "4132141412131111111211321412122",
            "1211141414121311111112111112141214",
            "121141414225111322121141332"
        };
        String result = "<html><body>";
        for (String str: data) {
            String[] strArray = str.split("");
            boolean toggle = true;
            String line = "";
            for (String s: strArray) {
                int n = Integer.parseInt(s);
                if (toggle) {
                    line += "●".repeat(n);
                } else {
                    line += " ".repeat(n);
                }
                toggle = !toggle;
            }
            result += line;
            result += "<br>";
        }
        result += "</body></html>";
        return result;
    }
    
    public static void main(String[] args) {
        new HelloWorld();
    }
}

javacでコンパイルするとHelloWorld.classファイルが出力されます。

$ javac HelloWorld.java
$ ls -l
合計 8
-rw-rw-r-- 1 izumi izumi 3294 12月 19 19:54 HelloWorld.class
-rw-rw-r-- 1 izumi izumi 2598 12月 19 19:50 HelloWorld.java

出力されたclassファイルはjavaコマンドで実行することができます。

$ java HelloWorld

“Hello World!“ボタンを押すとウインドウに"HELLO WORLD!“を表示します。
“終わりだよ〜(o・∇・o)“ボタンを押すとプログラムを終了します。

Javaプログラムの実行結果

Javaプログラムの実行結果