新春特別企画

2019年のJava

今後のJavaの成長と仲良く付き合う

時代の波にあったリリースモデルのアップデート

2017年Java SE 9がリリースされて以降、Java 10、11が半年に1度リリースされるようにリリースモデルが変更されました。このリリースモデルの変更に関して、グローバルのJavaエンジニアはとても好意的に受け取っています。

今までJavaは約3年に1度大きなメジャーバージョンアップを行っていました。しかし、今の時代、IT業界における3年という時間はあまりにも長すぎます。今から3年前、2016年のIT業界では、Dockerなどのコンテナ技術がトレンドになりました。このころは、まだKubernetesも主流になっていないころです。しかしこのたった3年で、IT業界のトレンドや情勢は大きく変わりました。

このような変化の激しいIT業界において、3年ごとにしかアップデートができないプログラミング言語は致命的です。3年前に策定した新しい言語仕様が、3年後ようやく使えるようになったとき、時代はさらに先に進みプログラミング言語としては時代遅れになっているでしょう。

時代の変化やニーズに対して迅速に対応するためには、Javaもまた高速な進化が必要なのです。実際、Java SE 8以降のリリースにおいて、言語仕様での改良はもちろんのこと、JavaアプリケーションをDockerなどのコンテナ環境で効率良く動作させるための改善がJava 9以降でいくつか入っています。

Java開発者もまた、この世界を取り巻くIT業界の現状を認識し、必要に応じてJavaの進化に追随し、可能な限り新しいJavaの最新動向をキャッチアップしていただければ幸いです。一度にすべてをキャッチアップするのが大変な場合もあるでしょう。その場合は、日本各地に存在するJavaコミュニティの勉強会に参加するなど、最新情報を徐々にキャッチアップして新しい年をお過ごしいただくのがよいかと思います。

Java is Still Free !!

2018年のJavaを振り返る

昨年一部メディアなどを通じて「Javaが有償化される」⁠Javaから他のプログラミング言語に移行をしなければならない」といった記事や情報が流れ、一部開発者、また製品選定者に動揺が走りました。しかし、最新動向のJavaを正しくチェックしているエンジニアは、すぐにそれらの情報が大きな誤解であったことに気付いたかと思います。

過去の経緯を知る者として申し上げるならば、Javaのサポート・サービスの提供は、決してOracle社に始まったわけではありません。Sun Microsystems時代から「Java for Business」として、Javaの商用サポートを提供していました。

実際のJavaサポートでは、障害対応(コア・ダンプ解析など)の他、Java VMのQ&A対応、さらには原因を特定するためのデバッグ情報付きの特別なJava VMの提供や、特定の顧客のもとで発生している問題を解決するためだけにビルドされた専用のJRE(一時的な利用)を提供することもありました。

また、PublicでEOLを迎えたJDKに対して、サポート期間を延長してバグ修正対応、Q&A対応なども行っていました。今までも、こうしたサポートを受けてこられた企業ユーザにとって今回の変更は、とくに今までと変わらない状況かと思います。こうした企業ユーザは、今後もLong Term Support(LTS)を提供するタイミングJava 11、17、23(3年ごと、バージョン番号で6飛ばし)でのアップグレードをご検討ください。

これからのアップデートに対するユーザの心構え

それでは、今までサポートを受けてこなかったJavaの利用者は、今後どうすれば良いのかという点ですが、次のようにいくつかの選択肢があるかと思います。

  1. 新しいリリースモデルに併せて、半年ごとにアップデートを実施
  2. 通常は、LTS 版を利用しインシデントが発生した時点で対応を検討
  3. サービスに影響のない範囲で自己責任において長期利用

①新しいリリースモデルに併せて、半年ごとのアップデートを実施

半年ごとのアップデートを行っていくためには、事前に次のような内容を準備しておくことでリスクを下げることができるでしょう。

●OpenJDKの動向ウォッチ

  • 正式リリースのスケジュールの把握
  • アーリー・アクセスビルドの入手とテスト
  • 新機能の確認、削除パッケージの有無などの確認

●テストコードの整備

●継続的インテグレーション(ビルドテスト)

 

まず、第一にOpenJDKの動向を常にチェックしましょう。最も大事なのは、OpenJDKのサイトで公開される正式リリースの日程を把握することです。この日程を把握することで、自身のアプリケーションの更新スケジュールを立てられるようになります。

次に、アーリーアクセス版のバイナリを入手し事前に検証をしましょう。仮に正式リリースまで検証を待つと、その時点で新たな課題を発見する可能性があります。これにより急な想定外の対応をしなければならず、結果として予定していたよりも導入までに時間を要する可能性があります。アーリーアクセス版で検証しておくことで、こうした課題を早く発見できるでしょう。

また、アーリーアクセス版を試していただくのと同様に、JDK Enhancement Proposal(JEP)を確認しておくこともとても重要です。これにより、新機能追加や変更に対する情報をいち早く入手でき、必要な変更箇所などをあらかじめ把握することが可能になります。

たとえば、Java SE 11より一部のパッケージ(JAX-WS、JAXB、CORBAなど)が削除されましたが、このような場合も、実装しているアプリケーション内で使用しているか、もしくは利用しているサードパーティ製のライブラリで利用されていないかを確認し、それに応じて事前に対応を施すこともできます。

これ以外にも、新機能の追加、さらにはJava VMやGCに対する変更もJEPで定義・記載されていますので、とても重要なドキュメントになります。

アップグレード戦略も次のの2つの方法があります。

  1. ソースコード未修正でアップデート
  2. 新しい言語仕様に沿ったソースコードの修正

1:ソースコード未修正でアップデート

1つ目の方法は、既存のソースコードには修正を加えず、Javaの実行環境だけをアップデートする方法です。この方法は今までもありましたが、ソースコードをコンパイルする際に、-source、-target、-bootclasspath オプションを指定してコンパイルします。これにより、-sourceで指定ソースコードを-targetで指定した環境下で動かすことができました。

Java SE 9からはこれらのオプションをまとめた新しい--releaseオプションが追加されています。これを利用することで、指定した環境用のクラスコードを出力してくれます。たとえば、下記の例のようにOpenJDK 11の環境で、Java SE 7のコードを「javac --release 7 Test.java」としてコンパイルが可能です。

この場合Java SE 7用のクラスファイルが生成され、さらにJava VM 11の環境でコードを動かすことができます。ソースコード未修正で環境をアップデートしたい場合は、今後--releaseオプションをご使用ください。

Java SE 7のソースコード例(Test.java)
public class Test{
    public static void main(String... args){
        int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        for (int number : numbers) {
            System.out.println("number = " + number);
        }
    }
}

OpenJDK 11がインストールされている環境で下記を実行します。

$ javac --release 7 Test.java 
$ java -version
openjdk version "11" 2018-09-25
OpenJDK Runtime Environment 18.9 (build 11+28)
OpenJDK 64-Bit Server VM 18.9 (build 11+28, mixed mode)
$ java Test
number = 1
number = 2
number = 3
number = 4
number = 5
number = 6
number = 7
number = 8
number = 9
number = 10
 

新しい言語仕様に沿ったソースコードの修正

新しい言語仕様に沿ったソースコードを修正するためには、上述したように、アーリーアクセス版による検証や、JEPのチェックなどが必要なのはもとより、柔軟なバージョンアップを行うためのビルドテスト環境の充実が必要になります。

JUnitや Seleniumなどによるテストコードの整備、さらにはソースコードのコミット時に自動ビルドや自動テストを行い、素早く変更に対する検証ができるような整備が必要になるでしょう。また素早く検証するために、必要に応じてコンテナ化なども見据えた対応も必要になってくるかと思います。

通常は、LTS版を利用しインシデントが発生した時点で対応を検討

また、従来型のシステム開発や運用、さらにはミッションクリティカル領域での運用においては開発期間も長く、頻繁なJavaのバージョンアップが難しい場合もあるでしょう。その場合はLTS版をご利用いただくことで不測の事態に対応することも可能になります。

通常は、LTS版を利用し開発・運用を行い、Java VMに対する不具合などが発生した場合ベンダ(Oracle、Red Hat、Azul Systemsなど)からのサポートを受ける選択肢を残しておくことで、より長くJavaアプリケーションを安心して本番環境で利用することができるようになります。サポート期間は各ベンダによって異なりますので、どの環境でJavaを動作させるのか、もしくはどのベンダのサポートを受けるのか選択肢の幅は広がっています。

サービスに影響のない範囲で自己責任において長期利用

また、システムを塩漬けにしたいニーズもあるかと思います。外部に公開されているシステムならば、塩漬けをお勧めしませんが、仮に社内ネットワークなど閉じた環境で、かつ信頼されるネットワーク環境下で運用される場合、古いJavaのバージョンのまま運用していただくことも可能かと想定します。この場合は、自己責任の範囲内で長期利用をご検討ください。

Oracle JDKとOpenJDKの違いについて

ここまで、サポートやバージョンアップ、システムへの適用についてまとめてきましたが、最後にOracle JDKとOpenJDKの違いについても触れます。

まず過去の経緯について紹介します。Java SEが初めてオープンソース化されたころ(OpenJDK 6)は、大きな差がありました。しかし、Java SE 8の開発では、Oracle JDKもOpenJDKをベースに開発がされるようになりましたので、以前に比べ差はほとんどありません。

そして、OpenJDKバイナリ の入手方法に関しても、本家 OpenJDKのサイトの他、Azul Systems社が提供するZulu、Javaコミュニティが主導するAdoptOpenJDKなどから入手可能です。その他、Eclipse OpenJ9など、さまざまな選択肢があります。またサポートに関しても Oracle 社によるOracle JDKはもちろん、他社からも各OpenJDKビルドに応じてサポートを受けることができるようになっています。

今では、Javaを無償で使う選択肢も、商用サポートを購入して利用する選択肢も以前より増えています。今後はユーザ自身がさまざまな情報を収集し、どのJava製品が自分の環境に最適かを考えて選択しなくてはならないでしょう。

OpenJDK 12について

2019年は、Java 12、13の2つのバージョンのリリースが予定されています。とくに直近のJava 12については、正式リリース日(米国時間2019年3月19日)や新機能もWebページ上で公開されています。 現時点で予定されている新機能は、下記の8つです。

開発関連

JVM関連

GC関連

ツール関連

とくに開発者が最初に押さえておきたい新機能は、JEP 325のswitch構文の拡張です。switch構文内において、local変数を定義可能になっている他、 switch構文の処理結果を新しい変数に代入するような構文が追加されています。これにより、今まで記述できなかった書き方ができるようになっています。

また、下記の例に記載しているように、switch文の演算子として「->(arrow operator⁠⁠」が利用できるようになっています。 詳細はJEP 325をご参照ください。

int numLetters = switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> 6;
    case TUESDAY                -> 7;
    case THURSDAY, SATURDAY     -> 8;
    case WEDNESDAY              -> 9;
};

それ以外で筆者が注目しているのは、JEP 310(JDK 10⁠⁠、JEP 341(JDK 11)など、Class Data Sharing(CDS)機能に対する改善です。Function as a ServiceやDockerなどのコンテナ環境で、Javaアプリケーションを高速に起動したいニーズがあります。これを改善するためにJDK 8u40以降でCDSに対していくつか改善されています。

実際に、JRubyのアプリケーションで30%高速に起動できるようになったというデータがある他、アプリケーションによっては 50%の高速化も可能です。Javaの起動時間が遅いと感じる方は、ぜひ、Class Data Sharingをお試しください。

その他、Java VMやGCでも改良が入っているため、コンテナ環境でJavaを扱う筆者は、OpenJDK 12 のリリースを心待ちにしています。

最後に

時代の流れはめまぐるしく、日々新しいテクノロジやフレームワークが生まれてきています。1年前は新しかった技術が1年後はあたりまえになったり、もしくは廃れている場合もあります。Javaのエンジニアとして今まで蓄えてきたノウハウや技術は、いつ古くなったり時代遅れになるかもしれません。

今の時代、勉強をやめた時点でエンジニアとしての人生が終わるといっても過言ではありません。現在の状況に満足せずに、エンジニアとして成長していくためにも、つねに業界の動向をウォッチし、新しいことにもチャレンジしながらJavaのエンジニアとして成長していきましょう!!

結果として、日々成長するエンジニアや、より優秀なエンジニアが、より良い環境で、より良い報酬を得て幸せに働ける日が来ることを願っています。

おすすめ記事

記事・ニュース一覧