2009年06月18日

月齢詐称疑惑

どうも、うちの小夏は成長が早いらしい。(10ヶ月超えたところ)
うちのmamiさんが親子サロン(母親学級)に行くと、1人だけ浮いていて大変なんだそうな。

以下に小夏の行動を列挙する。

  • 親子サロンで小夏は隙あれば部屋から出ようとする。(他の子はおとなしくお母さんの周りで遊んでいる)
    保母さんに連行されて戻ってきたらしいorz
  • 他の大人や子に興味がある。
    他人のおもちゃを奪って泣かせることあり。
  • 離乳食どころか、大人とほとんど変わらないものを食ってる
    おやつのケースを自分で開けて全部食ったという。
  • 既にスプーンとフォークを使っている。
    まだそんなに上手に使えないが、自分でやらせろと自己主張しまくり、上手く出来ると「うっー」っとガッツポーズしますw
  • 指差しで次から次へと要求をする。
    親子サロンに来ている子供たちと比べると、普通はまだ出来ないものらしい。
  • 子供番組で「ぐるぐる〜」と手を胸の前で回す動作(バスケのトラベリングを取られたときみたいなやつ)を真似し始めた。
  • 夜寝かすのに1〜2時間掛かることあり。
  • 歯が既に8本生えました。
  • パンとかあげると、自分でつかんでちぎってから口に入れ、のどが渇いたら自分でお茶を飲む。
    手間要らずです。
  • LEGOを嵌めようとがんばっているが、さすがにまだ出来ないらしい。
    でも、嵌めるという動作は理解しているようだ。(出来なくてイライラして叫んでたりしてます。)

ちなみに、うちの祖母は、小夏のことを「もう赤ちゃんじゃなくて子供だ」と言ってました。(3ヶ月前)
確かに、おいらたちも、「もう赤ちゃんじゃねぇ」と思うことも(多々)あります。

特に、指差しの要求がすごい。
GWではまだ指差しどころか、はいはいできるようになったばかりだったけど、すぐにつかまり立ちが出来るようになったかと思えば、いつの間にか指差しが始まっていた。

このあいだなんか、おいらを指差したので近づくと、腕をつかんで自分の後ろの方へ引っ張り、抱っこせよと要求し、だっこしたらさらに指差しで目的のものまで連れて行けと...(目的を達成できてうれしそうでしたorz)。

親が言うのもなんだけど、あいつヤバイ

そういえば、さっき家の固定電話から電話が掛かってきて、なんだろうと思ったら、小夏のいたずらだったらしい...短縮番号か???

posted by aki at 20:33| Comment(0) | TrackBack(0) | 小夏 | このブログの読者になる | 更新情報をチェックする

アノテーションについて

JDK5で導入されたアノテーションですが、最近その本質が解ってきたので、なんとなくだらだらと書いてみたいと思います。

大原則:「アノテーションは『注釈』であって、何もしない

...当たり前やん、といえば全くそのとおりw。
でも、おいらはこの当たり前が頭で理解しても、本質までなかなか理解していなかった。
ちなみに、コンパイル後にアノテーションがクラスパスに含まれていなくてもClassNotFouondExceptionとか発生しない。

で、何のために使用するかといえば、主な利用方法は以下の感じです。

  1. (実行時に利用できる)メモやコメント
  2. コンパイル時にチェックや制約を行なう(ための印)
  3. クラスやメソッドなどの実行時に処理を行なう(ための印)

さらに言及すると、所詮は印なので、後からその印に対して何か処理するやつがいて初めて利用できるということです。

...これまた当たり前なんですけどねw

JavaEE5のプログラミングをすれば、なんでもかんでもアノテーションで記述できてしまいますが、コンテナがアノテーションの処理(DI)をやってくれることで初めて利用できています。スタンドアローンで実行してもアノテーションを処理してくれるやつがいないので、何もおきません。
(コンテナの外(スタンドアローン)でユニット・テストしたいのであれば、アノテーション処理を他で行なってやれば実行できるわけです。 )

他の例では、最近blogに書いてみたBeanValidationのValidatorなんかもアノテーションを処理するやつです。

次に、アノテーションの処理タイミングについて考えてみます。概ね、以下のタイミングでしょうか。

  1. 初期化時
  2. 実行時
  3. 終了時

1.の例は、コンテナがDIを行なう時などです。Instrumentationを利用してmain実行前に処理するのも良いかもしれません。
Unitテストであれば、setUp時に処理を書いておいても良いと思います。

2,3.で最も相性の良い例は、アスペクトを織り込むことです。
Unitテストなどコンパイル済みのクラスを修正せずに行なうのであれば、Spring AOPを利用するのでも良いし、クラスを修正を伴うのであれば、AspectJでコンパイル時に織り込んでも良いと思います。

というか、実行時にアノテーションを処理するのであれば、選択肢はアスペクト(EJBのインタセプターなども含む)以外は考えられません
アスペクトとアノテーションの組み合わせはこれ以上ないほどに相性が良い、最強コンボです

おいらが考える、アノテーション+アスペクトを利用した場合のメリットとしては、「メインロジックから共通の処理(ロギング、バリデーションなど)を排除できる」に尽きると思います。
その副次的な効果として、コード量が減り、コードがシンプルになると思います。

ただ、これだけであれば、アスペクトだけでも十分効果が得られます。
しかし、アスペクトを用いてみれば解るんですが、ソースを見ただけではアスペクトを織り込んだ場所がわかり難く、意外とメンテナンス性が悪かったり、織り込み忘れが発生したりします

でも、アノテーションを用いていれば、ソースからもどこにアスペクトを織り込んだか判りやすく、またアスペクトを織り込む箇所を柔軟に指定することができます。
まさにアノテーションは、アスペクトの痒いところに手が届くためのようなものなんです。

で、結局のところ、JavaEE5やSpringなどでアノテーションを利用しているだけであればそれでも良いんですが、一歩進んで、自作アノテーション(+アスペクト)を利用するというのも非常に楽しいです。

posted by aki at 20:27| Comment(0) | TrackBack(0) | コンピュータ | このブログの読者になる | 更新情報をチェックする

2009年06月17日

GlassFish V3 previewを試してみた

Eclipse のGlassFish Pluginを最新版にし、GlassFish V3 preview(build 50)を試してみた。

JavaEE6のRIということもあるけど、今年のJavaOneのデモでOSGiの効果を目の当たりにしたんで、実際触ってみたかったんだよね。

あと、EJB 3.1+JerseyでEJBをリソースにして、AtmosphereのAjaxPushと組み合わせたり...etc

で、触ってみると、

まず、GUIインストーラができてるのが良いですね。
GUIインストーラのプロジェクトがあったのは知ってたけど、思った以上に良い感じです。

で、起動すると、ものの数秒で起動しました。停止なんか一瞬です!
余分なものをインストールしていないからというのもあるけど、この軽さを体感すると、いままでのバージョンに戻るのが嫌になりそうです。

管理コンソールについては、preludeのときみたいに不安定でなくなっている。
ただし、preview版だえあって、いくつかの設定メニューがなくなっており、JMSの設定ができない
インストールされている構成を見ると、OpenMQとか含まれているので、普通に使えるようだ(未確認)。
設定とかは、V2.1と同じ内容らしいので、domain.xmlを直接いじれば良いらしい。

あと、UpdateToolが管理コンソールに統合されていて、使う分には楽になってます。

ここまではかなりの好評価でしたが、「これはイケル」...と現在開発しているアプリケーションをV3にデプロイしたところ、V2.1で問題なかったアプリケーションのデプロイに失敗してしまった。

時間があったら詳細ログを取得してMLに投稿してもいいんだけど、今はあんまり暇ないし...。

ちょっと粘ってみたけど、この状況は変わりそうにないので、まぁ今回はこんなもんかな。定期的に最新ビルドをチェックしようと思います。

いま、デプロイ時間が長くなってきたので、ちょっと開発効率が落ちている。V3で少し楽になるかなと思ったけど、この状態だとJavaRebelの導入を真剣に考えてしまう。
ちょっと今の段階で仕事の開発プラットフォームとして使用するのは時期尚早でした。

それはそうと、V2.1でカスタムレルムを利用していたんですけど、LoginExceptionクラスのパッケージが変わっているため、V2.1までとV3以降ではレルムのクラスをそれぞれ用意しないといけない。パッケージ的にはV3の方が素直な名前なんだけど、互換性がなくなるのはちょっとやだったな。(まぁ自分だったら、互換性無視して変えてしまうけどねw

posted by aki at 18:11| Comment(1) | TrackBack(0) | コンピュータ | このブログの読者になる | 更新情報をチェックする

2009年06月15日

ListやMapの要素変更を忘れてた

前回、AspectJのサンプルでエンティティクラスに対するバリデーションを書いてみて、ListやMapなどに@Validアノテーションが付加されている場合、それらのListやMapにオブジェクトを追加するときにもJoinPointを設けてバリデーションしないとだめだよなぁ...と気付いてしまったorz

で、考えてたんですが、

@Pointcut(value = "call(boolean java.util.List.add(*)) && within(@javax.persistence.Entity *)") 
public void addList() {
}

とかやると、関係のないListのaddにアドバイスを織り込むし...結構めんどくさい。

いろいろ考えた末、args()やthis()などで対象のエンティティクラスを絞り込んで、バリデーションのロジックを分けた方が良いかなぁ。 (内部でinstanceofを実行して処理を振り分けるのはやだし)

@Before(value = "addList() && this(parent) && target(list) && args(child)") 
public void addProjectWork(JoinPoint jp, ParentEntity parent, List list, ChildEntity child) { 
    ... 
}

こうすれば、ParentEntityクラスのChildEntityリストに対するadd()のみにアスペクトを織り込むことができそうだ。

メインロジックからバリデーションの記述を分離できるけど、すべてのエンティティクラスについてのケースを記述しなくてはいけないから、結構めんどくさいのに気付いた。

でも、コード自体は非常に見易く、メンテしやすいのはグッときます。

ただし、ちょっと気になったのが、Beanのフィールドに値をセットするごとにバリデーションを行なうので、パフォーマンスがちょっと心配です。
コンストラクタでオブジェクトを作るだけで、下手すると10回ぐらいバリデーションかけるから、大量にインスタンスを生成するときがちょっと怖い...かといって、executionやcallでメソッドにアスペクトを織り込むと、フィールドに定義してあるBeanValidationのアノテーションが利用できないから、1メソッドごとにバリデーションの処理を書いてやらなきゃいけない...

...

うむ、祈ろう
(1フィールドに対するバリデーションなんて、きっとそんなにオーバヘッドではないよ〜)

posted by aki at 18:56| Comment(2) | TrackBack(0) | コンピュータ | このブログの読者になる | 更新情報をチェックする

2009年06月12日

BeanValidation(JSR-303) with AspectJ5

またまたしばらく音沙汰なくなっておりご心配掛けておりますが、おいらは元気です(多分)。
と、魔女宅のパクリでごまかしてみましたが、少しゆとりが出てきたと思い込んでblog再開してみました。

今日は久しぶりにお仕事関連でちょっとしたメモです。(興味のない方はスルーしてくださいな)

で、テーマはバリデーションをAOPで挿入してしまおうという試みです。

バリデーション(JavaBeans)するタイミングは、大体以下のパターンです。

  1. Beanを何かのメソッドに代入するとき
  2. 実行結果としてBeanが返ってくるとき
  3. Beanに値を代入するとき
  4. なんかキリの良いタイミング(←身もフタもねぇ)

まぁ、最後のは放っておくとして、このバリデーションをAOPで実現すると、ビジネスロジックがすっきりしてよい感じです。

 

1.Beanを何かのメソッドに代入するとき

メソッドをPointcutに指定し、アスペクトの@Beforeでバリデーションを掛ける。

@Aspect
public class InputCheck1 {
    private static Validator validator = javax.validation.Validation.buildDefaultValidatorFactory().getValidator();

    @Before("execution (メソッドの指定)")
    public void before(JoinPoint jp) {
        for (Object obj : jp.getArgs()) {
            Set violations = validator.validate(obj, obj.getClass());
            if (!violations.isEmpty()) {
                throw new ConstraintViolationException(violations);
            }
        }
    }
}

 

2.実行結果としてBeanが返ってくるとき

1.と同じことを@Afterで行なえばよいです。(略)

 

3.Beanに値を代入するとき

この場合、AOPのPointcutは以下のパターンがあると思われます。

@必ずsetterを通してのみ値を変更する場合はsetterをPointcutに指定する。
Aそうじゃない場合、フィールド単位でPointcutを指定(setを使用)する。

細かく指定するなら@だけど、一括で指定し、使用方法を強制するならAが楽かな。

上記のパターンでPointcutを指定し、@BeforeでValidator#validateValueを実行し、入力値がフィールドの制約に違反していないかを検証すれば入力前バリデーションの出来上がりです。バリデーションの結果としてConstraintValidation(のSet)が返されたら、適当にメッセージを作成し、IlleagalArgumentExceptionでも投げてしまえばよいかな。

以下の例はエンティティクラスにBeanValidation制約を掛けたときの例

@Aspect
public class InputCheck2 {
    private static Validator validator = javax.validation.Validation.buildDefaultValidatorFactory().getValidator();

    @Before("set (@javax.validation.constraints.* * @javax.persistence.Entity *.*)")
    public void before(JoinPoint jp) {
        FieldSignature signature = (FieldSignature)jp.getSignature();
        Class<?> cls = jp.getTarget().getClass();
        Object arg0 = jp.getArgs()[0];
        Set<?> violations = validator.validateValue(jp.getTarget().getClass(), signature.getName(), arg0);
        StringBuffer sb = new StringBuffer();
        for (Object e : violations) {
            sb.append(sb.length() > 0 ? ", " : "" + ((ConstraintViolation<?>)e).getMessage());
        }
        if (sb.length() > 0)
            throw new IllegalArgumentException("[" + cls.getSimpleName() + "#"+ signature.getName() + "(value=" + arg0 + ")] " + sb.toString());
    }
}

アノテーション最高です。(^^

ただし、実装ライブラリ(おいらはHibernateValidationを使っている)のLoggerの設定しなくてはいけないのがめんどい...どうせ適当な例外を返すからログはどうでも良かったんだけどな...。

posted by aki at 18:39| Comment(1) | TrackBack(0) | コンピュータ | このブログの読者になる | 更新情報をチェックする
×

この広告は1年以上新しい記事の投稿がないブログに表示されております。