JJUG CCC 2014 Spring
日時: 2014年 5月 18日 (日) 9:30 (開場 9:00)
場所: ベルサール西新宿
発表資料一覧
http://www.java-users.jp/?page_id=1048
全体感想
Java8でfor
文、forEach
文は禁止!
当日一番焼き付いた言葉といえば、これに尽きると思う。
もうこれオブジェクト指向言語なのか?ってくらい頭を切り替える必要あり。
JavaでのWeb開発の発表は凄まじかった。
https://speakerdeck.com/monzou/spa-development
このスライドみるだけでもだいぶおなかいっぱいになる。
結局自分は文法少し覚えただけでフレームワークなど何一つ使えてないなと反省。
「使いづらいから自作した」だとか「デザインは業務モデルの上に成り立つべき」などエンジニアとしての仕事に対する精神的な部分も大いに勉強になった。
あと聞いてないけど、自分の新人時代の研修内容と比べて他社の研修は素晴らしいなと感じた発表がこれ。
http://www.slideshare.net/satokoshiroi/jjug-20140518
精神的という意味では「確証バイアス」と「建設的相互作用」の話も心に残った。
開発プロセスやチーム体制の確立には心理的側面へのマネジメントが大きく占める。
以下セッション別メモと所感。
K-1 詳説 Java SE 8 – CCC Edition
櫻庭 祐一 (Java in the Box)
http://www.slideshare.net/skrb/java-se-8-ccc-edition
Java8の変更はやめぐり的な。
制御構造をシンプルにしたい
ProjectLambdaはパラレルコンピューティング用。
しかし、実際は制御構造の可視化が必要な時に多用する。
for
やif
のようなネストが深いような文は
projectLambdaのStream
などを使えばシンプルに記載することができる。
for
文、forEach
文は禁止!
パフォーマンスが上げたいとき
まずはパフォーマンス解析アプリを使おう。ソースを見るのはもっと後。
MissionControlやフライトシミュレータを使う。
Date/Calendar使いたくない。。。
Date
とCalendar
の行き来がめんどくさいときはDate&Time API使おう。
Date
とCalendar
クラスはUnixベース。
Date&TimeはISO8601ベース。そして Imutable。
ただし、若干クラスが増えている。日にちと時間が別になっていたりする。
LocalDate
とLocalTime
とか。
静的コード解析しないと眠れない時。。。
Type Annotation。Annotation for Code Checker。
例えば@NonNull
と型パラメータに指定しておくと、静的解析時に
Null
が入るようなシーケンスを発見するとエラーを出してくれる。
GUI。。。!
Swingは格下げ。Swing
は今後拡張や追加はされない。
JavaFXだよ!
JavaFXはGUIの構造をXML(FXML)で作成する。Androidのような感じ。
見た目はCSSで書ける。ロジックはJavaで書く(JavaScriptでも書ける)
Flashは使えないが、動画を埋め込んだり、3Dも利用できる。
サーバサイドJSに興味あり
Nashorn。NashornでInvokeDynamicを使えるようになった。
Java7と比較するとベンチマークテストで倍のスコアを出す。
まとめ
Java8を使うとプログラムスタイルが変わる。
Lambdaを使うだけでJava7以前のプログラミングを全く変化する。
もろもろは以下の連載ページで確認できる。
http://itpro.nikkeibp.co.jp/article/COLUMN/20140212/536246/
K-2 Java 8 ラムダ式と Stream の概要について
Stuart Marks (Oracle Corp.)
http://www.slideshare.net/OracleMiddleJP/overview-lambda-streams
Lambda式は関数であるので引数を取り戻り値がある。
Java8以前はファンクションはメソッドとして実装されるだけだった。
Lambda式ならばパラメータとして渡すことができる。
例えば以前の書き方だとSortを行いときはCollections.sort()
クラスに
インスタンス化したSort条件(名前でソート)などを受け渡す必要があった。
class Person {
String name;
int age;
String getaName() { return name; }
int getAge() { return age; }
}
List<Person> lis = ...;
class ComparePersonsByName implements Comparator<Person> {
@override
public int compare(Person p1, Person p2) {
return p1.getName().compareTo(p2.getName());
}
}
Clollection.sort(list, new ComparePersonsByName());
アノテーションオーバーライドで書くこともできたが、それでも冗長である。
Java8で書くと以下のようになる。コンパイラで型推論もできる。
List<Person> list = ...;
Collection.sort( list,
(p1, p2) -> p1.getName().compareTo(p2.getName()))
Lambda式はFunctionalInterfaceを必要とする。
http://www.ne.jp/asahi/hishidama/home/tech/java/functionalinterface.html
そして同期がされている。
Java8でシンプルになる実装例
List<Person> list = ...;
#Old Format
for (Iterator<Person> iter = list.iterator(); iter.hasNext; ){
Person p = iter.next();
it ("Jones".equals(p.getName())) {
iter.remove();
}
}
#Format Java8
list.removeIf(p -> "Jones".equals(p.getName()));
List<String> list = Arrays.list("Alpha", "Bravo",
"Charlie", "Delta", "Echo");
#Old Format
for (Iterator<String> iter = list.iterator(); iter.hasNext; ){
iter.set(iter.next().toUpperCase());
}
#Format Java8
list.replaceAll(s -> s.toUpperCase());
list.replaceAll(string::tiUpperCase); // method referecne
Java8からはDefault Methodが追加されている。
既存のインターフェースにメソッドの実装を追加することができる。
後方互換が保たれている。
Iteratable.forEach(lambda)
Collection.removeIf(lambda)
List.replaceAll(lambda)
List.sort(lambda)
// replaces static method
Java7ではCollections.sort()
でソートしていたが、
リストの特定の実装に対して最適化するのは困難だった。
しかしlist.sort()
はCollections.sort()
で提供される
一般的なsort
よりも最適化されたsort
を提供できる。
Streams API
ストリーム自体はアブストラクトな概念。
StreamsAPIの一番の特徴は並列性があること。
StreamsAPIはLambda式を用いる。
ストリームの例
persons.stream() #ストリーム化している
.map(p -> p.getName()) #nameの新しいストリームを生成している。
.filter(s -> s.codePointCount(0, s.length()) > 3) # 4文字以上というフィルター
.sorted()
.forEach(s -> System.out.println(s)); #終端操作。ストリームの操作を評価するLambda式
ストリーム中にparalell()
を利用することで並列処理も実行できる。
--
H-1 Java 8 で RDBMS を実装してみた
きしだ なおき (Java コミュニティ@九州)
http://www.slideshare.net/nowokay/with-java8
RDBの中ではリレーショナルエンジンと実行エンジンが大きな役割を占めている。
リレーショナルエンジンはSQLを実行エンジンに渡す物理プランを作成する。
つまりSQL文を実行エンジンが理解できるように変換するコンパイラと言ってもいい。
勉強用データベース仕様
- シングルスレッド
- JOINはLEFT INNERのみ。
Javaでのデータベース
- あんまり向いていない
- 関数言語(ScalaやHaskell)のほうがいい。
ただし、Java8ならばラムダ、ストリーム、Optionalを使えるので話は別。
Java8とlombokがあれば関数言語を使わなくてもRDBを使うことができる。
データベースを作成するときは。。。
データベースの寿命はアプリと比べて長い。
そのため、バージョンの有効期間が短い言語は不向きである。
パーサーとしては、JParsecライブラリを用いて実装した。
- トップダウン解析
- Haskelのparsecの移植
- パーサーコンビネータ(引数だけから結果が決まる関数)
- 内部DSL
- ただしドキュメントがないので、チュートリアル以上のことするのは辛い
字句解析
基本的に正規表現とした。
トークンのことを終端記号とする。
構文解析
トークン列から構文木を作成する
正規表現との違いはパターンの中にパターンを使える。定義の入れ子ができる。
数式解析
数式の優先順位決めはボトムアップ解析を用いる。
リレーショナル代数
SQLとリレーショナル代数とはことなる
ここらへんで挫折。
R2-2 Java ではじめる Apache Cassandra
森下 雄貴 (DataStax)
Cassandraは誕生から5年。
Javaで書かれた分散データベース。Facebook製でApacheソフトウェア財団に寄贈された。
利用事例
Cassandraが選ばれる理由は大きく3つある。
- スケーラビリティが優れている
- 時系列データの超高速書き込みができる
- アベイラビリティが優れている。データセンターロスなどに対応しやすい。
クラスタ
P2Pの分散システム
各ノードが同じ役割を思っているので、冗長性が高い。
マスターノードが無いので、単一障害点がない。ある程度のノードが落ちても問題ない。
データは複数のノードに保持される(レプリケーション)
複数のデータセンターにまたがってデータを保存するなどの設定も柔軟に設定可能。
マルチデータセンターに対応
東京のデータセンターにコピー、その後国内のデータセンターに転送、とか
オンライン/オフラインでノードを分けることも可能。
リニアスケーラビリティ
データセンターを追加したとき、Cassandraだけがしっかり線形に増加する。
データの書き込み
書き込み要求が来た時、ディスクI/Oの負荷が低く、クライアントへのレスポンスが早い。
定期的にメモリのフラッシュも行う。
データの読み出し
読み込みの速度は書き込みに比べて若干遅い。マージに少し時間がかかるため。
ストレージモデル
BigTableのColumnFamilyがベース
パーティションキーやセル名でソートされているので、時系列データと非常に相性が良い。
開発のしやすさ
CQL3という機能を持っている。
Thrift RPC API
元々のデータアクセス方法。ストレージエンジンを直接触るイメージ
CQL3
現在はSQLライクでデータを取得できるようになっている。
Cassandra Query Language ver.3
RDBと同じようにインデックスを作ったり、CRREATE USERできたりする。
SQLに似ているものの、以下は存在しない。
- JOIN
- 副問い合わせ
- 集計関数
CQL3はCassandraストレージエンジン上に作られている。
Javaアプリからのアクセス方法
Cassandraドライバーの選択
(Hector、Astynaxなど)RPCを特徴とするThrift APIの限界から、
CQL3のバイナリプロトコルが開発されている。
バイナリプロトコルを使うことで、
- 非同期通信のサポート
- サーバプッシュ
- ページング
- その他新機能を追加しやすい。(Thrift APIに依存しないので)
DataStax Java driver
オープンソースドライバ。Githubで公開しているし、Mavenなどから利用できる。
クラスタへ接続する。
RDBではないので、JDBCに準拠はしていない。
CQLの実行
Sessionオブジェクトを取得することで、CQLを実行できる。
QueryBuilder
CQL文を直接書くのでなく、プログラムで組み立てる。
ドキュメント
原則英文だが、JavadocなどをWebで公開している。
R1-3 Java 開発で活かしてほしい Git, CI, そして継続的デリバリー
長沢 智治 (アトラシアン株式会社 エバンジェリスト)
http://www.slideshare.net/tomohn/java-34819591
アトラシアンはJIRAやBitbucketなどのツールを提供している会社。
開発のライフサイクル全般をフォローすべく様々な開発支援ツールなどを取り扱っている。
ビジネス駆動開発の世界へ
ビジネスとソフトウェアの関係は表裏一体になっている。
ソフトウェアがビジネスをドライブするような状態がベスト。
ようこそ継続的デリバリーの世界へ
BLMサイクルを回していく(Build Learn Mesure)
企画からリリースまでの全てのトレーサビリティを確保する。(アトラシアンのアプリでできるよ!)
以下JIRA、SourceTree、Confluence、HipChat、Stash、Bumbooを利用したデモ。
- 全てのツールがシームレスに移動することが可能。
- デプロイなどの操作も可能
- SourceTreeから直接プルリクすることも可能。
- 自動テストした結果はHipChatなどに通知可能
- 全ての情報はJIRAに集約されている。
- レビューはStash上でできる。行単位でコメントをすることも可能
- ほとんどの操作がJIRAから行うことも可能。
- トレーサビリティがあるので、わざわざ報告書など作らなくても、企画要件からチケットやテスト結果を参照することができる。
- 全てのチケットが終了すれば、企画要件のステータスがCloseになる
まとめ
計画やコードは粒度が異なる。見る人も異なる。全ての流れがそれぞれの立場・それぞれの粒度で常に確認できる状態になっているのが大事。
- モチベーション
- 目的|規律|見える化
- 良い物を取り入れる有機
人が変わるには大人は1年以上かかると言われている。
自分が変わらなきゃと思わせる環境を作ることが大事。
確証バイアスに負けない。建設的相互作用ができる環境が大事
H-4 Java デバッガ活用術 ~勘デバッグ・print デバッグから抜けだそう~
山本 裕介 (サムライズム)
http://www.slideshare.net/yusukey/java-print-jjugccc-ccch4
デバッグとは
- バグ修正
- 副作用がないように。密結合だと大変
バグ発見のタイミング
コーディング中から始まり、プロダクション環境まで。早ければ早いほうが良い!
技術的難易度、政治的難易度が後工程になればなるほど高くなる。
デバッガはプロダクション環境でも活躍できる
デバッガ vs ユニットテスト
ユニットテスト
- 実装が期待通りか確認
- インプットに対して期待したアウトプットが出るか。
デバッガ
- 期待通りに動いていない実装を掘り下げる
- 多量のdebug/print文でコードを汚さない
ユニットテストでデバッグ
- デバッグ目的でユニットテスト作成するのは目的と手段がおかしくなる
- 粒度が細かくなりすぎるかも。本来はインターフェースの確認だけできれば良いはず。
ユニットテストはリグレッションを発見できる最低限のセット
ロジックの確認、デバッグはデバッガで行うべき。
デバッグの方法
再現条件確認、テストケース作成、当該コードの修正
再現条件の確認が非常に難しい!→デバッガで確認する!
デバッガのしてくれること
ステップ実行、値の書き換えなどなど
デバッガがしてくれないこと
パフォーマンスボトルネックの発見は出来ない。プロファイラなどで。
タイミングissueの原因究明もステップ実行などが主のデバッガでは難しい。
外部要因で発生する問題の発見も難しい。
今日説明すること
- ラインブレークポイント
- ステップ実行
- 条件付きブレークポイント
- 式評価/ウォッチ
ブレークポイントで良くある問題
- ループ内をデバックしたい
- ブレークポイントを設定するが、問題発生まで何回もコンテニューしなくてはいけない。。。 →条件付きブレークポイントを使いましょう。
リモートデバッグ
- JPDAを利用している
- デバッグをするための標準インターフェース
有効にするには実行オプションを追加する。suspend=n, address=5005
などが大事。
デバッガがリッスンするポートやアタッチするまで停止するのかを指定している。
プロダクション環境のデバッグ
有効化してもアタッチしなければパフォーマンスに影響なし。
セキュリティは大変脆弱な状態、認証機構もない。
不要な場合はかならず無効にしておくこと。
プロダクション環境ではリスンアドレスを指定すれば、localhostのみでアタッチ許可など。
リモート接続はsshトンネル経由でやるとある程度セキュア。
デバッグあるある問題
- CI環境のみで再現
- たまにしか再現しない
- print文を入れたら再現しない etc...
一般的な解決方法
Chronon: The Time Travelling Debuggerなどを使う便利
http://java.dzone.com/articles/introducing-chronon-time
IDE内でもCI環境でも情報を記録したりすることも可能。
パフォーマンスオーバーヘッドも低い。特定のクラスのみを記録することも可能。
IntelliJ IDEAを使っていれば無料。
まとめ
デバッグを利用するタイミング
- 一時的なデバッグ用のデバッグ文は入れない
ショートカット、条件付ブレークポイントで効率的にデバッグ
オフラインデバッグにはChronon Timetravellingデバッガが有効。
R1-6 最近の Java Web 開発 (2014 春)
文字 拓郎 (シンプレクス)
https://speakerdeck.com/monzou/spa-development
Java + SPAの開発事例、プロジェクトの全体感
基本的に盛り沢山だったので、メモが追いつかず。
スライド見たほうがたぶんよい。
プロジェクトの概要
金融機関向けWebアプリケーション。
海外向けの案件、WebLogic必須。はじめてのWeb案件。
既存システムの問題点
別機関向けの既存Webシステムを参考にしようとしたが、
構造の欠落と、クライアントサイドの進歩についていけない状況だった。
SPA (Single Page Application)
クライアントサイドとサーバーサイドを分離できる
不安要素
ノウハウの不足はbackbone.jsの解析やクローン作成することで大丈夫な見込み。
レイヤリング
Webの都合と業務の構造をきちんと分離できていることを徹底。
WebのレイヤーはAPIの提供のみ。
クライアントやAPIは用意に変化するが、ドメインは変化しない。
サーバサイド
WebLogicは重たいので、開発中はjettyで実施。
Gradle
Mavenと違って何も知らなくても使える。動的に環境も作成できる
Guava
使っていない人はいないと思うので割愛
DOMAIN MODEL
技術的な方法論の前に、
- 業務に興味を持つ
- As-Isだけでなく、To-Beを考える
- 進化を止めない
如何にビジネスモデルを設計できるか。
考える
- エンジニアが最も価値を出すべきところ
- ビジネス上の課題をエンジニア的に解釈する
進化を止めない
躊躇せずに直す。カイゼンしていく
ドメインモデルの実装方針
副作用がないような操作をドメインに、副作用がある操作をサービス側に。
依存情報は切り離してアプリケーション側で実装する。
サービス層の実装方針
業務的な要求に応じて作る。
Webを意識せずに作る
Web層の実装方針
業務ロジックは書かない
WebのAPI(IN/OUT)のみに専念する
採用したのはJAX-RS。Spring MVCが一番いいだろうけど、大きすぎる
スタートアップでよく使われるDropWizard
REST層
Jacksonを使ってJSON・YML変換をしている
気にしたところ
REST原理主義になりすぎない。
クライアントを意識したAPI
サーバサイドのまとめ
サーバサイドは全て「ふつう」の延長線
J2EEサーバは重いので開発には使用できないよーな
クライアント側
Gruntを中心にCofeeScriptとか。
AngularとかEmberはみたいなのは重々しいのでbackbone.jsにしている
不足機能はBackbone.Marionetteで補充している。
backboneで作ったサンプルをGithubにあげているのでコードなどはそちらで。
クライアント側のテストはほとんどしていない。
GUIのテストは実装コストに見合わない(頻繁にリリースがあるならば別)
クライアント側のまとめ
SPAは採用すべき。ユーザーにはUXの向上、開発面でも実装の分離ができる。
ただ、ネイティブにはまだまだ勝てない。レンダリングに介入できない。
まとめ
SPA開発は「普通」の延長線上にある。怖くない。(設計できれば
Simpleなコンポーネントの組み合わせでやったほうがいい
継続的なキャッチアップが必要。
R1-7 サーバサイド JavaScript 標準から見た Nashorn の意義
酒巻 瑞穂 (html5j エンタープライズ部/Firefox OS コードリーディング)
- ScriptのついてるほうのJavaの話
- Nashornコードや内部アーキテクチャの話はググればでてくるので割愛
Server Side JavaScript History
ネスケの上で動くMocha、後のLiveScriptが出来た。
その後ServerSide Javascriptの始祖、LiveWireが誕生した。
ネスケ2発表と共にLiveScriptからJavaScriptに。
同時期にSpiderMonkeyのClone、Rhinoの開発が開始される。
JavaScript系のECMAScriptが規格として制定、各ブラウザがJavaScriptを実装。
サーバサイドも順調に発展していたが、ASPの出現とともに廃れた。
GoogleがV8エンジン作ってからServerSideJavaScriptなどが盛り上がり始める。
独自インタプリタが乱立して混乱してくる。
CommonJSが出たことでアーキテクチャが標準に統一されるようになってきた。
Node.jsが発表、ECMAScript5.1も発表。Node.jsがCommon.jsから乖離始める。
2014年、Java8にNashornが搭載される
What is Nashorn
Java8から標準搭載されたJSエンジン。JREにも同梱
JavaでJavaScriptを使う理由
JavaScriptにより、サービスを組み合わせ得た開発(コンポジット開発)ができる
クライアントサイド(JavaFX)でもサーバサイドでもアプリケーションを書くことができる。
Nashornを使うときの留意事項
jdk/jre共に「jjs.exe」が入っている。
Java8からは「ScriptEnigineManager」の中身はNashorn
Server Side JavaScript of Now
レイヤー | 規格 |
---|---|
アプリケーション層 | ServerSide JavaScript Application |
インタプリタ層 | Vert.X、GromJS、NodeJS |
エンジン層 | Rhino SpiderMonkey、GoogleV8 |
記述言語 | Java、C/C++ |
Nashornはエンジン層。
JavaScript機能の比較
google octaneのベンチマークをnashornで使うと圧倒的にスコアが低い。
動作時にコンパイルが毎回動作しているため。
ちゃんとコンパイルすると、google V8エンジンレベルのスコアも出せる
ECMA-262基準になり、strictモードはちゃんとやっている。
処理系は一旦JIT後、実行すれば安定速度が出る。
エンジンという価値よりも、Java資産を使うためのインタプリタとしての価値がある
Summary
JavaエンジニアにとってのNashorn
JREに標準で入っているのは学習ハードルが低い
Javaで資産を作り、JavaScriptで資産を共有できる
JSエンジニアにとってのNashorn
エンジン層だけナマJSでアプリは普通作らない。
Shell用に機能が多少拡張されているが、アプリやサービス作成には力不足
今後NashornベースのVertXとかできれば知らずに恩恵を得ているかも。。。
サーバサイド系の人からするとNodeJSで十分かも。。。
JavaScriptについて
言語として学習が用意、ECMAScript6の登場によりJavaエンジニアはスキルコンバートがラクなはず。
フロント/バックエンド両方で使われる。
Web of Things(Web連携)が発展する中でJSの位置が高い。
各ベンダーも最近プッシュしている。