Ver 0.8.1 リリース

Ver 0.8.1をリリースしました。
BugFixを含め、ちょっとした機能も一緒に盛り込んだので
ここでも少し書き留めておきたいと思います。


1. Config(Properties)系の値に変数が利用可能になりました。
 ${hoge}形式の変数を利用することが出来るようになり、
 ${contextPath}/imageScaler
 というようなパスの設定が可能になりました。
 変数自体は
 ・MobyletFilterのInitParameter
 ・ServletContextのAttribute
 ・SystemProperties
 という順序で存在チェックが走り、指定したキー情報があれば置換します。
 その中でも${contextPath}は予約語として指定されていますので
 Tomcat6等、ServletAPI2.5以上のWASであればcontextPathを探索します。
 それ以下のWASの場合はInitParameter等に手動で設定の必要があります。


2. HTML/XHTMLのContentType切り替え
 携帯でHTML/XHTMLを切り替える場合はContentTypeも異なり
 ・HTML: text/html
 ・XHTML: application/xhtml+xml
 となります。
 デフォルトはHTMLで動作しますが(mobylet.xmlでデフォルトを変更可能)
 MobyletFactory.getInstance().setContentType()メソッドで
 個別にConetntTypeを切り替えることが出来ます。
 #ただし、レスポンスボディ情報を返却する前にメソッドコールの必要有り


3. istyleの指定
 というタグリブが仲間入りしました。
 このタグリブはで囲んだ中身の情報をラップするもので
 <input type="text" />
 とすると
 中身のinputタグにキャリア別のistyle系属性が付与されます。
 ちょっと変わった作りですが、
 Struts等を考えるとこの形が融和性が高いと思った判断です。
 #istyle(Docomo)の値で指定すると良い感じにキャリア別に変換します




だんだん充実してきたので
このままのペースで1.0.0まで突っ走りたいですね。

早速問題がありました。

竹内(stakeuchi)です。
長野の高原に合宿(避難)していたので東京が非常に暑いです。
避暑地に行くと、一瞬ブルジョワ気分が味わえるところが良いですね。


さて、0.8.0リリースした直後ですが
先ほど0.8.1-SNAPSHOTをリリースしました(core/s2extension)
#近日中に0.8.1をリリースしたいと思っています。


POSTでリクエストが飛んで来た場合に
パラメータ情報が取得出来ない問題があったのでこれを解決したのが大きな修正です。

最近GAE/Jでの確認が主だったので色々なWASで確認していなかった不注意での障害です。
トレンドに流されないように気をつけないといけないですね。


あとはリクエストのあった便利機能がちょっと増えました。
現時点で0.8.1修正した内容はこちら。
https://www.seasar.org/issues/browse/MOBYLET-26
https://www.seasar.org/issues/browse/MOBYLET-27
https://www.seasar.org/issues/browse/MOBYLET-28



特にMOBYLET-26は結構便利な気がします。
shinsukeさん、リクエスト有難う御座いました!

mobylet ver.0.8.0 リリース

竹内(stakeuchi)です。

一部の仕事でいわゆる火消し的な活動をしているため
ちょっと多忙を極め始めているこの頃ですが
ver 0.8.0をリリース致しました。


#コメントのお返事はもうちょいお待ちください。。。
#すいません。


何はともあれ
JVMパラメータを設定したり、エクステンションディレクトリに配置しなければいけなかった
mobylet-charset-xxx.jarを普通のjarと同じように
WEB-INF/lib配下に配置しても動作するようになりました。


あと画像変換ロジックのバグもちょこちょこ直したりしまして
段々皆様に使っていただけるものになってきたかな、
というところです。



これから合宿なので
来週はじめあたりに落ち着いてブログも書こうと思います。

Google App EngineのBootstrap仕様が変わった?

最近またGAE/Jと戯れているのですが
どうも変です。
絵文字を含むmobylet文字コードが機能していないように見えます。。。


色々とやってみたのですが
やはり機能していないので
どうもappsdk1.2.2が出たタイミングくらいで
Jettyの起動方式も変わったのではないか?と推測しています。


実際、ホントに変えられていて
SystemClassLoaderからcharsetのjarが読み出されなくなると
mobylet+GAE/Jとしては非常に相性が悪くなるので
もし、どうしようも無かったら非常に残念です。。。


なんとか出来ないか
色々探ってみたいと思います。

[T2 framework] mobylet+T2(+Guice)@Google App Engine for Java

T2Frameworkmobyletを組み合わせてGAE/Jで構築を試みて下さっている方からコメントを頂いた関係で
今日は合間を見つけながらT2+mobyletで格闘してみました。


T2の存在は知っていたのですが
使ったことが無かったので「どんなフレームワークなんだろうなぁ?」と思ったままの状態で
今日はじめて使って、個人的にかなりヒットしました。


というのも、T2の持つ一番小さくて大きな機能だと思う
URLとPageクラスのマッピングという処理のようなもの(REST風解決を図れるもの)を
mobyletに組み込もうかどうしようか、迷っていたところだったので
(この時点ではT2のこの機能を知らない訳では無かったけど、もっと大きなフレームワークだと勘違いしていた)
渡りに船のようなフレームワークに感じました。


GAE/Jを使っている関係上
T2(Lucy)を使った場合にjavax.xml.stream.XMLInputFactoryクラスが制限クラスになっていて
GAE/Jで動かないという問題にはまってしまいましたが(回避策あるのかな?)
Lucyの代わりにGuiceを使うことでさくっと解決しました。


(参考)
http://shin1o.blogspot.com/2009/04/gaejavat2-framework.html


まずは今回実装したサンプルサイト(画像リサイズだけです)
http://mobylet-example-t2gae.appspot.com/resize/


このexampleプロジェクトのリポジトリ
https://www.seasar.org/svn/sandbox/mobylet/trunk/mobylet-example-t2gae/


多分、ポイントはweb.xmlの書き方で
mobyletとT2でResponseの出力部分で少し競合している箇所があるようなので
Forward.toを使う場合にMobyletFilterのdispatch設定が必要になるようです。

                  • -


mobyletFilter
org.mobylet.core.http.MobyletFilter

mobylet.config.dir
WEB-INF/resources/



Guice Servlet Filter
com.google.inject.servlet.GuiceFilter



t2
org.t2framework.t2.filter.T2Filter

t2.rootpackage
org.mobylet.t2gae.page


t2.container.adapter
org.t2framework.t2.adapter.GuiceAdapter


t2.exclude-resources
css, js



mobyletFilter
/*
REQUEST
FORWARD



Guice Servlet Filter
/*



t2
/*

                  • -


あとはほぼ通常の設定と変わらない感じでいけるみたいです。



個人的にはSAStrutsのような大き目のフレームワークも好きですが(ちょっと大きめのサイト作る時とか)
GAE/Jでスモールスタートで作ってみよう!って時には
T2のような軽い感じのフレームワークは非常に良いですね。


今度は実際のサービスにも使ってみようと思います。

mobylet-0.7.0 リリース

お疲れ様です、竹内(stakeuchi)です。
最近またひとつ歳を取ったのですが
だんだんと老化を感じてきました。。。


運動しなきゃと思いながらも出来ない日々が続いています。
この業界でちゃんとジム行ったりスポーツしている人を見ると超人にさえ思えてしまいます。
深夜5時くらいまで開いているジムがあれば良いのに。



さて、表題の通りmobylet-0.7.0がリリースされました。
色々と新しい機能が増えているのですが
大きなところは以下のようなところでしょうか。


文字コードのバグ修正(とけびさんありがとう!)
・画像変換方式の追加(正方形クリッピングとか)
JSP依存の解消(表出側の動的ロジックをcoreに寄せた)



潜在的なところ(内部のクラス構成やI/Fなど)は結構変わっていて
特に画像の変換処理やキャッシュ機構は出来るだけ疎結合になるように変更しました。


これによって今後は画像変換部をJMagick(ImageMagick)に置き換えたり、
キャッシュ部分をMemcachedに置き換えたりということが可能になるので
0.8.0へ向けて、このあたりのextensionの拡充も行って行きたいと思っています。
#GAE/Jのextensionでは既にMemcachedへキャッシュする実装になっています。



もうすぐ実際にmobyletを使用したサイトも公開できると思うので
そちらを見ていただけたら「mobyletの使いどころ」がより理解していただけるような気がしています。



また、要望や障害など御座いましたら
どしどしお寄せください。
大歓迎体制でお待ちしています!

Google App Engineで画像処理とか変換とか

お久しぶりです、竹内(stakeuchi)です。
ブログは久々に書いてます。


このところmobyletの実装にやっきになっていたのですが
特に最近mobyletに搭載していた機能は
・色々な画像変換パターン
Google App Engineでのキャッシュ機能
というところでした。


今日は特に新機能(0.7.0搭載機能)のお話と
Google App Engineでの実装内容を書いてみます。


まず、新機能が画像変換パターンの追加になります。
今までは、特にブラウザ幅に合わせてリサイズできます。
というものだったのですが
身近なところから
「横長の画像と縦長の画像で出来上がりの画像の面積が違うのが嫌だ」とか
「正方形のサムネイル(画像の真ん中をくり抜いた)は出来ないの?」とか
そんなリクエストがあったので追加しました。


カスタムタグでやろうとすると

みたいにやっていたところを

とすると正方形のサムネイルが作れるようになりました。

とすると、縦長画像でも同サイズの画像になります。
(横幅ベースの正方形におさまる画像サイズに変換するという意味です)


これをやろうとしたとき、特に正方形くり抜き画像の作り方なのですが
Google App EngineのImage APIの仕様があまり公開されていないので
実際にEclipseでメソッドを検索しつつ、実装してみました。


JavaのImageAPIを利用した場合は
BufferedImage#getSubimage()
メソッドを使えば切り抜き画像を取得するのは簡単なのですが
Google App EngineのImageAPIを利用する場合は
ImagesServiceFactory#makeCrop()
メソッドを使用して実現出来ます。


さらにこのmakeCrop()メソッドは
double leftX, double topY, double rightX, double bottomY
の4つの引数を持っていて
何でdouble型?と思っていたのですが普通にpixel単位での座標を入れるとOUT!
実は縦横の幅を「1」とした0〜1の間の相対値を指定するというユニークなメソッドということが判明。


例えば画像を均等に十字に切った、右下の画像を取りたい場合は
makeCrop(0.5, 0.5, 1.0, 1.0)
となります。
なかなか面白い関数だなぁと個人的にはヒットしました。



また、Google App Engine用のmobylet-extensionライブラリに画像のキャッシュ機能も追加して
Memcachedを利用するようにして実装しました。


#試験的にJDOを使ってBigtable上にキャッシュするパターンも試してみたのですが
#見事に粉砕されました。(最近これに悩まされてブログもかけなかったのです)
#画像のリクエストで処理する形になるのでサーバ上ではマルチスレッドでBigtableにアクセスする形となり
#そのあたりとdetachableにしたりしなかったりとか、ごちゃごちゃしちゃって
#上手くいかず(1パターンしかコミットされない)、迷宮入りです。。。


Memcachedは使ったことあるのですがGAE/Jだと簡単に使えすぎて怖いくらいです。

        • -

//キャッシュクライアントを生成
Cache cache = CacheManager.getInstance().getCacheFactory().createCache(Collections.emptyMap());

//キャッシュにデータ投入
Object key = "key";
Object data = "data";
cache.put(key, data);

//キャッシュからデータ取得
data = cache.get(key);

        • -


うーん。非常に簡単ですね。
JavaのMapくらい簡単に使えます。


実際の速度面に関して
mobyletの標準実装ではHTTPで画像の最終更新日時をHEADで叩いてから処理するので
どうもそこのコストがちょっと高いのか
そもそもの通信コスト(サーバまでの距離とか間のルータの数とか)が高いのかで
あんまり早くないなぁというのが実感です。
#逆にGAE/JのImageAPIは結構処理が速い気がする。


とはいえ、GAE/Jで設定されている無料で使える範囲で考えると
ImageAPIを毎回叩いているとすぐ有料になっちゃいそうなので
Memcachedでcacheした方が良さそうな気はします。
Memcachedへのアクセス回数も多くなると有料モードに突入します)




まもなく0.7.0はリリースできると思いますが、
このバージョンでやっと実用出来るものになってきたかな
という感じはあります。

今だとちょっとJSP依存になっている部分がある(taglibありきな感じ)ので
ここを0.7.0で切り離すか0.8.0でやるかで迷っているところです。

あとはslim3+mobyletとか、Ymir+mobyletとか
ちょっとやってみたいですね。