月曜日(2013年9月23日)に聞いた技術セッションのレポートを書きます。
Java Caching (JSR 107): The State of the Union [CON10175]
事前予約していませんでしたが、当日の朝、飛び入りで参加しました。裏番組に人気の”The Road to Lambda”があったせいか、会場はそこそこ空いていました。
スピーカはOracle社の人とTerracotta社のふたりでした。
12年かかって、ようやくJava Caching(JCache)のAPIが標準化されそうです。スペックのリリース予定日は2013年12月12日です。
スペックや参照実装はGitHubから取得できます。JCacheのオープンソース参照実装としてはEhcacheが有名です。
キャッシュはいわば一種のKVSなので、JCacheのAPIは、原則、コレクションフレームワークのMapに似ています。ただ、JCacheはMapとは違う、という点がセッションの冒頭で強調されました。
JCache APIの特徴は次のとおりです(プレゼン資料から抜粋)。
- java.util.ConcurrentMap like API
- Atomic Operations
- Lock-Free
- Read-Through / Write-Through Integration Support
- Cache Event Listeners
- Fully Generic API = type-safety
- Statistics
- Annotations (for frameworks and containers)
- Store-By-Value semantics (optional store-by-reference)
Map風のプログラマブルAPI以外に、JCacheは下記のアノテーションを定義しています。これらのアノテーションは今後のJava EE8とSpring4に含まれる予定です(Spring3は異なるキャッシュアノテーションを既に提供しています)。
- @CacheResult
- @CachePut
- @CacheRemove
- @CacheRemoveAll
個人的にはキャッシュ制御をアノテーションで宣言的に書けるのか、やや疑問を持っています。と言うのも、多くの場合、キャッシュを破棄してよいタイミングの制御に、条件判定などの業務ロジックがからみそうだからです。
セッションの最後に商用製品のJCache対応予定の話がありました。スピーカふたりの会社、それぞれTerracotta社のBigMemory、Oracle社のCoherenceがJCacheに対応予定ということです。
Jump-starting Lambda Programming [TUT3877]
今回のJavaOneで数多くあったJava8のLambdaのセッションのひとつです。
Oracle社のStuart Marks氏がスピーカでした。JavaOneのLambda関係のセッションで人気のあるのはBrian Goetz氏のセッションです。Goetz氏は著名なのでありがたみがあります。しかし、いかんせんGoetzは早口で英語が聞き取りづらいです。客観的に見て、Lambdaの概要を知りたいなら、Stuart Marks氏のセッションのほうがお勧めだと思います。
全体的な構成は下記のとおりです。この構成は秀逸です。これらを理解すれば、Java8のLambdaを理解したと言えると思います。
- Lambda
- Streams API
- Parallelism
- Reduction
- Collectors
一般的なプログラミングにおける抽象化の話から始まりました。
値パラメータによる抽象化、クエリ言語による抽象化、振る舞いのパラメータ化による抽象化と話が進み、振る舞いを簡易に記述できるfunctional interface、つまりJava8で言うところのLambdaに話をつなげます。自分がLambdaを他人に説明するとしても、この順序になるかと思っています。
プログラミングという行為の本質は抽象化だと思います。
とかくLambdaと言うと、関数型プログラミングというパラダイムから話を始めがちです。しかし、その説明の順序は間違いだと思っています。パラダイムや技法より先に、どんな抽象化をするかという見極めが先に立つからです。可変部分と不変部分を見極めた抽象化です。このような抽象化の姿勢を持たず、単に、問題に対して特定のパラダイムや技法を当てはめようとするのは間違いです。個人的に、特定のパラダイム(オブジェクト指向だろうと関数型だろうとメタプログラミングだろうと)に極端に傾倒しすぎた開発者に微妙な不信を感じるのは、こういう理由です。
セッションに話を戻します。
繰り返し処理を、ループとして見る抽象化からパイプライン処理として見る抽象化への変化の説明がありました。コンピュータサイエンスの世界から見れば、特に目新しくない変化ですが、Java的にはパラダイムシフトです。
Java8ではパイプライン処理がStreamsとして抽象化されます。
ただ、Streamとは何か、に対する答えはなかなか面倒です。英語で「Streamとはa multiplicity of valuesだ」と回答していました。値の集まりと意訳してしまうと、コレクションとどう違うのかと突っ込まれそうです。実体としては、コレクションよりはイテレータのほうに似ています。イテレータとStreamの何が違うのかと言われると、イテレータはモノの集まりから要素を取り出す操作の抽象化、Streamはモノの集まりをパイプライン処理に通す操作の抽象化と説明したいと思います。かえって分かりづらかったらごめんなさい。
余談ですが、Streamをストリームと記述すると、従来からあるI/O処理のストリームと混同しそうなので、パイプライン処理のStreamは英語のまま記載します。概念上は、I/O処理のストリームとLambda絡みのStreamは同じなので、結局、同じ名称です。同じ名称つながりで言うと、おっさんは、Unix System VのSTREAMSも思い出すかもしれません。
閑話休題。
Streamパイプラインは、ひとつのソース(Source)、複数の操作(intermediate operations)、ひとつの終端処理(terminal operation)で形成されます。
Java8のStreamパイプライン処理は並列処理の指定もできます。元々、JavaのProject Lambdaは並列処理から始まった背景があります。Lambda相当の言語機能だけを見るとJavaは他言語にだいぶ遅れを取りましたが、並列化に関しては後発の強みかもしれません。
繰り返し処理をパイプライン処理として抽象化する話に続けて、パイプライン処理で要素の加算をする簡単なサンプルに話が移ります。ここでナイーブに書いて失敗する例を示します。パイプライン処理の外側にある変数に += 演算で加算をしようとして失敗します。Lambdaからローカル変数の書き換えはできないからです。理由は、これを許すと並列処理できなくなるからです。なお、AtomicLongを使うと回避できます。しかし、並列処理で競合状態が増えて効率的とは言えません。
この問題はreductionで解決できます。簡単に言えば、パイプライン処理の外側の状態変数を書き換える代わりに、計算結果をパイプラインに流して畳み込んでいきます。
セッションの最後の話題はCollectorです。Collectorとは何か、に対してはMutable Reductionと説明がありました。
Collectorの裏側のマジックはまだ調べ切れていませんが、collectorで可能になることを表層的に説明すると、競合状態を発生させることなく、並列パイプライン処理から結果オブジェクトを生成できます。例としてgroupingBy()などに使われています。
Demystifying Java EE [CON2231]
恥ずかしながらこのセッションで見るまでdemystifyという単語を知りませんでした。mystifyが、対象をmysteriousな状態にする意味の動詞で、demystifyはそれの否定で、謎を解き明かす、と言った意味です。
本セッションは、Java EEのありがちな謎を解き明かすもので、次々にJava EEの混乱しがちなポイントを挙げて、それを解説するスタイルで話が進みました。
内容は悪くないのですが、スピーカが早口すぎます。おまけに、プレゼン資料には混乱ポイントを書くだけで、回答は口頭のみです。回答を聞き取れないと問題はわかるけど答えはわからないストレスがたまります。実に日本人泣かせのセッションでした。
Java EEでの混乱ポイントのひとつに、似たようなアノテーションの存在があります。セッションで、@Inject、@Resource、@EJB、@PersistenceContextの4つをどう使い分けるかの説明がありました。@ResourceはAPサーバにJNDI経由で取得させるリソースの指定、@PersistenceContextはJPAのEntityManager専用、@Injectはその他すべてのDI用です。@EJBはlegacyと断定しました。自分も前からそう思っていましたが、不要と言い切っていいのかまでは自信がありませんでした。@EJBは不要と言い切っていいのだと知って安心しました。もっとも、今年のJavaOneでも、サンプルコードに@EJBを使う人は多数いたので、なかなか消えなさそうです。
他にもJava EEで作るWebアプリはStatelessにすべきかStatefulにすべきかという問いかけがありました。Statelessのほうが流行りで美しいけど、Java EEがターゲットとする業務アプリの大半はStatefulで作るほうがラクなので、べき論で考えすぎなくてもいい、と話していました(たぶん)。
Java Persistence for NoSQL [BOF2887]
JavaOneでは、毎回、NoSQL系のセッションにでています。率直に言って、JavaOneでNoSQL系セッションに出ても、たいした情報は得られません。それでも出る理由は、NoSQL系の動きの熱さを見ておきたいからです。ワールドワイドで見た時、NoSQLはまだ熱いのか、終わりつつあるのか、あるいはどちらでもなく安定期に入りつつあるのか、などの温度を感じたいと思って出ています。ガートナーのハイプサイクル風に言うと、NoSQLの流行期は過ぎたと思っていますが、幻滅期を越えて回復期に入ったかどうかは判断できません。
今回のJavaOneで、NoSQL系のセッションは本BOF2887ともうひとつBOF8022(後述)に出ました。
BOF2887は、JPAの関係者が壇上に座り、NoSQLに関して議論するセッションでした。
結論から言うと会場は大盛り下がりでした。どんどん会場から人が抜けていきました。壇上にはJPAのスペックリードのLindaがいるにも関わらずです。
理由は明白で、壇上のJPA関係者がNoSQLに懐疑的だからです。明確にNoSQLダメとは言いませんが、少なくともJPAのように標準化するには時期尚早との見解を示していました。このため会場のNoSQLファンが何か質問しても、常に議論がすれ違う印象でした。これはこれでNoSQLの現状を見るという目的にはかないましたが。
セッションが始まった最初には会場にだいぶ人がいました。最初に、NoSQLを使っている人?という形で挙手が求められました。NoSQL系のセッションだからかもしれませんが、相当数(70,80%?)の手が挙がっていました。MongoDB?、HBase?、と言う形で問いかけが進みました。この辺がやはりNoSQLで最初に名前が挙がる実装のようです。会場にやたら声の大きいCouchBase派がひとりいたので次にCouchBase、その後、Cassandraという流れでした。NoSQLのどんな実装の名前が挙がるかは、後述するBOF8022で再び取り上げます。
What’s New in Java Transaction Processing [BOF3433]
JTAのセッションです。
Java EE7にはJTA 1.2が含まれています。JTAはなんと10年ぶりのメジャーアップデートです。
JTAと言うと、人によるかもしれませんが、Java EEの中で地味な印象があります。少なくとも、Java EEの簡易的なチュートリアルに普通はJTAが登場しません。理由は簡単です。トランザクション管理はEJBで宣言的に記述可能で、JTAの出る幕がないからです。
@StatelessなどのEJBアノテーションをクラスに付与すると、そのクラスはセッションビーンになります。セッションビーンとだけ名前を聞くと役割が不明ですが、昔のJ2EE時代はともかく、今のJava EEでのセッションビーンの役割は、Webアプリにおいてトランザクション境界の役割と思えば充分です。
セッションビーンを使うと、トランザクションを開始したり、明示的なコミットやロールバックの指示が不要になります。その代わり、セッションビーンのメソッド呼び出しは暗黙にトランザクション開始になり、メソッドを普通に抜けると暗黙にコミット、実行時例外でメソッドを抜けると暗黙にロールバックになります。宣言的な記述には、単に記述が簡易になる以外にも利点があります。分散トランザクションなど、複雑なトランザクションであっても、その実行順序をAPサーバに隠蔽できます。EJBは歴史の中で紆余曲折ありましたが、宣言的トランザクションの機能が今や唯一に近いEJBの存在価値になっています。
JTAもトランザクション管理を行うAPIなので、原理的にEJBと役割がかぶります。JTA 1.2より前は、宣言的にやりたければEJB、プログラマブルつまり普通にAPI呼び出しをしたければJTA、という棲み分けでした。
しかし、今回のJTA 1.2で宣言的にトランザクション管理ができるようになりました。@Transactionalアノテーションです。ちなみに、Springを知っている人にとっては、JTAの@TransactionalはSpringのそれと位置づけはまったく同じです(細かい部分は違います)。
と言うわけで、トランザクション境界を宣言的に書ける手段として、Java EE7の中にEJBのアノテーションとJTAのアノテーションが混在することになりました。当然、どちらを使うべきか、という疑問がでます。多くのJava EE関連のセッションでこの疑問に対する質問があがりました。しかし、全般的に歯切れの悪い回答しか聞けませんでした
後日、他の人に聞いたところ、とあるセッションでは、基本はJTAを使って、EJBの機能(分散オブジェクトとセキュリティ)が使いたい場合のみEJBでトランザクション管理すればよい、という回答をスピーカーがした場面があったようです。
個人的には、EJBの分散オブジェクトとセキュリティはobsoleteな機能だと思っています。今や、EJBのレベルでの分散オブジェクトより、Webサービスでの分散処理やメッセージキューによる分散処理のほうが主流だからです。となると、自分にとってはEJBを使う理由はなくなったと言えます。
公式に、EJBは役目を終えたと言ってしまうほうが、Java EEにとってすっきりすると思います。少なくとも、EJB LiteはなくしてJava EEのWebプロファイル(普通のWebアプリに必要な規格)からEJBは一掃してもよい気がします。
Where Do I Put My Data? Relational, NoSQL, or Other? [BOF8022]
BOF2887に続いて、NoSQL系のセッションに参加しました。
タイトルからすると、RDBMSとNoSQL系DBの使い分けの判断基準などを話しそうですが、単にNoSQL系データベースの紹介だけでした。さらに言うとスピーカがCouchBase社の人なので、その辺を割り引く必要があります。たとえば、MongoDBの扱いが不当に小さかったです。しかし、客観的に見て、MongoDBの存在感はNoSQL系の中で圧倒的です。MongoDB社(旧10gen)はOracle OpenWorldの展示会場で去年より大きく拠点を拡大していました。一方のCouchBaseはこのセッションのスピーカ以外、特に存在感はありませんでした。
上記BOF2887にも書きましたが、NoSQL系セッションに出てもたいした情報は得られません。このセッションでも、相も変わらずのCAP定理の話がありました。整理のために便利なので言及するのが悪いわけではありませんが、個人的には聞き飽きました。
概念の整理は特に目新しくはないので、関心はどの実装が言及されるか、です。これによりNoSQL系の世界のトレンドを追えるからです。
最初に言及があったのはKVS/Cacheの代表格のmemcachedです。まあ妥当ですね。あまりに基本的すぎてmemcachedを飛ばして話を始めるケースも多いですが、NoSQLを最初から話すならmemcachedから、になるでしょう。
その後、KVSより構造化した形の代表として、redisの言及がありました。memcachedの次にredisというのは少し興味深い展開です。
次に、ディスクベースのNoSQLという展開で、membaseの言及がありました。ここはスピーカがCouchBase社の人というのを差し引く必要があります。CouchBase社はCouchDBとmembaseの開発者が一緒になって設立した会社だからです。
その後、Document DBという展開で、MongoDBではなくCouchBaseを取り上げました。ここもスピーカゆえですね。興味深かったのはCouchBaseを、CAP定理でAよりC優先と説明した点です。かつてのCouchDBはCよりA優先でした。マルチマスタ型で、(CouchDBの原型とも言える)Lotus Notesっぽく競合文書ができて、競合文書の解決はアプリに委ねられていました。CouchBaseの事情は追っていませんが、C優先になっているとしたら大きな方針転換です。CouchBaseになり、かつてのLotus NotesっぽいAP型からMongoDBっぽいCP型になったようのかもしれません。
その後、カラムオーバーレイ型の代表としてCassandraの説明がありました。Cassandraはカラムストア型として説明されがちですが、個人的にはデータモデルの説明とデータのストア方式の説明が混在して気持ち悪く感じます。データモデルを説明する用語としてカラムストア型は適切とは思えないからです。本セッションではカラムオーバーレイという用語をデータモデル名として使っていました。この用語が一般的なら倣ってもいいのですが、あまり一般的ではない気がします。
CassandraはCAP定理でAよりC優先と説明がありました。これは前からそうです。
最後にグラフ型として、お馴染みのNeo4jの紹介がありました。グラフデータベースは、NoSQL系のセッションで必ず最後におまけのように扱われます。その時、実装として挙がるのはたいていNeo4jです。日陰っぷりがオブジェクトデータベースやXMLデータベースっぽいですが、もはや誰も言及すらしないふたつに比べるとグラフ型は日が当たる存在です。
最後に、説明なしで一覧に追記されたのが、redisと並んで(Oracle社の)coherence、membaseと並んでriak、CouchBaseと並んでMongoDB、Cassandraと並んでHBaseでした。ここ1,2年での新顔はないですね。
関連文書:
最近のコメント