JJUG CCC 2014 Springに参加してきました

本日、日本Javaユーザーグループ(JJUG)主催のCCC 2014 SpringというJavaの勉強会に行ってきました。会場は、ベルサール西新宿で、都営大江戸線都庁前のA5出口を出て、新宿中央公園の5分くらい歩いたところにありました。今はスマートフォンで地図を確認しながら行けるので、初めての場所でも方向音痴の私でも電車の駅さえ間違わなければ大丈夫ですね。

CCCというのはCross Community Conferenceの略で、さまざまなコミュニティーの交流の場となる会議という趣旨でしょうか?このCCCというイベントは2012から開催されているようなのですが(CCC | 日本Javaユーザーグループ)、今回初めて参加させていただきました。残念ながら個人的な都合から、基調講演と午後の前半のセッションのみで後半と懇親会には参加できませんでしたが、参加したセッションについてまとめます。その他のセッションについては、以下に情報があります。

K-1 詳説 Java SE 8 – CCC Edition(櫻庭 祐一氏)

最初のセッションは、最先端のJava技術を研究し、最近Java8紹介記事も多く執筆されている櫻庭さん(@skrb)より、Java SE8の新機能のポイントについて紹介していただきました。Java SE8というと、まず、Lambdaプロジェクトの成果であるラムダ式やストリームAPIを使った新しい関数型のJavaプログラミングが注目されますが、それ以外にも、

など、その他の新機能についても解説されました。途中、

「for文やforEachを使ったら負け。ラムダ式禁止と戦おう」

というコメントが印象的でした。現状は後の岩崎氏の講演で説明があったように、アプリケーションサーバーなどの対応が進んでいないという制約から、Java8が実際の案件で普及するまでにはにはもうしばらく時間がかかるだろうとは思いますが、今のうちに新しい機能について先行して学習しておき、実際使えるチャンスがあったら、便利な新機能を積極的に導入できるよう準備しておきたいですね。

なお、この基調講演の元ネタは、「現在、ITpro において連載している詳説 Java SE 8 を CCC で再現します。」とのことですので、
詳解 Java SE 8 第1回 Java SE 8概説
からはじまる、素晴らしい詳細な連載記事も是非ご覧ください。

K-2 Java 8 ラムダ式と Stream の概要について(Stuart Marks氏)

基調講演の2番目は、オラクルのStuart Marks氏より、ラムダ式、ストリームAPIについて、基本的なところから解説していただきました。いきなり、新しい関数型の記述方法で説明されると、慣れていない場合混乱する場合もあると思いますが、以前の書き方と対応させながら丁寧に解説していただき、理解しやすかったです。
今回の講義で特に印象的だったのは、関数型や不変性という話を前提にせず、あくまでも従来からある無名内部クラスの代替として型安全にコードブロックを渡すための便利な記法、内部イテレーターの記述手段としてラムダ式を説明していたことです。例として

List<Person> list = ... ;

// Java7 
for (Iterator<Person> iter = list.iterator(); iter.hasNext();) {
    Person p = iter.next();
    if("Jones".equals(p.getName())) {
        iter.remove();
    }
}

// Java8
list.removeIf(p -> "Jones".equals(p.getName()));

のように、Collectionインターフェースに追加されている、removeIfを使って、従来のイテレーターの処理を置き換えるコードが出てきました。さらに、従来の外部イテレータとfor文を使って処理した場合と比較して、同期化が必要なコレクションの場合に、きちんと同期化をしてくれるというようなところも便利ですね。*2

先の櫻庭さんの発言にもありますし、今まで私自身ラムダ式を使う以上、なるべく関数型の発想で考えるべきであり、可変な(mutable)な操作は避けるべきと考えていました。しかしながら、もともと、Javaは可変な変数を当たり前に使う手続き型(imperative)なコードを前提としており、不変性などは後から追加されたというところがありますし、このようにラムダ式は可変な操作にも使えるのだというのはかえって新鮮な発見でした。特に、古いコードをラムダ式を使って簡潔にリファクタリングするという場合などには、あえて不変性にこだわらないというのも一つの考え方かもしれません。

Stuart氏の話で、もう一つ印象的だったのは大量の基本型の数値を使った計算に、ストリームAPIを適用するという以下の例*3です。

System.out.println(
    LongStream.range(0, 1_000_000L)
        .parallel()
        .map(i -> ((i & 1) == 0 ? 1 : -1 * (2 * i + 1))
        .mapToDouble(i -> 4.0 / i)
        .sum());

従来の常識としては、大量の数値をListなどのコレクションを使って計算すると、基本型からオブジェクへの変換(boxing)が行われて性能で問題が出るので、代わりにlong[]のように基本型の配列を使わなくてはならないということがありました。しかし、これはコレクションなど便利なAPIが使えずC言語のようなコードを書かないといけないということを意味し、パラレル化などの最適化には相当の努力が必要でした。ストリームAPIでは、LongStreamやmapToDoubleといった基本型専用のAPIをきちんと使いさえすれば、遅延評価がきちんと行われ、実際に大量の値のboxingが発生せず、オーバーヘッドを最小限に抑えることが可能なようです。確かに、Javaでは基本型の扱いはユーザーにとって完全に透過というわけにはいかず注意が必要なのですが、こうした数値計算にも関数型を活用できるというのは面白いですね。

R1-1 Java 8 for Java EE 7/6(岩崎 浩文氏)

金融、製造、公共など様々なドメインJavaEEを使った多くのシステム開発を担当してこられ、雑誌等への執筆もされている楽天の岩崎氏(@HirofumiIwasaki)より、アプリケーションサーバーのJava8対応の状況についてお話いただきました。
JavaSE 8が正式にリリースされたということで、早速現在のプロジェクトで活用しようという気になってしまいますが、実際のところは、JavaEE 7ではJavaSE 8はサポート対象外であり、さらに、そもそもJavaEE 7に対応したアプリケーションサーバーがGlassfishWildFlyといったオープンソースのサーバーに限られ、その他の商用のサーバーではいまだにJavaEE6しかサポートされていないという事実があります。ただし、講義中で紹介されていたようにGlassfishのdaily build版ではJava8が使えるということですし、WildFlyなど他のサーバーについても比較的早く対応されるのではないかという期待がありますね。

また、パラレルコレクションなどは通常のEJBのようなオンライントランザクション系のシステムとは相性が悪いと思います。しかし、EJBJavaEEのすべてではないですし、JavaSE 8が利用できるようになれば、日付APIやラムダを使ったロジックの簡潔化など、いろいろなメリットがあるものと期待されます。

なお、日本語の情報が少ないという問題はありますが、JavaEEについては以下のNetBeansチュートリアルにあるサンプルに取り組むのがよいとのことです。
https://netbeans.org/kb/trails/java-ee.html

H-2 Javaトラブルに備えよう(上妻 宜人氏)

上妻氏は見習いプログラミング日記Java EEを中心とした情報の発信をされていますが、単にプログラミングを中心とした開発手法のみならず、運用時に必要なモニタリングツールの知識など有用な情報を書かれています。どうしても、新しいAPIや言語の機能、開発ツールなどに興味がいきがちですが、実際には運用時のトラブルシューティングをするためのログ解析手法などは非常に大切です。また、必要なツールを正しく使いこなせば、トラブルシューティングが容易であるというのもJavaの重要な特徴の一つなのではないかと思います。つまり、Javaは単にプログラミング言語というだけではく、デプロイメント・運用時の環境まで含めたプラットフォームなのであるということですね。

講義の中では、トラブルシューティングのために適切な情報の取得が大切であるとして、まず、以下の情報出力の方法について説明されました。

  • GCログの出力設定
  • クラスヒストグラムの出力
  • ヒープダンプの出力と解析
  • スレッドダンプの出力

さらに、OutOfMemoryErrorが発生するさまざまなケースを突出型、じわじわ型などパターンごとに解析する手法について解説されました。基本的な手法は昔から大きく変わっていないとはいえ、具体的なコマンドの使い方はバージョンによって異なっているため、上妻氏の最近の経験に基づいた情報は非常に有用なものであると思います。いざ、トラブルが発生すると焦ってしまい、冷静な判断ができないということもあると思いますので、Javaのエンジニアとしては日頃からこうした解析の手法に慣れておくことは大切だと思いました。*4

H-3 初めての Java EE 開発から学んだこと(菊田 洋一氏)

株式会社 構造計画研究所の菊田氏(@kikutaro_)より、ご自身が初めてJava EEの開発に取り組まれたプロジェクトの経験をもとにお話されました。菊田氏は以下のブログでもJava EEの情報を発信しておられます。Challenge Java EE !

恥ずかしながら、講演の中で私のブログもちょっと紹介していただいたのですが、3年近く前(もうそんなに経つんですね)にちょっとJavaEE 6について調べてこのブログでも紹介したことがあった(Java EE6標準の範囲でフルスタックのWebアプリケーションが簡単に作成できることを確かめてみました。 - 達人プログラマーを目指して)ので、昔のことを思い出してちょっと懐かしくなりました。

残念ながら、私自身はその後JavaEEから離れてしまい、新しいEEのフレームワークを実際の案件で使うことはできなかったのですが、菊田氏の発表はJavaEEを実際に適用した成果に基づくものとして、大変興味深く聴かせていただきました。
発表にもあるように、もともと.NET系の開発からJavaEEに移行されて、まだほんの一年半という短い期間にも関わらず、データ層からプレゼン層まで「フルスタック」のアーキテクチャを構築されたということは大変感銘を受けました。これはもちろん菊田氏の努力の賜物だと思いますが、JavaEEが標準のフレームワークを組み合わせるだけで実用的に使える、.NET並みに簡単に使えるようになったということの証明となる事例なのではないかと思います。

  • 標準以外のフレームワークやツールがたくさんあって選択にまようけど、いろいろ悩むのは楽しい
  • 日本語の書籍が少ない
  • Javaはコミュニティーが盛んで初心者にも間口が広い

といったことは、私も以前から感じていたことで、多くの点で大変共感しました。菊田さんご本人の以下のエントリーもどうぞ
#JJUG_CCC Spring 2014で「初めての Java EE 開発から学んだこと」というタイトルで発表させて頂きました! - Challenge Java EE !

*1:時間の関係で残念ながらほとんどスキップされましたが、櫻庭さんはJavaFXを推進されており、日頃プレゼン資料自体もJavaFXで作成しているとのことです。http://www.slideshare.net/skrb/20140321-javafx8も参考になります。

*2:Coolectionsのようなユーティリティクラスと違い、インターフェースに定義されたデフォルトメソッドはオーバーライド可能なので、サブクラスごとに独自の実装が持てる。

*3:円周率を計算するテイラー級数の計算

*4:DevOpsという考え方があるように、最近はプログラマーも開発だけでなく、サーバーの運用やトラブルシュートをすることが多いと思われます。