Javaの利用とサポート期間の振り返り

Javaは以前は無償で使えていたのですが、今は商用利用は有償となっておりサポート期間もバージョンによって違います。Java(Oracle JDK)を使ってみようと思い、今更ながらまとめてみました。

2014年3月 Java8がリリース
Java8までが無償利用が出来て、且つ、バグフィックスやセキュリティパッチの提供も(無償で)受けられたJavaです。6→7→8とメジャーバージョンアップが行われてきましたがバージョンアップの間隔は3〜4年となっていて特に決まっていませんでした。また、次のバージョンが出たからといって前のバージョンのパッチ提供がすぐになくなるということはなかったと思います。今は、商用利用でのJava8のパッチの提供は終了しています(2019年1月に終了)。個人利用の場合は2020年12月までパッチ提供があります。

= = 追記 = =
Java8の個人利用ですが無期限に変更されたようです。パッチ提供をやめる場合は18か月前には通知するようです。2020年5月13日付けの Oracle Java SE Supportロードマップ の抜粋です。

2017年9月 Java9がリリース
Java9からはバージョンアップは半年ごとになりました。パッチのサポートも半年間のみです。Java9を使い始めて半年後にはJava10が出るのでそちらに移行すれば良いわけですが、商用利用している場合はそう簡単に載せ換えられるものでもありません。半年後にパッチのサポートがないからと言ってJava9が使えなくなるというわけではないのですが、商用利用の場合は不安があります。その場合はお金を払うことで(つまり、有償で)Oracleからパッチを提供してもらうことはできます。

2018年9月 Java11がリリース
Java11からは商用でJavaを利用する場合は有償となりました。Oracleとライセンス契約が必要です。非商用(開発環境での利用)もしくは個人利用であれば無償です。またJava11では有償としたためか半年のサポートではなく5年間の長期サポート(LTS:Long Time Support)となっています。Java11以降もJavaのバージョンは半年ごとにあがっていきますが、Java11のようなLTS版は3年ごとに出るようです。次のLTS版はJava17です。non-LTS版も有償ですがサポート期間は半年間です。
個人の場合は無償で利用はできますがOracleからのサポートはなさそうです。

= = 2022年5月追記 = =
2021年9月 Java17がリリース
この記事を執筆した時点ではLTS版は3年ごとのリリースだったのですが、現在では2年ごとのリリースになるようです。ですのでJava17の次のLTS版はJava21になります。ただ、Javaのロードマップの注釈に「LTSの指定と日付は変更される場合があります」のコメントもありました。

2018/09 Java11 LTS
2019/03 Java12 non-LTS
2019/09 Java13 non-LTS
2020/03 Java14 non-LTS
2020/09 Java15 non-LTS
2021/03 Java16 non-LTS
2021/09 Java17 LTS
2022/03 Java18 non-LTS
2022/09 Java19 non-LTS
2023/03 Java20 non-LTS
2023/09 Java21 LTS
2024/03 Java22 non-LTS
2024/09 Java23 non-LTS

Java11以降、商用でJava(Oracle JDK)を利用する場合はタダではなくなったということです。ですが、OpenJDKというものを使えば商用でも無償でJavaが利用できます。OpenJDKは、OpenJDKコミュニティが作成したソースコードをOracle社がビルドしたものなのでOracle JDKとほぼ同じと考えてよいでしょう。ただOpenJDKも半年ごとにバージョンアップが行われていて、パッチも半年間のみの提供です。半年ごとに次のバージョンのOpenJDKに載せ換える手間があります。

ちなみにOracle社の製品(ウェブアプリケーションサーバーのweblogic)を使用している場合は製品のライセンス契約の中にJavaの利用が含まれるようなのでそれを使ってもよいかもしれません。Oracle社の方でweblogicのバージョンとJavaのバージョンとの整合性を確認してくれるようです。

以下はOracle社が行うJavaのサポート期間です(2020年4月現在)。

Premier Support、Extended Support、Sustaining Support の3つがあります。Oracleの「ファースト・ステップ・ガイド 第8版」によると「通常、ソフトウェア製品は出荷開始後の5年間をPremier Support期間とし、包括的なメンテナンスとソフトウェア・アップグレードを提供します。Premier Support期間終了後は、特定のプログラム・リリースについては、追加料金設定により、Premier Supportに準ずるサービス・レベルを維持するExtended Support期間が通常3年間提供されます。Extended Supportが設定されないリリースおよびExtended Support期間の終了後はSustaining Support期間となります。」とあります。

ちなみに、Java8のPremier Support期間が2022年3月までとなっているのが疑問だったのだけれど(Java8の商用利用でのサポートは2019年1月に終了したはず)、、これは本来は無償で使えたJava8を有償でOracle社と契約することでサポートしてもらえるということなのかな?と思いました。

マルチキャストプログラミングと、その時のネットワークの動き

前回はブロードキャストのパケットを送受信する場合を考えてみましたが、今回はマルチキャストの場合です。前回同様、C言語でプログラミングしています。

マルチキャストの場合

ブロードキャストと同様に、マルチキャストのパケットを送れるのはUDPのみです。ですので、マルチキャストパケットを送るプログラミングを行うにはUDPのユニキャストの手順をマルチキャスト用に修正します。修正点は以下の3つです。ユニキャストの手順については前回説明しています。

  • 送信側で送信パケットのTTLを設定する。
  • 送信先IPアドレスにマルチキャストアドレスを指定する。
  • 受信側でマルチキャストグループに参加する。

送信パケットのTTLを設定するには、setsockopt()でIPPROTO_IPのIP_MULTICAST_TTLに値を設定します。TTLとはパケットの生存時間です。パケットがルーターを通過するごとに値が減算され、0になった時点でパケットは破棄されます。

setsockopt(socket, IPPROTO_IP, IP_MULTICAST_TTL, *optVal, optLen);

socketはソケットディスクリプタ、*optValはTTLとして設定する値のポインタ、optLenはoptValの長さ、を示します。ブロードキャストの場合は送信パケットのTTLを設定しませんでしたが、これはブロードキャストパケットはルーターを超えることがないためTTLを設定しても意味がない(TTLが減らない)からです。

送信先アドレスにはマルチキャストアドレスを指定しますが、マルチキャストアドレスには範囲があり、以下の範囲内のIPアドレスを指定します。

マルチキャストアドレスの範囲
224.0.0.0 〜 239.255.255.255

受信側の設定の方ですが、受信側ではマルチキャストグループに参加します。マルチキャストグループに参加するには、setsockopt()でIPPROTO_IPのIP_ADD_MEMBERSHIPにマルチキャストグループ(つまり、送信側が送信パケットに指定したマルチキャストのIPアドレス)を設定します。

setsockopt(socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, *optVal, optLen);

TTLの設定と同様に、socketはソケットディスクリプタ、*optValはマルチキャストグループのポインタ、optLenはoptValの長さ、を示します。

マルチキャストパケットを送受信する手順をまとめると以下となります。

[広告]

プログラムの手順は上図に示した通りですが、マルチキャストパケットが各ホストに届くにはネットワークのほうで「お膳立て」のようなことを先にやっています。それについて書いておきます(以下)。

まず、マルチキャストパケットを届けるためにはルーターのマルチキャストルーティングを有効にしておく必要があります。これによりPIM(Protocol-Independent Multicast)というプロトコルがマルチキャスト専用のルーティングテーブルをルーター間で共有します。PIMはマルチキャスト専用のルーティングプロトコルです(代表的なルーティングプロトコルとしてRIPやOSPFなどがあります)。マルチキャストパケットはこのルーティングテーブルをもとにルーター間を転送されていきます。

また受信ホストがマルチキャストグループへの参加をすることによりNICがマルチキャストパケットを受信するようになります。通常NICは自身のIPアドレスのパケットかブロードキャストパケットしか受信しませんが、マルチキャストグループへの参加を行うことによりマルチキャストパケットも受信するようになります。

もう一点、受信ホストがマルチキャストグループへの参加を行うと、ホストからネットワークにIGMP(Internet Group Management Protocol)というプロトコルが送られます。IGMPはそのホストが属するセグメントのルーターに届き、ルーターは自分の属するセグメント内にマルチキャストグループに参加しているホスト(つまり、マルチキャストパケットを転送するホスト)があることを知ります。これによりルーターはマルチキャストパケットをそのホストが属するセグメントに転送します(通常のルーターはマルチキャストグループに属するホストがいなければマルチキャストパケットを転送しません)。

なおNICにはプロミスキャスモードというすべてのパケットを受信するモードがあります。プロミスキャスモードにすることによりマルチキャストパケットを含むすべてのパケットを受信しますが、プロミスキャスモードにするだけではIGMPによるルーターへの通知は行われません。

[広告]

実際に、送信側ホストから受信側ホストにマルチキャストパケットが転送されていく際のイメージの絵です。

マルチキャストパケットはマルチキャスト用のルーティングテーブルをもとにルーター間を転送され、宛先ネットワークまで届けられます。宛先ネットワークに届いたパケットはイーサーネットのフレームに乗りますが、その際の宛先MACアドレスはマルチキャスト用のMACアドレスとなります。マルチキャスト用のMACアドレスはOUI(前半の24ビット)が「01-00-5E」となります。このパケットはブロードキャストパケットと同じくスイッチでは全ポートにフラッディングされます(正確に言うと、宛先MACアドレスのI/Gビットが「1」のものがフラッディングされます)。これによりマルチキャストグループに参加していないホストにまでマルチキャストパケットは届いてしまいますが、マルチキャストグループに参加していないホストのNICはマルチキャストパケットを無視します。

なお、不要なホストにまでマルチキャストパケットが届いてしまうとネットワークの帯域を圧迫するのでスイッチには「IGMPスヌーピング」という機能を持つものがあります。これは、受信側ホストがマルチキャストグループの参加を示したときに送られるIGMPをスイッチが盗み見しておいて、マルチキャストパケットが届いたときに必要なポートにのみマルチキャストパケットを送る機能です。