CDIのBeanをInjectしないで取得する

Seam2のComponent.getInstanceのCDI版を探しています。

これでいけるのかな?
http://soras.sblo.jp/article/35292434.html

BeanManager bm = InitialContext.doLookup("java:comp/BeanManager");

Bean<?> bean = bm.resolve(bm.getBeans(ClassA.class));
CreationalContext<?> cc = bm.createCreationalContext(bean);
ClassA result = (ClassA)bm.getReference(bean, ClassA.class, cc);

EntityListenerからEntityManagerやQueryを触るの禁止。

Hibernateのドキュメントより。

A callback method must not invoke EntityManager or Query methods!

stackoverflowを探してみるとJPAの仕様でも非推奨のようです。


それよりもEntityにEntityManagerをインジェクトしたい…。
Springなら楽そうなのになぜCDIで方法が見つからないのか。

DDD(ドメイン駆動設計)をやってみように参加しました。

遅ればせながらDDDをやってみよう勉強会に参加しましたので、内容を自分なりにまとめてみます。
当日の資料はこちらです。
資料があるので自分が気になったところを簡単にまとめます。

ドメインというのを「利用者の関心事」と表現

毎回ドメイン駆動設計を説明する際にドメインという言葉で初っ端からつまづくのでこの解釈は参考になりました。

イテレーティブな開発は改善体質のある組織にしか求められないため、役所等は向かないのではないか?

これは特許庁の話で話されていたことですが、役所に限らず旧体質の巨大な企業、いわゆるお役所仕事にも言えるかと思います。
こういったところが顧客でイテレーティブな開発をしたい場合はどうしたらいいんでしょうかね…。

DDDを実際にやってみるにはとにかくドメインモデルを置く場所を作ることから始める

ORM系フレームワークを使った場合ではオブジェクトによるデータ表現を行う必要があるので、これを元にしてDDD的なアプローチをすると良いのではないかと思います。
JPAではネイティブなSQLを投げると痛い目を見るので、オブジェクトの関連とかを予めしっかりと考える必要があり、この時点でそれなりにDDD的なアプローチができているのではないかとも思います。
ただ、ORM系フレームワークでの実装がそのままドメインモデルにはならないですし、ドメインモデル貧血症というアンチパターンに陥りがちなのでうまく誘導したいところです。
あとフレームワークのいうエンティティとDDDのいうエンティティは別モノなのは注意点ですね。

ドメインクラスにはフレームワークのパッケージはインポートされてはならない

またORM系の話になりますが、アノテーションとかはいいですよね…?

困ったら対象業務に関する英語の本を漁れ。これは単語の宝庫。

識別子、いつも困ってます。これはたしかにいい方法ですね。

Stringが1つだけでもドメインモデル的に分割可能なら値オブジェクトにしてラップしてしまう。これにより型宣言による表現力向上が見込まれる。また、不変であることから取り扱いが簡単になりバグが減る。

値オブジェクトの扱いについては、細かくし過ぎると逆にわかりづらくなるんじゃないか、という心配がありました。
しかし型宣言の表現力向上という観点は眼から鱗でした。

○○手順とか単語が出たらとりあえずドメインのクラスにする。ただしステートレス。

批判があるかもと話されていましたが、わかりやすくはあるのかなと思います。試してみたいところです。

自分自身での課題として状態遷移やイベントソーシング(と他4つ)がある。

この2つに関してはオブジェクト指向でわかりやすく表すのが難しいというところが問題と認識しています。
これに関してはJBossにあるjBPMのワークフローエンジンやDroolsのルールエンジンなどが一種の解なのかなと思ったりしました。
どちらもオブジェクト指向に「別のパラダイム」を「わかりやすく」持ち込むという点で有効な気がします。


エリック・エヴァンスドメイン駆動設計は中々読むのが大変でしたが、読んだ甲斐あって中々えるものが多かったです。
この本は原本も難解だそうで、DDD難民なる言葉もあるそうです。

東京node学園4時限目参加しました。

東京node学園4時限目(ハッカソン)に参加してきました。
ハッカソンです。

会社ではJava屋な自分としてはnode.jsのSocket.ioとJava間でイベントのやり取りができるとnode.jsの部分を最小化できるかな、と。
そうすることで、仕事の中でひょこっとnode.jsを組み込めないかな、と思ったわけですが。。。
見事にSocket.ioのJavaクライアントライブラリが動かず撃沈しました…。
ちなみに使おうとしたのはこんなのです。
https://github.com/benkay/java-socket.io.client
JBoss上、JRE上、双方ともハンドシェイクあたりでぬるぽってました。。。
使い方が悪いわけでもなさそうなんですが…なんともかんとも。

そこでふと冷静になると、別にクライアントとnode.jsがSocket.ioならnode.jsとJavaは普通のHTTPでいいじゃないか、と。
そして方針転換し、ブラウザ⇔node.js⇔JAX-RSなリアルタイムなチャットを作ってみました。
あえなく時間切れで完成はしなかったのですが、自分なりの使い方が見いだせたかと思います。
Java部分なしのnode.js単体で動くチャットアプリはgithubに上げてあります

さて、ビアバッシュにていろんなかたと話しましたが、軽くまとめてみます。
・コンシューマー系多し。エンプラは自分が知ってる限り2/6。
・自分の周りではPHP使いが多かった。
・node.jsのメリットは何か?
  ・Socket.io
  ・JavaScriptで言語が統一できる
  ・でも、Socket.ioを使わない限り中々node.jsの意義を見出すのは難しいのでは?
・シングルスレッドで例外がとび出すとサーバーが停止するので、例外処理が難しい。
  ・ビアバッシュ時に例外のハンドルの仕方について議論が起きて、例外教室が開催。
・AmazonEC2でロードバランサが入るとSocket.ioが使えない?
  ・会話してるのが聞こえただけですが…。

それにしても普通の勉強会と比べると、ハッカソンということもあるのか、よりスキルのある人間が多くいた感じがします。
話すだけでも楽しかったです。皆様どうもありがとうございました。

Bytemanでビルドいらずの時間計測処理追加

JBoss.orgにて公開されているBytemanというバイトコードインジェクションツールを用いて、ソースコードに変更を加えず、処理時間を計測する方法を紹介。
再起動とか設定の追加はゆるされるけれど、ソースコードの修正は許されないような場合に便利。
あとはフレームワークやライブラリのような手を出したくない場所の処理時間計測。

まずはJVMに仕込む。
パス等は適当に置き換えて。

export JAVA_OPTS="-javaagent:$BYTEMAN_HOME/lib/byteman.jar=script:$SCRIPT_HOME/TimerRule.btm"

次にルール(Byteman用のスクリプト
とりあえず見た通りなんだけれども、はまりどころはルールの記述順番等形式を勝手に変えられない点(だと思っている)。

JavaのGCログを日付時刻で表示する

こんなのを見て。
http://www.theserverlabs.com/blog/2010/05/26/human-readable-jvm-gc-timestamps/

まずは基本編。
 -Xloggc:

 -Xloggc: タイムスタンプが付いたファイルにGCステータスのログを記録する

 -XX:+PrintGCDetails

 Print more details at garbage collection. Manageable. (Introduced in 1.4.0.)

次に問題のやつ。Oracleのサイトで資料が見つからない…。
 -XX:+PrintGCDateStamps

で試しにこんなのを設定すると、

 -Xloggc:./gc.log -XX:+PrintGCDateStamps -XX:+PrintGCDetails


こうなる。

2012-02-21T23:24:35.564+0900: 0.712: [GC [PSYoungGen: 16448K->2686K(19136K)] 16448K->2906K(62848K), 0.0158370 secs] [Times: user=0.03 sys=0.00, real=0.02 secs]
2012-02-21T23:24:35.981+0900: 1.129: [GC [PSYoungGen: 19109K->2679K(35584K)] 19329K->5567K(79296K), 0.0235950 secs] [Times: user=0.03 sys=0.00, real=0.03 secs]
2012-02-21T23:24:37.045+0900: 2.192: [GC [PSYoungGen: 35575K->2678K(35584K)] 38463K->15244K(79296K), 0.0277780 secs] [Times: user=0.04 sys=0.00, real=0.02 secs]
2012-02-21T23:24:37.276+0900: 2.424: [GC [PSYoungGen: 10039K->2678K(68480K)] 22606K->17616K(112192K), 0.0168570 secs]

とってもイイ。

JPA2タイプセーフクライテリアを使ってみた

まずは環境を準備。

  • JBoss AS 7を用意。
  • Eclipse3.7.1を用意。
  • JBoss Toolsをマーケットからインストール。
  • ランタイム設定でJBoss AS 7を設定しておく。
  • forge consoleビューを表示。
  • 三角ボタンでforgeを起動。
  • プロジェクトを作成する(好きなディレクトリに移動して)

$ new-project --named jpa2sample --topLevelPackage sekky.jpa2sample
? Use [/home/sekky/dev/jpa2sample] as project directory? [Y/n] Y

  • JPA2を追加(入力欄はTABで補完アリ)

$ setup persistence
? [provider=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAProvider)]: HIBERNATE
? [container=ARG (of type org.jboss.forge.spec.javaee.jpa.api.JPAContainer)]: JBOSS_AS7
? The JPA provider [HIBERNATE], also supplies extended APIs. Install these as well? [y/N] N(きっと移植なんて未来永劫ないけどね)

  • 一応JSFCDIとかも突っ込む。

$ setup scaffold
? No scaffold type was selected, use default (JSF)? [Y/n] Y
? Scaffold provider [faces] is not installed. Install it? [Y/n] Y
? Facet [forge.maven.WebResourceFacet] requires packaging type(s) [war], but is currently [jar]. Update packaging? (Note: this could deactivate other plugins in your project.) [Y/n] Y

  • pomを修正する(メタモデルクラスを自動生成する注釈プロセッサー)

http://docs.jboss.org/hibernate/jpamodelgen/1.0/reference/en-US/html_single/参照

ここまでで何とか準備が完了。

これでEntityを作りCriteriaを投げる。
Entity作りは省略。ここら辺はJPAを調べてくださいな。
Criteriaの例はこんな感じ。

流れるようなインターフェースではなく、APIの使い勝手は正直微妙な感じがする。
が!タイプセーフなおかげでEntity(DB)修正しても怖くない!

一気に書き上げてるので間違いがあるかも。
何かあればTwitterにでもどうぞ。