本日がJavaOne Day Two(通算3日目)となります。
TUT2161: Preventing Errors Before They Happen
8:30-10:30
型検査を強化するためCheker Frameworkを使うお話です。
Javaの型システムは弱いので、NullPointerException、UnsupportedOperationExceptionなどの実行時例外の発生、SQLインジェクションに対する脆弱性などのエラーを型チェックシステム(コンパイラ)で検出することはできません。
解決策として、型システムを拡張します。型システムの拡張については10年以上前から様々な理論が登場しており、研究から実践の段階に移っています。
そこで、コンパイラに型検査のプラグイン(アノテーションプロセッサ)を追加するChecker Framewrokを作りました。
Checker Frameworkが提供するアノテーション
@NonNull @Untainted @Regex @Immutable @Linear @FullyQualified @GuardedBy @Interned @Fenum @Encrypted @Localized @State
Java 8からアノテーションを型を記述する各所に指定できるようになったので、その機能を使っています。また、Java 6/7でもコンパイルできるようにすることも考慮して、List*@NonNull*/ String>というコメントで記述することも可能にしています。
さらに、Java標準APIに対して検査アノテーションを付加したjdk.stubを用意しており、標準APIを呼び出すコードに対する型システムの拡張検査も可能にしています。
また、自前のチェッカーも作成可能です。
フロー解析をしているので、一時変数で受けるとき等で逐一型アノテーションを指定しなくてもよいようになっています。また、条件分岐があっても検査します。
CON4180: Lambda Under the Hood
11:00-12:00
Brian Goetz氏の人気セッションです。
ラムダ式をJava言語にどのように導入したかについてその裏事情を紹介するセッションです。
ラムダ式の必要性は並列化
Javaへのラムダ式導入にあたり、ラムダの型をどうするか? 多くの言語は関数型を導入しています。JavaではVMのシグニチャ・呼び出し(invoke)、変数、ヴァリアントをどう表現するかが課題で、関数型の導入はVMの大改造を招く上、既存の膨大なライブラリについてラムダ対応版と非対応版を両方揃えるのはおぞましいので、既にあるインタフェース(メソッドが1つのfunctional interface)をラムダ式の型とすることにしました。
次にラムダ式を無名インナークラスで実現すると、生成されるクラス数が増大する上、一旦生成されたクラスは(今後のバージョンアップでも)変更が許されないので将来の縛りが生じます。また、毎回メモリアロケート(インスタンス化)が走ります。
メソッドハンドルで実現する方法は、すべてのラムダ式がMethodHandle型になってしまい、ラムダ式のバイナリインタフェースを特定の実装(MethodHandleのこと?)に結びつけてしまいます。
そこで、新たな間接化の仕組みとしてinvokedynamicを使います。
性能については、invokedynamicはインナークラスより通常5-20倍、ワーストケースで同等です。
CON4946: API Design Checklist
12:30-13:30
スピーカーは日本語翻訳もある書籍APIデザインの極意 Java/NetBeansアーキテクト探究ノートの著者です。
APIの定義は、他の外部から依存されるものすべてでJavadoc(シグニチャ)だけではなく、ファイルレイアウト、プロトコル、振る舞い、メモリアロケーションレイアウト、リフレクションを使われるとprivateなメソッドやフィールドも含まれます。
APIとSPIについて・・・。
APIの利用者がきれいなコードを書けるのであれば、APIの実装は互換性を保つなどのために汚いコードになるのは許容されます。
APIレビュープロセスのポイントとして、互換性、ドキュメント、テスト、進化の余地があります。
Javadocは万能ではありません。
そのほか、バージョニング、パッケージ自体の公開(public)、非公開(private)について・・・。
CON5435: The Modular Java Platform and Project Jigsaw
14:30-15:30
Java SE 8からスリップしJava SE 9への導入を目指しているJavaのモジュール化仕様Jigsawについてのセッションです。
sun.* パッケージと*.internalパッケージは使っちゃだめ!
パッケージとは別の「モジュール」を導入するものです。
例)java.base、java.sql
.jar --+ +--> .jmod .class --+-> jlink --+--> .jar .jmod --+ : +--> JVM image
モジュール化に伴い、現行のJREにあるrt.jarとtools.jarを見直します。
以下イメージ(javaのバイナリはext下に入る?)
$JRE +-- bin +-- ext +-- include +-- lib +-- $ARCH +-- *.so +-- $VM +-- *.so
Jigsowプロトタイプでは、各モジュールがjmodになっています。例)java.sql.jmod
log4jをモジュール化してlog4j-api-2.0.2.jmod をjlinkで生成できます。
なお、バージョン管理(バージョン依存関係の定義)は、今年は説明からごっそり取り除かれ、質問に対しては課題だね、といった回答でした。
感想とメモ
Jigsawは最初の壮大な構想からどんどんシェープアップ(フィーチャーを片っ端から除外)しています。でもまだモジュールの数と依存関係がスパゲッティーの様相なので、このまま仕様化するのではなく、もう一回抜本的な見直しが必要と思います。
CON2265: Productive JavaFX 8
16:00-17:00
質問者にTシャツをプレゼント、背中の柄はなんとソースコードです。
JavaFXのGUIプログラムをMVP(Model-View-Presenter)パターンで設計するafterburnerフレームワークの紹介セッションでした。
1つのビューについて、FXMLファイル、FXMLViewのサブクラスとしてViewクラス、Initializeを実装するPresenterクラスを作成します。FXMLのコントローラクラス指定はPresenterクラスにします。
画面分割に対応できる仕様となっており、例としてSplitPaneの上半分をFXMLファイル、Viewクラス、Presenterクラスで実装していました。
Presenterはビューモデルなので、実際のモデル(データ)は別になります。afterburnerでは、サービスクラスおよびモデルクラスをPresenterにインジェクションする機能を用意しています。なお、Q&Aでのやり取りから、インジェクションするクラスのインスタンスはシングルトンらしいです。複雑な状況ならば、SpringなりGuiceなりを使ったらどうかとのことです。
また、Q&Aでナビゲーションがある等の複雑なGUIはどうする?に対して、NetBeans Platformにしたらという回答でした。
CON2259: Class Transformer: One of the Best-Kept Java Secrets
17:30-18:30
クラスローダーでロードしたクラスに手を入れる技術の解説セッションです。
アプリケーション開発者はこの技術の使い方を知らず、フレームワーク開発者は既にこの技術を知っています。そのためか知識の伝播がなかなか行われません。
クラスローダーは、load、link、verificationの3段階を経ます。loadでクラスのバイナリ表現を読み、linkでVMの中に入れ、verificationで様々なチェック(コンスタントプール、finalのオーバーロード、アクセスコントロール違反、正しい引数の数と型のメソッドを呼んでいるか、等)をしています。
verificationについては、最近Java SE 8u11でコンストラクタのsuperでverificationエラーが生じる問題がありました。
クラスローダーの種類とタイミングは、-verbose:classオプションをjavaに指定してプログラムを実行すると見ることができます。
次に、Agentでクラスの変換をします。
Agentを指定してプログラムを実行します。使用例はモニター、ビルドプロキシ(JPAの関連)、finalの除去、コードカバレッジの記録などいろいろ考えられます。
クラスの変換にはjavasistを使っています。
詳細な作成例はスライドを参照してください。
BOF4957: The New Real-Time Specification for Java
19:00-19:45
Javaのリアルタイム仕様RTSJ(Real-Time Specification for Java)は、Java言語仕様を堅持したまま同一バイトコードで動作させることを目指したリアルタイム実行の仕様です。最初のRTSJはJSR 1として(2002年に)仕様化され、2006年にRTSJ 1.0.2がリリースされています。JSR 282は、このRTSJのupdateを目指すもので、昨今の技術進化(よいリアルタイムGC、速いCPU、Java 1.4ベースから1.8ベース、Android)やマーケティングニーズを取り入れたRTSJ 1.1を定める活動です。
update対象のRTSJ 1.0.2の問題として
- デバイスメモリへのアクセスが効率悪い
- Happeningの定義が不適切
- 新たなClock(インターバルタイマ)の定義ができない
- ScopedMemoryの使い勝手の悪さ
- マルチコア対応がよくない
- ほかにもあれこれ
これを解決するためにいろいろな技術を盛り込んでいます。
- RawMemoryとRawMemoryFactory
- メモリマップドデバイス、I/Oマップドデバイス、汎用マップドデバイス
- 例)class IOBusController implements RawShort
- DMAサポート
- DMAコントローラからアクセス可能なByteBuffer
- バリアタイプ
- イベント機構の見直し
- AbstractAsyncEvent、AsyncEvent、AsyncObjectEvent、AsyncLongEvent、
- Happening
- トリガー、JVMの外で起きたものを扱う
- ユーザー定義Clock
- ISRのようなもの、Timerに関連して駆動
- Affinity
- ThreadとAsyncEventHandlerをどれかのプロセッサに固定する
- ScopedMemoryの改良
- PinnedMemory、StackedMemory
- その他の改善
- モジュラー構成
BOF3312: The Sumatra OpenJDK Project: What Can I Offload to the GPU?
20:00-20:45
プロジェクトSumatraは、JavaVMレベルで処理の実行をCPUとGPUとの双方に委ねることで並列処理性能を高め、CUDA/OpenCLと違いアプリケーションプログラマがGPUを意識する必要はないものと認識しています。
HSAアーキテクチャ
Sumatraでは新しいAPIを導入することはありません。ただしプログラマがヒントを与えます。といっても、Stream APIのparallel等を呼ぶことでヒントとなります。
GPUオフロード可能にするには、再帰はだめ、バーチャルメソッド呼び出しはプロファイル後、JDKメソッドの中の処理のみ対象、などの制約があります(現時点の制約?)。
セッション内容は昨年からさほど変わっておらず、あまり進展がないように思えるのですが・・・
去年のセッションの報告は次
JavaOne 2013 SF(09-24) - torutkの日記
BOF3604: JDK Tools and Beyond: A Closer Look at Pre-existing and New Tools in JDK 8
21:00-21:45
JDKの基本4ツール、javac、java、jar、javadocから始まって、JDKに含まれるコマンドを順次解説するセッションでした。
最後にダンプデータを表示するツールとしてJDK以外のSamuraiを紹介していました。
その他
遅い夕食
@bitter_foxさんと最後のBOF終了後、ヒルトンホテルから2ブロック北にあるタイ料理屋さん(Chabaa Thai Cuisine)にご飯を食べに行きました。この時間帯になるとほとんどのレストランは閉まってしまい、飲み処になってしまいます。そこで、タイ料理屋さんに行くことに。
テーブルに着いたら隣の席の人に声をかけられました。見ると、さきほど19:00〜のBOFセッションのスピーカーであるJames Huntさんでした。セッション終了後に名刺交換をしたので覚えてもらえていたようです。
リアルタイム仕様Javaの適用分野とか、Linux以外の組み込み系OSへの対応とかいろいろお話を伺いました。また、リアルタイム関係の別な仕様がJSR 302(Safety Critical Java Technology)で進められているようなので、そちらについても聞いてみました。
Jamesさんの会社(Aicas GmbH)はドイツのカールスルーエにあります。リアルタイム仕様のJava製品(JamaicaVM)を開発しており、適用分野としてはFA(ファクトリーオートメーション)、自動車、航空、医療など、米国より欧州向けが多いそうです。
JSR 302は、RTSJよりさらに制約の厳しい小さな環境を目指しており、GCとヒープを排除し、すべてScopedMemoryとStackedMemoryで実現するような仕様のようです。