ぱと隊長日誌

ブログ運用もエンジニアとしての生き方も模索中

Java Day Tokyo 2013 レポート

はじめに

Java Day Tokyo 2013に参加してきましたので、そのレポートを公開します。
地鎮祭のお問い合わせ | 地鎮祭お届け隊

資料を補足する形でまとめているので、資料と併せて読んでいただけると幸いです(ほとんどの資料は参加者向けにしか公開されていないようですが…)
資料が一般公開されました!以下のサイトをご参照ください。Oracleありがとう!!
online20130514-javaday
これに伴い、A-1, A-3の参考資料(スライド)を削除しました。

なお、[参考]としている個所は私が挿入しています(内容確認のために参考にしたサイトなど)。発表者の意図したものではありませんので、その旨ご了承ください。

L-1 Keynote

Java SE Strategy

Java7に移行することでセキュリティやパフォーマンスを向上させることができる。

Java8では言語の拡張。JVMの進化。大小様々な機能の追加を行う。

言語の追加として大きいのはLambda式を導入したこと。同期コードを少ないコード量で書くことができる。また、より良いパフォーマンスを引き出すことができる。
単なるforループではシリアルな処理しかできず、マルチコアでパフォーマンスを引き出せない。forEachを使うことで並列処理が可能になる。

後方互換性の問題の解決のため、defaultメソッドを導入した。

新しいJDKをぜひ試して欲しい。そしてフィードバックして欲しい。今ならそのコメントを取り込みやすい。

Java8以降も多くのアイディアがある。これからもさらに進化させて行く。

急いで品質の悪いものを出すより遅らせてでも品質の高いものを出す。
リリースサイクルは2年で考えている。

JavaFX Strategy

JavaFXはSwingを置き換えるものだ。

大企業のアプリケーションでも使われている。

ランタイムとアプリケーションをバンドルすることもできる。
[参考]
こちらで紹介されている機能と思われます。
Oracle Blogs 日本語のまとめ: [JavaFX] Native packaging for JavaFX

JavaFXオープンソース化されており、Red Hatからのコントリビューションもある。

JavaFXのロードマップはJavaSEとシンクロしている。NetBeansやScene Builderも同様だ。

Java Embedded Strategy

1990年代にインターネットが登場。
2000年代はネットを介して人同士が繋がった。
これからはネットでデバイス同士が繋がる。

人間よりもデバイスがつながる時代がくる。それにより、新しい価値が創造される。

ユースケース
都市の交通管理。
産業向けの自動化。末端のデバイス自身がデータを処理できる。
貨物管理。
医療分野。高齢化社会で医療費が上がる中、自宅で治療を受けられることが大切になる。
スマートホーム。デバイスは常にONになっている。信頼できるサードパーティのアプリからのみコントロールできることが重要。夜間の自動アップデートやデバイス間の通信も必要だ。

Javaがそこに適しているのは成熟したプラットフォームがあり、多くの技術者がいることだ。

性能の高い製品にはSE。コスト重視ならME。といったように適用することができる。

ME,FX,SEのロードマップは同期している。内容についても同期している。
例えば、Jigsawを活用してよりコンパクトにするなど。

Java EE strategy

15年前には企業向けアプリケーションのプラットフォームが無かった。EEはそのプラットフォームを作った。
標準化には多くの企業のコントリビューションがある。

Java EE 6は非常に普及している。

非常に包括的なプラットフォームを提供している。ただ、これをフルに使う必要はない。プロファイルを使って必要な機能だけ使えばいい。

WebSocketを使ったアプリケーションを構築できる。バイナリもテキストもやり取りできる。また複数台と通信のやり取りができる。

java EE 8への取り組みを始めている。Project Avatarはその一つ。

java EE 7の標準参照としてGlassFish4.0を使える。

Java Community & Japan Java User Group

Javaにとってコミュニティは重要。新しい技術を伝える場となる。

スピーカーの話を聞くだけでなく、質問をして欲しい。それを通してユーザーが必要としているものを知ることができる。

学びはこの場だけで終わるものではない。人生を通して学び続けるのだ。

Java User Group, JCP, Twitterといった方法で参加して欲しい。
Java User Group(JUG)を通して新しいアイディアを議論できるということはとても大切。日本にもJUGがある。(ここで会場にJJUGへの参加アンケートを取り、)もし来年(こうしたイベントに)参加できるなら、この場にいるみんなが参加していて欲しい。

Javaとは革新そのもの。それはコミュニティに支えられている。コミュニティとはここにいるみなさんです。

S-1 Ask The Experts!

こちらについては別エントリにてまとめましたので、そちらをご参照ください。
Java Day Tokyo 2013 レポート(Ask The Experts!) - ぱと隊長日誌

A-1 ここからはじめる、JSR-356 WebSocket

HTTPはデータ共有のため開発された。
ただ、冗長なところがある。例えば、リクエスト・レスポンスに付随する多くのヘッダー。コネクションも毎回作り直しになる。
これまではそうした弱点を避けるためにCometを使ったりしてきた。ただ、標準的な技術がなかった。

そこでWebSocket!
双方向通信が可能。通信をサーバからでもクライアントからでも開始することができる。これらを1つのコネクションで実現できる。

ブラウザでWebSocketを使うならJavaScript APIを使う。

HTTPがUpgradeしていくように、WebSocketもUpgradeする。
WebSocketはハンドシェークから始める。
[参考]
Cutting Edge - WebSocket の能力について
"WebSocket プロトコルについて"を参照ください。

一方が切断すれば通信は切断される。
WebSocket通信を切断すると、TCPコネクションも切断する。

HTTPプロトコルはハンドシェークでのみ必要となり、WebSocketとして通信を確立したあと、HTTPは無関係となる。

通信を確立するとクライアントもサーバもPeerと呼ぶ。それぞれ対等な関係。
また、リクエスト・レスポンスとは言わない。メッセージと言う。
クライアントはメッセージを送り続けることができ、サーバはすぐにレスポンスする必要はない。いくつかのメッセージを受け取ってからメッセージを返すことができる。

エクステンションを使うことでデータの圧縮が可能。

IEは10になってからWebSocketに対応した。他のモダンブラウザは以前から対応している。
[参考]
資料では以下のURLの情報が引用されていました。
Can I use Web Sockets

RESTとWebSocketを比較すると、WebSocketのほうが圧倒的に早い。これはRESTのオーバーヘッドがそれだけ大きいということ。

アノテーションの説明:
@ServerEndpoint
 サーバーエンドポイントとなる。
@OnMessage
 メッセージの処理。戻り値がサーバからクライアントへのメッセージとなる。

簡単なチャットアプリなら1クラスだけで実現できる。

WebSocketのURIはws://で始まる。
[参考]
RFCの該当箇所
RFC 6455 - The WebSocket Protocol

DIをフルサポートしている。そのため、ビジネスロジックをInjectionできる。

HTTPをWebSocketにアップグレードすると説明したが、この仕組みはWebSocketに限らず他のプロトコルでも利用可能。

WebSocketのメッセージはWiresharkで確認できる。Chromeでも同様。
Wiresharkでのcaptureを見て)プロトコルがHTTPからWebSocketに切り替わった後、HTTPは出てこないことがわかる。

デモのサンプルは以下を参考にしてほしい。
Collaborative Whiteboard using WebSocket in GlassFish 4 - Text/JSON and Binary/ArrayBuffer Data Transfer (TOTD #189) | Oracle Arun Gupta, Miles to go ... Blog
Chat Sever using WebSocket in GlassFish 4 (TOTD #207) | Oracle Arun Gupta, Miles to go ... Blog

A-2 Java SE 8 による関数プログラミングの構文と並列処理のシンプル化

A Bit Of Background

Lambda式は単なる構文の置き換えではない。パフォーマンスを向上させるためのものだ。
コンピュータの進化をさかのぼって考える。
これまでムーアの法則に従って進化してきた。そして、トランジスタをクロックの向上に使ってきたが、最近はコア数の増加に使っている。

並列処理のコードを簡単に記述できるようにLambda式を導入した。それだけが導入の理由ではないが、重要な理由の一つだ。
並列処理ではデータの共有が問題となる。このコードを正しく書くことは難しい。Javaではバージョンアップ毎にその助けとなるような機能追加を行ってきた。Lambda式の導入はその一つだ。

並列処理の詳細はライブラリに隠し、プログラマが高レベルな処理にフォーカスできるようにしたい。
ライブラリで実現するということが大切。言語の構文自体を変えると後方互換性を損なうことがある。ライブラリならそのリスクがない。Lambda式の導入もその発想で行った。

Bringing Lambdas To Java

The Problem:External Iteration
for文のようなExternal Iterationは本質的にシリアル処理である事が問題。
また、forループ外の変数にアクセスするような場合はスレッドセーフでもない。

Internal Iteration With Inner Classes
filter,map,reduceを使ったパターンであればパラレル処理が可能。
ただ、コードの記述量が多く、可読性が悪い。

Internal Iteration With Lambdas
Lambda式を使うことで非常に簡潔に記述できる。コードが本質的なロジックのみとなる。

Lambda式はメソッドに似ているが、コンパイラは匿名関数として扱う。これにより、メソッド宣言が不要となる。

匿名内部クラス以外の変数を参照する時、Lambda式はfinal宣言していない変数も参照できる。その場合、final宣言されたものとして扱う。

Lambda式でthisはエンクロージングオブジェクトを指す。Lambda式自身は指さない。なぜならオブジェクトではないから。

Library Evolution

現行のインタフェースの後方互換性を保ちつつ、新しい機能を追加することは難しい。この解決のためにdefaultを導入した。

streamという考え方を導入した。
filter,map,reduceは全ての処理を終えてから次の処理を始める必要はない。これは並列化の観点から見ても良い。
例えば、検索処理であれば随時検索結果を返せる。全ての結果が揃うのを待つ必要はない。

Javaはこれまでもtypeについてはmultiple inheritanceを導入していた。
defaultはbehaviorの追加だ。
C++と異なるのはstateを扱わないということ。

Lambda Implementation

Lambda式のバイトコードへの変換を考える。
一つの方法はコンパイラが匿名内部クラスとして扱うこと。このアプローチの問題はクラスが追加されてしまうこと。また、匿名なのに実体があることになる。
Method Handlerとして扱う方法もある。この場合、バイナリの後方互換性の問題がある。
これらの解決策としてInvokedynamicを使うことにした。実行時にコンストラクトすることで両方の問題を解決した。実行時にコンストラクトするので(コンパイルしていないので)今後処理性能を改善できる。


A-3 Java プラットフォームにおける Batch アプリケーション (JSR 352)

Q.
Batch APIスタンドアロンでも使えるか?
A.
GlassFish上で動かすのが楽だが、スタンドアロンでも可能。

Q.
Java Batchを使うメリットは?
標準化されていること。java SE/EEと統合されていること。

Q.
アプリケーションを設計する上で参考にできるリソースは?
A.
チュートリアルを用意するので、それを参考にして欲しい。
あと、ロジックがアイテム指向なのかバルク指向なのかを見極めることが大切。


C-4 エンタープライズ環境における並列処理の実装方法について

Javaの初期バージョンからマルチスレッドをサポートしている。

Runnableを直接実装し、スレッドを無制限に生成するのはパフォーマンス上問題あり!
⇒スレッドの生成コストは高い!
この方法ではコアの利用率が低い。Concurrencyを使えばフルに使える。

[ここでデモ。以下がその様子です。条件などはコマンドでご確認ください。]

ExecutorServiceはスレッドの再利用が可能。
⇒これによりスレッド生成のコストを抑える事ができる。

JavaEE7でJMSの実装がかなり楽になった。

同期と非同期の違い。同期は処理が終わるまでレスポンスできない。非同期は別スレッドで処理を行い、その処理が終わる前にリクエストに対してレスポンスできる。

Servletでスレッドを生成すると、アプリケーションサーバー上ではなくJavaSE上で動いてしまう。そうするとスレッドはアプリケーションサーバーのリソースにアクセスできない。

InvocationHandlerはオリジナル処理の前後に別の処理を追加することができる。

コンテキスト情報を付加してEE環境でタスクを実行可能にすることをInvocationHandlerで実現している。これはサーバー側で実現している。
ExecutorServiceはコンテキスト情報を利用しているが、この仕組みのおかげで意識しなくて済む。

ただし、以下の制限がある。
JavaEE7のConcurrencyでForkJoinPoolは利用できない。アプリケーションクライアントコンテナでも同様。
JavaSEでできてJavaEEでできないのはshutdown。JavaEEでshutdownを管理しているため。

最後に

間違いや補足などありましたら、ご一報いただけると幸いです。
最後まで読んでいただきありがとうございました。