IntelliJ IDEA 2020.2でJavaFXのランタイムが同梱されなくなりました
IntelliJ IDEA の最新版 2020.2 がリリースされましたね。日本語でも新機能について案内する記事がアップされています。
この記事の最後のように次のような個人的に気になる記述がありました。
まず多くの人は「JCEFって何?」ってなると思います。これはアプリケーションに Chromium を組み込めるようにするためのフレームワーク CEF (Chromium Embedded Framework) の Java ラッパーのことです。
- CEF のプロジェクトページ - https://bitbucket.org/chromiumembedded/cef
- JCEF のプロジェクトページ - https://bitbucket.org/chromiumembedded/java-cef
IntelliJ は IDE 内部で使う Web ブラウザコンポーネント (Markdown エディタの HTML プレビューなどで使っています) として今後は JCEF を使うようになったということです。これまでは IDE 内部で使う Web ブラウザコンポーネントとしては JavaFX の WebView を使っていましたが、2020.2 でこれをやめることになります。本件について JetBrains の Blog 記事で説明がありました。
ご存じの通り IntelliJ は Swing をベースに作られています。従って JavaFX の WebView は JFXPanel を通して使うことになりますが、そのために性能やレンダリングの問題を解決できなかったとのことです。
実際、JavaFX と Swing はレンダリングスレッドもタイミングも異なり、Swing アプリの上で JavaFX ノードを描画するときは JavaFX のレンダリングエンジンである Prism エンジンではなく Java2D を使って描画するため、JavaFX のパフォーマンスを 100% 発揮することができないのも確かです。この不整合を解決しようとする計画も過去にはありましたが、 Oracle の JavaFX へのやる気が無くなった ので...。
というわけで上記の記事では IntelliJ のプラグイン開発者に対して今後は JavaFX への依存をやめ、Web ブラウザコンポーネントを使いたいときは JCEF を使うことを促しています。
ですが、JCEF は現在絶賛開発中のステータスで、ユーザーとして利用できるような段階にありません。ビルド方法のガイドはありますが利用方法のガイドはなく、API ドキュメントもありません。ラップ対象の CEF については既に利用可能なステータスにあり (C++ のライブラリです) 、ある程度ドキュメントもあるので、こちらを参照して利用方法を推測することになります。
さすがにこの状態で使うのは辛いので、JetBrains 側でラップした API をプラグイン開発者向けに用意したようです。以下のドキュメントで解説されています。
というわけで IntelliJ IDEA 2020.2 からは JavaFX のランタイムは同梱されなくなります。この点について個人的に1点気になることがありました。
実は IntelliJ は Java IDE の中で唯一 JavaFX Scene Builder を内部に組み込んでいた IDE でした。JavaFX のランタイムが同梱されなくなる 2020.2 ではどうなってしまうのでしょうか?
というわけで早速 FXML ファイルを開いてみました。すると...
「Scene Builder Kit をダウンロードしてくれ」というリンクが表示されました。このリンクをクリックすると次に JavaFX Runtime のダウンロードが求められ、それも行うと次のように Scene Builder が表示されました。
というわけで別途ランタイムをダウンロードする必要があるものの、Scene Builder が使えなくなったわけではないのでご安心ください。
以上、誰も気付かないであろう IDEA 2020.2 の変更点についてのお話でした。
JavaFX 11に追加されたRobotクラスの紹介
このエントリは じゃばえふえっくす Advent Calendar 2018 の 3 日目のエントリとしてぶっ込みました。もうクリスマスは終わってますが、まだ空いていますし、 1 日目のエントリ で次のようなことを書いていたのをまだ放置していたので、それを拾うエントリとなります。
上記の Maven リポジトリをご覧になると分かりますが、Java FX 11 もリリースされました。リリースノートは次の通りです。
https://github.com/javafxports/openjdk-jfx/blob/jfx-11/doc-files/release-notes-11.md
まあ新機能は少ないのですが、
Spinner
コントロールに改善が加えられていたり (詳しくは Yucchi_jp さんのこのブログエントリ を) 、新たに Robot というクラスが追加されています。このRobot
クラスについては別のエントリで触れる予定です。
というわけで、JavaFX 11 になって新たに追加された Robot
クラスについて触れたいと思います。
Robot
クラスはプログラムから画面操作を行うために必要なメソッドが実装されたクラスです。あたかもロボットが画面操作を人の代わりに行うようなことを実現するというわけです。 AWT にも同様のクラス があります。一番のユースケースは GUI の自動テストを実装することで、それを実現するために次のような操作を実行するためのメソッドが実装されています。
- マウスの各種操作 (移動、クリック、スクロールホイール) を行う
- マウスの現在位置を取得するためのメソッドもあります
- キーボードをタイプする
- タイプとは別にプレスとリリースにもメソッドが用意されています
- 画面のスクリーンショットを撮る
- 指定した座標の色を取得する
モジュールは javafx.graphics
に、パッケージは javafx.scene.robot
に入っています。
画面を操作するのに必要なものは一通りそろっているので、これで定形作業を肩代わりするプログラムを作るのに使えますね。ゲームの周回操作とかにもいいかも。
実はこのクラス、昔からあったのですが internal なクラスとなっていました。このクラスを使って自動テストフレームワークを作っていたライブラリが多く、Java のモジュール化に伴い「外に出してほしい」というリクエストが非常に多かったのですが、11 になって晴れて表に出てきてくれました。
ところで以前、自分の書いた次のエントリで、JavaFX で xeyes のクローンを作った話をしました。
そこでこんなことを書いていました。
てなわけで、早速この Robot
を使って "Pure JavaFX" なアプリにしちゃいましょう。
まずは 10 以前のマウスポジションを取得するコード。
private void updateMousePosition() { SwingUtilities.invokeLater(() -> { final Point pointerLocation = MouseInfo.getPointerInfo().getLocation(); Platform.runLater(() -> updateEye(pointerLocation.x, pointerLocation.y)); }); }
Swing の EDT と JavaFX のアプリケーションスレッドを行ったり来たりして見通しが悪いですね。これを 11 の Robot
クラスを使うように変更します。使い方は簡単で、普通にインスタンスを取得すればいいです。Controller の初期化処理で取得しておきます。
private Robot robot; @Override public void initialize(URL location, ResourceBundle resources) { robot = new Robot(); // (以下略)
後はこのインスタンスを使ってマウスカーソルのグローバルポジションを取得するだけです。 updateMousePosition()
メソッドの内容が次のように変わりました。
private void updateMousePosition() { updateEye(robot.getMouseX(), robot.getMouseY()); }
はい、これで複数スレッドを行き来する必要がなくなりました。しかも java.desktop
モジュールへの依存も無くなるので、配布 JRE のイメージサイズも小さくすることができますね。 *1
少し付け加えると、 Robot
から取得するマウス座標の値は AWT と違って double
型になります。なので updateEye()
メソッドの引数の型を変える必要がありました。
というわけで JavaFX 11 の新機能である Robot
クラスの紹介でした。さすがに今年の Advent Calendar への投稿はこれで終わりかな。皆様良いお年を。
IntelliJ形式のJavaFXプロジェクトをJavaFX 11にアップグレードしたら色々ハマった話
このエントリは じゃばえふえっくす Advent Calendar 2018 の 2 日目のエントリとして作成しました。場所がたくさん空いてるので、みんなも気軽に参加してねー。
さて今回は 1 日目 として書いた記事で次の様なことを書いていたのですが、その内容について触れたいと思います。
Java 11 から JavaFX は Java の 1 ライブラリになりましたが、Maven のリポジトリにも "org.openjfx" というグループ名でアーティファクトが登録されました。
https://mvnrepository.com/artifact/org.openjfx
モジュール別にアーティファクトが登録されています (実はこれを利用する際にちょっとした罠にはまったのですが、それは別のエントリで) 。
IntelliJ プロジェクトからこの Maven リポジトリを利用しようとした際に罠にはまりました。まあ、純粋な IntelliJ 形式のプロジェクトで開発している人は少ないと思うのですが、OpenJFX の Maven リポジトリの解説にもなるので、独立したエントリとしました。
IntelliJ プロジェクトを JDK11 にアップする
まず、既存の JDK10 を利用するプロジェクトとして作成した IntelliJ プロジェクトを JDK11 にアップしてみます。
JDK11 には JavaFX は入っていません。当然このように JavaFX 関連の API が赤くなってしまいます。悲しい。
IntelliJ から Maven を利用したライブラリ設定を行う
嘆いていても仕方ないので、JavaFX のライブラリ設定を行うことにします。IntelliJ には依存するライブラリを Maven リポジトリから取ってくる機能があるので、これを利用して MavenCentral に登録された OpenJFX のライブラリを取ってくることにします。
次のように MavenCentral からアーティファクトを検索してくれます。
これでエディタから赤色が無くなる...と期待したのですが無くなりませんでした! Maven からダウンロードした OpenJFX の JAR の中身を見ると MANIFEST ファイルしか置いていないのです!
Maven リポジトリへの OpenJFX JAR の配置について
どうしてこうなったのかは Maven のリポジトリの内容を見て分かりました。OpenJFX は OS 別のネイティブ実装を含むため、OS 別に JAR ファイルが用意されていたのです。例えば javafx-controls モジュールのリポジトリ を覗いてみると次のようになっています。
Windows、Mac、Linux 向けに artifact classifier を使って JAR が分けられています。色々調べましたが、IntelliJ では artifact classifier で細分化された JAR を取ってくることができませんでした。しくしく。
普通に OpenJFX SDK をダウンロードして利用する
仕方が無いので古き良きライブラリ直接ダウンロードという方法を採ることにします。なお、今回対象としたプロジェクトは一応 GitHub に公開しており、また自分自身 Windows と Mac の両方で使うようにしていたので、環境依存的な設定が入ることを避けるようにします。
ダウンロードは前回のエントリで紹介した かっこいい Web サイト からできます。実行する環境に利用する OS のものを選んでダウンロードして解凍します。なお、IntelliJ はホームディレクトリ以下のパス設定は自身の環境変数を使って設定に記述するので、どの OS でもホームディレクトリの下のディレクトリに解凍すると環境依存が無くなるのでお勧めです。
ダウンロード、解凍が終わったら IntelliJ からこれを利用するように設定します。プロジェクト設定の [Libraries] から普通に [Java] を選んで、先ほどダウンロードした OpenJFX SKD ディレクトリの lib
サブディレクトリを選択します。
これでエディタから赤色が消えました。が、これで終わりではありませんでした。OpenJFX SKD の lib
ディレクトリの下にはソースコードをアーカイブした src.zip
が置かれています。そのままでは IntelliJ がこれもコンパイル対象にしようとして、ビルド時にエラーになってしまいました...。
そこで、lib
ディレクトリの下にある src.zip
ファイルを別の場所に移動し、さらに IntelliJ のライブラリ設定からソース参照の設定 (次の図で赤色で囲っている部分) を除去します。
これで無事にビルドもできるようになりました。やれやれ。
忘れてはいけない実行時の注意点
さて、実際に実行する際にも注意点があります。これは IntelliJ 固有の話では無く、Java 11 以降の JavaFX アプリケーション実行時の共通した注意点です。
詳細については id:torutk さんの次のエントリで解説されていますが、Main クラスが javafx.application.Application を継承している場合、実行時に --add-modules による JavaFX モジュールの指定が必須です。
また、アプリケーション自体をモジュール化している場合は実行時にモジュールパスの指定も必要になります。次のように実行設定を編集して、必要なパスの設定を忘れないでください。
以上です。えっと結論としては素直に Maven か Gradle で開発プロジェクトを作りましょう、ですw 今はどの IDE もこれらのツールで作ったプロジェクトならそのまま取り込めるので *1 、一見面倒そうに見えても後がすごく楽です。
2018年のJavaFXに関するできごと
このエントリは じゃばえふえっくす Advent Calendar 2018 の 1 日目のエントリとして作成しました。今年は無いかと思っていたのですが、@Yucchi_jp さんが立ててくださったので、まずは 1 日目を埋めることにしました。
とりあえず初日分と言うことで 2018 年に JavaFX に関して起こった出来事をまとめます。大きな出来事はこんなところでしょうか (最後だけは個人的に注目していた小ネタかな) 。今年は激動の 1 年でしたね。
- Oracle による Client Roadmap の発表とそれに伴う JavaFX の JDK からの分離
- OpenJFX コミュニティ環境の整備が進む
- JavaFX 11 のリリース
- OpenJDK ディストリビュータによる JavaFX サポート表明が相次ぐ
- 生きていた JSR-377
以降、順番にその詳細について記載していきます。
Oracle による Client Roadmap の発表とそれに伴う JavaFX の JDK からの分離
はい、2018 年の前半に出た衝撃の発表です。詳細については私自身が 2 回に分けてポエムを書いたので、そちらをご覧になってください。
これにより、Oracle JDK からも JavaFX は分離され、Java 標準の GUI ツールキットとしての地位は失いました。しかしながら、結果として OpenJFX プロジェクトはより独立して自由に動けるようになりました。
OpenJFX コミュニティ環境の整備が進む
OpenJDK と OpenJFX のつながりが小さくなったので、OpenJFX プロジェクトはより自由に動けるようになりました。これまではどうしても Oracle の動向に縛られることが多かったのですが、JavaFX をビジネスの中心に据えている Gluon 社主導でより外部の人が自由に参加できるような環境が急速に整えられました。
まず、リポジトリのクローンが GitHub に作成されました。
プルリクエストを出すためには OCA へのサインが必要ですが、Issue の報告などがこれまでよりもずっとやりやすくなりました。何しろ OpenJDK の JIRA は誰もが参加できるものでは無かったですから (ただし、メインのバグトラッカは依然としてここです) 。
そしてかっこいい Web サイトもできあがりました。
この Web サイトからドキュメントの閲覧やライブラリのダウンロード、GitHub リポジトリへのジャンプなどができます。今後は JavaFX の動向をチェックする際はこの Web サイトを拠点にするといいでしょう。
Java 11 から JavaFX は Java の 1 ライブラリになりましたが、Maven のリポジトリにも "org.openjfx" というグループ名でアーティファクトが登録されました。
https://mvnrepository.com/artifact/org.openjfx
モジュール別にアーティファクトが登録されています (実はこれを利用する際にちょっとした罠にはまったのですが、それは別のエントリで) 。Maven や Gradle 用のプラグインも用意され、それらと併用することで簡単にOpenJFX のライブラリが利用できるようになります。
このように Gluon が旗振り役となり、急速に環境が整えられました。「主体が Oracle から Gluon に変わっただけ?」みたいな言われ方をすることもありますが、やる気があるところが引っ張るようになっただけでも大きいと思います。
JavaFX 11 のリリース
上記の Maven リポジトリをご覧になると分かりますが、Java FX 11 もリリースされました。リリースノートは次の通りです。
https://github.com/javafxports/openjdk-jfx/blob/jfx-11/doc-files/release-notes-11.md
まあ新機能は少ないのですが、 Spinner
コントロールに改善が加えられていたり (詳しくは Yucchi_jp さんのこのブログエントリ を) 、新たに Robot というクラスが追加されています。この Robot
クラスについては別のエントリで触れる予定です。
OpenJDK ディストリビュータによる JavaFX サポート表明が相次ぐ
Oracle JDK の有償化に伴い、Linux 黎明期を彷彿とさせるような OpenJDK ディストリビューションの戦国時代に突入した感のある Java 界ですが、次の OpenJDK ディストリビューションが JavaFX の同梱を表明しました。
Amazon の Correto については、AWS が提供しているサービスの中に JavaFX を利用したツール (AWS Schema Conversion Tool が JavaFX で作られています) が存在することが一番大きな理由でしょうね。
Zulu については Azul 社の顧客に JavaFX を利用しているところが多かったのが理由だそうです。CTO が JavaFX と関わりの深かった Simon Ritter 氏であることも大きかったでしょうね。
生きていた JSR-377
最後は割と小ネタです。以前、自分のブログでも取り上げたことのある JSR-377 がまだ生きていましたw Java のデスクトップ、組み込み GUI アプリケーションのフレームワークを作ろうというもので、JavaFX に限ったものではないですが、ほぼ JavaFX をターゲットとしたものです。
この JSR 引っ張っていた方が Oracle の発表を受けて こんなツイート をしていたので、てっきりもうやめるのかと思いましたが、GitHub を見ると、再び更新が行われるようになっています。
ただこの JSR、Renewal Ballot が 3 回も行われており、 3 度目 では Oracle から「もう次はないぞ」と言われ、JetBrains からは「もっと真剣に取り組めよ」といった旨のコメントをチクリと言われる始末ですが。ですが、とても価値のあるものだと思っているので個人的には進めてほしいと思っています。
JavaFXの非矩形ウィンドウにおけるWindowsとMacでのマウスイベントの違い
しばらく blog を書いていなかったので先日気がついた小ネタでも書きます。
かなり昔に JavaFX で xeyes のクローンを作ってみた話 を書いたことがあったのですが、最近あれをイチから作り直してみました。コードも GitHub にアップしています。 *1
以前のブログエントリからは次のようにかなり作りが変わっています。
- 以前は Mac 上で Swing の EDT を実行すると HeadlessException が飛ぶ問題があり、仕方なく Swing を土台として作っていたのですが、現在はこの問題は解消されているので、JavaFX を土台としたものに変更しています。
- マウスカーソルの座標を取得するタイミングを以前は Swing の Timer で起こしていたのですが、これを JavaFX の AnimationTimer を利用するように変更し、より滑らかに目玉が動くようになっています。
- Stage のスタイルを StageStyle.TRANSPARENT に変更し、本家 xeyes のように背景を透過するようにしました。
最後のポイントに書いたように、Stage のスタイルを StageStyle.TRANSPARENT
に変更したため、ウィンドウのタイトルバーやウィンドウ枠がなくなるため、ウィンドウの移動やリサイズを自力で実装する必要があります。
その際に気が付いたことがありました。リサイズや移動が可能であることをが分かるように、アプリケーション上でのマウスカーソルの位置によってマウスカーソルの形状を変えるようにしました。ところが Windows 上で動かした場合と Mac 上で動かした場合に次のような違いが見られたのです。
- Mac 上で動かした場合、マウスカーソルが (透明になっている) ウィンドウの端や隅に到達してもちゃんとカーソル形状が変わる。
- Windows 上で動かした場合、「目」の上でしかマウスカーソルの形状が変更しない。
- と言うか、マウスイベントが全て「目」の上でしか発生しない。
この動きの違いに悩んで色々調べてみたのですが、どうも JavaFX 側の考え方としては Windows 版の動きが正 のようです。Mac 版の動きについて次のようなバグチケットが作られていました。
https://bugs.openjdk.java.net/browse/JDK-8088104
まあ考えてみれば理屈は分かります。非矩形に作ったのにマウスが矩形に沿って反応するのは確かに不自然です。自分が作ったこの xeyes については Windows 版ではウィンドウの四隅からリサイズが行えないという不便な点がありますが、縦方向と横方向のリサイズは可能なので、まあこれでいっかーとそのままにしましたw
というわけで小ネタでした。
Java Client Roadmap Updateによせて (後編)
というわけで先日アップした次のエントリの後編です。
前回は年寄りの思い出話という感じでしたがまさかの大きな反響を頂いて驚いています。後編については JavaFX や Swing、そしてクロスプラットフォーム GUI の今後について思うところを書いていきたいと思います。
JavaFX は今後どうなる?
今回の決定で JavaFX は JDK リリースから分離されることになったわけですが、逆に言うと JDK のリリースサイクルに縛られること無く開発を進められることになります。そして、私の感覚からすると、当面 JavaFX が廃れるような心配はしなくていいと見ています。
JavaFX は Java EE と同様によりオープンソースコミュニティに今後の開発をゆだねることになりましたが、JavaFX のコミュニティは今でもとても盛り上がっています。OpenJFX の ML では今でも盛んに議論がされていますし、先のホワイトペーパーでも「情熱的なコミュニティ」であると賞賛しています。
実は今回の発表の少し前に OpenJFX のリーダーである Kevin Rushforth 氏から OpenJFX コミュニティの今後の方向性について問いかけがありました。
http://mail.openjdk.java.net/pipermail/openjfx-dev/2018-February/021335.html
この議論では大変な盛り上がりを見せ、より外部の人が入りやすくなるような雰囲気にしようという方向になりました。その一環として GitHub に OpenJFX のリポジトリのミラーも作られ、PR を受け付けられるようにしています (OCA へのサインは必要です) 。
このように、JDK のリリースサイクルに縛られず、より外部も参加しやすくなることで、かえって開発のスピードが上がる可能性もあると考えています。前編でも述べたように海外では結構採用事例があり、Gluon のように JavaFX をビジネスのメインにしている会社もあります *1 。
と言うわけで、Java の標準 GUI では無くなりましたが、優秀なライブラリとしてあり続けるだろうと思っています。前編でも述べましたが、とても開発しやすい API ですし、Java で GUI を作るときの最有力候補であることは変わらないと思っています。コミュニティとの連携も取りやすくなる方向になっていますし、業務で JavaFX を採用したところがあってもそんなに心配しなくてもいいと思います。
私自身はここ数年フロントエンドとは余り縁の無い仕事をしている事もあり、業務で JavaFX を触る機会は無かったのですが、自分の身の回りでで GUI を使った道具が必要な時は JavaFX で作っていました。今後もそのためには JavaFX を使い続けると思っています。
Swing について
紆余曲折を経て、Java のデフォルト GUI は Swing に戻った感があるのですが、前編でも述べたように OpenJDK では再び Swing に力が入りそうな雰囲気になっています。Swing に JavaFX の良いところ (FXML とかバインディングとか) が移植されるような流れにならないかなあ。
私は Swing は一定の成功を収めたと思っています。何より Swing が覇権を握っている分野があります。それは IDE です。NetBeans と JetBrains の IDE だけじゃないかと突っ込まれそうですが、特に JetBrains IDE のここ最近の躍進ぷりはすごいです。JavaScript、Python、PHP、Ruby、Go など実に様々な言語コミュニティで人気を博しています。
クロスプラットフォーム GUI の今後
今回の件でクロスプラットフォーム GUI というのはやっぱり難しいものだなとは思いました。でも需要があるのは確かです。ゲームエンジンの様にユースケースをより絞ったものは普及していますしね。
汎用的なクロスプラットフォーム GUI で一番成功しているのはやはり Qt でしょうか。モバイルへの進出にも成功していますし。開発言語は C++ ですが、他のプログラミング言語へのバインディング も多いです。ですが、Java バインディングである Jambi が死んでしまったんですよね...。 *2
後は有力候補としてはやはり Electron なんですかねえ。私は好きじゃないんですよ。ぶっちゃけ Chrome ブラウザそのものなので、Electron アプリを 1 つ立ち上げると (潤沢にリソースを使う) Chrome ブラウザが余計に 1 つ立ち上がるようなものなので、使う側としてそんなに好きじゃないんです。Web 開発の難しさをデスクトップ GUI アプリ開発に持ち込みますし、そんなに JavaScript + CSS で開発したいですか?と言いたい感じです。まあ古典的なスタイルの GUI 開発が好きな人間としては、WebComponents に期待しているところです。
モバイル OS 戦争に敗れ去った MS は Xamarin に力を入れていますし、最近は Flutter なんてのも登場しましたし、今後もクロスプラットフォーム GUI へのトライアルは色々な形で出てくるでしょうね、というところで雑感垂れ流しのエントリを締めくりりたいと思います。
Java Client Roadmap Updateによせて (前編)
既にご存知の方も多いと思いますが、先日 Oracle から JavaFX をはじめとする、Java のクライアントテクノロジーについて今後のロードマップが発表されました。
上記ブログエントリでは主に JavaFX の今後の扱いについて述べていますが、以下のホワイトペーパーにはそのほかに Applet や Java Web Start、そして Swing/AWT といった Java のクライアントテクノロジー全般の今後のロードマップについて記載されています。
http://www.oracle.com/technetwork/java/javase/javaclientroadmapupdate2018mar-4414431.pdf
このホワイトペーパーを読んで、まあ色々思うことがありました。Java のクライアントテクノロジーについての過去も振り返りながら私が感じたことを色々語りたくなったので、このエントリを書きました。まあ巷で言う「ポエム」ってやつですね。
長くなったので前後編に分けて書くことにしました。
ホワイトペーパーに書かれていたこと
ホワイトペーパーに記載されていた内容を簡単にまとめると次の通りです。
- Oracle Java SE 11 からは JavaFX を同梱しないことを確定
- Applet のサポートは予告通り Java SE 8 までで、Java SE 11 には含まれなくなる
- Java Web Start についても Java SE 11 以降には含まないことを明言
- これは今回の発表で初めて明らかになったこと
- Swing と AWT については Java SE 11 においても開発を継続する
JavaFX については後ほど述べるとして、注目してもらいたいことは Applet、Web Start の扱いです。 これらに対する実行環境のアップデートが提供され続けるのは Java SE 8 のサポート期間の間だけ ということです。
よって、特に Applet を使った業務システムを展開しているところは Java SE 8 の無償アップデート提供期間中に対応を検討する必要があります。特にブラウザ Java Plug-in 部分はクライアント PC のセキュリティに直結するため、アップデートせずに放置するという選択肢は危険です。対応策としては次のようになります。
- Oracleの商用サポートを契約し、継続して実行環境のアップデートを受け取る
- アプリケーションを改修し、ブラウザ上で動かすのではなく、JRE を同梱したスタントアロンアプリケーションとしての配布に切り替える
- Oracle もホワイトペーパーで推奨している対応です
- 既に JDK にはそのための javapackeger というツールが同梱されている ので、これを活用しましょう
というわけで、このロードマップ発表で Java のクライアントテクノロジーは転換点を迎えることになりました。これまでの経緯をちょっと振り返ってみようかなと思います。
Java クライアントテクノロジーの変遷について振り返り
Java 誕生時の GUI
Java は誕生時から AWT という GUI ツールキットを同梱していました。Java の主な目的の1つに Web ブラウザ上で GUI アプリケーションを動かせるようにすることがあったからです。
AWT は画面に描画する GUI 要素は Windows や Mac といった実行環境のコントロールを使っていました。それに対して抽象化層を提供するものであったため、用意された GUI 要素は最大公約数的なものでした。そこで、AWT をベースに、Java2D を使用して全ての GUI 要素を自分で描画するSwing というツールキットが登場します。これは当時 Netscape 社が独自に開発したものに Sun が目を付けて共同開発したものです。
Swing はどの OS でも動く GUI を構築できるということで非常に画期的でしたが、如何せん登場時期が早すぎました (20世紀のことです) 。当時のクライアント PC のスペックでは動作が重すぎました。私は MMX Pentium 166MHz のマシンで初めて Swing を動かしたのですが、全ての動きがスローモーションで笑っちゃうしかなかったのを覚えています。
ですがこれにめげることなく継続的にアップデートを続け、JDK1.4 あたりでようやく実用的な速度が出るようになり、この頃から業務アプリケーション向けクライアント開発をはじめ、そこそこ採用されるようになってきた印象があります。私もこの時期に Swing での開発を経験しています。
Swing の発展
そして Java 5 から 6 に掛けた辺りで、当時既に普及していた Web アプリケーションに対して、当時の HTML の表現力の限界からリッチクライアントが再び見直される流れが出てきます。特に Macromedia (現在は Adobe に吸収) が Flash を業務クライアントとして推すことに熱心で、ここから Flex が誕生します。その流れを受け、Java SE 6 の頃に Sun は Swing 関連の技術に大きなてこ入れを行います。
- Java.net にデスクトップ専用のプロジェクトができる
- Java Plug-in の強化
- デスクトップ環境と連携する API の追加
- Swing 開発のためのアプリケーションフレームワークプロジェクトとその関連技術の開発が始まる
RIA の潮流と JavaFX の登場
この頃が Swing の全盛期だったかなあと思っています。そして大体同じ頃に別の流れが出てきました。それがコンシューマ向け Web を対象とした RIA の流れです。Microsoft が Silverlight をリリースした辺りから Flash と共に次のような特徴を備えたものとして注目され始めました。
もちろん Java にも Applet や Web Start という同様の技術がありました。Swing も GUI 要素を自分で描画する仕組みになっているため、頑張ればどんな見た目にすることもできます。しかし、デザイナが扱うのには向いていないプラットフォームでした。
そこで Sun が目を付けたのが、Sun が買収した企業である SeeBeyond に所属していた Christopher Oliver 氏が開発していた Form Follows Function (F3) というプロジェクトでした。 これは確か Swing を開発しやすくするための DSL だったと思います。 (さくらばさんより指摘があり、これは正しくないとのことでした。F3 は Flash + ActionScript な DSL を目指したもので、たまたま実行の土台として Swing を使っていたとのことです。) Sun はこの技術をベースに JavaFX というプロジェクトを立ち上げ、次のような特徴を備えたコンシューマ向け GUI 開発、実行環境としてデビューさせます。
- デスクトップ、スマートフォン、TV など様々な機器を対象
- JavaFX Script という GUI 構築のための DSL の採用
- CSS によるスタイリングの分離
- Adobe Illustrator や Photoshop に対してプラグインを提供し、デザイナが GUI 要素をデザイン可能
最初は Swing のラッパーコンポーネントという印象もあった JavaFX ですが、Sun はこれを AWT に頼らない GUI ツールキットとして発展させます。Prism エンジンを開発して GPU を積極的に活用する新世代の Java GUI ツールキットになっていきました。この頃から Sun は Swing への投資を急速にトーンダウンさせ、先ほど挙げた Swing App Framework 関連の JSR は中止してしまいました。これは当時 Swing 開発者からの反発もかなり大きかったことを覚えています。
ともかく Sun は JavaFX をすごくアピールしていました。Sun の開催するカンファレンスでは JavaFX を使った流麗なインターフェースをよくデモしていました。ですが、最も JavaFX を浸透させたかったスマートフォンへの展開を失敗してしまいます。旧 Windows Mobile に提供したのみで、水面下で Android への採用も持ちかけていたという話を聞いたこともあるのですが、現実はそうでないことは皆さんのよく知るところです。
そして Oracle による Sun 買収というイベントが起きます。
Oracle の買収と JavaFX の方向転換、発展
Oracle の買収で JavaFX がどうなるか不安視されましたが、JavaFX は引き続き盛り上げていくことを宣言します。ですが、Oracle は JavaFX をコンシューマ向け開発では無く、あくまで業務向け開発のツールにすることを重視しました。...とは Oracle ははっきり言っていませんが、その後の動きや Oracle のビジネス領域から考えれば明白でした。
JavaFX 2.0 において、JavaFX Script を廃止することが決まりました。そして、Java + FXML で開発するというスタイルに変わります。当然のことながらこれは大騒ぎになりました。 *1
ですが、結果としてこれは JavaFX にはプラスとなりました。本来の Java 開発者層が JavaFX に関心を持ち、注目度がぐっと上がりました (そのかわり Web デザイナ層は離れていきましたが...) 。古くささが見えてきた Swing と比べ、次のような点が優れていました。
- FXML による GUI 構造の分離
- プロパティとバインディング API によるリアクティブなスタイルでのビュー更新
- これは遅延実行の仕組みを備えるなど、他のプラットフォームと比べても優れていました
- Lambda Ready
私が JavaFX を本格的に触りだしたのもやはりこの時期でした。Flex による RIA 開発経験をしたこともあり、ユーザーに様々な UX を提供可能な RIA の可能性に目を向けていたところ、Java で開発可能な RIA プラットフォームが登場したので注目をしたのです。Flex と比べて優れているところも多いと評価していました。
2013 年の Java Day Tokyo の Java the Night に登壇したとき はこんなツールをデモして、JavaFX の魅力をアピールしたりしてました。
Oracle は積極的に JavaFX の開発を進め、JavaFX 8 までは盛んに機能追加も行い、今後 Java の標準 GUI は JavaFX になると宣言しました。JavaOne で iOS、Android デバイスでの稼働をデモしたりと、Oracle は本気だと私もすごく期待していました。
主に欧州を中心に業務系システムやトレーディングツールなどでの採用例が出てくるようになります。NASA など科学技術研究の現場での採用も多かったように思います。 Eclipse GEF も最新版では JavaFX ベースになっています。
そして Oracle の方向転換
ですが、JavaFX 8 のリリースがピークでした。JavaFX 8 リリースの後辺りから次のように徐々に暗雲が垂れ込んできました
- iOS、Android への搭載の話はトーンダウンし、OpenJFX でソースだけ公開してお茶を濁す
- 肝心の JVM 部分の公開がなかった
- Raspberry Pi での実行にも積極的になったかと思えば、1 年後にはトーンダウン
- Scene Builder も 2.0 リリースを最後にメンテナンスモードに
- 現在は Gluon がメンテナンスを継続 しています
Java 9 では Jigsaw 対応で手一杯で新機能の追加はほとんどなく、明らかにリソースを絞っているように見えました。そして今回の発表につながります。
ホワイトペーパーを見る限り、Oracle は Java のクライアントテクノロジーに対する興味がほとんど無いことが分かります。現在は Web ファースト、モバイルファーストの流れであると結論付けています。まあ Oracle の立ち位置的にここまで見てくれたのが奇跡的ですらあったのかも知れませんが。
なお OpenJDK コミュニティは AWT、Swing、Java2D の強化に積極的で、そういう意味では様々な紆余曲折を経て Java 標準 GUI の座は再び Swing に戻ってきたのかも知れません。
と言うわけで Java のクライアントテクノロジーの歴史を振り返ったところで前編終了。長くなりすぎて疲れましたw 後編では JavaFX 、そしてクロスプラットフォーム GUI の今後について思うところを書こうかなと思っています。
*1:当時のさくらばさんの怒り様はまあすごかったです (^^;;