JavaOne参加レポート (9/23)

それでは2日目となる9/23のレポートについてまとめます。
この日からが本番と言った感じで、朝から晩までびっちりとセッションが埋まっています。結構ハードです。

この日に参加したセッションは以下の通りです。

  • All the Nodes That Are Fit to Print: A Tour of the New JavaFX Printing APIs [CON2662]
  • Securing JAX-RS RESTful Services [CON5179]
  • Architecting Enterprise JavaFX 8 Applications [CON2229]
  • Introducing the Java Time API in JDK 8 [CON6064]
  • Type Inference in Java SE 8 [CON8165]
  • Lightning-Fast Access to Big Data [BOF5957]
  • JAX-RS and JSON Binding: Past, Present, and Future [BOF5519]

Java SE、Java EEJavaFX をまんべんなく取りました。型推論のセッションがちょっと自分には難易度が高かったですね。

All the Nodes That Are Fit to Print: A Tour of the New JavaFX Printing APIs

JavaFX8 でようやく印刷のためのAPIが導入されました *1 。それについて解説するセッションでした。
JavaFX8 の印刷 API は開発者向けには分かり易い API を提供し、業務アプリケーションに要求されるレベルを満たすことを目標として設計したとのことです。

中心となるクラスは javafx.print.package.PrinterJob クラスで、このクラスが印刷ジョブを制御します。
このクラスの showPrintDialog() メソッドで画面に印刷設定ダイアログを出し、printPage() メソッドに印刷したい範囲のシーングラフを渡します。そして startJob() メソッドで印刷ジョブを開始します。
印刷ダイアログは、独自のダイアログをだしてエンドユーザーに嫌われることが多かったSwingの時の反省から、プラットフォームネイティブなダイアログを出すようにしています。

他に重要なクラスとして、プリンターデバイスを表す Printer クラス、プリンターの機能に関する情報 (サポートしている用紙サイズとか) を保持する PrinterAttribute クラス、印刷ジョブの設定 (サイズ、枚数、色など) を保持する JobSettings クラス、印刷レイアウトの情報 (ページ方向、マージン、 Node の表示範囲など)を保持する PrinterLayout クラスがあります。

デモをあり、JavaFX で描いた円や、JavaFX8 に付いてくる新しい Ensemble アプリケーションのサンプルを印刷する様子を見せてくれました。なお、新しい Ensemble には印刷ボタンが付いています。

総じて中々使い易そうな API だと感じました。現在は Java2D の印刷機能をベースに実装しているようです (WebView については WebKit のプリントレイアウトエンジンを使っている) 。そのため、Java SE 8 のフルプロファイルが必要となります。将来的にはリライトしたいとのことです。
今後は、よりプリンターフレンドリーに、また CSS にも対応して、HTML のように media=print と書けるようにして、画面と印刷で別のスタイルを定義するようなことをやっていきたいとのことでした。

Securing JAX-RS RESTful Services

JavaEE7 に含まれる JAX-RS2.0 について、サーバーサイドの認証/認可、クライアント API 側の認証、そして JAX-RS サービスで OAuth 認証に対応する方法について解説するセッションでした。

サーバー側の認証/認可についてですが、サーブレットコンテナが用意している仕組みはそのまま使えます。この方法は記述が冗長であり、メンテしにくいと言う欠点があります。
JAX-RS では SecurityContext を用意しており、@Context アノテーションでインジェクトできるようになっています。このオブジェクトを使えば、メソッド内の特定の範囲だけ認可の仕組みを入れるなど、柔軟な制御が可能になります。
また、javax.annotation.security パッケージには @PermitAll などと言った認可のための各種アノテーションが用意されており、クラスやメソッド単位で宣言的に認可の設定を行えるようになっています。
また、Jersey2 + MOXy 限定ですが、Entity フィルタリングという機能が用意されています。これはリソースメソッドが返すエンティティのプロパティにアノテーションを貼って、アクセス元の権限に応じてエンティティの特定の属性だけを見せない、といった制御を可能にする機能です。

次にクライアント側についてです。
まず SSL で保護されたサービスにアクセスするために SslConfigurator というクラスが用意されています。ここにキーストアファイルなどの設定を行えます。
認証が必要なサービスへのアクセスですが、Jersey にはリクエスト、レスポンスをフィルタするための ClientRequestFilter、ClientResponseFilter というものがあります。そして、Web サービス側の認証方法に応じた、BasicAuthFilter や OAuth1Filter、OAuth2Filter が用意されていて、これら認証処理に容易に対応できるようになっています。

最後に JAX-RS (Jersey) を使って構築した Web サービスが、OAuth による認証を行う第3者サービスを利用する方法についての解説がありました。
Jersey では OAuth1.0a、2.0 をサポートしており、それぞれ OAuth1AuthorizationFlow, OAuth2AuthorizationFlow というクラスが用意されています。
この Flow オブジェクトにリダイレクト URI やプロンプト方法、識別子を設定し、 start() メソッドで認証を開始します。
そしてサービスプロバイダからコールバックしてもらうためのリソースメソッドを用意し、このメソッドの中で Flow オブジェクトが取得できると認証が成功となります。
実際に Google Task サービスにアクセスするデモを行って見せてくれました。

Architecting Enterprise JavaFX 8 Applications

Adam Bien さんによるセッションです。JavaFXエンタープライズ向けアプリケーションを構築する際のアーキテクチャはどうあるべきか、そしてその考え方を実装した自身作のフレームワークである afterburnerfx の実装について説明を行ってもらいました。

一般的に GUI アプリケーションのアーキテクチャとしては Smalltalk 由来の MVC パターンが良いとされています。しかしながら、近年になって複雑化する一方の GUI アプリケーションにおいては不十分であると考えられるようになってきました。
特にアプリケーションのリッチ化が進むにつれて、View 側のロジックが複雑化する一方です。View のテストは難しいです。そこで、MVC を変形したパターンとして、MVP (Model View Presenter) パターン、Presentation Model パターンなどといった新しいパターンが出てきました。 *2
MVP パターンは簡単に言うと Controller に View を操作する役割を持たせたパターンで、Presentation Model パターンはプレゼンテーションに関連するステートを保持する Model (Presentation Model) 用意し、View と Model の間に置くというパターンです。

JavaFX では FXML という仕組みがあります。FXML はマークアップ側 (View) と1対1で結びつく Controller が存在し、@FXML アノテーションで View 側のコントロールを Controler にインジェクション、さらにメソッドに対しても @FXML アノテーションで View 側で発生したバインディングさせることができます。
よって、FXML の Controller は MVP パターンにおける Presenter の役割を持たせることができます。
さらに JavaFX にはバインディングという優れた仕組みがあるため、Presentation Model を用意すれば、バインディングを利用することでプレゼンテーション側の実装コードを減らすことができるようになります。
そこで、afterburnerfx では次の図の様なアーキテクチャを取っています。

Presenter はサービス (主にネットワーク経由で外部サービスからレコードを取得するコンポーネント) と Presentation Model にアクセスします。サービス経由で取得したデータで Presentation Model をアップデートし、View は Presentation Model のプロパティとバインドしているので、自動的に表示が更新されます。
コンポーネントの結び付けは afterburnerfx 独自で開発した DI の仕組みを使って結びつけています*3 。FXMLLoader には setControllerFactory() というメソッドがあり、ここをフックして Presenter に対してサービスや Presentation Model のインジェクションを行うようにしています。View と PresentationModel のバインドは Presenter が行います。
View の更新はバインディングを利用して極力 PresentationModel のステート変化だけで行えるようにし、イベントハンドリングは FXML のメソッドバインドを使って Presenter のメソッドをそのまま呼び出すようにすることで、JavaFX 固有の API への依存が減るため、よりテスタブルになるというわけです。

JavaFX ではこれまでこのような本格的な GUI アーキテクチャに関する話があまり出ていなかったので、とても興味深いセッションでした。こういう議論が出てくるようになったということは、ある程度 JavaFX が普及期に入りつつあるといえるのかも知れません。

Introducing the Java Time API in JDK 8

Java8 で新たに導入された Date Time API (JSR-310) について、スペックリードの Stephen Colebourne 自身に説明してもらうというセッションです。とりあえず噂の Colebourne さんのお顔が拝めただけでも良かったと思っています。

Date Time API はイミュータブル、流れるような API、明確な API であることを目標として設計したとのことです。日付や時刻を取り扱う上で登場する概念をきちんと分類して、対応するクラスを用意しています。
おかげで沢山の種類のクラスが登場します。日付を表す Date クラス、時刻を表す Time クラス、両方を組み合わせた DateTime クラス、そしてこれらには Local**、Offset**、Zoned** クラスが用意されます。
そして時刻のある時点を指す Instants、時系列に縛られない時間の量を表す Amount (時刻ベースは Duration、日付ベースは Period) といったクラスもあります。
これらクラスにはインスタンスを取得するための now() メソッドや of() メソッド、各種演算メソッドや変換メソッドなどが用意されています。メソッドの意味は比較的明確で、メソッドチェーンができるようになっているので、流れるように記述されます。

各所で色々言われているように、覚えることが多くて大変かもしれませんが、API の意図は非常に明確であるので、個人的には以前のひどかった API よりは随分良くなったと思っています。
Colebourne さんはセマンティクスを明確にすることを重視される方に見受けられました。後日セッションがあった Colebourne さんが中心になって仕様を策定しているの Money and Currency にもそれが良く現れていました。
やっぱり仕様を考えた人のお話を直接聞くというのは理解する上でとても価値があるなあと思いました。

Type Inference in Java SE 8

Java SE 8 での型推論についてのセッションです。私自身が型システムに対して不勉強なこともあり、ちょっと難しい内容のセッションでした。

基本的に Java には型推論はありませんが、型パラメータの指定部分だけではちょっとだけ推論が効きます。Java SE 7 のダイアモンド演算子がそうですね。ただ、Java SE 7 ではこの推論が余り賢くなく、メソッド引数では効かなかったりしていました。それが Java SE 8 では改善されています。また、ラムダ式でもメソッドパラメータの型についてはかなり推論が効くようになっています。
このセッションでは、Java SE 8 ではコンパイラのストラテジーをどのように変更することで改善を行ったかの説明がされていました。

型の推論はプログラムの記述から読み取れる変数の上限、下限境界の情報から連立不等式を組み立て、それを解くような感じになります。不等式が解けない場合は型の推論ができず、コンパイルエラーが起きます。
Java SE 8 ではこの式の組み立てや条件の与え方をより改善することで、これまでは NG だったメソッド引数での型パラメータの省略や、ジェネリックな返値の解決などができるようになっています。条件演算子を挟んでも推論が効くようになります。
このように Java8 では型推論がかなり改善されたため、ダイアモンド演算子が大概の場所で使えるようになるので、より複雑な API を設計可能になるとのことです。

What's New in Java Transaction Processing [BOF3433]

Java EE 7 に含まれる、JTA 1.2 についての解説です。JTA は実に 10 年振りの改訂となったそうです。

2 つの大きな仕様追加があり、1 つは @Transactional アノテーション、もう 1 つは @TransactionScoped アノテーション。どちらも CDI に関わるものです。
@Transactional アノテーションEJB と深く結びついていた CMT を EJB から切り離すためのものです。CDI の管理対象 Bean にこのアノテーションを貼ることで、EJB の CMT と同じ機能が得られるようになります。サポートしているトランザクションタイプとか、デフォルトは実行時例外でロールバックし、チェック例外ではロールバックしないのも同じです。
@TransactionScoped アノテーションCDI 管理対象 Bean のスコープを定めるもので、トランザクションの範囲内でコンテキストが維持されるというものです。

Java EE の持つ機能は元々 EJB と強く結びついていたものが多かったのですが、このトランザクションのようにどんどん EJB から機能を独立して使えるようにしている流れになっているように見受けられます。今後は EJB は元々の役割であった分散処理、非同期処理の専用コンポーネントに戻っていくことになるのでしょうね。

Lightning-Fast Access to Big Data

IBM の方による BOF でしたが、分散インメモリキャッシュの話でした。一般論的に話そうとはしていましたが、まあ IBM の製品の話だったのでつまんなかったです。
やはり「ビッグデータ」なる言葉に釣られるとネタであってもロクなことがないと強く感じましたw

JAX-RS and JSON Binding: Past, Present, and Future

Java EE 7 では JSON をパースするための JSON-P は入りましたが、JSON のデータを JavaBeans にバインドするための JSON-B は結局入りませんでした。
次の Java EE に向けて、JSON-B の仕様が検討されているところのようですが、現在検討されているアノテーションについて淡々と説明する内容でした。
現在、JavaJSON バインディングのライブラリとしては Jackson や Gson あたりが有名だと思いますが、どうも Jackson をベースにしたものになりそうです。ただ、それに MOXy の機能も入れてみたいと考えているようです。(JAX-RS の参照実装である Jersey は 2.x で MOXy を使うようになっていますしね)

*1:JavaFX2.x の時は時間が足りず、ドロップしたそうです。

*2:Martin Fowler の GUI Architectures が参考になります

*3:ただし、インジェクションポイントを示すアノテーションには JSR-330 で定められている @Inject アノテーションを使っています