
java -version を実行したら 1.8.0_412 と表示された。これはJava 1.8なのか、Java 8なのか。どちらも正しい、というのがややこしいところです。
Javaのバージョンが分かりにくいのは、製品として発表される名前と、開発者向けコマンドの表記が別のルールでスタートしたからです。しかもそのルールは途中で二度変わっています。この記事では、まず手元のバージョンを確認する方法を整理したうえで、なぜこの表記になったのかをこれまでの履歴から確認します。
実行環境のバージョンはこれで分かります。
$ java -version
openjdk version "1.8.0_412"
OpenJDK Runtime Environment (build 1.8.0_412-b08)
OpenJDK 64-Bit Server VM (build 25.412-b08, mixed mode)コンパイラ側は別に確認します。開発環境では両者がずれていることがあり、その場合ビルドは通るのに実行時に落ちるといった形で表面化します。
$ javac -version
javac 1.8.0_412| 出力 | 実際のバージョン |
|---|---|
1.4.0 | Java 1.4 |
1.5.0 | Java 5 |
1.6.0 | Java 6 |
1.7.0 | Java 7 |
1.8.0_412 | Java 8 |
11.0.22 | Java 11 |
17.0.10 | Java 17 |
21.0.2 | Java 21 |
先頭の 1. が付くのはJava 8までです。1.8.0 はJava 8を指します。 Java 9から表示される数字がそのままメジャーバージョンになりました。
なぜ8まで 1. が付いていたのか。これからご紹介します。
/images/blog/truth-about-java-version-chaos/mid-01.png
WhaTap LabsはITサービスの性能を分析する総合オブザーバービリティーメーカーとして、顧客の開発言語とバージョンに注視しております。なかでもJavaはエンタープライズで最も使われている言語で、バージョンによって取得できるデータの範囲が変わるため、開発でも商談でも重要な確認項目になります。
そこで毎回起きるのが、同じものを別の名前で呼んでいるという行き違いです。営業担当が「Java 8」と言い、開発者が「1.8」と言い、資料には「J2SE」と書いてある。原因は、Javaが四半世紀のあいだに製品名のルールを変えながら、開発者向けの表記だけを互換性のために据え置いてきたことにあります。
Javaは今でこそWebの言語ですが、最初からWeb向けに作られたわけではありません。
1990年12月、ワークステーション市場を牽引していたSun Microsystemsが、次の市場を取るための専門家チーム「Green Project」を立ち上げ、Patrick Naughton、Mike Sheridan、James Goslingらが参加しました。チームが着目したのは成長中の家電市場で、さまざまなプロセッサ上で動く、プロセッサ非依存の言語が必要だと考え、James Goslingが開発を始めたその言語が Oak でした。
1992年、チームはOakの可能性を示すため、双方向ポータブル端末 Star7 を作ります。Green OS、Oak、ツールキット、ライブラリ、ハードウェアを統合したものでした。当時のケーブルテレビ会社はこの手の技術にまったく関心を示しませんでしたが、タッチ操作の端末が普及したのはそれから20年後のことです。早すぎた技術でした。
1993年、チームはスマート家電市場の見込みが過大だったと判断し、双方向テレビのセットトップボックス用OSへ方向転換します。こちらも市場参入には失敗しました。
1994年、転機が来ます。セットトップボックス向けに求められた性質、つまり小さく、プラットフォームに依存せず、安定していることが、そのまま当時の初期Webの要件だったのです。チームはWebベースの三つ目のプロジェクトに着手し、Patrick Naughtonが週末に書き上げたプロトタイプブラウザが「WebRunner」でした。
商標の問題でOakはJavaに改名され、1995年のSunWorldカンファレンスでHotJavaブラウザとともに発表されます。以降の流れをまとめると次のようになります。
| 年 | 製品名 | コードネーム | java -version | 主な追加 |
|---|---|---|---|---|
| 1996 | JDK 1.0 | - | 1.0 | 最初の安定版は1.0.2 |
| 1997 | JDK 1.1 | - | 1.1 | JavaBeans、JAR、JDBC |
| 1998 | J2SE 1.2 | Playground | 1.2 | Java 2へ改称、SE/EE/MEに分離 |
| 2000 | J2SE 1.3 | Kestrel | 1.3 | - |
| 2002 | J2SE 1.4 | Merlin | 1.4.0 | JCPによるオープンソース管理 |
| 2004 | Java SE 5 | Tiger | 1.5.0 | Generics、Autoboxing、Enum |
| 2006 | Java SE 6 | Mustang | 1.6.0 | - |
| 2011 | Java SE 7 | Dolphin | 1.7.0 | Diamond演算子、try-with-resources |
| 2014 | Java SE 8 | - | 1.8.0 | Lambda、Stream、Default Method |
| 2017 | Java SE 9 | - | 9 | モジュールシステム、JShell |
| 2018 | Java SE 11 | - | 11.0.x | LTS |
| 2021 | Java SE 17 | - | 17.0.x | LTS |
| 2023 | Java SE 21 | - | 21.0.x | LTS、仮想スレッド |
名前が三度変わっているのが分かります。順に見ていきます。
Javaの最初のバージョンが公開されます。最初の安定版は JDK 1.0.2 で、これを「Java 1」と呼びます。
同年の第1回JavaOneには6,000人を超える開発者が集まりました。登場から1年も経っていない言語を中心に、まったく新しい市場が立ち上がった瞬間です。このイベントには160を超える企業がJava関連の製品とサービスを出展しました。
発表時の名称はJava Development Kit 1.1です。JDK 1.1は3週間で22万回以上ダウンロードされ、Javaは約40万人の開発者が使う世界2位の言語に成長します。
追加された主な機能はJavaBeans 1.0、JAR形式、JDBCでした。
一度目の改名がここです。 コードネームPlayground、発表時の正式名称はJava 2 Platform, Standard Edition 1.2。製品の変更が大きすぎたため「Java 2」としてリブランドされました。
ここで表記のねじれが生まれます。製品名は「Java 2」なのに、開発者コミュニティは以前どおり「JDK 1.2」と呼び続けました。略称もJava2SDKとすべきところがJDKのまま定着します。そしてこのJDK 1.2以降、Javaの製品はStandard、Enterprise、Microの三つに分かれました。
二度目の改名で、ここが 1.8 = Java 8 の直接の原因です。
コードネームTiger。正式名称はまだ「J2SE 5.0」でしたが、バージョン番号だけが1.5ではなく5.0として発表されます。番号の飛び方が現在と同じルールになったのはこの時点です(「Java 2」の名称自体が外れて「Java SE」になるのは、2年後のJava SE 6からです)。
ところが java -version が返す値は 1.5.0 のままでした。既存のスクリプトや互換性チェックが先頭の 1. を前提に書かれていたためです。製品名は5、内部表記は1.5。このずれがJava 8まで13年続きました。
この回のJavaOneでは、Javaをオープンソースにするかが大きな論点になりました。Sunは互換性認証を必須としたい立場、支持者はより自由な形での提供を望む立場で、James Goslingは複数のオープンソース実装を認めるとUnixのような非互換を招きかねないと反対しています。
主な追加はGenerics、Autoboxing/Unboxing、Enum、Static importでした。なお、WhaTapモニタリングの主要機能であるActive StackはJava SE 5以降で動作します。
コードネームMustang。ここで「Java 2」の「2」が正式に外れ、製品名はJava Platform, Standard Edition 6になりました。
2007年、SunはJavaクラスライブラリの完全なソースコードをGPLで公開します(Sunがライセンスを受けていたコンポーネントは除外)。同じ2007年にiPhoneが登場しますが、これはOakを積んだStar7のデモから15年後のことでした。
2008年、それまで新バージョンが2年単位で発表しておりました。2009年4月、OracleによるSun買収が発表され(買収完了は2010年1月)、同年12月にJCPがJava 7と8のロードマップを承認しました。
コードネームDolphin。JDK 1.0からJDK 6までは2年ごとに更新されていましたが、JDK 7は5年ぶりの更新でした。
期待されていたLambdaやJigsawは結局入りませんでした。OracleのJavaグループ担当副社長Georges Saabは、この空白期間をJavaの歴史で最も残念だったと振り返っています。
追加された機能はDiamond演算子、Genericsの利便性向上、try-with-resourcesによるリソースの自動解放、Garbage Collectorの強化、switch文での文字列サポートです。
Java 7から3年。7で実装しきれなかった変更の多くがここに入ります。Lambda式、Streams API、インターフェースのDefault Methodが追加され、Javaの書き方そのものが変わった年でした。
そして java -version が 1.x を返す最後のバージョンがこのJava 8です。
企業システムでJava 8がいまだに広く残っているのは、この年の変更が大きく、かつ次のJava 9で互換性に影響するモジュールシステムが入ったことが重なったためです。
三度目の変化はバージョン番号ではなくリリースの間隔でした。
Java 9からOracleはリリースサイクルを6ヶ月単位に切り替えます。毎年3月と9月に新バージョンが出る形です。同時に java -version の先頭の 1. が外れ、Java 9は 9、Java 11は 11.0.x を返すようになりました。ようやく製品名と内部表記が一致します。
ただし6ヶ月ごとのバージョンすべてを本番で追う必要はありません。数年おきに LTS(Long Term Support) が指定され、長期のサポートを受けられます。
| バージョン | 公開 | 区分 |
|---|---|---|
| Java 11 | 2018年9月 | LTS |
| Java 17 | 2021年9月 | LTS |
| Java 21 | 2023年9月 | LTS |
| Java 25 | 2025年9月 | LTS |
LTS以外のバージョンは次のリリースが出るまでの6ヶ月間だけ更新されます。本番環境ではLTSを選び、それ以外は新機能を試す用途と考えるのが一般的な運用です。
Java 9はモジュールシステム(Jigsaw)、JShell、HTML5 Javadoc、匿名クラスでのDiamond演算子、Process APIを追加しました。以降、仮想スレッド(Java 21)のような大きな機能もこのサイクルの中で入っています。
java -version の出力で先頭に 1. が付くのはJava 8まで。1.8.0 はJava 8。1.5.0 に据え置いた。1. が外れ、リリースは6ヶ月ごと。本番はLTS(11、17、21、25)から選ぶ。Javaは長く発展してきた汎用言語です。バージョンを決めるという一見単純なことにも、互換性を壊さずに前へ進むための判断が積み重なっています。長く使われるサービスやオープンソースを作る側に回ったとき、この履歴は手本として読めるはずです。