SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

初めての6カ月定期アップデートで変わったJava 10、ポイントを押さえよう

Javaのサポートはこう変わる! 強化されたDocker対応

初めての6カ月定期アップデートで変わったJava 10、ポイントを押さえよう 第2回


DockerでのJavaの利用

 筆者はJava自体がある種のコンテナでもあると考えているため、Dockerというコンテナ上で動かし、二重のコンテナを作る必要性はあまりないと感じてきました。

 しかし、今回のサポート変更にともない、OpenJDKベースのすばやいバージョンアップに追従していくことや、アプリケーションとともにJRE環境を含めて配布することを考慮すると、Docker環境下でのJavaの利用は、今後のJavaのバージョンアップ対応として有効な手段なのではないかと思っています。

 そしてJava 10では、CPUやメモリなどDocker環境下で動作するための改善が行われています。そこで今回はJava 10での改善点だけではなく、Dockerを用いたJavaの利用も紹介します。

Dockerのインストール

 今回はDocker自体の詳細な導入方法は紹介しませんが、DockerをWindowsもしくはMacにインストールするには、Docker Storeからインストーラーをダウンロードする必要があります。Dockerには有償版のDocker EEと無償版のDocker CEがありますが、今回は無償版のDocker CEを使って説明します。

 インストールが終了したら、正常にインストールされたことを確認するために、「docker version」コマンドを実行して、リスト1に示すようにインストールされているバージョンが出力されることを確認してください。リスト1はMac環境で実行した結果ですが、WindowsのPowerShell環境下で実行してもほぼ同様の結果となります。

[リスト1]Dockerをインストールした結果の確認
bash-3.2$ docker version
Client:
 Version:      18.03.1-ce
 API version:  1.37
 Go version:   go1.9.5
 Git commit:   9ee9f40
 Built:        Thu Apr 26 07:13:02 2018
 OS/Arch:      darwin/amd64
 Experimental: false
 Orchestrator: swarm

Server:
 Engine:
  Version:      18.03.1-ce
  API version:  1.37 (minimum version 1.12)
  Go version:   go1.9.5
  Git commit:   9ee9f40
  Built:        Thu Apr 26 07:22:38 2018
  OS/Arch:      linux/amd64
  Experimental: true

Dockerを使ったJavaの実行

 Dockerではあらかじめ定義された環境を簡単に作ることができ、OpenJDKのさまざまなバージョンがあらかじめ使えるようにすでに定義が用意されています。

 したがって、Dockerを使えば「JDKのダウンロードページに遷移し、ダウンロードし、インストールする」といった手間を省けます。また例えば、JDK 9からJDK 10への乗り換えの際にJDK 10用のDockerイメージを使えば、すぐにバージョンアップが可能です。そして、ちょっとした利用確認をしたい場合にも、さまざまなバージョンがすぐに確認できるために非常に便利です。

 例えば、OpenJDK版のJava 10を試したければ、リスト2のように実行するだけで、JDK 10版のJShellが起動された状態になります。

[リスト2]Java10のDockerコンテナの起動(JShell)
$docker run -it openjdk:10-jdk
Jun 17, 2018 3:33:56 AM java.util.prefs.FileSystemPreferences$1 run
INFO: Created user preferences directory.
|  Welcome to JShell -- Version 10.0.1
|  For an introduction type: /help intro
jshell> 

 また、JShellではなく、bashなどのコマンドを起動したい場合には、リスト3のように実行します。後は、そこからjavaコマンドやjavacコマンドなどが利用できます。

[リスト3]Java10のDockerコンテナの起動(bash)
$docker run -it openjdk:10-jdk bash
root@3e4f20be9148:/# java -version
openjdk version "10.0.1" 2018-04-17
OpenJDK Runtime Environment (build 10.0.1+10-Debian-4)
OpenJDK 64-Bit Server VM (build 10.0.1+10-Debian-4, mixed mode)

 初めての起動の場合にはイメージをダウンロードする必要があるため、少々時間がかかります。しかし、2回目以降はすぐに実行されます。

 すでにリリースされたJava 9や、まだ正式リリースされていないJava 11についても「openjdk:10-jdk」というタグの部分を書き換えればすぐに実行が可能です。

 これ以外にもさまざまなタグが用意されいて、OpenJDK用のDocker Hubの情報を参照するとこれ以外にも利用できるバージョンがあることがわかります。

 また、Oracle版JDKのDockerイメージはDocker Storeから取得可能です。ただし、こちらのイメージを利用する際にはDocker Storeのアカウントが必要になります。

Java 10で修正されたDockerへの対応

 JavaをDocker環境で利用しようとすると、ライセンスなどの問題で一癖あったのですが、OpenJDKであればライセンスの問題もクリアされるので、Docker環境での利用もより進んでくるはずです。しかし、Java 10まではDocker環境で動作する際、Docker上でのリソース制限などに一部対応していませんでした。具体的には、メモリやCPUの制限に関してDocker上で指定した制限ではなく、Dockerホストの制限がそのまま使われてしまうケースがありました。

 例えば、ヒープメモリに関して、Java 8の環境で確認したものがリスト4です。

[リスト4]Java 8にてヒープメモリについて確認した結果
$docker run -it -m1024m openjdk:8-jdk
#cat /proc/meminfo | grep MemTotal
MemTotal:        2046796 kB
#java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
    uintx MaxHeapSize                              := 524288000                           {product}
openjdk version "1.8.0_171"
OpenJDK Runtime Environment (build 1.8.0_171-8u171-b11-1~deb9u1-b11)
OpenJDK 64-Bit Server VM (build 25.171-b11, mixed mode)

 2G(2046796 kB)というのはDockerに割り当てているメモリ量です。ただし、コンテナを起動する際に1G(1024M)のメモリ上限を設定して起動しています。

 ただし、Java 10以前では512Mと認識されています。Javaはヒープサイズの最大にメモリ数の1/4か1Gの小さい方を選択しますので、512Mという値になります。

 同じコマンドをJava 10の環境で実行したものが、リスト5です。

[リスト5]Java10にてヒープメモリについて確認した結果
$docker run -it -m1024m openjdk:10-jdk bash
root@6314b958ec52:/# java -XX:+PrintFlagsFinal -version | grep MaxHeapSize
   size_t MaxHeapSize                              = 268435456                                {product} {ergonomic}
openjdk version "10.0.1" 2018-04-17
OpenJDK Runtime Environment (build 10.0.1+10-Debian-4)
OpenJDK 64-Bit Server VM (build 10.0.1+10-Debian-4, mixed mode)

 こちらは正しく256Mと認識されています。メモリ量の指定に関しては、Xmxオプションで指定可能です。こちらを指定すれば間違った認識をしてしまっていても手動で変更することができます。

 また、CPU数に関してもDocker側の起動で、--cpusにて利用できるCPUの数を制限した場合に、そのCPU数を正しく取得できない問題がありました。

 Java 9にて利用できるプロセッサ数の数を取得した結果がリスト6です。

[リスト6]CPU数を制限したDockerコンテナで利用できるCPU数(Java 9)
bash-3.2$ docker run -it --cpus 2 --rm openjdk:9-jdk
jshell> Runtime.getRuntime().availableProcessors();
$1 ==> 4

 Docker全体で指定しているプロセッサ数が4つなのですが、そのままその数がJava内からも4つと認識されてしまっています。

 そして、Java 10で同様のことを確認した結果がリスト7です。

[リスト7]CPU数を制限したDockerコンテナで利用できるCPU数(Java 10)
bash-3.2$ docker run -it --cpus 2 --rm openjdk:10-jdk
jshell> Runtime.getRuntime().availableProcessors()
$1 ==> 2

 こちらはCPUの数が正しく取得できています。

 CPUの数が正しく取得できないと、JVM内で行っているガベージコレクションでの最適化に影響が出る場合があります。一部のプログラムには、CPUの数をスレッドプール数の決定に用いているものもあります。そのため、実際のCPU数とDocker上で許可されているCPU数に大きく違いがある場合などはその影響をより受けやすくなってしまいます。

 こういったことが原因の問題は開発時にはあまり生じないと思いますので、もし、何らかの影響で問題が起きても原因まで特定することは難しいはずです。そんな中、Dockerなどのコンテナ上での動作も前提としていることは、利用する側の安心につながります。今回の対応改善は大きな安心材料の1つだと思います。

 また、今回Docker自体については詳しく説明できませんでしたが、Dockerを使うと非常に簡単にJava環境を構築できることがわかったと思います。

最後に

 Java 10は、大きく仕様が変更されたJava 9と今後の長期利用バージョンとなるであろうJava 11の中間のバージョンであることも影響してか、それほど大きな変更点はありませんでした。

 一方で、今後のバージョンアップの方向性がJava 9で示されてから、今までのJavaの方向性と本当に変わるのだろうかと半信半疑の方もいたのではないかと思います。とはいえ、Java 10は予定通りリリースされ、Java 11に関してもその後の変更計画などもなく予定通りのリリースとなりそうです。

 個人的にはJava 11でOpenJDKのLTS版ができるのか、できないのか注目したいですが、一方で6カ月ごとのJDKもしくはJREのリリースサイクルに対応できる体制や仕組みなどのノウハウが共有されることにも期待しています。

 また、既存資産の保守の面に目を向ければ、今回の有償化の流れは新たなコストの発生というマイナス面が目立ってしまいますが、Java EE(Jakarta EE)でも述べた通り、今後クラウドとの連携が強くなるとJavaという実行環境も1つのクラウドリソースとして広く利用されるようになるかもしれません。そうなれば、その他のクラウドリソースと同様に、サポートに関しても稼働分にのみ課金するモデルになるかもしれません。

 いずれにしても、今後のJavaに注目していくトピックスが増えたことには間違いないと思います。

参考資料

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
初めての6カ月定期アップデートで変わったJava 10、ポイントを押さえよう 連載記事一覧
この記事の著者

WINGSプロジェクト 小林 昌弘(コバヤシ マサヒロ)

WINGSプロジェクト について> 有限会社 WINGSプロジェクト が運営する、テクニカル執筆コミュニティ(代表 ...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/10939 2018/07/13 14:37

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー