Furyu

[フリュー公式] Tech Blog

フリュー株式会社の技術ブログです

2017年03月17日

araki

DroidKaigi 2017 に参加しました。会場の様子をレポートします!

コンテンツ・メディア第1事業部の荒木です。ピクトリンクというプリントシール画像を使ったアプリの Android 版を開発しています。

前回の記事では、DroidKaigi 2017 の参加前レポートを書きました。今回は、DroidKaigi 2017 の参加後レポートとなります。ほとんどのセッションはスライドと動画が公開されるようなので、この記事では DroidKaigi に参加できなかった方に向けて、会場の様子をお伝えします!

DroidKaigi とは?

※ 前回の記事と同じ内容を、再掲いたします。

公式サイト より引用:

DroidKaigiはエンジニアが主役のAndroidカンファレンスです。
Android技術情報の共有とコミュニケーションを目的に、2017/3/9(木)、3/10(金)の2日間開催します。

DroidKaigi とは、Android エンジニアのカンファレンスです。参加者は500人を超え、日本国内の Android カンファレンスとしては最大級の規模を誇ります。2015 年から開催されており、今回の DroidKaigi 2017 で3回目の開催となります。私は今回が初めての参加となります。

会場の様子

会場の様子をレポートいたします。今回の会場は、ベルサール新宿グランド コンファレンスセンターでした。

セッション

セッションルームは全部で6つありました。どのセッションも多くのエンジニアが発表を聞きに来ており、人気のセッションでは立ち見の人が出るほどでした。写真は Room3 の真ん中くらいから撮影したもので、私の後ろにもたくさんの聴講者がいました。

Session Room3

Session Room3 の様子

ランチ、おやつ

会場には、お菓子部屋がありました。各社のロゴの入ったお菓子や、マフィンなどがおいてあります。運営の方曰く、無限に湧いてくるとのことでした。

IMG_20170310_095808

 

他にも記念撮影スポットがあったり、

IMG_20170309_184112

 

バリスタの方がコーヒーを淹れてくれるというサービスもありました。常に長蛇の列ができていて、私は飲みそびれてしまいました。。

オフィスアワー

各セッションの後には、オフィスアワーが設けられました。オフィスアワーでは、発表者の方が質問やフィードバックを受けるために、お菓子部屋にしばらく滞在していました。発表者の周りには多くのエンジニアが集まり、発表内容について熱い議論を交わしていました。私もオフィスアワーで議論に参加したり、発表内容に関する疑問をぶつけてみたりしました。こうした貴重な経験は、カンファレンスに参加したからこそ得られるものだと感じました。

 

こちらのセッションのオフィスアワーで、MVVM について発表者の方と議論を交わしていました。とても楽しかったです!

アフターパーティー

全てのセッションが終わった後のアフターパーティーの様子です。ここでも、たくさんのエンジニアの方たちと交流することができました。

IMG_20170310_183106

 

寿司職人が握るお寿司。去年もあったそうです。大人気で、すぐに売り切れてしまいました。

IMG_20170310_191355

 

遠いですが、運営責任者の mhidaka さんが壇上にいらっしゃいます。この後、運営スタッフの方々に会場全体から感謝の拍手がありました。スタッフの方々のおかげでカンファレンス中、気持ちよく過ごすことができました。ありがとうございました!

IMG_20170310_202008

さいごに

今回は、DroidKaigi に参加できなかった方に向けて会場の様子をお伝えしました。楽しそうな雰囲気が伝わって「来年は DroidKaigi に参加するぞ!」と思っていただければ幸いです。私は来年も参加する予定ですので、ぜひみなさんも参加しましょう!


2016年10月13日

sakata

JavaOne 2016 サンフランシスコに参加しました!(その4) #javaone #j1jp

Hello world! コンテンツ・メディア第1事業部のjyukutyoこと阪田です。

前回はコレクションのセッションについてのレポートでした。今回はクラスローダーのセッションについてレポートします。

Join the War on ClassLoader Leaks

スライドはこちらにあります。

https://static.rainfocus.com/oracle/oow16/sess/1461358415846001E0TZ/ppt/Classloader%20leaks%20public.pptx

内容

java.lang.OutOfMemoryError(OOME)はみな出会ったことがあるだろう。Java 8になってPermGen spaceとは出なくなったが、代わりにMetaspaceが出るようになった。ローカルでの開発時にも、継続的デプロイでもOOMEは出る。このセッションのアジェンダは次のようなものだ。

  • OOMEは何を意味するのか?
  • OOMEはなぜ起こるのか?
  • どこでリークするのか?
  • どのように避けるのか?
  • OSSの例
  • トレーニング

OOMEは何を意味するのか?

JVMのメモリはヒープとPermGen/Metaspaceとスタックである。スタックはスレッドごと、ローカル変数やメソッドのパラメータを持つ。ヒープはオブジェクトのインスタンスを持つ。PermGen/Metaspaceはjava.lang.Classインスタンスなどを持つ。PermGenという名前はJava EEとクラスのアンロードができる前に名付けられた。Java 8でMetaspaceへ置き換えられた。OOME PermGen space/Metaspaceは、あまりに多くのクラスをロードしたときに起こる。

OOMEはなぜ起こるのか?

OOME PermGen space/Metaspaceが起こる原因は次の2つが考えられる。

  1. アプリケーションが大きすぎる。Java 7までは-XX:MaxPermSize=256Mなどと指定すればよい。Java 8ではMetaspaceは自動的に増えていく。
  2. java.lang.Classインスタンスが再デプロイ後にガベージコレクトされない

参照の型は次の4つがある。

  • 強い参照:到達可能なときは決してGCされない
  • ソフト参照:OOMEになる前にGCされる
  • 弱い参照(WeakHashMap):強い参照とソフト参照がないときにGCされる
  • ファントム参照:GCは妨げない

GCの到達可能性は以下の図のようなことである。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-05-17-40-30

再デプロイでは、新しいWARファイルをデプロイすれば前のクラスローダはGCされる。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-05-17-43-30

クラスローダーの参照は次の図のようになる。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-05-17-44-55

どのようにリークが起きるのか。GCルートからクラスローダへ到達可能だと、クラスローダをGCすることができない。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-05-17-45-38

どこでリークするのか?

Tomcatなどアプリケーションサーバのバグだ。他にCommons LoggingやLog4Jなどロギングフレームワークのバグ、Bean Validation APIやUnified Expression Languageのバグといったこともある。

GCルートでも起こる。まず、システムクラスローダによってロードされるクラス。JDKのクラスにおけるstaticフィールドで起こる。ライブスレッドではローカル変数、メソッドのパラメータのスタック、java.lang.Threadインスタンスで起こる。

システムクラスでは、java.sql.DriverManagerやBean introspectionのキャッシュ、シャットダウンフック、カスタムでデフォルトにしたAuthenticator、カスタムのセキュリティでのProvider、カスタムMBean、カスタムのThreadGroup、カスタムのプロパティエディタ…最初の呼び出し元でのcontextClassLoaderへの参照などで起こる。

DriverManagerをもう少し詳しく見てみよう。たとえばMySQLのJDBCドライバを使うときはこうするだろう。

com.mysql.jdbc.Driverクラスにはstaticイニシャライザがある。

registerDriver()メソッドは以下のようになっている。

このregisterDriversという変数は、以下のものだ。

図で表すと以下のようになる。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-06-16-55-03

そのため、コンテキストのシャットダウンで以下のように書かなければ、リークしてしまう。

スレッドもここで止めておかなければならない。次のようにスレッドを実装するのは悪いアイデアだ。

止められるようには以下のようにする。

このことは、次の記事に紹介されている。

Heinz Kabutz / Java Specialists’ – The Law of the Blind Spot

次にThreadLocalについて考えてみよう。次のように実装してはならない。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-06-17-09-13

ThreadLocalのJavaDocには以下のようにある。

Each thread holds an implicit reference to its copy of a thread-local variable as long as the thread is alive and the ThreadLocal instance is accessible; …

各スレッドは、スレッドが生存していてThreadLocalインスタンスがアクセス可能である間は、スレッド・ローカル変数のコピーへの暗黙的な参照を保持します。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-06-17-13-40

プールされたスレッドではスレッドはクラスローダより長生きする。ThreadLocalはThreadGlobalになる!

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-06-17-17-35

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-06-17-18-20

ThreadLocalMapのJavaDocには以下のようにある。

However, since reference queues are not used, stale entries are guaranteed to be removed only when the table starts running out of space

(私訳)しかしながらリファレンスキューが使われないので、テーブルが容量不足になり始めたときだけ失効したエントリが削除されることが保証されます。

参照を含んだカスタムの値は、staticなThreadLocalであればリークし、そうでなければ予測されていないGCとなる。カスタムのThreadLocalであればリークしない。

ThreadLocalはクリアするようにしよう。

実際には、多くのOSSライブラリが違反している。

どのように避けるのか?

リーク防止のライブラリがある。アプリケーションサーバ非依存、Tomcatよりも多くをカバーしており、ログで警告を出力、ライセンスはApache 2ライセンスだ。実行時の依存は0で、設定は必要ない。Mavenであれば以下のように依存ライブラリを追加する。

これはServlet 3.0以降用だが、2系のものもある。

OSSの例

Bean Validationの1.0.0.GAでは以下のようになっていた。

(私訳)List<ValidationProvider>はキーであるクラスローダに強い参照を持っている。JPAのCachingPersistenceProviderResolverと同じモデルを使うようにして。

jyukutyo調査

Bean Validationの1.1.0.GAではこのクラスは次のようになっています。

providersPerClassloader.put( classLoader, new SoftReference<List<ValidationProvider<?>>>( providers ) );とあるので、ソフト参照を使うようになったようです。

JPAのCachingPersistenceProviderResolverクラスも調べてみました。

その他のOSS

javax.el.BeanELResolverやorg.apache.cxf.transport.http.CXFAuthenticator、com.sun.star.lib.util.AsynchronousFinalizerも該当する。

トレーニング

Eclipse Memory Analyzer(MAT)を使おう。

http://www.eclipse.org/mat/

次のオプションをつけてアプリケーションを実行しよう。

感想

最後に出てきた、MATについてはこのブログで私が記事を書いています。

ヒープダンプをEclipse Memory Analyzerで解析しよう!

セッションとしては非常におもしろかったです。とくにOSSの実例を挙げながらリークの原因を解説する箇所ではとても興奮しました。こういう内容のセッションはJavaOneだと他にもいろいろとあります。なかなか普段の勉強会でこの分野を扱っていることは少ないと思いますので、興味がある人にはJavaOneはとても楽しめるカンファレンスです!


2016年10月12日

sakata

JavaOne 2016 サンフランシスコに参加しました!(その3) #javaone #j1jp

Hello world! コンテンツ・メディア第1事業部のjyukutyoこと阪田です。

前回はAngular 2とGWTのチュートリアルセッションをレポートしました。今日はJDKの開発者であるStuart Marksさんのセッション”Collections Refueled”をレポートします。

Collections Refueled

スライドはこちらにあります。
https://stuartmarks.files.wordpress.com/2016/09/collectionsrefueled-final.pdf
タイトルの通り、Javaのコレクションフレームワークについての話です。その歴史とJava 8での拡張、Java 9での拡張と将来の作業についてでした。

内容

JDK 1.0はレガシーコレクション、VectorやHashtableなどである。1.2はコレクションフレームワークが導入された。インタフェースとしてCollection、List、Set、Map、Iteratorが、具象クラスとしてArrayList、HashSet、HashMap、TreeSet、TreeMapがある。5.0ではジェネリクス、java.util.concurrentパッケージが追加された。

Java 8

Java 8ではラムダとストリームが追加され、インタフェースにデフォルトメソッドとstaticメソッドが定義できるようになった。15年経って初めての変更だ。

 


CollectionはIterableのサブインタフェースなので、これはすべてのコレクションで動作する。
Iteratorインタフェースでは、ほとんどのイテレータは削除をサポートしていない。そのためこう書く必要があった。



remove()のデフォルトメソッドがまさにこれだ。削除できないイテレータを作るときは、単にremove()を省くだけでよい。削除できるものを書くときは、remove()メソッドをオーバーライドするだけだ。

Collectionインタフェースでは、removeIfでバルク更新ができるようになった。


もしコレクションがArrayListなら、7の場合の計算量はO(n^2)であり、8の場合はO(n)となる。

List

ListインタフェースのreplaceAllもバルク処理だ。


ただし、要素の型を変更することはできない。そうしたいときはStreamを使う。

List.sortはCollections.sortよりなぜよいのか?Collections.sortは3つのステップを使う。

  • 一時的な配列にコピーする
  • 配列をソートする
  • リストにコピーして戻す

List.sortはデフォルトでは上記と同じだが、ArrayList.sortはオーバーライドしてin-placeでソートするため、コピーはしない。Collections.sortは現在単にList.sortを呼び出すだけだ。

Map

MapインタフェースにもforEachがある。



replaceAllもある。



Java 7までMulti-mapはとても扱いづらかった。Multi-mapはキーに対して複数の値があるマップだ。

Java 8ではこうなる。

Comparator

Comparatorを書いて楽しい人はいる?Comparatorは多くの条件とコードの繰り返しだ。Java 8はComparatorにstaticとデフォルトメソッドを追加した。名字とnullがある名前でソートし、nullを最初に持ってくる2レベルのソートのサンプルを見てみよう。まずはJava 7から。

Java 8ではこうできる。

Java 9

JEP 269: Convenience Factory Methods for Collectionsだ。こういったAPIが追加される。

設計と実装の課題としては以下のものがあった。

  •  Immutability
  •  Iteration Order
  •  Nulls Disallowed
  •  Duplicate Handling
  •  Space Efficiency
  •  Serializability

新しいstaticファクトリメソッドが返すコレクションはイミュータブルとなる。これは従来の不変性であり、不変の永続性ではない(addなどはUnsupportedOperationExceptionをスローする)。不変性はよいものである。一般的な場合、コレクションは既知の値で初期化した後、変更することはない。不変であれば自動的にスレッドセーフになる。効率、とくにスペースについて改善するチャンスがある。JDKには一般的な目的のための不変コレクションはない。

Setの要素とMapのキーのイテレーションの順序については、HashSetやHashMapであれば公式には順序が保証されないとしていたが、長い間たいてい一貫していた。これを変更すると、順序に依存しているコードは動作が変わってしまう。適用するのは新しいコレクション実装だけにする。既存のコレクションは同じままとなるだろう。

ListやSetの要素、Mapのキーや値にnullを許可しない。NullPointerExceptionをスローする。1.2でコレクションにnullを許可したのは失敗だった。Java 5以降コレクションではnullを許可していない。とくにjava.util.concurrentのコレクションではそうだ。nullはNullPointerExceptionの原因だからだ。

Setの要素やMapのキーで重複したときはIllegalArgumentExceptionをスローする。”コレクションのリテラル”で重複があるのはプログラミングのエラーである可能性が高い。理想的にはこれをコンパイル時に検出する。値はコンパイル時の定数ではない。次にいいのは、実行時の生成においてフェイルファストにする。

2つの文字列の要素を持つSetを考えてみる。

どのぐらいスペースを使っているのか?オブジェクトを数えてみる。

  • unmodifiableなラッパーが1つ
  • HashSetが1つ
  • HashMapが1つ
  • 長さが3のObject配列のテーブルが1つ
  • Nodeオブジェクトが2つ、各要素に1つずつ

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-03-14-36-08

サイズの見積もりとしては、オブジェクトごとに12バイトのヘッダーがある(64ビットJVMで32GB未満のヒープ、OOP圧縮あり)。int、float、参照フィールドごとにプラス4バイトだ。ということは、先ほどのオブジェクトを合計すると152バイトになる。

 

  • unmodifiableなラッパー: ヘッダー + 1フィールド = 16バイト
  • HashSetが1つ : ヘッダー + 1フィールド = 16バイト
  • HashMapが1つ: ヘッダー + 6フィールド = 36バイト
  • 長さが3のObject配列のテーブル: ヘッダー + 4フィールド = 28バイト
  • Nodeオブジェクトが2つ、各要素に1つずつ: (ヘッダー + 4フィールド) * 2 = 56バイト

フィールドベースのSet実装だとオブジェクト1つとフィールド2つで20バイトとなる。

 

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-03-14-43-09

実装はすべてstaticファクトリの背後にあるプライベートなクラスとしている。

コレクションはすべてシリアライズできる。ただ、デフォルトのシリアライズ形式は内部実装について漏らしてしまっていた。新しいコレクションの実装は、カスタマイズしたシリアライズ形式となる。

将来的な作業

これらはまだ計画されていない将来的な作業だ。

VectorやHashtableといったレガシーなコレクションは非推奨にする。LinkedListもそうするかもしれない。

コアなコレクションのイテレーション順序をランダムにする。新しいミューテータのデフォルトメソッドを追加する。ArrayDequeへのインデックスアクセスを追加する。

JEP 269のコレクション拡張では、パフォーマンスの改善と、順序があるSet/Mapを追加する。

Project ValhallaでのValue typesなど。

感想

Stuartさんのセッションは熱い感じで印象深かったです。これはStuartさんの最後のセッションでしたが、他2つ、Stuartさんのすべてのセッションを聴きました。

このセッションの内容としては、Javaプログラミングで使わないことはほぼないであろう、コレクションについて歴史をたどれ、興味深いものでした。

JEP 269については、以前私は個人ブログにて動作確認していました。

そのためAPIの追加は知っていました。しかしほかにも数多くの改善があり、とくにコレクションが使うスペースについて理解が深まったのはうれしいです。


2016年09月30日

sakata

JavaOne 2016 サンフランシスコに参加しました!(その2) #javaone #j1jp

Hello world! コンテンツ・メディア第1事業部のjyukutyoこと阪田です。

前回の投稿ではJavaOneへの行き方を中心に書きました。今後数回に渡っていくつかのセッションの内容を紹介します。

Building Angular 2 Applications in Java 8

チュートリアルセッションです。Angular 2とGWT、Spring Bootでアプリケーションを作るには、という内容でした。スライドはこちらにあります。
http://lteconsulting.fr/angular2boot-javaone/#/
Angular 2とGWT 2.8を使う際の問題点と解決策が中心となっています。

内容

Angular 2はJavaScriptに加えてTypeScriptをサポートしている。Modules、Components、Dependency Injection、Change Detectionが基本的なものである。さらにJSR-269のPluggable Annotation Processing APIを使ってコードを生成する。バックエンドは、シンプルで強力なSpring Bootを使う。

GWTは今のWebからは遠いところにあるものなのは事実だ。GWTにあるものは、以下のもので置き換えられる。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-29-12-59-15

ただ、GWT 2.8は将来の過渡期にある。

  • JsInterop
  • Java 8対応
  • Widgetや古いものをなくす

GWT 3はJ2CL (Java to Closure) となり、今標準となっている多くの機能をなくす。

GWTはモダンで最適化されたJavaScriptへコンパイルしてくれる。JsInteropはJavaScritpとJavaコード間を双方向で統合する。JavaScriptのXMLHttpRequestは以下のようなJavaクラスとなる。
%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-29-13-16-14
これを次のように使うことができる。
%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-29-13-16-27
そしてSuper Dev Modeには開発用の早いインクリメンタルなコンパイラがある。

JSR-269のPluggable Annotation Processing APIでは、独自のアノテーションプロセッサを登録する。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-29-13-23-34

そして、Angular2GwtというGWTとAngular 2を統合するライブラリを使う。 Angular2Gwtがすべてやってくれる。User moduleなしのGWTのコンパイルは早い。アプリケーションに依存ライブラリを1つ足すだけでできる。

アーキテクチャは次のようになる。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-29-13-28-11

デモアプリケーション

セッションではデモもありました。デモのリポジトリはこちらです。
https://github.com/ltearno/angular2boot-demos

デモアプリケーションはいくつかあります。ここではセッションで実行していた”my-first-tree-orchard”を動かしてみましょう。

$ cd my-first-tree-orchard
$ mvn spring-boot:run

僕の環境ではjava.lang.IllegalArgumentException: Can not copy a non-root Methodが出ましたが、起動しました。http://localhost:8080/にアクセスすると、”Application is loading”が出た後、次の画面になります。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-29-13-53-23

あとは”Roll 6 faces dice”ボタンを押せば動作します。

さて、target/generated-sourcesディレクトリを見ると、コードが生成されています。
%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-09-29-14-00-06
ライブラリがPluggable Annotation Processing APIを使って生成したコードですね。

このままではコンポーネントのテンプレートを変更しても、即座に反映されません。Super Dev Modeを使ってみましょう。spring-boot:runはしたままで、別のウィンドウを使って同じディレクトリで次のコマンドを実行します。

$ mvn gwt:run-codeserver
...
[INFO] Super Dev Mode starting up
...

Super Dev Modeが起動しました。画面をリロードします。”Compileing Application”と表示されるようになります。

最後に、起動時のjava.lang.IllegalArgumentException: Can not copy a non-root Methodですが、古いバージョンのSpring Loadedの問題のようです。angular2boot-demosディレクトリにある親pom.xmlのspringloadedを1.2.0から現時点で最新の1.2.6にすると、例外は出力されなくなりました。

感想

Angular 2にもGWTにもほとんど知識はありませんでしたが、おもしろいアプローチではあると感じました。現時点ですぐにJavaにすべてを寄せるアプローチを使う予定はないのですが、こういった方法もあることは知っておいてよいですね。


2016年09月29日

sakata

JavaOne 2016 サンフランシスコに参加しました!(その1) #javaone #j1jp

Hello world! コンテンツ・メディア第1事業部のjyukutyoこと阪田です。

私は昨年に続き、今年もJavaOneに参加しました。

JavaOneとは

JavaOneをご存知の方はここは読み飛ばしてくださいね。

JavaOneは、オラクル社(以前はサン・マイクロシステムズ)が1996年から毎年開催している、Javaに関する最大級のカンファレンスです。サンフランシスコで5日間、400以上のセッションがあります。朝から晩までJavaに浸っていられる、夢のような内容となっています。

毎年9月、10月といった秋に、ユニオンスクエアの近くにあるヒルトンやPark 55といったホテルや、国際会議場モスコーン・センターを会場としています。なお、同時にオラクルのOpen Worldというカンファレンスも開催されています。ビジネスとしてのメインはOpen Worldの方ですね。

モスコーン・センターは道を封鎖して、期間中ずっとイベント会場となっています。
img_2211img_2212

英語について

海外のカンファレンスに参加する際に、私も含めみんなが気になることは英語だと思います。もちろんまったく下地がない状態でセッションの英語を聴くのはおそらく難しいです。ただ、普段から技術文書を少しでも英語で読んでいて、セッションの対象となる技術分野をある程度知っていれば、スライドの文章もあるので大まかには理解できます。

私自身は海外留学の経験もなく、英語が話せるわけではありません。ですがJava Magazineを英語で読んでいたこと、去年参加してからNHKラジオのストリーミングを毎日聴いていたことで、昨年より聞き取ることができるようになりました。

費用について

次に気になる点は費用だと思います。参考までにだいたいの費用を載せますね。

飛行機

日本からサンフランシスコへ直行便を利用すると、2016年9月現在では往復15万円ほどかかります。飛行時間は行きが10時間、帰りが12時間です(関西空港-サンフランシスコ国際空港)。

なお、乗り継ぎ便を利用すると、現実的な乗り継ぎで10万円となり、5万円抑えることができます。私は今年香港経由でサンフランシスコへ行きました(業務での出張ではありましたが)。直行に比べて7時間ほど余計にかかりました。ただ、行きは朝早くの出発、帰りは深夜出発で、とても時差調整がしやすかったです。行きのサンフランシスコ到着時間や帰りの関西空港到着時間も、直行便を利用するときとほぼ同じで出発時間が早くなるだけです。すると帰りの1日分宿泊費がかからないため、ホテル代2,3万円を抑えることができます。

想定費用:10万円〜15万円

img_2198

ホテル代

サンフランシスコは大変物価が高いところです。ホテルも同様で、通常でも日本のビジネスホテルより設備が悪いところが1万円以上します。そして、数万人集まるOpenWorldとJavaOneの期間中は、ホテル代が高騰します。最低でも1泊2万円はかかると考えてください。ただし、安くて会場に近いホテルはすぐに埋まるため、よほど早く準備するか、会場からとても遠いホテルでないとこの価格では泊まれないと考えてください。

私は1ヶ月前にホテルを予約しましたが、会場から5分のところでやや広い部屋しかなく、1泊3万5千円でした。会場からかなり遠いところであれば、2万5千円もあります。Uberを使えば20ドル前後で会場まで移動できるので、その方法を使うのも一手です。その分移動に時間は取られてしまいますが…

宿泊期間は土曜日から金曜日まで、6泊となります(日曜日から木曜日の夕方までが開催期間)。前述の通り、木曜日の夜便を使えば5泊にできます。

想定費用:13万円〜20万円(3万円前後 * 5,6泊)

img_2200

パス代

JavaOneのパスは、直前に購入すると2050ドル、つまり20万円以上します。ですが、早期に購入すると割引があります。登録開始から1ヶ月ほどは、1650ドルでした。4万円抑えられます。ただ、まだJUGディスカウントもあります。JUG、つまりJavaユーザグループにはディスカウントコードが発行され、それを使うとさらに200ドル安くなります。JavaOne登録開始から数ヶ月経った後JUGに配布されますので、日本のJUG、JJUGあるいは関ジャバのTwitterアカウントをフォローしておくとよいかと思います。関ジャバの会長は私ですので、私に直接問い合わせていただいても大丈夫です。

ただし、スピーカーになればパスが無料でもらえます!スピーカーは公募制、Call for Papersを通過すれば誰でもなることができます。

このパスには、月曜日から木曜日のランチ、日曜日の夜のWelcomeレセプション、水曜日の夜のAppreciation Eventが含まれます。食事代がいくらか浮きます。

想定費用:15万円〜20万円

総費用

合計すると安くても38万円となります。安くはない金額ですね。また、食事も高い物価の影響で、ファーストフードであっても10ドルはします。レストランでは30ドルは見ておいたほうがよいです。

どんなことが得られるのか?

まず、日本でこの規模のカンファレンスはありません。そして、JavaOneには世界各国から人が集まってきています。日本人とか外国人とかそういったものは関係なく、すべての人が英語で発表し、質問もします。日本語母語の人も、英語でスピーカーをしています。これが世界的には普通だという感じられます。みなネイティブのように話すわけではありません。きれいな発音でなくても、堂々と大きな声で質問しています。参加すれば、きっと自分もそうなるのが普通であり、これからも技術と英語を深めていけばそうなる、と思えます。これは、言葉で読むよりももっと大きなインパクトです。私は若い方ではありませんが、とても大きな体験でした。できる限り若い年齢で行ってみれば、さらに大きな体験となります。少し無理をしてでも、ぜひ行ってみてほしいです。

もちろん、JavaやJVMの最新情報を手に入れることができます。それだけでなくJava Platform GroupチーフアーキテクトであるMark Reinholdさんなどに直接質問できるQ&Aセッションもあります。また、JCP(Java Community Process)メンバーになっていれば、夜に会員限定のパーティもあり、各国のJUGメンバーやJava Championに話かけることができます。こういったことは、ここに来ないとできません。

ただ参加するだけではそう得られるものはありません。年間を通じてJavaコミュニティに関わっていればいるほど、JavaOneで得られるものは指数関数的に大きくなります(私自身もまだまだです)。JavaOneとJavaコミュニティへの参加を通じて、フィードバックサイクルを回しながら進めば、とんでもないところに行けるのではないかと思っています。

次回予告

次回からは時系列順ではなく個別のセッションをいくつかピックアップして記事を書いていきます。お楽しみに!