CDI を理解する為に重要なレシピ


Java Day Tokyo 2015 で私が発表した内容を下記に公開しました。本セッションは、資料を作成する上で、今回ご紹介する内容を、より重点的に説明した方が良いと判断し、アジェンダに記載した若干内容を変更しお届けさせて頂きました。しかし本セッションは、日本でまだ不足している情報をお届けする内容であるため、皆様のご理解のお役に立てば誠に幸いです。

Java EE を利用して Web アプリケーション、企業アプリケーションを構築するためには、Webのデザイン、データ・アクセス部の実装、そしてそれらをつなぐビジネス・ロジックの3階層から構成する事が多いかと思います。これらの構成要素の中で、今回は、ビジネス・ロジックの実装部で重要な役割を担う CDI について焦点をあて、利用する上で重要な点について 14 点ご紹介しました。

本セッションは単に CDI の機能の紹介にとどめる事なく、何らかの処理を実装する上での課題を示し、今までの実装方法や各機能の利用上好ましくないやり方を 赤文字で “Yucky(まずい)” 示した上で注意点を促すと共に、解決策、改善方法を青い文字で説明するというやり方で説明しています。

また、CDI を正しく利用するために必要となる前提知識や、関連機能についても順に説明し、DI や CDI を理解する上で必要な情報を提供しています。今まで、CDI を限定的にしか利用していなかった開発者に対して、CDI にはこのような機能があったのか、このような使い方ができるのかといった事を理解して頂けると共に、何故 CDI が必要なのかを理解する事ができる内容になとしています。
今回、ご紹介する内容は下記になります。

問題1:リソースの参照について
問題2:ライフサイクル管理について
問題3:横断的関心事の分離方法について
問題4:値の検証方法について
問題5:依存性注入について
問題6:依存性注入対象の限定方法について
問題7:不変オブジェクトとしての注入方法について
問題8:文字で対象選択
問題9:CDI の有効化について
問題10:有効範囲の設定について
問題11:唯一の選択方法について
問題12:柔軟なインスタンスの生成方法について
問題13:アノテーションの整理
問題14:イベント処理

今回、構成の都合上、アジェンダに記載しながらも扱う事ができなかった、Concurrency Utilities for Java EE や WebSocket 等につきましては、過去の資料でご紹介していますので、併せて下記もご参照ください。

2015年4月15日 at 1:19 PM コメントをどうぞ

Java Day Tokyo 2015 の御礼


2015 年 4 月 8 日(水) Java Day Tokyo 2015 を開催しました。イベントにご参加頂いた皆様、ご登壇者の皆様、スポンサー企業の皆様、そして事務作業からイベント運営まで裏方として支えていただいた多くの皆様、誠にありがとうございました。
当日は、あいにくの天気でございましたが、最後まで特に大きなトラブルもなく終わる事ができたのは、一重にご参加頂いたすべての皆様ご協力のおかげです。

下記の文章は、諸般の事情で記載する文面を「である調」で記載しているため内容が固くなっておりますが、基調講演で語られた様々な内容をまとめてみましたので、どうぞお時間のある時にご覧ください。また、本ブログの最後に、ニュース記事や、Toggetter、ブログ等のリンクも記載しています。併せてご覧下さい。

■ 日本オラクル社長からのご挨拶

冒頭、日本オラクル取締役 代表執行役 社長兼CEO 杉原 博茂より、オラクルにおける Java の重要性について語られた。
 杉原はオラクルが他の企業とオラクルは何が違うかについてラリー・エリソンに尋ねたという、その際ラリー・エリソンは「我々には Java がある」と語ったという。杉原もまた、オラクルにとって Java は重要なテクノロジーであり、今後「Digital Disruption(デジタルによる破壊)」が訪れる中で、Javaが重要な役割をもたらすと語った。例えば、企業においてソーシャル・ネットワークの影響はかつてない程大きくなっており、その影響はもはや無視できない所まできている。また新しい産業革命の波が訪れており、Java がこうした時代において何をもたらすのか、非常に興味深いと語った。さらに、2020年までに人口の約3割が 65歳以上になり、250万人の人口が減少すると統計学的に予想されている、このような将来において1人1人の生産性が今まで以上に重要になる。オラクルは今後、迎えるさまざまな時代の変革において、生産性の高いITの提供方法を考え、一つの解をだした。それが完全な「クラウド・シフト」である。もちろん、今まで同様にオラクルはオンプレミスの環境でのサービスも提供するが、それと同様にクラウド上でも同様に様々なサービスを提供する。現在のIT社会において、「IoT」、「Social」、「Big Data」、「Mobile」といったサービスが提供されているが、これらを実現するために、最も重要なのが「Java」であると語った。世界的視野でみると、様々なデバイスで Java が動作し、将来的には車も Java で制御されるような時代がおとずれ、今まで以上にさまざまな物がJava で動くようになると語る。世界にはJavaの開発者が900万人いると言われるが、Java Day Tokyo にお越し頂いた開発者が、世界の開発者の一員である事に対して誇りに思うと語った。
最後に杉原は、次の日に開催される、Oracle Open World Tokyo 2015 で発表予定の「Java クラウド・サービス」を、Javaの開発者に対して先がけて発表を行った。これは Java の技術をクラウド上でより簡単に使いやすく利用できる物であると語り、皆様とともにクラウドの社会を作っていきたいと強く語って挨拶を締めくくった。


■ Java 20 周年のハッピー・バースデー

 2015年は Java が世界に発表されて20周年を迎える記念の年で、Java Day Tokyo に参加した開発者と共に、ハッピー・バースデーを歌い祝った。さらに Java の生みの父と言われる「James Gosling 氏」より、来場する Java 開発者に向けてビデオ・メッセージが贈られた。

James Gosling は Java の20年を振り返りとても広範囲に利用される言語になった事、Java コミュニティの成長が素晴らしい事、特に日本は素晴らしい土地で、過去に何度も来日しお客様とお話をした事、数えきれない程のイベントを行った事を思い出した。その際、日本のお客様や、パートナー、Javaのゲーム・コミュニティなど、お会いした皆様はとても素晴らしい方々だった事を覚えていると語った。また、イベントでコンテストを開き審査員を務めた事も楽しい思い出だったと回想した。日本のJava開発者コミュニティの皆様が行ってきた事はとても素晴らしい事で、今後 20年をとても楽しみにしています。皆様本当にありがとう、といったメッセージを開発者に届けた。

■ Java 開発者コミュニティへの参加の呼びかけ貢献について

続いて、JavaOne Conference の委員長を務めるSharat Chanderより、Java コミュニティへの参加の呼びかけが行われた。そして開発者の皆様とオラクルが良好な関係を築くためにコミュニケーションを持つ事がとても重要だと語った。冒頭で、Sharatは、「我々オラクルの来日理由は、開発者の皆様と良好を築くためであり、それはとても重要な事」だといった。なぜなら、過去20年間にJavaコミュニティからの多大な貢献があり、もしコミュニティや開発者の皆様との良好な関係がなければ Java の品質を向上する事はできなかったと言う。日本には「日本Javaユーザ・グループ」、「関西Javaエンジニアの会」という大きな Java コミュニティがあるが、この日本のJavaコミュニティの貢献に対してぜひ感謝を送りたいと語り、会場の来場者と共に拍手を贈った。さらに日本から OpenJDK コミュニティへの参加者が増えている事にも感謝を述べたいとし、実際に参加されている、末永恭正氏、久保田祐史氏、吉田真也氏、大村忠史氏を紹介し同様に感謝の拍手を送った。また、Sharat はここで、Java SE 8 用の新しい資格試験の提供開始も発表した。

オラクルは、今後も継続した Java 開発者の皆様と良好な関係、強力な関係を構築したい、そのためにソーシャル・ネットワークを通じて情報交換を行いたいと言い下記をそれぞれ紹介した。

情報収集のため
* G+ : plus.google.com/+javaplatform
* Twitter : twitter.com/java
* YouTube : youtube.com/java
* Facebook : facebook.com/ilovejava
* Blog : blogs.oracle.com/java

Java コミュニティへの参加のため
* home.java.net/jugs
* java.net
* openjdk.java.net
* jcp.org

最後に、次の Java の 20年を作っていくために、フィードバックやアイディアを直接 Java コミュニティ経由で届けて欲しいと語り締めくくった。

■ Java SE 8 & ME 8 に関するアップデート

続いて、Java Platform Development の Vice President を務める、Georges Saab よりJava SE 8 と ME 8 に関するアップデートを行った。
 Georges は冒頭、自身の Java の経歴について語った、彼は1996年のJavaの提供開始当時、Sun Microsystems に在籍し Java のクライアント・ライブラリの開発業務に従事していた。その後、BEAに移動し JRockit の開発部門を率いた。JRockit は日本でも非常に多くのお客様に利用して頂き感謝を述べたいと語った。さらにOracle との統合後、Javaの開発部門を率いる事になり、自分にとってもこの20周年はとても感慨深いと語った。
 昨年、JDK 8 をリリースしたが、JDK 8 は非常に多くの機能を持っている。これら全てを語る事はできないが、オラクルの投資は今後も継続し、Java コミュニティと共にさらにより扱いやすい物を提供していきたいと考えていると語った。また、Java を近代的なプログラミング言語にするために導入したLambda 式(関数型プログラミング手法)について説明した。Lambda 式は言語仕様に対して大幅な変更を加えた他、Java仮想マシンにも手を加えてパフォーマンスの向上を図っていること、さらにコレクション・ライブラリをより効果的に分かりやすく記述できるように Stream API を提供したことについても紹介した。そしてこれらを適切に利用する事により、JDK 7 で実装したコードに比べ最大で40%のパフォーマンス向上が期待できる事を紹介した。さらにセキュリティ対応はオラクルにとって最も重要である事も付け加えた。
この Java SE 8 における変更は今までのJavaの歴史の中で、かつて無い程に大きな変更を行った事を紹介した。

■ Pepper の制御用 Java SDK の提供開始について

 Georges Saabより Aldebaran Robotics の Software Director である Laurent Lec 氏が壇上に招かれ、Laurent 氏より、「Pepper」の制御用 Java SDK が正式に発表された。また、あわせてデモンストレーションも行われた。(「Pepper」は最寄りの SoftBank ショップでご覧頂く事ができる)

Aldebaran(https://www.aldebaran.com/ja)はフランス企業でソフトバンク関連企業の1社でもある。Aldebaran は人間型のロボット(NAO,Romeo,Pepperなど)を提供している。Pepper はバッテリーや音声検知用のセンサー、タッチセンサーなど、様々なセンサーを内蔵しており、それらを検知して動作するようになっている、さらにスクリーン・モニターにはビデオやWebページ等を描画する事も可能だ。そして Pepper は自由にプログラミングが可能になっている。
デモンストレーションでは、声を発声するためのコンポーネントをドラッグ&ドロップで開発環境に配置しPepper で挨拶をさせた他、複数のコンポーネントを同様にドラッグ&ドロップでつなぎ合わせる事で複数の動作を連携して実行する事が簡単にできることを紹介した。その後、Java で制御するサンプル・コードを示し Java で動作させた。(ご興味ある方は、パッケージ名com.aldebaran.qi から検索頂きたい)

■ Java SE 8 のロードマップについて

Georges は、最後にJava SE 8 のロードマップを示した。現在提供されている Java SE 8 update 40は様々な新機能が組み込まれており素晴らしいできで、現在 update 60 の実装を進めている。また来年には JDK 9の提供も検討されている事が説明された。JDK 9 では Project Jigsaw として知られているモジュール化の機能が導入される予定で、アプリケーションのパッケージの仕組みが大きく変わる事を紹介した。モジュール化による恩恵はセキュリティや、パフォーマンス、起動時間の高速化などで期待ができる事だと語った。最後に、Georges は JDK 8 を是非本番環境で積極的にご利用いただきたいと語った。また、さらに Java SE 9 も、jdk9.java.net にアクセスし、早期お試し版をクオリティ改善のために試し頂きフィードバック、バグ報告などを行って頂きたいと語った。

■ Java ME 8について

Java ME は過去、Java SE と Java ME との間にあった大きなギャップを埋め、Java SE 8 で蓄えたノウハウが、そのまま Java ME でも利用できるように、言語仕様やライブラリの統合化を進めていると語った。これに対して業界は非常に好意的で、ダウンロード数も非常に多くなり、業界間におけるコラボレーションも行われている。これにより実装改善が行われ、パフォーマンス改善もされているという。また、Java SE 8 Embedded や Java ME Embedded 8.1 等新しい製品もリリースされ、様々な環境で利用可能になっている点を報告した。

■ Java ME 8 のデモンストレーション

ルネサス エレクトロニクス株式会社の米山氏を壇上に招き、オラクルと共に作成した Java ME 8 のデモを紹介した。米山氏によると、IoT 市場は今急激に拡大し、膨大なデータのやりとりを行っている。デバイス側の観点で考察すると、IoTゲートウェイはどのようにセンサーを管理しているか、サーバはどのように受信したデータを分析しているかが分からない。一方でサーバ側では、どのように IoT ゲートウェイとセンサーが通信しているのか、各種センサーでどういった事ができるのか、どのようなデータを取得できるのかを把握する事は困難であると語る。ルネサス エレクトロニクスは、デバイス・センサーの提供者側として、デバイス側であらゆるデータ処理加工を行い、IoT ゲートウェイに対して価値のある小さなデータを送る事がとても重要であり、そこに価値があると考えていると語る。その際に、Java が持つ資産はとても魅力的であり、デバイスが異なってもそのノウハウを流用できる事は、より効果的で新しい未来が訪れるだろうと語った。
今回、組み込みデバイスで実装された自動車をバスに見立て、バス停毎に容易されたツイッター・クライアントからバスの運行状況をリアルタイムに通知するデモンストレーションを行った。これを実装する際、Java ME は mbed を標準でサポートしているため、mbed 上で簡単にアプリケーションを作成する事ができ、デバイス上からクラウドに対して簡単に情報配信するための仕組みを実装、提供できるようになったと語った。Java と組み込みのデバイスは、アイディア次第で新たな価値を創造できる、Java の開発者の皆様と共に新しい物を創造していきたいと語った。

■ Java Car のデモンストレーション

続いて、Internet of Things のアーキテクトを務める Jasper Potts 氏より Java Car に関するデモが行われた。このデモは昨年のJavaOne 2014 サンフランシスコで世界中のJava開発者に披露したデモと同様で本場のデモを日本に持ってきた形となる。この車に見立てたデバイスのデモは様々なセンサー・デバイスが搭載されており、例えば重力センサーも搭載されており、車がカーブした際にかかる G(重力) の情報も画面に表示できるようになっている。また、音楽も聞く事ができるようになっている他、光を検知するためのライトセンサーも持つため、ライトセンサーが夜を検知した際に、モニター表示も自動的に夜の描画モードに変更可能だ。この車の各種デバイスは、各種センサー情報をIoTゲートウェイ通じて、センサー情報のデータをクラウド上にのサーバに対してリアルタイムで情報をアップデートできる。またバッテリーの使用状況も監視し、バッテリーの寿命が来た際に自動的にサーバ側から、車上のモニターに警告情報を通知し、併せてあらかじめ登録された携帯電話に対してメールで通知可能という。さらに車のディーラにも情報を通知する事でメンテナンスの予約情報なども通知できるようになっている。
JavaOne 2014 San Francisco の日本語字幕付きデモはコチラでも視聴可能。(https://www.youtube.com/watch?v=IK11x-Nr8Qs)

■ Java EE の現在と将来について

Java EE に関して、Cloud Application Foundation の Senior Vice President である Cameron Purdy より説明が行われた。Cameron は冒頭で、James Gosling のビデオに触れ、James Gosling といえば、JavaOne で T-シャツ投げをする事が有名で覚えている方もいるかと思うといい、同様にTシャツ投げをするといい壇上からTシャツ投げを行い、会場を盛り上げた。

Java EE は様々なアプリケーション・サーバ・ベンダーで対応されており、世界中のJavaコミュニティ・メンバーから多大な貢献を頂き提供をしていると語った。

Java EE 7 は様々な機能を新規追加したが中でも HTML 5 対応はより重点をおいて対応したと語った。HTML 5対応として新しく、WebSocket や JSON 対応等がある。また、開発生産性の向上は引き続き行われ、アノテーション・ベースの開発として CDI も継続して改良を行った。また企業アプリケーションの開発ニーズに対応するために、バッチ処理の標準化なども行った他、メッセージング・サービスの実装機能として、JMS 2.0 も大幅に開発生産性を向上したことなどを紹介した。
また、昨年、Java EE の参照実装である、GlassFish v4.1 をリリースしたが、このリリースでは数多くのバグ対応を行った他、Java SE 8 にも対応したと語った。

Java EE 8 の正式リリースに向けて我々はすでに検討を重ねており、現在の市場が求める技術トレンド等を調査している。検討中の内容として、例えば、新しい HTTP の仕様である HTTP/2があるという。また、RESTful Webサービスによる実装は現在多く行われているが、サーバとのデータ交換に JSON のデータ・フォーマットが利用される事が多いという。Java EE 8 では、この JSON データをより簡単に扱うため、Java オブジェクトと JSON を直接バインド(結びつけ)する、JSON-Binding の導入も検討している。もちろん、こうした技術においてセキュリティは非常に重要であるため、セキュリティに対する実装も改善を予定している他、サーバ側のイベントに応じてクライアントに対して通知をするための、Server-Sent Event の導入なども検討されているという。
その他、CDI 2.0 や JMS 2.1、JSF 2.3、MVC 1.0、Java EE Management 2.0 等も予定されているという。これらは全て Java EE 8 の仕様に含まれ、Java EE 8 のProposalドラフトは全会一致で承認されたことを報告した。また、オラクルのパブリック・クラウドのサービスについて Cloud Developer Outreach の Stephen Chin からライブのデモンストレーションが行われた。Steve は事前に用意した WebLogic が稼働する、Java Cloud Service のインスタンスと、Coherenceを連携し、大量データの効率的な処理を行うデモンストレーションを行った。

Cameron は最後に、Java EE のロードマップについて紹介した。Java EE 7 は2013年に正式リリースを行ったが、その後、Java EE 8 の提供に向けて動き始めた。まず、最初に行ったのが世界中の Java EE の開発者に対するアンケートだ。どのような機能が実際に必要とされるのかを開発者自らに問い合わせた。その結果を交え Java EE 8 に含む技術を検討し、昨年より Java EE 8 を開始した。来年末までには Java EE 8 と併せて参照実装である GlassFish を提供したいと考えていると語った。Java EE 8 の提供に対して、世界中の Java コミュニティが Adopt-A-JSR というプログラムを通じて貢献している。日本 Java ユーザ・グループも、JSR 371 : Model-View-Controller(MVC 1.0)に対する貢献の意向を表明していると聞いおり、JJUG に対して大変感謝していると述べた。Java EE では、まだ他にも様々な仕様が存在しており、是非エキスパート・グループ・メンバーに参加し Java EE 8 の標準化に対して参加して欲しいと語った。参加のご意向がある方は glassfish.org/contribute へアクセスをして欲しいと言いセッションを締めた。

■ Java への新たな取り組み – JCP への参加とコミュニティ参加

Cameron に代わり、基調講演最後のセッションをまとめたのは、日本オラクル Fusion Middleware 事業統括本部の伊藤 敬だ。
伊藤は冒頭、Java は20周年を迎え、これから新しい事を始める事に対して日本オラクルとして今後も貢献していきたいと語った。日本オラクルの取り組みとして、Java for Kids, Java for Students, 小学生、中学生、高校生に向けた Java の勉強会を開いている。
小学生でも、楽しみながら Java を勉強し、中学生以上になると本格的に Java を教えている。
学生に、早い時期からプログラミングを教える事は今後の時代を変えていける事でもありとても重要であると考え、今後も続けていきたいと語った。

オラクルの取り組みを紹介した後、伊藤は3名のゲストを壇上に招き入れた。

➢ 楽天株式会社 技術理事:      仲宗根 徹也氏
➢ 日本 Java ユーザ・グループ 会長: 鈴木 雄介氏
➢ 関西 Java エンジニアの会 会長:  阪田 浩一氏

楽天株式会社の仲宗根氏から、楽天における JCP 参加(2014年9月)の経緯について語られた。楽天では E-コマース、トラベル、金融、メディア、広告など様々なサービスを展開している。特に楽天会員、楽天スーパーポイントといったサービスを「楽天経済圏」と名付けて構築している。楽天のサービスは PHP や Ruby 等で構築されているサービスも存在するが、「楽天経済圏」のコアなサービスは全て Java で構築していると語った。JCP の参加は日本オラクル社員の紹介で、初めてその機関の存在を知り興味を持ちはじめたが、当初は加入に対して不安要素もあった。楽天はテクノロジーを売りにする企業ではなく、サービスを提供する企業であるため、サービス企業が Java の仕様策定に関わる事ができるのか、またそのような時間を割く事ができるのか不安だった。しかし、「楽天経済圏」のコア部分は全て Java でできているため、Java に対して貢献する事が、自分達の将来の開発に役に立つのではないかと考えた。エキスパート・グループへの参加や、参照実装を作るまでの事ができない場合も、Java の動向を正しく理解し、将来に対し意見が言える場にいる事は利点でないかと考えた。これらを総合的に判断し楽天は JCP への参加を決定したと語った。まず JCP の参加に辺り、JCPチームを作り、Java に興味のある社員を集めた、そこで参加者が興味のある JSR(仕様) を観察し、JCP チーム内で情報共有する所から始めている。そして将来的には世の中に対して情報発信をしていきたいと考えていると語った。また、実際の JCP への参加事例として JSR 372 : JavaServer Faces 2.3 の仕様に対する実際の貢献内容について報告した。JSF のスコープという機能に対して、ある楽天のエンジニアが新しいスコープを考え、その参照実装を作成し JSF のエキスパート・グループ・メンバーに提出した所、それが採用され、次期 JSF 2.3 の標準仕様内に取り込まれる事になったという。これにより自社のアプリケーション開発においても将来、自分が提案した技術を利用できるようになる日がくるという。そして、それが世界の開発者にとっても開発生産性を高める事になるのであれば、楽天という会社にとっても大きな社会貢献になるのではないかと考えていると語った。
自分たちが使う言語を自分たちが良くしていく事は、開発者自身のためであり、楽天が提供しているサービスのためでもあり、大きな社会貢献であると考えていると語った。仲宗根氏は最後に、自らの経験から来場者にむけて「スモール・スタートで JCP を始めては如何でしょうか?」と語った。

続いて、日本 Java ユーザ・グループ(JJUG)会長の鈴木雄介氏が登壇した。JJUGは現在会員数が約3000名で、Java の技術向上やエンジニアの地位の向上を目的として活動している。主な活動内容として年に2回開催するクロス・コミュニティ・カンファレンスのほか、毎月定例のナイトセミナーを開催している。さらに日本全国に存在する地方のJavaコミュニティに対して東京から講師派遣も行っているほか、国際会議へも参加していると語った。今年、JJUG として重点的に取り組みたい内容として、JSR への参加があるとした。Java は Java Community Process(JCP)の中で Java Specification Request(JSR)が登録され、いくつかのレビュー・プロセスを通じ最終版が確定するプロセスになっている。JSR に対する貢献は、楽天のような営利企業として参加する事も可能だが、ユーザ・グループのメンバーとして参加可能だと語った。ユーザ・グループ用に用意されているプログラムとして Adopt-A-JSR プログラムという物がある。このプログラムは比較的、緩い関わりを持ちながら参加ができる内容で、仕様のパブリック・レビューや各仕様の啓蒙活動を行う事が目的になっている。JJUGでは今回 JSR 371 : MVC 1.0 への参加を表明し、Struts に置き換わる軽量な MVC として期待される、新しい仕様を評価しフィードバックを行うほか、これを日本の開発者に伝えていきたいと語った。

最後に、関西 Java エンジニアの会(関ジャバ)会長の阪田浩一氏が登壇した。関ジャバは2009年設立で年3、4回のイベントを開催しており、2014 年日本では2例目となる java.net で公式な JUG として認められたという(https://java.net/projects/kanjava)。活動は地方コミュニティのため少数で行う事が多く、約 20〜70 名程の参加者で勉強会を開催している。そして阪田氏は、来場者にむけて「是非、ローカルのJUGに参加してください」と呼びかけた。大規模なイベントの場合、中々参加者同士交流を持つ事は難しい。しかしローカルの JUG であれば発表者と参加者の双方向なコミュニケーションが容易にでき、また参加者同士も人数が少ないため交流がやりやすくなるという。さらに地域特有の情報が得られるほか、転職活動を考えた場合も様々な情報を入手しやすいといい、こうした活動はエンジニアにとって重要なポイントだと語った。一方で地方の JUG はスピーカー不足に悩まされており、毎回同じ人がスピーカーになる事が多いため、継続してコミュニティ活動を行っていくためにも、参加者自らが積極的に登壇者になって頂きたいと語った。仮に自分がお住まいの地域に JUG が無いならば自らが JUG を作りましょうと熱く語った。関ジャバの設立のきっかけも、自らがブログを書いた事がきっかけだったという。阪田氏が「関西で Java のコミュニティを作りたい」とブログで書いた所、同様の考えを持つ方が現れ、興味を持つメンバーで集まって何ができるか考えた所から始まったという。最初から大きな事は考えず、まずはやりたいという事を表明する所から始めて、地域にいる Java の開発者同士が繋がっていけば、次第に新しいユーザ・グループができるのではないだろうかと語った。関ジャバとしては、今まで内輪のお友達感覚のユーザ・グループだったが、今後正式 JUG と認定されたため、コミュニティの質を向上していきたいと語った。具体的にはコミュニティの認知度をさらに向上させたいと考えている。またJJUG と同様に1つの JUG として JCP に加入しているため、JSR を通じて、模索しながらも Java に貢献していきたいと考えている。さらにコミュニティの運営方法についても改善していきたいと語った。日本全国でJUGがたくさんできた暁には、関ジャバも一緒にイベントを行いたいと語りまとめた。こうした活動は、全て特別な事ではなく誰でもがすぐにできる事であり、ぜひ日本の Java 開発者の皆様も積極的なコミュニティ参加を呼びかけた。

最後に、伊藤 敬より参加者に Java Day Tokyo で学んだ事、感じた事をSNSやブログ等に投稿して欲しい。そして積極的なコミュニティへの参加を呼びかけ Java Day Tokyo の基調講演を終えた。

★ Java Day Tokyo 後のニュース・メディアや Twitter 、ブログのまとめ記事など。

JSF の相関項目チェック by Bean Validation


このエントリは、半分以上お遊びですのであまり詳しくは説明しません。ご興味ある方はお試しください。JSF で複数入力項目がある場合の相関チェックをする場合、通常は JSF のコンポーネントにバインドさせてバリデーション・フェーズで検証を行っていましたが(ご参照:本エントリの一番下に例を記載してますがそちらの方が楽です)、今回、Bean Validation、カスタム Bean Validation さらに CDI と PhasesListner を駆使して複数入力項目がある場合の相関チェックをしてみました。

JSF では直接 Bean Validation のクラスレベルの検証ができないので、無理矢理クラスレベルでチェクをするために、PhasesListener 内で ValidatorFactory をインジェクトして、validateメソッドに渡す事で Person クラスをValidate しています。おもしろいのが、JSF のライフサイクルで「モデル値の適用」フェーズ後は Person に代入された値が @Inject Instance<Person> でインジェクトできるようになるので、直接 Person としていじくれるようになる事です。

JSF の Facelets の内容

<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html">
    <h:head>
        <title>Facelet Title</title>
    </h:head>
    <h:body>
        <h:form prependId="false">
            <h:outputLabel id="birthDay" value="Input Birth Day"/>
            <h:inputText id="inputYear" value="#{personManaged.person.birthYear}"/>/
            <h:inputText id="inputMonth" value="#{personManaged.person.birthMonth}"/>/
            <h:inputText id="inputDay" value="#{personManaged.person.birthDay}"/><br/>
            <h:outputLabel id="age" value="Input Age"/>
            <h:inputText id="inputAge" value="#{personManaged.person.age}"/>
            <h:commandButton value="Check Multi Value" action="#{personManaged.execSubmitButton()}"/>
            <h:messages/>
        </h:form>
    </h:body>
</html>

faces-config.xml の内容

<?xml version='1.0' encoding='UTF-8'?>
<faces-config version="2.2"
              xmlns="http://xmlns.jcp.org/xml/ns/javaee"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
 <lifecycle>
        <phase-listener>jp.co.oracle.jdbcrealm.cdis.phaselisteners.ValiationPhaseListener</phase-listener>
    </lifecycle>
</faces-config>

Facelets のバッキング・ビーン

package jp.co.oracle.jdbcrealm.cdis;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import jp.co.oracle.jdbcrealm.customvalidations.Person;

@Named(value = "personManaged")
@RequestScoped
public class PersonBirthDayValidatorBackingBean {

    @Inject
    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

    public void execSubmitButton() {
        System.out.println(person.getBirthYear() + "/" + person.getBirthMonth() + "/" + person.getBirthDay() + "\t" + person.getAge());
    }
}

Person クラス

package jp.co.oracle.jdbcrealm.customvalidations;
import java.math.BigDecimal;
import javax.enterprise.context.RequestScoped;
import javax.validation.constraints.Digits;
import javax.validation.constraints.NotNull;

@RequestScoped
@PersonClassLevelValidator // <---- カスタム・バリデータ
public class Person {

    @NotNull 
    private Integer name;
    @NotNull @Digits(integer = 3,fraction = 0)
    private Integer age;
    @NotNull @Digits(integer = 4,fraction = 0)
    private Integer birthYear;
    @NotNull @Digits(integer = 2,fraction = 0)
    private Integer birthMonth;
    @NotNull @Digits(integer = 2,fraction = 0)
    private Integer birthDay;

    /**
     * @return the name
     */
    public Integer getName() {
        return name;
    }

    /**
     * @param name the name to set
     */
    public void setName(Integer name) {
        this.name = name;
    }

    /**
     * @return the age
     */
    public Integer getAge() {
        return age;
    }

    /**
     * @param age the age to set
     */
    public void setAge(Integer age) {
        this.age = age;
    }

    /**
     * @return the birthYear
     */
    public Integer getBirthYear() {
        return birthYear;
    }

    /**
     * @param birthYear the birthYear to set
     */
    public void setBirthYear(Integer birthYear) {
        this.birthYear = birthYear;
    }

    /**
     * @return the birthMonth
     */
    public Integer getBirthMonth() {
        return birthMonth;
    }

    /**
     * @param birthMonth the birthMonth to set
     */
    public void setBirthMonth(Integer birthMonth) {
        this.birthMonth = birthMonth;
    }

    /**
     * @return the birthDay
     */
    public Integer getBirthDay() {
        return birthDay;
    }

    /**
     * @param birthDay the birthDay to set
     */
    public void setBirthDay(Integer birthDay) {
        this.birthDay = birthDay;
    }
}

Person クラスのバリデータ(相関チェックの実装)

package jp.co.oracle.jdbcrealm.customvalidations;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.time.DateTimeException;
import java.time.LocalDate;
import java.time.Period;
import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import javax.validation.Payload;

@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.PARAMETER})
@Retention(RUNTIME)
@Constraint(validatedBy = PersonClassLevelValidator.PersonClassValidtor.class)
@Documented
public @interface PersonClassLevelValidator {

    String message() default " Invalid input of the Birthday or Age";

    Class<?>[] groups() default {};

    Class<? extends Payload>[] payload() default {};

    class PersonClassValidtor implements ConstraintValidator<PersonClassLevelValidator, Person> {
        PersonClassLevelValidator constraintAnnotation;
        @Override
        public void initialize(PersonClassLevelValidator constraintAnnotation) {
            this.constraintAnnotation = constraintAnnotation;
        }

        @Override
        public boolean isValid(Person person, ConstraintValidatorContext context) {
            if ( person == null) return true;

            // Person として直接扱えるので色々楽
            int age = person.getAge();
            int birthYear = person.getBirthYear();
            int birthMonth = person.getBirthMonth();
            int birthDay = person.getBirthDay();

            LocalDate birthDate;
            try {
                birthDate = LocalDate.of(birthYear, birthMonth, birthDay);
            } catch (DateTimeException de) {
                return false;
            }
            LocalDate today = LocalDate.now();
            Period period = Period.between(birthDate, today);
            return age == period.getYears();
        }
    }
}

JSF の PhasesListener でモデル値適用後に Person をバリデート

package jp.co.oracle.jdbcrealm.cdis.phaselisteners;
import java.util.Set;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.inject.Inject;
import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ValidatorFactory;
import javax.validation.groups.Default;
import jp.co.oracle.jdbcrealm.customvalidations.Person;
import jp.co.oracle.jdbcrealm.customvalidations.PersonClassLevelValidator;

public class ValiationPhaseListener implements PhaseListener {

    @Override
    public PhaseId getPhaseId() {
        return PhaseId.UPDATE_MODEL_VALUES;
    }

    @Inject
    ValidatorFactory validFactory;

    @Inject
    javax.enterprise.inject.Instance<Person> instanceOfPerson;

    @Override
    public void afterPhase(PhaseEvent event) {
        //どこからリクエストが来たかを検証 // ここの実装を綺麗にしたかったが難しかった。
        FacesContext fContext = event.getFacesContext();
        ExternalContext extContext = fContext.getExternalContext();
        String url = ((HttpServletRequest) extContext.getRequest()).getRequestURL().toString();
        if (!url.contains("PersonBirthDayValidate.xhtml")) {
            return;
        }

        //モデルに値が適用された後(PhaseId.UPDATE_MODEL_VALUES)は、Person に値が代入されているためインジェクト可能
        Person person = instanceOfPerson.get();
        // Execute only PersonClassLevelValidator(Class-Constraint) Validation
        Set<ConstraintViolation<Person>> violations = validFactory.getValidator().validate(person, Default.class);
        //Bean Valiadtion の検証結果
        violations.stream()
                .filter(consts -> consts.getConstraintDescriptor().getAnnotation() instanceof PersonClassLevelValidator)
                .map(violation -> violation.getMessage())
                .findFirst()
                .ifPresent((String errMsg) -> {
                    FacesMessage facesMessage = new FacesMessage(FacesMessage.SEVERITY_ERROR, errMsg, null);
                    fContext.addMessage("ERROR", facesMessage);
                    fContext.validationFailed();
                    fContext.renderResponse(); //SKIP lifecycle
                });
    }

    @Override
    public void beforePhase(PhaseEvent event) {

    }

}

ちなみに、従来の JSF コンポーネントバインドを使った相関チェックのやり方はこんなかんじ

    <f:view>
        <f:metadata>
            <f:viewAction action="#{indexManaged.checkArgument()}" onPostback="true" phase="PROCESS_VALIDATIONS" />
        </f:metadata>
        <h:head>
            <title>Facelet Title</title>
        </h:head>
        <h:body>
            <h:form>
                <h:inputText id="text1" value="#{indexManaged.text1}" binding="#{indexManaged.bindComp1}"/>
                <h:inputText id="text2" value="#{indexManaged.text2}" binding="#{indexManaged.bindComp2}"/>
                <h:messages id="error_message" style="color:red;margin:8px;"/>
                <h:commandButton value="OK" action="#{indexManaged.pushButton()}"/>
            </h:form>
        </h:body>
    </f:view>
package jp.co.oracle.jsf22.multivalidate;

import javax.inject.Named;
import javax.enterprise.context.RequestScoped;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.component.html.HtmlInputText;

@Named(value = "indexManaged")
@RequestScoped
public class IndexManaged {

    private String text1;
    private String text2;
    private HtmlInputText bindComp1;
    private HtmlInputText bindComp2;    

    /**
     * Creates a new instance of IndexManaged
     */
    public IndexManaged() {
    }

    /**
     * @return the text1
     */
    public String getText1() {
        return text1;
    }

    /**
     * @param text1 the text1 to set
     */
    public void setText1(String text1) {
        this.text1 = text1;
    }

    /**
     * @return the text2
     */
    public String getText2() {
        return text2;
    }

    /**
     * @param text2 the text2 to set
     */
    public void setText2(String text2) {
        this.text2 = text2;
    }

    public String pushButton() {
        return "";
    }

    /**
     * @return the bindComp1
     */
    public HtmlInputText getBindComp1() {
        return bindComp1;
    }

    /**
     * @param bindComp1 the bindComp1 to set
     */
    public void setBindComp1(HtmlInputText bindComp1) {
        this.bindComp1 = bindComp1;
    }

    /**
     * @return the bindComp2
     */
    public HtmlInputText getBindComp2() {
        return bindComp2;
    }

    /**
     * @param bindComp2 the bindComp2 to set
     */
    public void setBindComp2(HtmlInputText bindComp2) {
        this.bindComp2 = bindComp2;
    }
    public void checkArgument() {
        String val1 = bindComp1.getValue() ;
        String val2 = bindComp2.getValue() ;

        if (!val1.equals(val2)){
            FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_ERROR, "入力内容が不正です。", "テキスト・フィールドに正しい値が入力されていません。");
            FacesContext.getCurrentInstance().addMessage(null, msg);
        }
    }
}

2015年3月26日 at 1:58 AM コメントをどうぞ

Java Day Tokyo 2015 まであと2週間



(2015年 3月24日時点の状況)

皆様、Java Day Tokyo 2015 まで、あと丁度2週間となりました。満席セッションもかなり多くなってきましたが、今年は会場が広いのでまだまだ魅力的なコンテンツをご選択・ご覧頂く事ができます。今からでもまだお申し込み可能なセッションを下記にご紹介します。(中には残りわずかなセッションも含まれますので)

● Java SE 系の情報を取得されたい方
【1-1】Lambdas and Streams: Taking the Hard Work Out of Bulk Operations in Java SE 8
【1-2】Date & Time API and other technologies of Java SE 8
【3-1】Javaの関数型言語への挑戦/ベターオブジェクト指向言語からの脱皮
【3-2】Java EEアプリケーションサーバの開発現場で見たJava SEの実際
【4-5】Java Flight Recorder のご紹介 (残りわずか)
【5-2】NetBeans IDE最新情報 (残りわずか)

● JavaFX 系の情報を取得されたい方
【6-1】FXML for Structure, CSS for Styling, and JavaFX as Standard GUI Library (残りわずか)

● Java EE 系の情報を取得されたい方
【2-1】Java EE 8 – directions and new features
【2-3】Applied Domain-Driven Design Blue Prints for Java EE 7
【2-4】CDI and EJB – Java EE alignment and strategy
【2-5】Reactive Java EE 7 – Let Me Count the Ways !
【4-1】Javaクラウド・サービスが実現する新しいエンタープライズJava (残りわずか)
【4-2】Oracle Developer Cloud Service, what can you do?

● Java ME/SE Embedded 系の情報を取得されたい方
【1-3】Java SE Embedded 8 / Java ME Embedded 8 Overview
【1-4】Programming the Real World
【1-5】Java and The Internet of Things For Automotive Applications
【7-1】IoT時代のエッジデバイス向け無線モジュールとJavaMEの取り組み
【7-3】Java Embedded で始める IoT

その他
● SDN(Software Defined Networking)
【7-2】OpenDaylightがやってきた!

●初心者向け
【9-1】Say Hello to Java

●Java 認定資格試験受講者向け
【9-5】最新 Java 認定資格ガイド

Java SE 8 や JavaFX、Java EE 7&8 、Embedded などの重要な情報を入手する事が今からでも間に合います。是非、皆様の周りの同僚やお友達、後輩にお声掛け頂けないでしょうか。現在「Java 20周年 盛り上げ大作戦!」を行っています。より多くの方へお誘い頂いた方にはここでしか入手できないレア・グッズをプレゼント予定でございます。

● Java 20周年 盛り上げ大作戦!の詳細はコチラ
◎ https://www.facebook.com/JavaDayTokyo/posts/674620795996755
◎ https://www.facebook.com/JavaDayTokyo/posts/687490008043167

最後に
先日もご案内さし上げましたが、Java Day Tokyo 終了後、東京国際フォーラムの近くで懇親会も実施します。こちらは、Java Day Tokyo に参加されていない方でも、今まで Java に携わられてこられた方や、Java の 20周年を一緒にお祝いしていただける方、どなたでもご参加頂ければたいへん嬉しく思います。

4/8(水) : 20th Anniversary Java コミュニティ・パーティの詳細

あと2週間でございますが、皆様のご参加を心よりお待ち申し上げます。

2015年3月25日 at 11:40 AM コメントをどうぞ

4/8(水) : 20th Anniversary Java コミュニティ・パーティ



既に、JJUG コミュニティのメーリング・リスト等ではご案内を差し上げておりますが、Java Day Tokyo の終了後、東京国際フォーラムの近くで、関係者(外人スピーカー、日本人スピーカーなど)を交えた懇親会を開きたいと思います。すでに、基調講演に登壇頂く Java SE の開発部門の責任者である George Saab さんや Cameron Purdy さん、Stephan Chin さんがくる事が決まっている他、Simon Ritter さん, Sharat Chandar さん Caicedo Angela なども参加すると言って頂いています。もちろん、日本人のご登壇者の皆様も多く参加していただきます。
このように直接、Java 業界で著名な方々と一同を介して交流を持てる機会は多くなく、基調な場になるかと思いますので是非多くの皆様にご参加いただけないでしょうか。

************************************************************************************
日付:2015/4/8
時間:PM 8:30 – 10:30
場所:Alice aqua garden
http://r.gnavi.co.jp/g105302/
参加費: 6,000 円
登録サイト URL:http://javadaytokyonightparty.peatix.com/
************************************************************************************

Java Day Tokyo の余韻もさめぬまま、4/8 (水) はJava 20 周年を祝う日として最後の最後まで盛り上がりませんか?お祝いという事でちょっとした催しも考えています。参加者数に限りがあるため、大変恐れ入りますが参加ご希望の方はどうぞお早めにご登録頂けますよう宜しくお願いします。

あと1ヶ月を切りましたが、皆様と当日お会いできる事を心より楽しみに致しております。
以上、今後ともどうぞ宜しくお願いします。
寺田

2015年3月24日 at 10:57 AM 1件のコメント

日本語 Java SE 8 API ドキュメント URL 変更につきまして


皆様
いつも大変お世話になっております。

現在、Java SE 8 に関連したドキュメントを大幅に更新を掛けております。
http://docs.oracle.com/javase/jp/8/

その過程で、Java SE 8 API ドキュメントへのリンクが下記に変更されました。

旧:http://docs.oracle.com/javase/jp/8/api/
新:http://docs.oracle.com/javase/jp/8/docs/api/

これは、USのオリジナルのドキュメントがディレクトリ構成を変更したためで、USに併せて日本でも今後、上記のURLが正しいURLとなります。つきましては、大変恐れ入りますが、上記に対して現在ブックマークされている場合は改めて御変更いただけませんでしょうか。

また、現在トップページにおいてもいくつかの不具合も確認しております。
http://docs.oracle.com/javase/jp/8/

●リンク切れ
Java チュートリアル・ラーニング・パス
Java言 語および仮想マシン仕様

●リンク間違い(英語サイトへ遷移)
Java SE 8について
新機能(機能および拡張機能)
商用機能アイコン: リンクは新しいウィンドウで開きます
互換性ガイド
既知の問題

●ページ内の画像リンク間違い
Java Platform, Standard Edition HotSpot Virtual Machineガベージ・コレクション・チューニング・ガイド
Java Platform, Standard Editionトラブルシューティング・ガイド
ダウンロー ドとインストールの方法
Java SEツール・リファレンス(UNIX)
Java SEツール・リファレンス(Windows)

上記は、Firefox で見た場合、画像が読み込めないためページの読み込みに非常に時間が掛かります。Chrome ならば、画像リンク切れを無視し表示できます。
上記の3点の不具合は既に認識しており修正中でございますので何れ正しく表示されます。

一方で、繰り返しますが、API ドキュメントに対するディレクトリ構成の変更は US 側で実施されている物であるため、新しいURLで再度ブックマーク等をして頂ければ誠に幸いです。

新しい Java SE 8 日本語 API Doc の URL
http://docs.oracle.com/javase/jp/8/docs/api/

以上、どうぞ宜しくお願いします。
寺田

2015年3月10日 at 5:10 PM コメントをどうぞ

Java Day Tokyo 2015 追加情報


Java Day Tokyo 2015

先日、ご案内させて頂きましたように、4/8(水)に Java Day Tokyo 2015 を東京国際フォーラムで開催致します。

Java Day Tokyo 2015 Offcial Site :
http://www.oracle.co.jp/jdt2015/

既にご登録頂きました皆様におかれましては、ご登録頂きまして誠にありがとうございます。

登録サイトオープン後にセッションが追加されておりますので下記にご案内差し上げます。また今後も追加予定がございますので、セッション情報につきましては定期的にご確認頂ければ誠に幸いです。

※セッションは登録後も変更可能でございますので、必要に応じて登録ページよりセッションをご変更ください。

●15:10-16:00 実践的なJavaアプリケーションサーバの構築・運用~転ばぬ先の杖
山田 貴裕氏 伊藤忠テクノソリューションズ株式会社

●16:15-17:05 アジャイル時代のモデリング
平鍋 健児氏 株式会社チェンジビジョン

最後に
改めまして皆様にお願いがございます。

ご登録者数の状況は昨年、一昨年よりも良好ですが、まだまだより多くの開発者の皆様にご登録頂く事ができます。今年の Java Day Tokyo は、Java の生誕 20 周年を記念して、昨年、一昨年に比べ、規模を大幅に拡大して実施します。そして、このように規模を拡大してイベントを実施できたのも、過去の Java イベントにご参加頂いた皆様のおかげです。

今、ご登録頂いている皆様におかれましては、大変恐れ入りますが是非周りのご友人や後輩にもお声掛け頂き、より多くの Java 開発者の皆様にご参加いただけるように、ご協力頂けませんでしょうか。Java Day Tokyo のオフィシャル・アカウントからも告知がございましたが、より多くの方をご招待頂いた方には、何か良い事があるとの事です。是非、まわりの Java 開発者の皆様にお声掛け頂けませんでしょうか。

オラクルユニバーシティが提供する、Java 初心者用のセッションにもまだ余裕がございますので Java 初心者の方にもどうぞお声掛け頂ければ幸いです。

皆様、お一人お一人のお力をどうぞお貸し頂けないでしょうか。
以上、どうぞ宜しくお願いします。
寺田

2015年3月9日 at 6:47 PM コメントをどうぞ

過去の投稿


ご注意

このエントリは個人の見解であり、所属する会社の公式見解ではありません

JavaOne

カレンダー

2015年4月
« 3月    
 12345
6789101112
13141516171819
20212223242526
27282930  

カテゴリー

Twitter

clustermap

ブログ統計情報

  • 632,760 hits

Feeds


フォロー

新しい投稿をメールで受信しましょう。

現在4,349人フォロワーがいます。