<?xml version='1.0' encoding='UTF-8'?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/'><id>tag:blogger.com,1999:blog-4008248627112177435</id><updated>2008-07-19T10:25:20.187+09:00</updated><title type='text'>STBBS.NET blog</title><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default?start-index=26&amp;max-results=25'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default'/><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>230</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-5507983628298567393</id><published>2008-07-19T01:21:00.006+09:00</published><updated>2008-07-19T10:25:20.205+09:00</updated><title type='text'>Springと一緒に Wicketを使う</title><content type='html'>我が社は主に Flexと BlazeDSを用いた RIAに注力している。このプラットフォームを用いる場合、サーバ側ではほぼ純粋にビジネスロジックを提供するだけで良いため典型的なMVCタイプの Webアプリケーションよりもさらに分業が容易であるという利点がある。&lt;br /&gt;&lt;br /&gt;しかしながら、常にユーザの環境が RIAに適しているとは限らないし、「文書を読ませる」機能に関して言えばそれを Flash Player上に実現した場合あまりユーザにとって快適とは言い難いものになる可能性が高い。&lt;br /&gt;&lt;br /&gt;などの理由から、従来通りHTMLで表現される Webアプリケーションを実装する場合も少なからずあるため、近頃先進的な向きに人気の高い Wicketを調べてみた（むろん、同様の目的には Spring MVCや Struts2を使っても良いのだが）。&lt;br /&gt;&lt;br /&gt;ここでは、既に Spring Frameworkが Webアプリケーションに導入されていることを前提に Wicketを動作させるために必要な最低限のセットアップを行う手順を示す。&lt;br /&gt;なお、アプリケーションに BlazeDSが既に導入されている場合でも共存が可能であることを確認している。&lt;br /&gt;&lt;br /&gt;WEB-INF/lib に設置した jarファイルは下記の通り。&lt;br /&gt;&lt;br /&gt;wicket-1.3.4.jar&lt;br /&gt;wicket-ioc-1.3.4.jar&lt;br /&gt;wicket-spring-1.3.4.jar&lt;br /&gt;wicket-spring-annot-1.3.4.jar&lt;br /&gt;slf4j-api-1.5.0.jar&lt;br /&gt;slf4j-jcl-1.5.0.jar&lt;br /&gt;&lt;br /&gt;slf4jについては好きな実装を用いて良いと思うが、Springが前提であれば Commons Loggingが存在するはずなのでここでは slf4j-jclを用いている。&lt;br /&gt;&lt;br /&gt;必要なライブラリを追加したら、web.xmlに Wicketの設定を追加する。Wicketはサーブレット又はサーブレットフィルタとして適用することが出来るが、後者が推奨されているようだ。&lt;br /&gt;&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;filter&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;filter-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;wicket&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/filter-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;filter-class&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    org.apache.wicket.protocol.http.WicketFilter&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/filter-class&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;init-param&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;param-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;applicationFactoryClassName&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/param-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;param-value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      org.apache.wicket.spring.SpringWebApplicationFactory&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/param-value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/init-param&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/filter&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;filter-mapping&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;filter-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;wicket&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/filter-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;url-pattern&amp;gt;&lt;/FONT&gt;&lt;/B&gt;/*&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/url-pattern&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/filter-mapping&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;br /&gt;典型的な Wicketアプリケーションを構成する要素は、ひとつの WebApplicationクラスと ページ数分の WebPageクラス（とそれぞれに対応するHTMLファイル）である。&lt;br /&gt;applicationFactoryClassNameに SpringWebApplicationFactoryをセットすることで、Wicketは Springの applicationContext.xml内に定義されている Beanの中から WebApplicationのインスタンスを選び出して自動的に用いるようになる。&lt;br /&gt;（そのため、ことSpringを用いる場合は web.xmlにWebApplicationの実装クラス名を直接書き込む必要がない）&lt;br /&gt;&lt;br /&gt;この設定では、Webアプリケーションに対する全てのリクエストが Wicketのフィルタに一旦渡されるが、Wicketは自身の守備範囲でない URIへのリクエストをスルーするため、画像などのリソースや他のサーブレット（BlazeDSの通信エンドポイントもそうだ）に対するリクエストを妨害されることはないようだ。&lt;br /&gt;&lt;br /&gt;さて、最小限の WebApplicationはこのような実装になる。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;package&lt;/FONT&gt;&lt;/B&gt; net.stbbs.wicket;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;import&lt;/FONT&gt;&lt;/B&gt; org.apache.wicket.spring.injection.annot.SpringComponentInjector;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; WebApplication &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;extends&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    org.apache.wicket.protocol.http.WebApplication {&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;void&lt;/FONT&gt;&lt;/B&gt; init()&lt;br /&gt;  {&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;super&lt;/FONT&gt;&lt;/B&gt;.init();&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;this&lt;/FONT&gt;&lt;/B&gt;.addComponentInstantiationListener(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;new&lt;/FONT&gt;&lt;/B&gt; SpringComponentInjector(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;this&lt;/FONT&gt;&lt;/B&gt;));&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  @Override&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; Class getHomePage() {&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;return&lt;/FONT&gt;&lt;/B&gt; HomePage.&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt;;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;Springと統合するために、initメソッドに対し addComponentInstantiationListenerの呼び出しを追加している。これによって、WebPageクラスのインスタンスが生成される際にはアノテーションに従って自動的にフィールドインジェクションが行われるようになる。例えばこのように。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; HomePage &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;extends&lt;/FONT&gt;&lt;/B&gt; WebPage {&lt;br /&gt;  @SpringBean(name=&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;helloService&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;private&lt;/FONT&gt;&lt;/B&gt; HelloService helloService;&lt;br /&gt;  :&lt;br /&gt;  :&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;上記の例ではアノテーションのパラメータとして name を渡しているが、型の合致するBeanがアプリケーションコンテキスト内にひとつしか無い場合は省略しても良い。&lt;br /&gt;&lt;br /&gt;WebPageオブジェクトのライフサイクルは Wicketの管理下にあり Springのそれとは一致しないが、WebPageオブジェクトにフィールドインジェクションされた Beanは実際には適切に自動生成されたプロキシであり、これによりライフサイクルの差異は吸収されるらしい。&lt;br /&gt;&lt;br /&gt;インジェクションの対象となるフィールドには初期化の記述をしないように注意すること（例えば private HelloService helloService = null; のように）。インジェクタはフィールドの初期化処理よりも前に走るため、フィールドの初期化を記述するとそれで上書きされてしまうそうだ。&lt;br /&gt;&lt;br /&gt;あとは Wicketの作法に従って WebPageクラスと HTMLファイルを必要なだけ作ることで UIを構築していけば良いだろう。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/07/spring-wicket.html' title='Springと一緒に Wicketを使う'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=5507983628298567393' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/5507983628298567393'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/5507983628298567393'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-7633693611938986486</id><published>2008-07-13T22:53:00.011+09:00</published><updated>2008-07-15T22:30:36.999+09:00</updated><title type='text'>Windows XP Professionalをマルチユーザー仕様に改造する</title><content type='html'>ここで紹介するハックはマイクロソフトのEULAに抵触する可能性が高いため、あくまで海外サイトから得た情報を参考までに紹介するに止めるうえ、上級者向けに必要最低限の内容のみ掲載する。情報を利用した結果ついて当方では一切の責任を負うことができないので、各自自己責任のもとで行って頂きたい。&lt;br /&gt;（なおこのネタ自体は 2006年頃から存在するようだが、要点だけまとめた日本語の情報が他に見あたらなかった）&lt;br /&gt;&lt;br /&gt;Windows XP Professionalはリモートデスクトップクライアントを用いることで離れた端末からネットワークを通じてログインし、利用できる。しかしながら、同時に利用することが可能なセッションはローカル・リモート合わせてひとつだけである。つまり、誰かがリモートからログインしようとするとその WinXP Proマシンを操作中のユーザはログアウトを迫られる。&lt;br /&gt;&lt;br /&gt;複数のユーザが同時にログインしてオペレーティングシステムの機能を利用することは、UNIXやその派生OSでは当たり前に出来ることであるが、Windows（サーバ向け除く）はそのマーケティングにおける性質上、「技術的には出来るけど、出来ないようにしてある」といったところだと思われる。実は以前 Windows XP SP2でこの制限が緩和され同時に2セッションまで利用出来るようになるという噂が流れたのだが、これはガセネタだったようだ。&lt;br /&gt;&lt;br /&gt;ここからが本題である。この制限は、&lt;strong&gt;termsrv.dll という DLLを3バイト書き換え、いくつかのレジストリ項目を登録し、グループポリシーを修正することで外すことが出来る&lt;/strong&gt;。&lt;br /&gt;&lt;br /&gt;termsrv.dllは Windowsフォルダ以下の system32,  ServicePackFiles/i386, system32/dllcache にそれぞれ存在している可能性がある（環境によってそれぞれ存在してしていたりしなかったりするようだ）。そこにある全ての termsrv.dllに対し、下記のような書き換えを行う（全て同じ内容のはずなので、1個書き換えてコピーすれば良い）。&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;0x00022A17&lt;/strong&gt;&lt;br /&gt;0x74を、0x75に変更&lt;br /&gt;&lt;strong&gt;0x00022A69-0x00022A6A&lt;/strong&gt;&lt;br /&gt; 0x7F 0x16を、0x90 0x90に変更&lt;br /&gt;&lt;br /&gt;もちろん Windows XP Professionalが通常起動した状態では、このDLLを書き換えることは出来ない。セーフモードをうまく使うか、一旦 Linuxでブートして書き換えるなどの方法があるだろう。ここでは詳しい説明を省くが、セーフモードを使う方法については下記サイトに含まれている。&lt;br /&gt;&lt;a href="http://www.mydigitallife.info/2008/06/13/enable-multiple-concurrent-remote-desktop-connections-or-sessions-in-windows-xp/"&gt;Enable Multiple Concurrent Remote Desktop Connections or Sessions in Windows XP&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;DLLを書き換えたら Windows XP Professionalを通常起動し、レジストリに下記のような変更を加える。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Terminal Server\Licensing Core]&lt;br /&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]&lt;/pre&gt;&lt;br /&gt;に、それぞれ DWORD値 "EnableConcurrentSessions"を作成し 1にセットする。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]&lt;/pre&gt;&lt;br /&gt;に、DWORD値 "AllowMultipleTSSessions" を作成し 1にセットする。&lt;br /&gt;（これは環境によっては既にそうなっているかもしれない）&lt;br /&gt;&lt;br /&gt;レジストリの書き換えが終わったら、「ファイル名を指定して実行」から gpedit.msc （グループポリシーエディタ）を起動し、「コンピュータの構成」→「管理用テンプレート」→「Windowsコンポーネント」→「ターミナル サービス」まで降りていき、「接続数を制限する」設定を「有効」にし、最大接続数を好きな値にセットする。&lt;br /&gt;次にコントロールパネルから「ユーザー アカウント」→「ユーザのログオンやログオフの方法を変更する」へ降りていき、「ユーザーの簡易切り替えを使用する」をチェックする。&lt;br /&gt;&lt;br /&gt;上記で作業はおおかた終了である。リモートデスクトップをまだオンにしていないならば、「システムのプロパティ」→「リモート」からリモートデスクトップを有効にする。これで PCを再起動すれば、Windows XP Professionalが複数ユーザー同時ログイン可能な状態で動作する。&lt;br /&gt;なおコンピュータがドメインに参加している場合、書き換えたレジストリの内容が戻ってしまう問題があるらしい。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;関連記事&lt;/h4&gt;&lt;br /&gt;&lt;a href="http://www.stbbs.net/blog/2007/08/blog-post_15.html"&gt;パスワードなしのアカウントで Windows XP Professionalにリモートデスクトップ接続する&lt;/a&gt; ( 推奨はしない )&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;関連サイト&lt;/h4&gt;&lt;dl&gt;&lt;dt&gt;&lt;a href="http://www.microsoft.com/japan/mac/products/rdc/default.mspx"&gt;Remote Desktop Connection Client for Mac&lt;/a&gt;&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;Microsoftが開発・配布している Mac版リモートデスクトップクライアント。Messengerもそうだが、意外と Mac版の存在を知らない人が多い。&lt;/dd&gt;&lt;br /&gt;&lt;dt&gt;&lt;a href="http://www.rdesktop.org"&gt;rdesktop: A Remote Desktop Protocol Client&lt;/a&gt;&lt;/dt&gt;&lt;br /&gt;&lt;dd&gt;オープンソースのリモートデスクトップクライアント&lt;/dd&gt;&lt;/dl&gt;&lt;h4&gt;おまけ&lt;/h4&gt;&lt;br /&gt;Linuxでバイナリファイルを書き換える時は bvi というプログラムが便利だ。操作は viに似ており、: で行番号のかわりにアドレスを16進入力して目的のオフセットへ飛べる。ファイルを開いた時はリードオンリーモードになっているが、:set mm コマンドで書き換えが可能なモードに切り替わるので後は x や i といったように viのような使い方で書き換えを行い、終わったら :wq で上書き終了すると良い。&lt;br /&gt;&lt;br /&gt;Xenのハイパバイザ（完全仮想化）モードで運用しているバーチャルマシンの仮想ディスクに含まれているパーティションを Linuxでマウントしたい場合は、multipath-toolsに含まれる kpartxコマンドを使う。&lt;br /&gt;参考記事：&lt;a href="http://www.stbbs.net/blog/2007/08/blog-post_13.html"&gt;ディスクイメージとパーティション&lt;/a&gt;</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/07/windows-xp-professional.html' title='Windows XP Professionalをマルチユーザー仕様に改造する'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=7633693611938986486' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/7633693611938986486'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/7633693611938986486'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-3233362346324548185</id><published>2008-06-29T23:08:00.008+09:00</published><updated>2008-06-29T23:55:46.373+09:00</updated><title type='text'>ファイル型データベースをリモートで使う</title><content type='html'>普段 Macや Linuxで仕事をしている人間にとっては、Windows機で作業をするのが苦痛だ。&lt;br /&gt;しかし世の中には dBASEや Microsoft Accessで作られたデータベースというものがあって、時にはそういった「ファイル型データベース」を読み書きする仕事もあったりする。&lt;br /&gt;&lt;br /&gt;Microsoft SQL Serverのようなクライアントサーバ型データベースであれば、それがたとえ Windowsでしか動作しなくとも JDBCを使ってリモートから利用できるため手元の Macで開発作業が出来るわけだが、ファイル型データベースの場合はそうもいかない。&lt;br /&gt;&lt;br /&gt;最近 dBASEファイルをどうしても読み書きする必要があって、仕方ないので &lt;a href="http://vjdbc.sourceforge.net"&gt;Virtual JDBC&lt;/a&gt;を使って Windows機上にあるデータベースファイルをリモートからアクセス出来るようにしてみたのが下記。&lt;br /&gt;（なおWindowsには dBASEの ODBCドライバが標準で搭載されている）&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.stbbs.net/blog/uploaded_images/remote-dBASE-via-vjdbc-776642.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://www.stbbs.net/blog/uploaded_images/remote-dBASE-via-vjdbc-776640.png" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Windowsで作業したくないばかりにこんなことまでやるかという気もしないでもないが、それはさておき。&lt;br /&gt;&lt;br /&gt;(a) JDBC URLとして サーブレットのURLと vjdbcに設定したDB名を与える。&lt;br /&gt;"jdbc:vjdbc:servlet:http://my-windows-host:8080/vjdbc/vjdbc,mydb"&lt;br /&gt;&lt;br /&gt;(b) web.xmlにて vjdbcサーブレットをマッピングする。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;servlet&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;servlet-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;VJdbcServlet&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/servlet-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;servlet-class&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    de.simplicit.vjdbc.server.servlet.ServletCommandSink&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/servlet-class&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/servlet&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;servlet-mapping&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;servlet-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;VJdbcServlet&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/servlet-name&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;url-pattern&amp;gt;&lt;/FONT&gt;&lt;/B&gt;/vjdbc&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/url-pattern&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;(c) vjdbcがリクエストを転送する先となるターゲットデータベースの設定を /WEB-INF/vjdbc-config.xmlに記述する&lt;br /&gt;&lt;br /&gt;(d) (vjdbc-config.xml内) JDBC-ODBCブリッジのURLで ODBCデータソース名を指定&lt;br /&gt;"jdbc:odbc:mydbase"&lt;br /&gt;&lt;br /&gt;(e) Windowsの「管理ツール」→「ODBC」で dBASE用のデータソースを設定する（*.DBFファイルの置いてあるフォルダを指定）。データソース名は (d)で指定した物と合わせる。&lt;br /&gt;&lt;br /&gt;この構成で JDBCを使って dBASEファイルへリモートアクセスが出来るようになった。&lt;br /&gt;・・・なったのだが、トランザクション操作をしようとするとこの通り・・・&lt;br /&gt;&lt;pre&gt;java.sql.SQLException: &lt;br /&gt;[Microsoft][ODBC dBase Driver]オプションの機能は実装されていません。&lt;/pre&gt;&lt;br /&gt;Windowsに標準でくっついてるようなドライバにそこまで期待すんなということですな。&lt;br /&gt;&lt;br /&gt;ちなみに &lt;a href="http://www.csv-jdbc.com/stels_dbf_jdbc.htm"&gt;dBASEの JDBCドライバ（商用）&lt;/a&gt;もあって、5同時アクセスライセンスが 150ドルで買える。お金を取るくらいだからもちろんトランザクションもサポートしているに違いない。真面目に今後もdBASEと付き合っていく必要がある、かつ、ライセンス料を顧客に負担してもらえる場合はこれを使ったほうが無難だと思う（試してないけど）。&lt;br /&gt;&lt;br /&gt;JDBC-ODBCブリッジを使ってファイル型データベースにアクセスする用途以外でも、何らかの理由で データベースアクセスをHTTPで中継したい場合に vjdbcは役に立つだろう。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/blog-post_29.html' title='ファイル型データベースをリモートで使う'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=3233362346324548185' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/3233362346324548185'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/3233362346324548185'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-6632023774928886500</id><published>2008-06-29T14:24:00.003+09:00</published><updated>2008-06-29T15:12:01.780+09:00</updated><title type='text'>Macと Xenと VNCクライアント</title><content type='html'>Xenで動作する仮想マシンの画面を表示するインターフェイスとしては、SDLとVNCの2種類がある。&lt;br /&gt;SDLの場合、（特別な設定をしなければ）画面表示に X Window が用いられる。XなのでSSHを経由してリモートに画面を表示させることも出来るが、画面を閉じると仮想マシンも強制終了してしまうという凶悪な仕様なため主にリモートでヘッドレス運用をする場合は使えない。&lt;br /&gt;VNCと比べた場合の利点は、（ローカルマシンで画面を表示するなら）高速だろうという点である。&lt;br /&gt;&lt;br /&gt;いっぽう、VNCを使用する場合、仮想マシンごとに 5900番以降の空いているポートを用いて VNC接続の待ち受けが行われる（VMの設定ファイルでポート番号を固定することもできる）。&lt;br /&gt;リモート運用にはこれが最も適しているのだが、ひとつ重大な問題がある。&lt;br /&gt;&lt;br /&gt;Mac OS Xでまともに動く唯一のフリーな VNCクライアントである Chicken of the VNC (a.k.a. cotvnc) と Xenの VNCサーバの相性が悪く、使えないのだ（画面が全く表示できない又は乱れる、エラーで接続が切れる）。&lt;br /&gt;&lt;br /&gt;cotvncが悪いのか Xenに内蔵されているVNCサーバが悪いのか（もしくは両方なのか）知らないが、Xenのメーリングリストで「cotvncでちゃんとVMの画面が表示できないよー」という投稿が過去に一度あったものの解決されずに今に至っていることや cotvncの開発が止まっていることから、もはや状況は絶望的かと思われた。&lt;br /&gt;X over SSHを使って dom0上の vncviewerを動かすという手は使えるのだが、ものすごく遅いし受け付けてくれないキーがあったりするしたまにバグって切れたりするので絶望的な状況であることに変わりはなかったと言えよう。&lt;br /&gt;&lt;br /&gt;そんな時に現れた救世主、&lt;br /&gt;&lt;a href="http://www.redstonesoftware.com/products/vine_viewer"&gt;Redstone Software社の Vine Viewer&lt;/a&gt;&lt;br /&gt;Vineといっても昔あった Linuxのそれとは関係ないし、Windows互換レイヤのソフトウェアでもない。&lt;br /&gt;&lt;br /&gt;・XenのVNCサーバと接続できる&lt;br /&gt;・VNC over SSHサポート（出先からのアクセスも安心）&lt;br /&gt;・画面の録画ができる（QuickTime形式の動画ファイルになる）&lt;br /&gt;&lt;br /&gt;これでバーチャルマシンの管理がしやすくなるなあ。&lt;br /&gt;値段は 35ドル。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/mac-xen-vnc.html' title='Macと Xenと VNCクライアント'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=6632023774928886500' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/6632023774928886500'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/6632023774928886500'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-1723213136748279615</id><published>2008-06-25T06:14:00.005+09:00</published><updated>2008-06-25T13:30:06.005+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>SpringでJNDIを提供する 続き</title><content type='html'>&lt;a href="http://www.stbbs.net/blog/2008/06/springjndi.html"&gt;以前のエントリ&lt;/a&gt;で、XBeanの成果物を拝借して Springで JNDIを提供させる方法を示したのだが、この org.apache.xbean.spring.jndi.SpringInitialContextFactoryは Beanファクトリとして ApplicationContextのバリアントを使っていないためそのままだと PropertyPlaceholderConfigurerなどを使って Bean定義ファイル内の値をパラメタ化することが出来ない。&lt;br /&gt;（ApplicationContextの子孫は、BeanFactoryPostProcessorを自動処理するのだが、それ以外の BeanFactoryではプログラムコードで明示的に postProcessBeanFactoryを呼んでやらなければ処理されない）&lt;br /&gt;ApplicationContextはあくまで「アプリケーションの」コンテキストであるため JNDIの提供に適用しない事自体は正しいと思うが、せめてpostProcessBeanFactoryを呼んで欲しいところだ。&lt;br /&gt;&lt;a href="https://issues.apache.org/activemq/browse/SM-237"&gt;この問題（？）は2005年に報告されている&lt;/a&gt;が完全に無視という形のようだ。こんなのただの副産物だから本来の用途にさえ使えればよくてそれ以外興味ないねということだろうか。&lt;br /&gt;&lt;br /&gt;仕方がないのでSpringInitialContextFactoryの派生クラスを作って BeanFactoryの生成を行っているメソッドをオーバーライドし、postProcessBeanFactoryの呼び出しを追加することにした。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;package&lt;/FONT&gt;&lt;/B&gt; net.stbbs.xbean.spring.jndi;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;import&lt;/FONT&gt;&lt;/B&gt; java.util.Map;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;import&lt;/FONT&gt;&lt;/B&gt; org.apache.xbean.spring.context.impl.XBeanXmlBeanFactory;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;import&lt;/FONT&gt;&lt;/B&gt; org.springframework.beans.factory.BeanFactory;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;import&lt;/FONT&gt;&lt;/B&gt; org.springframework.beans.factory.config.BeanFactoryPostProcessor;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;import&lt;/FONT&gt;&lt;/B&gt; org.springframework.core.io.Resource;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; SpringInitialContextFactory &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;extends&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    org.apache.xbean.spring.jndi.SpringInitialContextFactory {&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;protected&lt;/FONT&gt;&lt;/B&gt; BeanFactory createContext(Resource resource) {&lt;br /&gt;        BeanFactory factory = &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;super&lt;/FONT&gt;&lt;/B&gt;.createContext(resource);&lt;br /&gt;        Map&amp;lt;String,Object&amp;gt; postProcessors = &lt;br /&gt;          ((XBeanXmlBeanFactory)factory)&lt;br /&gt;            .getBeansOfType(BeanFactoryPostProcessor.&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt;);&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;for&lt;/FONT&gt;&lt;/B&gt; (Map.Entry pp:postProcessors.entrySet()) {&lt;br /&gt;          ((BeanFactoryPostProcessor)pp.getValue())&lt;br /&gt;            .postProcessBeanFactory((XBeanXmlBeanFactory)factory);&lt;br /&gt;        }&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;return&lt;/FONT&gt;&lt;/B&gt; factory;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;jndi.propertiesは&lt;br /&gt;java.naming.factory.initial=org.apache.xbean.spring.jndi.SpringInitialContextFactory&lt;br /&gt;を&lt;br /&gt;java.naming.factory.initial=net.stbbs.xbean.spring.jndi.SpringInitialContextFactory&lt;br /&gt;に書き換えた。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/springjndi_25.html' title='SpringでJNDIを提供する 続き'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=1723213136748279615' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/1723213136748279615'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/1723213136748279615'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-3656587894519210895</id><published>2008-06-25T03:19:00.005+09:00</published><updated>2008-06-25T04:14:20.447+09:00</updated><title type='text'>DbUnitでテーブルをエクセル出力する</title><content type='html'>&lt;a href="http://www.stbbs.net/blog/2008/06/spring-dbunit.html"&gt;以前のエントリ&lt;/a&gt;で、DbUnitを使ってフィクスチャによるデータベース事前条件の定義を含むユニットテストを行う方法を示した。&lt;br /&gt;&lt;br /&gt;事後条件については、ターゲットとなるメソッドの実行が完了した後にSimpleJdbcTemplateなどでデータベースに対しクエリを行うことでチェックすることが出来る。理想としてはそのようにしてプログラムコードだけで事後条件を自動的に検査出来るほうが良い。よく練られた多角的なテストケースが存在することにより、プログラムは修正作業によるエンバグの発生から逃れやすくなるだろう。&lt;br /&gt;&lt;br /&gt;しかし、テストケースに山のような数のselect文やループ構文を記述している時間が惜しい時があるのも事実だ。人間が表の状態を視覚的に確認することで、（ミスの検出確率は下がるものの）事後条件のチェックにかかる時間が節約出来ることも多々ある。&lt;br /&gt;&lt;br /&gt;ところが、基本的にフィクスチャを用いるユニットテストは各テストメソッドの実行が１つのトランザクションとなっており、成功にせよ失敗にせよテストの完了時にトランザクションはロールバックされてしまいデータベース上のテーブルは空に（正確にはテスト実行前の状態に）戻ってしまうため、テストの実行後に GUIのフロントエンドなどを用いてデータベースの内容を確認しようとしても無駄である。&lt;br /&gt;&lt;br /&gt;DbUnitには、テーブルの内容をファイルにダンプする機能があるので、それをテスト中の任意の時点で呼び出すことでこの問題を解決出来る。下記の例では、addCommentToArticle()メソッドの実行後に users, articles, commentsという3つのテーブルをエクセルファイルに出力している。エクセルファイル上では、1つのテーブルが1つのシートに割り当てられる。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;void&lt;/FONT&gt;&lt;/B&gt; testAddCommentToArticle()&lt;br /&gt;{&lt;br /&gt;    target.addCommentToArticle(1, 2, &lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;コメント&amp;quot;&lt;/FONT&gt;&lt;/B&gt;);&lt;br /&gt;&lt;br /&gt;    &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;// addCommentToArticle()実行後のデータベース内容をエクセルファイルにダンプ&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;    IDatabaseConnection con = &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;this&lt;/FONT&gt;&lt;/B&gt;.getConnection();&lt;br /&gt;    IDataSet dataset = con.createDataSet(&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;new&lt;/FONT&gt;&lt;/B&gt; String[]{&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;users&amp;quot;&lt;/FONT&gt;&lt;/B&gt;,&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;articles&amp;quot;&lt;/FONT&gt;&lt;/B&gt;,&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;comments&amp;quot;&lt;/FONT&gt;&lt;/B&gt;});&lt;br /&gt;    OutputStream os = &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;new&lt;/FONT&gt;&lt;/B&gt; FileOutputStream(&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;addCommentToArticle.xls&amp;quot;&lt;/FONT&gt;&lt;/B&gt;);&lt;br /&gt;    XlsDataSet.write(dataset, os);&lt;br /&gt;    os.close();&lt;br /&gt;    con.close();&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;繰り返しになるが、ダンプされたエクセルデータを目視で確認し事後条件の検査をするという方法はユニットテストのあり方として理想的ではない。いうまでもなく、事後条件の検査はテストケースの中に assert文を使って記述されるべきだ。それをわかった上でどこを妥協するかは時間的制約との兼ね合いだろう。&lt;br /&gt;&lt;br /&gt;事後条件の検査以外にもテーブルのダンプは有益な場合がある。たとえばロジックの実装者はデバッグのためにそれがあると便利なはずだ。事後条件の検査を自動で行う行わないに関わらず、テーブルのダンプを常に生成するようにしておいた方が実装者に優しいといえる。ただ、テストの最後でダンプを行うようにテストメソッドをコーディングした場合、途中のassertに引っかかるとダンプが行われないためデバッグ時には不便かもしれない。ダンプのタイミングは状況に応じて選ぶと良いだろう。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/dbunit.html' title='DbUnitでテーブルをエクセル出力する'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=3656587894519210895' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/3656587894519210895'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/3656587894519210895'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-7153613656141883913</id><published>2008-06-22T02:42:00.002+09:00</published><updated>2008-06-22T02:46:48.325+09:00</updated><title type='text'>Railsとsqlite3</title><content type='html'>RedmineをGentooで動かそうとしたら、"Unable to create the anonymous user"と言われて動かない。&lt;br /&gt;Macだと(Railsを2.0.2に更新すれば)同じようにして動いたのにおかしいなと思ったら、どうやら RailsではSQLite 3.3.8以降をうまく扱えないらしい。&lt;br /&gt;参考記事：&lt;a href="http://weblog.rubyonrails.org/2007/1/29/using-sqlite3-with-rails"&gt;Using SQLite3 with Rails&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ところが Portageに入っているSQLite3は 一番古くても 3.4.1からだったりするもので。バカー！&lt;br /&gt;&lt;br /&gt;仕方ないので MySQLで運用する事にした。めんどくせえなあ。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/railssqlite3.html' title='Railsとsqlite3'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=7153613656141883913' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/7153613656141883913'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/7153613656141883913'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-2420304252873739906</id><published>2008-06-15T23:31:00.003+09:00</published><updated>2008-06-16T14:51:35.343+09:00</updated><title type='text'>スパースファイルの作り方</title><content type='html'>Portageに入っている iscsitargetがアップデートされ、今使っている Xenのカーネル(2.6.20)でもビルドできるようになったので MacProの TimeMachine用にiSCSIを立ち上げることにした。&lt;br /&gt;&lt;br /&gt;iSCSIを使っていて思ったんだけど、LVMで作った論理ボリュームをSCSIディスクとして他のホストへ提供していると、そこに作られたパーティションを udevが勝手に認識してしまい面倒なことになったりする。これを避けるため、（少々のオーバーヘッドは覚悟の上で）ホスト側でいったんファイルシステムを作成しその中のイメージファイルをディスクとして提供することにした。&lt;br /&gt;&lt;br /&gt;しかしながら、何百ギガバイトものファイルを ddで普通に作成するのにはかなり時間がかかる。なのでここはスパース（sparse, 疎な）ファイルを使うことにしたのでその方法をメモしておく。&lt;br /&gt;&lt;br /&gt;私はこのようにして 400GBのスパースファイルを作成した。&lt;br /&gt;dd if=/dev/zero of=timemachine-for-macpro.img bs=1M seek=409600 count=0&lt;br /&gt;&lt;br /&gt;この操作は一瞬で終わるが、ls -l でファイルサイズを表示してみると確かに400GBの長さがあることになっている。&lt;br /&gt;しかしこの段階では実際にはディスク容量を消費しておらず（それは dfで確認できる）、ファイルに対し書き込みが行われるにつれ順次ディスク容量を消費していくことになる。&lt;br /&gt;&lt;br /&gt;巨大なファイルを作成するための時間と、初期のディスク容量を節約したい向きにはスパースファイルがお勧めである。&lt;br /&gt;ただし運用中にフラグメントが発生しやすいであろうと想像できるため、パフォーマンスを稼ぎたい場合には向かないだろう。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/blog-post.html' title='スパースファイルの作り方'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=2420304252873739906' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/2420304252873739906'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/2420304252873739906'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-9195594388610033280</id><published>2008-06-08T03:46:00.004+09:00</published><updated>2008-06-25T12:39:40.227+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Springベースのユニットテストに DbUnitを組み合わせる方法</title><content type='html'>DbUnitは、JUnitにデータベース入出力のテストを行うための各種便利機能を提供するための拡張である。&lt;br /&gt;ここでは、フィクスチャのロードを行う機能にスコープを絞って DbUnitを取り上げる。&lt;br /&gt;フィクスチャとは、ユニットテストの事前条件となるテストデータである。&lt;br /&gt;&lt;br /&gt;DbUnitを使うには、クラスパスに下記のjarファイルを追加する。&lt;br /&gt;&lt;br /&gt;dbunit-*.jar&lt;br /&gt;slf4j-api-*.jar&lt;br /&gt;slf4j-jcl-*.jar&lt;br /&gt;&lt;br /&gt;フィクスチャを使うユニットテストは、各テストメソッド毎に下記のような流れで実行される。&lt;br /&gt;&lt;br /&gt;a) トランザクション開始&lt;br /&gt;↓&lt;br /&gt;b) フィクスチャをデータベースにINSERT&lt;br /&gt;↓&lt;br /&gt;c) テスト対象メソッドの呼び出し&lt;br /&gt;↓&lt;br /&gt;d) 実行結果のチェック&lt;br /&gt;↓&lt;br /&gt;e) トランザクションをロールバック&lt;br /&gt;&lt;br /&gt;a, e は Springの機能で自動的に行われる。&lt;br /&gt;c, d はテストケースの実装者がコーディングするとして、残る b を DbUnitで行うということになる。&lt;br /&gt;&lt;br /&gt;テストケースの各トランザクションを常にロールバックする設定にしておけば、データベースは各テストメソッドが終了するたびにテストを開始する前の状態へ戻るため、INSERTされたフィクスチャも取り消される。そのため、固定のテストデータを用いても2回目以降のテストで重複キーの問題が発生するということは無い。&lt;br /&gt;&lt;br /&gt;前回のエントリ&lt;a href="http://www.stbbs.net/blog/2008/06/spring.html"&gt;Springとユニットテスト&lt;/a&gt;で解説したような、Springによって自動的にトランザクション管理が行われるように構成された、つまり&lt;br /&gt;&lt;br /&gt;@RunWith(SpringJUnit4ClassRunner.class)&lt;br /&gt;@TransactionConfiguration&lt;br /&gt;@Transactional&lt;br /&gt;@ContextConfiguration&lt;br /&gt;&lt;br /&gt;といったアノテーションの付加されたテストケースをさらに DbUnitへ対応させるには、テストケースに下記のような追加を行う。&lt;br /&gt;&lt;br /&gt;1) DataSourceBasedDBTestCaseを継承させる&lt;br /&gt;2) DataSource型のプロパティを持たせ、Springでインジェクトさせる&lt;br /&gt;3) protected DataSource getDataSource()メソッドを実装する (単に 2のデータソースオブジェクトを返すだけで良い)。このメソッドはDbUnitが利用する。&lt;br /&gt;4) @Beforeアノテーションを付けて、public void setUp()を実装する。単に super.setUp()をコールするだけで良い。&lt;br /&gt;5) protected IDataSet getDataSet()をオーバーライドする。ここには、フィクスチャとなるデータセットオブジェクトを返す処理を記述する。このメソッドはDbUnitが利用する。&lt;br /&gt;&lt;br /&gt;注意しておきたいのは 2 のデータソースである。Springと DbUnitを一緒に使うためのデータソースは &lt;strong&gt;TransactionAwareDataSourceProxyでなくてはならない&lt;/strong&gt;。&lt;br /&gt;DbUnitはデータソースから取得した物理コネクションをフィクスチャのINSERTが完了した後に一度クローズしてしまう。Springのトランザクション管理下ではこれは不正な操作であり（DbUnitは Springの事など知らないのでやむを得ないのだが）、このため素のデータソースを DbUnitへ渡すとテスト本体が正常に実行できなかったりする。&lt;br /&gt;Springの TransactionAwareDataSourceProxyでデータソースを包んでおけば、物理コネクションが適切な Proxyオブジェクトによって保護されるため、この問題を防ぐことができる。&lt;br /&gt;&lt;br /&gt;デフォルトでは、DbUnitはフィクスチャをデータベースに INSERTする際にテーブルを一旦クリアしてしまう。もし接続先のデータベースがユニットテスト専用ならばこの動作は妥当だが、そうでない場合（同じデータベースを結合テストにも使用するなど）はテーブルをクリアしてほしくないだろう。ユニットテスト実行時にテーブルをクリアせずフィクスチャの INSERTだけを行うようにするには、protected DatabaseOperation getSetUpOperation() メソッドをオーバーライドして DatabaseOperation.INSERT を返すようにすると良い。&lt;br /&gt;（但し、できれば結合テスト用のデータベースとユニットテスト用のデータベースは別々に設けたいところである。例えば Ruby on Railsではそのような習わしになっている）&lt;br /&gt;&lt;br /&gt;フィクスチャは Excelで記述することが出来る（私が DbUnitを使いたいと思った唯一の理由がこれだ）。&lt;br /&gt;Excelの各シートがデータベースのテーブルに対応する。シート名としてテーブル名を用いることによって、シートがテーブルと対応づけられる。&lt;br /&gt;各シートの最上行にはカラム名を記載し、2行目以降に INSERTしたいデータを並べる。このようにして作成した　Excelファイルを fixtures.xls として保存したなら、先の 5番にある protected IDataSet getDataSet() の実装はこのようになるだろう。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;@Override&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;protected&lt;/FONT&gt;&lt;/B&gt; IDataSet getDataSet() &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;throws&lt;/FONT&gt;&lt;/B&gt; Exception {&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;return&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;new&lt;/FONT&gt;&lt;/B&gt; XlsDataSet(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;new&lt;/FONT&gt;&lt;/B&gt; File(&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;fixtures.xls&amp;quot;&lt;/FONT&gt;&lt;/B&gt;));&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/spring-dbunit.html' title='Springベースのユニットテストに DbUnitを組み合わせる方法'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=9195594388610033280' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/9195594388610033280'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/9195594388610033280'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-360800460702806229</id><published>2008-06-06T04:40:00.003+09:00</published><updated>2008-06-06T13:16:48.697+09:00</updated><title type='text'>HttpServletRequestについて思う事</title><content type='html'>Googleウェブマスターツールなるものを使ってこのブログへ到達する人々の検索ワードなんかを調べてみると、HttpServletRequestについて調べに来ている人がかなり多いことに驚いたのでエントリを起こしてみた。というか、うちのブログに書いてある HttpServletRequestの情報って Apache CXFのサービスからサーブレットリクエストを参照する方法のメモとかごく一部の人しかわからない超ニッチな奴なんで、ガチでHttpServletRequestについて知りたくて検索した人からすればかなりガッカリというか意味不明だと思う。それじゃ申し訳ないので Googleで HttpServletRequestについて検索したとき上位に出てくるコンテンツについて思った事とか述べてみることにした。これでどう申し訳が立つのか知らないけど。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://sdc.sun.co.jp/java/docs/j2ee/sdk_1.3/ja/techdocs/api/javax/servlet/http/HttpServletRequest.html"&gt;Java 2 Platform EE 1.3.1: インタフェース HttpServletRequest&lt;/a&gt; sdc.sun.co.jp&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;さすが Google先生、トップには最も妥当な物を出してくれます。&lt;br /&gt;&lt;br /&gt;英語でもいいから最新の情報が欲しいという人は &lt;a href="http://java.sun.com/javaee/5/docs/api/javax/servlet/http/HttpServletRequest.html"&gt;HttpServletRequest (Java EE 5)&lt;/a&gt;をどうぞ。そういう人はここに来ないと思うけど・・・&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.javadrive.jp/servlet/request/"&gt;リクエスト情報の取得(HttpServletRequest)&lt;/a&gt; www.javadrive.jp&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;いつの記事かわからなかったのだけど Tomcat6の話と並べてあるしスクリーンショットが IE7なので最近だと思う。比較的どうでもいいことだけど、&lt;br /&gt;&lt;br /&gt;・日本語パラメータの対応(getBytes)&lt;br /&gt;・日本語パラメータの対応(setCharacterEncoding)&lt;br /&gt;&lt;br /&gt;後者を解説するなら前者は何のために必要だったんだろう。とはいえ HttpServletRequestを単一キーワードで検索した人にとっては望みのページだろう。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://sengoku.ath.cx/java/contents/contents3/contents3_5.jsp"&gt;HttpServletRequest - Java 入門 JSP サーブレット etc.&lt;/a&gt; sengoku.ath.cx&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;この記事も Tomcat5.5 や IE7を使って解説しているのでそんなに古くないと思われる。というか実際古くない。これも多分 HttpServletRequestを単一キーワードで検索した人にとっては望みのページかと。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.kab-studio.biz/Programing/JavaA2Z/Word/00000768.html"&gt;JavaA2Z【HttpServletRequestとは】&lt;/a&gt; www.kab-studio.biz&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;2005年の記事？にしては古いかな？setAttribute()でセットした値を JSP側で使うためには jsp:useBeanはもう使わず JSTLを使われたし。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.atmarkit.co.jp/fjava/onepoint/svltjsp/svltjsp06.html"&gt;@IT:Javaプログラミング・ワンポイントレクチャー：HttpServletRequestオブジェクトの役割&lt;/a&gt; www.atmarkit.co.jp&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;2003年の記事。記事は古いが内容が役に立たなくなっているというわけでもない。が、HttpServletRequest を単一キーワードで検索した人にとっては、直接欲しい情報ではないだろう。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;&lt;a href="http://www.site-cooler.com/java/j2ee/03_06.htm"&gt;J2EE講座 [ リクエストの取得　HttpServletRequestインタフェース］&lt;/a&gt; www.site-cooler.com&lt;/h4&gt;&lt;br /&gt;&lt;br /&gt;あくまで HttpServletRequestのページなので getParameter() とかの解説が無い。検索でダイレクトにこのページへ飛んでしまった人はガッカリかもしれない（このページの前の、スーパーインターフェイスたる ServletRequestの解説ページに書いてある）が、一連のページはとてもまっとうな内容。まっとうな内容だけに、「目の前にある仕事をやっつけるためだけに調べ物をしている人」向けではない。しかしそういう人でも &lt;a href="http://www.site-cooler.com/java/j2ee/07_01.htm"&gt;J2EE講座 [ JSP、Servletの文字化け対策 ］&lt;/a&gt;はチェックしておいて損しないとおもう。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;HttpServletRequest雑感&lt;/h4&gt;&lt;br /&gt;日本語文字列の入力エンコーディングを正す方法については setCharacterEncoding()を使いなさいということで正しいんだけど、仕事で作る Webアプリケーションだったら出来れば&lt;a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/web/filter/CharacterEncodingFilter.html"&gt;こういうサーブレットフィルタ&lt;/a&gt;を使って解決したいところ（後でそのプログラムをメンテナンスする人のためにも）。&lt;br /&gt;&lt;br /&gt;多くの入門サイトではコンテンツの文字コードを Shift_JISで扱ってるけど、マルつき数字とかキロとか昭和とかの字が化けるよーとか余計な悩みを抱えるのを避けたければ UTF-8を使うほうが良いかもしれない(データベースを使うならそれも合わせる)。周りがユニコードなんてしらねーよ、シフトJISでいいだろ！とか言う人ばかりで UTF-8なんて使わせてもらえない状況であればもう仕方ないので頑張って解決するしかないけど。ヒント：MS932、Windows-31J&lt;br /&gt;&lt;br /&gt;しかしなんで HttpServletRequestについてみんなそんなに検索するんだろうなあ。もっと高位のフレームワークを使わないで仕事になるのかなあ（会社の方針でオープンソース禁止なのだろうか、だとしたら難儀なことだ）。むしろフレームワークを作ってる人なら HttpServletRequestについてすごくよく知りたいと思うかもしれないけど、そういう人そんなにたくさんいないだろうし。&lt;br /&gt;Webアプリケーションの動作原理まで詳細に勉強したいとか、いやちょっと試してみるだけだからフレームワークみたいな大げさなのは・・・、とかいうのでなければ、サーブレット APIを直接呼び出すようなやりかたをしないで何かのフレームワークを使ったほうがいいかと。英語がだめなら Seasar2 あたりをあたってみるのがいいんじゃないかな。余計なお世話か。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/httpservletrequest.html' title='HttpServletRequestについて思う事'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=360800460702806229' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/360800460702806229'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/360800460702806229'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-1734175851950538874</id><published>2008-06-04T06:31:00.002+09:00</published><updated>2008-06-04T06:36:11.274+09:00</updated><title type='text'>MySQL: DDLとトランザクション</title><content type='html'>MySQLでは（他のDBMSでもおおよそ似たようなものだと思うが）、トランザクションの途中で CREATE TABLE文や DROP TABLE文のようなDDLを実行すると強制的にコミットが行われる。これに気付かないと、ロールバックしているはずなのになんかデータが残留してる、ということが起こる（そもそもトランザクションの中でDDLを呼ばなければいけない事態を何とかすべきだが）。DDL以外でも、TRUNCATE TABLE文などでもそうなる。でも、CREATE TEMPORARY TABLEは大丈夫のようだ。&lt;br /&gt;&lt;br /&gt;参考 &lt;a href="http://dev.mysql.com/doc/refman/5.1/ja/implicit-commit.html"&gt;12.4.3. 暗黙のコミットを引き起こすステートメント&lt;/a&gt;</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/mysql-ddl.html' title='MySQL: DDLとトランザクション'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=1734175851950538874' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/1734175851950538874'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/1734175851950538874'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-3003937368743162150</id><published>2008-06-04T03:47:00.008+09:00</published><updated>2008-06-25T12:39:58.597+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Springとユニットテスト</title><content type='html'>テストケースくらいはなるべく特定のフレームワークに依存させたくないという気持ちはあるものの、さすがに Hibernateやらといったヘヴィな奴をインスタンス化する長い道のりを手でコーディングしたり、単一責任の原則に基づいて真面目に分割されたコンポーネント群のワイヤリングを手でコーディングしたりするのはかなり厳しいものがあるので、そこは目をつぶってテストケースもやはり Springの助けを借りて実装するのが現実的だ。&lt;br /&gt;&lt;br /&gt;なお JUnitと Springを連携させるには、spring.jarの他に spring-test.jar が必要となる。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Eclipseについてる JUnitを捨てる&lt;/h4&gt;&lt;br /&gt;Eclipseについている JUnitはちょっと古くて、Springに対応するために必要なインターフェイスJUnit4ClassRunnerが存在していない。なので Eclipseに標準で付属している JUnitをビルドパスから外し、最新の JUnitへビルドパスを通す必要がある。その場合でも "Run as"→"JUnit TestCase"はちゃんと動くので心配ない。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;テストケースに Beanをインジェクトさせる&lt;/h4&gt;&lt;br /&gt;テストケースに Springサポートを適用する一番シンプルな方法は、下記のふたつのアノテーションをつけてやることである。&lt;br /&gt;&lt;br /&gt;@RunWith(SpringJUnit4ClassRunner.class)&lt;br /&gt;@ContextConfiguration&lt;br /&gt;&lt;br /&gt;これらのアノテーションがついたテストケースを走らせると、最初にテストケースと同じパッケージ階層とクラス名+"-context.xml"という名前を持つ Bean定義ファイルが読み込まれる。&lt;br /&gt;テストケースに @Autowired （もしJava EEのアノテーションが使えるなら @Resource でも良い）の付いたプロパティがあれば、それぞれのプロパティと同じ型の Beanが自動的にインジェクトされる。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- src/test/com/acme/DataImporterTest-context.xml --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;beans&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- 中略 --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean id=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataImporter&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;com.acme.DataImporterImpl&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; ref=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/beans&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;package&lt;/FONT&gt;&lt;/B&gt; com.acme;&lt;br /&gt;&lt;I&gt;&lt;FONT COLOR="#B22222"&gt;// 中略&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;@RunWith(SpringJUnit4ClassRunner.&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;@ContextConfiguration&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; DataImporterTest {&lt;br /&gt;  @Autowired&lt;br /&gt;  DataImporter dataImporter;&lt;br /&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;void&lt;/FONT&gt;&lt;/B&gt; testDoImport()&lt;br /&gt;  {&lt;br /&gt;    dataImporter.doImport();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;これなら、テストケースの中に何らインスタンス化やワイヤリングの処理を記述しなくても良く非常に簡潔である。&lt;br /&gt;読み込むBean定義ファイルを変更したり名称を指定してプロパティに Beanをインジェクトしたり（@Qualifierアノテーションを使う）も出来るので、詳しくは Spring 2.5のドキュメント &lt;a href="http://static.springframework.org/spring/docs/2.5.x/reference/testing.html#testcontext-ctx-management"&gt;8.3.7.2. Context management and caching&lt;/a&gt; あたりを参照されたし。&lt;br /&gt;&lt;h4&gt;トランザクション制御も自動化する&lt;/h4&gt;&lt;br /&gt;典型的には、データベースアクセスを行うコンポーネントに適用するテストケースの各メソッドはそれぞれがひとつのトランザクション単位として考えられるだろう。したがって、各テストメソッドの開始時点で自動的にトランザクションがBEGINされ、終了時には自動で COMMIT又は ROLLBACKが行われると便利である。&lt;br /&gt;そうしたい場合は、先の @RunWith, @ContextConfigurationアノテーションに加えて下記のアノテーションをつけてやると良い。&lt;br /&gt;&lt;br /&gt;@TransactionConfiguration&lt;br /&gt;@Transactional&lt;br /&gt;&lt;br /&gt;各テストメソッドの実行にあたり、Bean定義ファイル内で定義された transactionManagerという名前のトランザクションマネージャを勝手に使ってトランザクションの制御を行ってくれる。&lt;br /&gt;（使用するトランザクションマネージャの名前は@TransactionConfigurationアノテーションのオプションで変更が可能）&lt;br /&gt;&lt;br /&gt;デフォルトでは、各テストメソッドの終了時にはトランザクションがロールバックされるようになっている。つまりテストの実行によってデータベースの内容を変更しないということだ。ユニットテストは外部リソースの状態から独立しているべきなのでこの動作が理想的なのではあるが、どうしてもテストケースを回した後に Microsoft Accessやら Navicatやらといった GUIツールでテーブルの中身を確認してみたい場合もある。そういう時は @TransactionConfigurationアノテーションのオプションで defaultRollback=falseを与えてやるか、テストメソッドへ明示的に @Rollback(false) のようにアノテーションでロールバックを行わないことを記してやる必要がある。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean id=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;transactionManager&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;  class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;org.springframework.jdbc.datasource.DataSourceTransactionManager&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; ref=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;@RunWith(SpringJUnit4ClassRunner.&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;@ContextConfiguration&lt;br /&gt;@TransactionConfiguration&lt;br /&gt;@Transactional&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; DataImporterTest {&lt;br /&gt;  @Autowired&lt;br /&gt;  DataImporter dataImporter;&lt;br /&gt;&lt;br /&gt;  @Rollback(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;false&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;void&lt;/FONT&gt;&lt;/B&gt; testDoImport()&lt;br /&gt;  {&lt;br /&gt;    dataImporter.doImport();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;気になったのだが、テストメソッドがロールバックを行わない設定になっていると、テストが失敗した（キャッチされない例外が上がった、アサーションに引っかかった）場合でもトランザクションは容赦なくコミットされてしまうようだ。中途半端なデータをデータベースに残さないよう、実装の初期段階ではロールバックを行う設定でユニットテストを行う方が良さそうである。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Beforeと After&lt;/h4&gt;&lt;br /&gt;Springによるトランザクション管理が適用されたテストケースでは、JUnitの標準的な @Before, @Afterメソッドの他に @BeforeTransaction, @AfterTransactionメソッドを持つことが出来る。&lt;br /&gt;@Before, @Afterはトランザクション内で実行されるが、@BeforeTransactionはトランザクションの開始前、@AfterTransactionはトランザクションの終了後に実行される。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;少しだけ記述を減らす＋α&lt;/h4&gt;&lt;br /&gt;もしテストケースが他のクラスを継承していないのであれば、@RunWith, @TransactionConfiguration, @Transactionalアノテーションを付ける代わりに AbstractTransactionalJUnit4SpringContextTests を継承させることもできる。&lt;br /&gt;&lt;br /&gt;アノテーションの記述を省略できることに加え、このクラスにはデータベース操作のユニットテストを行う際に便利かもしれない下記のものが装備されている。&lt;br /&gt;・Beanファクトリへのアクセス (applicationContext)&lt;br /&gt;・ログAPIへのアクセス (logger)&lt;br /&gt;・SimpleJdbcTemplateのインスタンス (simpleJdbcTemplate)&lt;br /&gt;・データベース操作のテストに便利かもしれないいくつかのメソッド(countRowsInTable,deleteFromTables,executeSqlScript,setSqlScriptEncoding)&lt;br /&gt;&lt;br /&gt;最後のはフィクスチャのロードなどに使うことを想定した機能かもしれないが、そのあたりを本格的にやるなら DbUnitを組み合わせて使うのが良いと思う。&lt;br /&gt;言うまでもなく Javaは多重継承ができないので、DbUnitの DatabaseTestCaseを継承するかこのAbstractTransactionalJUnit4SpringContextTestsを継承するかの選択を迫られることになるのだが。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/spring.html' title='Springとユニットテスト'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=3003937368743162150' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/3003937368743162150'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/3003937368743162150'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-7864906841570162081</id><published>2008-06-03T22:58:00.004+09:00</published><updated>2008-06-25T12:39:00.547+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>SpringでJNDIを提供する</title><content type='html'>「え、それって&amp;lt;jee:jndi-lookup/&amp;gt; のこと？」&lt;br /&gt;・・・だったらわざわざブログのエントリなぞ起こさんわい。JNDIを参照する側ではなく、提供する側の話。&lt;br /&gt;&lt;br /&gt;Springは JNDIを参照することは出来るけど、JNDIサービス自体は提供していない。&lt;br /&gt;ふつう JNDIはアプリケーションサーバが提供するものなので（ついでに言えば Java EEのサービスなので） Springの守備範囲ではないのだが、何らかの理由でユニットテストのターゲットが JNDIを参照しているとか（レガシーなSLSBを使い回してるとか、中のJRubyで activerecord-jdbc-adapterを使ってるとかね）、ユニットテスト用の Bean定義ファイル内でもデータソースの参照は JNDI経由で行いたいとか、Webアプリケーションではなくstatic public void main()から始まるスタンドアロンのプログラムなんだけどやっぱり Bean定義ファイル内でのデータソース設定は JNDIを参照する形の記述にしたいとか、そういう特殊な事情のある人またはマニアックな人は Springベースの JNDI実装が欲しくなったりもするのである。そして、やっぱりそういうものが存在する。&lt;br /&gt;&lt;br /&gt;Springベースの JNDI実装 org.apache.xbean.spring.jndi.SpringInitialContextFactory は &lt;a href="http://geronimo.apache.org/xbean/"&gt;Apache Geronimoのサブプロジェクト XBean&lt;/a&gt;の成果物である xbean-spring-*.jarに含まれている。これを拝借して自分のユニットテスト用クラスパスに追加してやろう。&lt;br /&gt;&lt;br /&gt;JNDIの実装クラスを指定する方法には下記のようなものがある。&lt;br /&gt;・システムプロパティjava.naming.factory.initial にクラス名をセットする&lt;br /&gt;・クラスパスに jndi.propertiesというファイルを置き、java.naming.factory.initial=行にクラス名を記述する&lt;br /&gt;どちらでも良いが Eclipseで Runする時に VM引数を設定するのは面倒なので私は後者にしている。&lt;br /&gt;&lt;br /&gt;jndi.propertiesの内容は下記のようになる。&lt;br /&gt;java.naming.factory.initial=org.apache.xbean.spring.jndi.SpringInitialContextFactory&lt;br /&gt;&lt;br /&gt;SpringInitialContextFactoryは jndi.xmlという名前の Bean定義ファイルをクラスパス上で探しだし、それを JNDIの設定ファイルとして用いる（jndi.propertiesと同じ場所にでも置いておけば良いだろう）。この Bean定義ファイルには少なくとも、jndi という名称で org.apache.xbean.spring.jndi.DefaultContext クラスの Beanを定義しておく必要がある。空の JNDIツリーを提供するだけならばこの Beanに何らプロパティをセットする必要はないが、典型的にはここにデータソースをバインドすることになるだろう。データソースをJNDIにバインドしたければ、jndi.xmlは下記のような記述になる。例はMySQLの場合だが、DBベンダの独自な DataSource実装を使うのが嫌であれば Springの DriverManagerDataSourceなどといった汎用のDataSource実装を使えば良いと思う。&lt;br /&gt;（個人的には、ことユニットテストに用いる場合などコネクションプーリングの必要ないケースに限って言うならば DataSourceの実装が DBベンダのものか Springのものかは大した問題ではないと考えている。アプリケーションの利用するDBMSが差し替わるというのは、いろんな意味でよほどのことだ）&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;?xml version=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;1.0&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; encoding=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;UTF-8&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;?&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;beans xmlns=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean id=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;    class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;com.mysql.jdbc.jdbc2.optional.MysqlDataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;url&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;jdbc:mysql://localhost/mydb&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;user&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;username&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;password&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;secret&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;zeroDateTimeBehavior&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;convertToNull&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;useUnicode&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;true&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;characterEncoding&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;UTF8&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean id=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;jndi&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;    class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;org.apache.xbean.spring.jndi.DefaultContext&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;entries&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;map&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;entry key=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;java:/comp/env/jdbc/dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;ref bean=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/entry&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/map&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/beans&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;h4&gt;ずるをする&lt;/h4&gt;&lt;br /&gt;Springのトランザクション管理下で JDBCの呼び出しをしたい場合、下記のいずれかの条件を満たしている必要がある。&lt;br /&gt;&lt;br /&gt;1)常に Springの JdbcTemplateを経由してJDBCの呼び出しを行う&lt;br /&gt;2)常に SpringのDataSourceUtilsを経由してデータソースからコネクションを取得する&lt;br /&gt;3)DataSourceを Springの TransactionAwareDataSourceProxyでラップし、常にそれを使う&lt;br /&gt;4)JtaTransactionManagerを使う&lt;br /&gt;&lt;br /&gt;JNDIから直接データソースを取得するように実装されているレガシーなJEEコードも Springのトランザクション管理下で動作させたい場合、Java EEコンテナ上で動作させる時は 4の方法でコンテナ管理のトランザクションマネージャとくっつけてやれば裏でうまく処理してくれそうな気がするが、Java SEベースの開発環境でユニットテストをするときはその方法が使えない。&lt;br /&gt;&lt;br /&gt;では、TransactionAwareDataSourceProxyでラップ済みのデータソースを JNDIに登録してはどうかということで、やってみたところ一応期待通りの動作をするようだ。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;?xml version=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;1.0&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; encoding=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;UTF-8&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;?&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;beans xmlns=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;http://www.springframework.org/schema/beans&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean id=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;    class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;constructor-arg&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;com.mysql.jdbc.jdbc2.optional.MysqlDataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;url&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;jdbc:mysql://localhost/mydb&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;user&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;username&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;password&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;secret&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;zeroDateTimeBehavior&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;convertToNull&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;useUnicode&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;true&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;characterEncoding&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;UTF8&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/constructor-arg&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean id=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;jndi&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;org.apache.xbean.spring.jndi.DefaultContext&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;entries&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;map&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;entry key=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;java:/comp/env/jdbc/dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;ref bean=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;dataSource&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/entry&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/map&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/beans&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;Springのドキュメントによると、DataSourceTransactionManagerにセットする dataSourceは TransactionAwareDataSourceProxyでは駄目・・・なんだけど、そういう場合は勝手に TransactionAwareDataSourceProxyから中の本物データソースを取り出して使うよ。ということになっていて、実際ソースを確認したところそうなっていたので、JNDIからもってきたデータソースが既に TransactionAware...でラップされていても大丈夫みたい。</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/06/springjndi.html' title='SpringでJNDIを提供する'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=7864906841570162081' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/7864906841570162081'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/7864906841570162081'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-2685558238545010572</id><published>2008-05-28T21:00:00.006+09:00</published><updated>2008-06-25T12:41:49.065+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JRuby'/><title type='text'>JRubyで DBIを使う ( DBI / Jdbc )</title><content type='html'>Javaでいうところの JDBCに相当するレイヤが Rubyにおける DBIである。&lt;br /&gt;&lt;br /&gt;ActiveRecord用に最初から設計されたデータベースじゃないと ActiveRecordで使うのはとても厳しい。そういう場合に取り得る選択としてはひとまず ORMの使用をあきらめて SQLを用いたDBアクセスをするというのがあるが、そうするにしても JRubyから java.sql.* を使うようではなんだか負けた気分（っていうか最初から Javaで書けば？って話）なので、 ここはひとつ JRubyから DBIを使ってデータベースにアクセスすることにする。&lt;br /&gt;&lt;br /&gt;以下、$JRUBY_HOME/binに PATHが通っている前提で。&lt;br /&gt;&lt;h4&gt;JRubyに DBIをインストール&lt;/h4&gt;&lt;br /&gt;RubyForgeから "Ruby/DBI"を探し、dbi-*.tar.gz をダウンロード・展開したら、&lt;br /&gt;&lt;br /&gt;jruby setup.rb config --without=dbd_sqlite,dbd_sybase&lt;br /&gt;jruby setup.rb setup&lt;br /&gt;jruby setup.rb install&lt;br /&gt;&lt;br /&gt;のようにする。これで JRubyに DBIがインストールされたのだが、これとは他に DBIと JDBCをブリッジするドライバが必要となる。&lt;br /&gt;&lt;h4&gt;JDBC用のDBIドライバをインストール&lt;/h4&gt;&lt;br /&gt;RubyForgfeで "Ruby DBI-JDBC driver" を探し、dbi-jdbc.tar.gzをダウンロード・展開する。&lt;br /&gt;アーカイブの中に入っていた DBD ディレクトリを $JRUBY_HOME/lib/ruby/site_ruby/1.8/ に放り込む。&lt;br /&gt;結果、&lt;br /&gt;$JRUBY_HOME/lib/ruby/site_ruby/1.8/DBD/Jdbc/Jdbc.rb&lt;br /&gt;$JRUBY_HOME/lib/ruby/site_ruby/1.8/DBD/Jdbc/JdbcTypeConversions.rb&lt;br /&gt;が存在する状態になれば OK&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;DBI-JDBCの使い方例&lt;/h4&gt;&lt;pre&gt;require 'dbi'&lt;br /&gt;&lt;br /&gt;url = 'DBI:jdbc:mysql://localhost/mydb'&lt;br /&gt;username = 'username'&lt;br /&gt;password = 'password'&lt;br /&gt;driver = 'com.mysql.jdbc.Driver'&lt;br /&gt;DBI.connect(url, username, password, 'driver'=&gt;driver) do |dbh|&lt;br /&gt;  p dbh.select_all('show tables')&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;なお型変換やNULLの扱いのあたりで制限事項が色々あるため、dbi-jdbc.tar.gzに含まれているREADMEには一度目を通されたし。&lt;br /&gt;JNDIからデータソースを取ってきてそこからgetConnection()する方法は用意されていないようだ。簡単なハックで出来るようになると思うけど。&lt;br /&gt;&lt;br /&gt;DBIの API仕様については下記を参照のこと。&lt;br /&gt;&lt;a href="http://ruby-dbi.rubyforge.org/DBI_SPEC.html"&gt;DBI Interface Specification Version 0.2.2 (Draft)&lt;/a&gt;</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/05/jruby-dbi-dbi-jdbc.html' title='JRubyで DBIを使う ( DBI / Jdbc )'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=2685558238545010572' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/2685558238545010572'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/2685558238545010572'/><author><name>shimarin</name><uri>http://www.blogger.com/profile/13486480903464752231</uri><email>noreply@blogger.com</email></author></entry><entry><id>tag:blogger.com,1999:blog-4008248627112177435.post-6608540719635613634</id><published>2008-05-26T12:59:00.009+09:00</published><updated>2008-06-25T12:42:56.669+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JRuby'/><category scheme='http://www.blogger.com/atom/ns#' term='Flex'/><title type='text'>Flexと JRubyで作るリアルタイム投票システム</title><content type='html'>&lt;object width="320" height="266" class="BLOG_video_class" id="BLOG_video-60095d82f1677e5b" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"&gt;&lt;param name="movie" value="http://www.blogger.com/img/videoplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DqgAAAIiSxp13MRsP2RXZVN7myjL-cfFh4RnSnzl_sqOzqnMSqyJvF7Z5VQkPnQRx49mJ56llRNFjQWhOxFw5AMMPZ4QQvFrtcKohBf5YUWLcGnE5XSTcg3_QgDV_2aVWRYGUi45l9DJy1Z9hg_AO4dfV0MQJ23Y_XOICAN1nnJOFrewetFlzIF5OE__dUWLxMjXzpA_AzisMEoVMxsr_PIAHTx99hYsFUYkDCUOBPfBLpUzj%26sigh%3DFvp-asZtiDjcPbkHI2qnnTAz12g%26begin%3D0%26len%3D86400000%26docid%3D0&amp;amp;nogvlm=1&amp;amp;thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer2%3Fapp%3Dblogger%26contentid%3D60095d82f1677e5b%26offsetms%3D5000%26itag%3Dw320%26sigh%3Dp9LVnInRkcRky5qhoQr96lLkZQ8&amp;amp;messagesUrl=video.google.com%2FFlashUiStrings.xlb%3Fframe%3Dflashstrings%26hl%3Den"&gt;
&lt;param name="bgcolor" value="#FFFFFF"&gt;
&lt;embed width="320" height="266" src="http://www.blogger.com/img/videoplayer.swf?videoUrl=http%3A%2F%2Fvp.video.google.com%2Fvideodownload%3Fversion%3D0%26secureurl%3DqgAAAIiSxp13MRsP2RXZVN7myjL-cfFh4RnSnzl_sqOzqnMSqyJvF7Z5VQkPnQRx49mJ56llRNFjQWhOxFw5AMMPZ4QQvFrtcKohBf5YUWLcGnE5XSTcg3_QgDV_2aVWRYGUi45l9DJy1Z9hg_AO4dfV0MQJ23Y_XOICAN1nnJOFrewetFlzIF5OE__dUWLxMjXzpA_AzisMEoVMxsr_PIAHTx99hYsFUYkDCUOBPfBLpUzj%26sigh%3DFvp-asZtiDjcPbkHI2qnnTAz12g%26begin%3D0%26len%3D86400000%26docid%3D0&amp;amp;nogvlm=1&amp;amp;thumbnailUrl=http%3A%2F%2Fvideo.google.com%2FThumbnailServer2%3Fapp%3Dblogger%26contentid%3D60095d82f1677e5b%26offsetms%3D5000%26itag%3Dw320%26sigh%3Dp9LVnInRkcRky5qhoQr96lLkZQ8&amp;amp;messagesUrl=video.google.com%2FFlashUiStrings.xlb%3Fframe%3Dflashstrings%26hl%3Den" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;br /&gt;※音が出るので注意※&lt;br /&gt;&lt;br /&gt;シンプルな人気投票のプログラムなんだけど、Flex/BlazeDSのメッセージング機能により他人の投票もリアルタイムに見ることが出来るのが特徴。&lt;br /&gt;&lt;br /&gt;操作してみたい人はこちら（期間限定、飽きたら消えるので悪しからず）&lt;br /&gt;&lt;a href="http://minami.stbbs.net/vote.html" target="_blank"&gt;微妙なリアルタイム投票システム&lt;/a&gt;&lt;br /&gt;多人数で操作したほうが楽しいので皆様お誘い合わせの上どうぞ。&lt;br /&gt;一人でもブラウザを複数枚開いて操作してみれば意味がわかるかも（うるさいけど）。&lt;br /&gt;あと、右クリックで View Sourceも出来るようにしてみた。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;技術的トピックなど&lt;/h4&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.stbbs.net/blog/2008/05/spring-blazeds-jruby.html" target="_blank"&gt;Flex +  BlazeDS + Spring + JRuby&lt;/a&gt; + ActiveRecord で実現。Railsは使っていない。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;BlazeDSの Pub/Subメッセージングも JRubyから使ってみた（&lt;a href="http://blog.masuidrive.jp/index.php/2008/02/13/air_blazeds_ruby/" target="_blank"&gt;参考記事: AIRとBlazeDSとRubyでメッセンジャーを作る&lt;/a&gt;）。参考記事では、メッセージングにのみ BlazeDSを使っており通常のリクエストは JRuby on Railsで受けているようだ。&lt;/li&gt;&lt;br /&gt;&lt;li&gt;データベースは H2を使ってみた。これについては特記事項なし&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Migrationでのスキーマ管理は Railsがなくても出来るらしいけどなんだか大変そうなのであきらめて普通にDDLを書いた&lt;/li&gt;&lt;br /&gt;&lt;li&gt;パイチャートの表示には、Professional版のFlex Builder にしかついていないチャーティングコンポーネントを使用。Adobeもエンタープライズ向けの有料コンポーネントがこんな使われ方をするとは&lt;strong&gt;夢にも思っておるまい&lt;/strong&gt;。&lt;/li&gt;&lt;br /&gt;&lt;h4&gt;サーバ側ソース&lt;/h4&gt;&lt;br /&gt;Flexに対する公開インターフェース ( VoteService )&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;package&lt;/FONT&gt;&lt;/B&gt; net.stbbs.jrubytest;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;import&lt;/FONT&gt;&lt;/B&gt; java.util.Map;&lt;br /&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;interface&lt;/FONT&gt;&lt;/B&gt; VoteService {&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; Map getProgress();&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;public&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;void&lt;/FONT&gt;&lt;/B&gt; doVote(String name, String comments);&lt;br /&gt;}&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;VoteServiceの実装が下記。Springの Bean定義ファイル内にそのまま Rubyで書き込んでいる。なお、標準Rubyライブラリや RubyGemsを使うためにアプリケーションサーバに対して VM引数 jruby.homeの設定をしてやる必要がある。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;lang:jruby id=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;voteService&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;  script-interfaces=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.jrubytest.VoteService&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;  init-method=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;init&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;lang:inline-script&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;![CDATA[&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#5F9EA0"&gt;require&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;'rubygems'&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#5F9EA0"&gt;require&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;'active_record'&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    include_class &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;'flex.messaging.MessageBroker'&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    include_class &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;'flex.messaging.util.UUIDUtils'&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    include_class &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;'flex.messaging.messages.AsyncMessage'&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; Nomination &amp;lt; ActiveRecord::Base&lt;br /&gt;      has_many :comments, :order=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;id&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; Comment &amp;lt; ActiveRecord::Base&lt;br /&gt;      belongs_to :nomination&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;class&lt;/FONT&gt;&lt;/B&gt; VoteService&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;def&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;setJndiName&lt;/FONT&gt;&lt;/B&gt;(jndiName)&lt;br /&gt;        &lt;FONT COLOR="#B8860B"&gt;@jndiName&lt;/FONT&gt; = jndiName&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;def&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;setDDL&lt;/FONT&gt;&lt;/B&gt;(ddl)&lt;br /&gt;        &lt;FONT COLOR="#B8860B"&gt;@ddl&lt;/FONT&gt; = ddl&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;def&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;init&lt;br /&gt;&lt;/FONT&gt;&lt;/B&gt;       &lt;I&gt;&lt;FONT COLOR="#B22222"&gt;#logger = ActiveRecord::Base.logger = Logger.new(STDOUT)&lt;br /&gt;&lt;/FONT&gt;&lt;/I&gt;       ActiveRecord::Base.allow_concurrency = &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;true&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;br /&gt;        ActiveRecord::Base.establish_connection(&lt;br /&gt;          :jndi=&amp;gt;&lt;FONT COLOR="#B8860B"&gt;@jndiName&lt;/FONT&gt;, :adapter =&amp;gt; &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;'jdbch2'&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;begin&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          ActiveRecord::Base.connection.execute(&lt;FONT COLOR="#B8860B"&gt;@ddl&lt;/FONT&gt;)&lt;br /&gt;          Nomination.transaction {&lt;br /&gt;            Nomination.create(:name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;konata&amp;quot;&lt;/FONT&gt;&lt;/B&gt;, :full_name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;泉 こなた&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;            Nomination.create(:name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;kagami&amp;quot;&lt;/FONT&gt;&lt;/B&gt;, :full_name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;柊 かがみ&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;            Nomination.create(:name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;tsukasa&amp;quot;&lt;/FONT&gt;&lt;/B&gt;,:full_name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;柊 つかさ&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;            Nomination.create(:name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;miyuki&amp;quot;&lt;/FONT&gt;&lt;/B&gt;,:full_name=&amp;gt;&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;高良 みゆき&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;          }&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;rescue&lt;/FONT&gt;&lt;/B&gt; Exception=&amp;gt;e&lt;br /&gt;          print e.backtrace&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;raise&lt;/FONT&gt;&lt;/B&gt; e&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;def&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;getProgress&lt;br /&gt;&lt;/FONT&gt;&lt;/B&gt;       progress = Hash.new&lt;br /&gt;        Nomination.find(:all).each {|n|&lt;br /&gt;          progress[n.name] = {&lt;br /&gt;            :full_name=&amp;gt;n.full_name,&lt;br /&gt;            :votes_obtained=&amp;gt;n.votes_obtained,&lt;br /&gt;            :recent_comments=&amp;gt;n.comments.last(5).collect {|c|&lt;br /&gt;              {:comment=&amp;gt;c.comment}&lt;br /&gt;            }&lt;br /&gt;          }&lt;br /&gt;        }&lt;br /&gt;        progress&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;def&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#0000FF"&gt;doVote&lt;/FONT&gt;&lt;/B&gt;(name, comment)&lt;br /&gt;        Nomination.transaction {&lt;br /&gt;          n = Nomination.find_by_name(name)&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;return&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; n == &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;nil&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;if&lt;/FONT&gt;&lt;/B&gt; comment != &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;nil&lt;/FONT&gt;&lt;/B&gt; &amp;amp;&amp;amp; comment != &lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;&amp;quot;&lt;/FONT&gt;&lt;/B&gt; &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;then&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            Comment.create(:nomination_id=&amp;gt;n.id, :comment=&amp;gt;comment)&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          n.votes_obtained += 1&lt;br /&gt;          n.save&lt;br /&gt;        }&lt;br /&gt;        broker = MessageBroker.getMessageBroker(&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;nil&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;        msg = AsyncMessage.new&lt;br /&gt;        msg.setDestination(&lt;B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&amp;quot;vote&amp;quot;&lt;/FONT&gt;&lt;/B&gt;)&lt;br /&gt;        msg.setMessageId(UUIDUtils.createUUID)&lt;br /&gt;        msg.setBody({:name=&amp;gt;name,:progress=&amp;gt;getProgress})&lt;br /&gt;        broker.routeMessageToService(msg, &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;nil&lt;/FONT&gt;&lt;/B&gt;)          &lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;end&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;br /&gt;    VoteService.new&lt;br /&gt;    ]]&amp;gt;&lt;br /&gt;  &amp;lt;/lang:inline-script&amp;gt;&lt;br /&gt;  &amp;lt;lang:property name=&amp;quot;jndiName&amp;quot; value=&amp;quot;java:/comp/env/jdbc/vote&amp;quot;/&amp;gt;&lt;br /&gt;  &amp;lt;lang:property name=&amp;quot;DDL&amp;quot;&amp;gt;&lt;br /&gt;      &amp;lt;value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &amp;lt;![CDATA[&lt;br /&gt;      drop table if exists nominations;&lt;br /&gt;      create table if not exists nominations (&lt;br /&gt;        id integer IDENTITY primary key,&lt;br /&gt;        name varchar not null,&lt;br /&gt;        full_name varchar not null,&lt;br /&gt;        votes_obtained integer default 0&lt;br /&gt;      );&lt;br /&gt;      create unique index nominations_idx on nominations(name);&lt;br /&gt;      drop table if exists comments;&lt;br /&gt;      create table if not exists comments (&lt;br /&gt;        id integer IDENTITY primary key,&lt;br /&gt;        nomination_id integer not null,&lt;br /&gt;        comment varchar not null,&lt;br /&gt;        created_at timestamp not null     &lt;br /&gt;      );&lt;br /&gt;      ]]&amp;gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/lang:property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/lang:jruby&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;h4&gt;BlazeDSの設定&lt;/h4&gt;&lt;br /&gt;BlazeDSの設定は WEB-INF/flex/services-config.xmlに書くのが通常だが、Springの applicationContext.xmlで設定してしまえたほうが個人的に気分が良かったので Spring用のカスタム ConfigurationManagerを書いた。これはそれを使った場合の設定。なので自分にしか役に立たない。ごめん。&lt;br /&gt;net.stbbs.blazeds.springパッケージは時間が出来たら githubあたりで公開したいと思うんだけど、あきらかに自分が使わない設定項目については対応していないし対応する気にもならないのでどうしたものか。&lt;br /&gt;&lt;PRE&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!--&lt;br /&gt;  BlazeDS用コンフィギュレーション&lt;br /&gt;  MessageBrokerServletの services.configuration.managerパラメータに&lt;br /&gt;  net.stbbs.blazeds.spring.FlexSpringConfigurationManagerを与えると、&lt;br /&gt;  WEB-INF/flex/services-config.xmlの代わりにこちらが使われる&lt;br /&gt;--&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.blazeds.spring.MessagingConfiguration&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;channelSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- 非ポーリングAMFチャンネル (RPC用) --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.blazeds.spring.AMFChannelSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;constructor-arg value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;my-amf&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- mx:RemoteObjectの endpointプロパティにセットするURL --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;uri&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;          value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;http://{server.name}:{server.port}/{context.root}/messagebroker/amf&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- ポーリングAMFチャンネル (Pub/Sub用) --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.blazeds.spring.AMFPollingChannelSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;constructor-arg value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;my-polling-amf&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- mx:AMFChannel の uri プロパティにセットするURL --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;uri&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&lt;br /&gt;          value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;http://{server.name}:{server.port}/{context.root}/messagebroker/amfpolling&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;serviceSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- リモーティング(RPC)サービス --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.blazeds.spring.RemotingServiceSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;constructor-arg value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;remoting-service&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;adapterSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.blazeds.spring.JavaAdapterSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;              &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;constructor-arg value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;java-object&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;              &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;default&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;true&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- RPCサービスでは非ポーリングAMFを使用 --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;defaultChannels&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;my-amf&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- Destinationアノテーション付き、又は RemotingDestinationインターフェイスつきの&lt;br /&gt;          Beanを自動的に destinationとして登録する --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;destinationsByAnnotation&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;true&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- Pub/Subサービス --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.blazeds.spring.MessageServiceSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;constructor-arg value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;messaging-service&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;adapterSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;bean class=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;net.stbbs.blazeds.spring.ActionScriptAdapterSettings&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;              &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;constructor-arg value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;actionscript&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;              &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;default&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt; value=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;true&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;/&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- Pub/SubサービスではポーリングAMFを使用 --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;defaultChannels&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;my-polling-amf&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;!-- destination(JMSでいうところの Topic)を定義 --&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;property name=&lt;/FONT&gt;&lt;/B&gt;&lt;FONT COLOR="#BC8F8F"&gt;&lt;B&gt;&amp;quot;destinationNames&amp;quot;&lt;/FONT&gt;&lt;/B&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;            &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;vote&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/value&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;          &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;        &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;      &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;    &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/list&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;  &lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/property&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;B&gt;&lt;FONT COLOR="#A020F0"&gt;&amp;lt;/bean&amp;gt;&lt;/FONT&gt;&lt;/B&gt;&lt;br /&gt;&lt;/PRE&gt;&lt;br /&gt;&lt;h4&gt;個人的なメモ&lt;/h4&gt;&lt;br /&gt;activerecord-jdbc-adapterはバージョン 0.8から JRuby 1.1専用になってしまった。仕方ないので DBMS特有のモジュールも含めバージョン 0.7.2をインストールする必要がある。&lt;br /&gt;&lt;br /&gt;jruby -S gem install activesupport&lt;br /&gt;jruby -S gem install activerecord&lt;br /&gt;jruby -S gem install -r activerecord-jdbc-adapter -v 0.7.2&lt;br /&gt;jruby -S gem install -r activerecord-jdbch2-adapter -v 0.7.2&lt;br /&gt;&lt;br /&gt;Gentoo(Portage)の JRuby 1.0.3は Java 1.6.0で動かせないみたい。仕方ないのでデフォルトJVMを 1.5.0に切り替え。&lt;br /&gt;rubygemsをインストールしようとしたら OutOfMemoryErrorが出る。仕方ないので/usr/bin/jrubyを編集してVMオプションに -Xmx512mをつけた。そしたら 512でも足りなかった。64bitだからってそんなに使いますか。1024で解決。&lt;br /&gt;&lt;br /&gt;PortageのJRubyGemsから参照されているutf8procのネイティブ(utf8proc_native.so)部が怪しくてActiveSupportをロードしたときにエラーが出る。lddで見てみたが特に外のライブラリ（iconvとか）に依存してるわけではなさそうで、外的要因じゃなければと仕方なく /usr/share/jruby/lib/ruby/gems/1.8/gems/activesupport-2.0.2/lib/active_support/multibyte/chars.rbの最後の方で「ネイティブ版のutf8procが使えたらそっちを使う」ってなってる所を手で削除した。&lt;br /&gt;&lt;h4&gt;関連記事&lt;/h4&gt;&lt;br /&gt;&lt;dl&gt;&lt;br /&gt;  &lt;dt&gt;&lt;a href="http://www.stbbs.net/blog/2008/05/spring-blazeds-jruby.html"&gt;Springのスクリプト言語サポートを使って BlazeDSと JRubyを統合する&lt;/a&gt;&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;実際に BlazeDS経由で ActionScript3から呼び出せるように Rubyスクリプトを配置する方法&lt;/dd&gt;&lt;br /&gt;  &lt;dt&gt;&lt;a href="http://www.stbbs.net/blog/2008/05/flexruby.html"&gt;なぜ Flex向けのサービスをRubyで記述することにこだわるのか&lt;/a&gt;&lt;/dt&gt;&lt;br /&gt;  &lt;dd&gt;こっちの記事は Flex - JRubyの実用的なシチュエーションについて&lt;/dd&gt;&lt;br /&gt;&lt;/dl&gt;</content><link rel='alternate' type='text/html' href='http://www.stbbs.net/blog/2008/05/flex-jruby.html' title='Flexと JRubyで作るリアルタイム投票システム'/><link rel='enclosure' type='video/mp4' href='http://www.blogger.com/video-play.mp4?contentId=60095d82f1677e5b&amp;type=video%2Fmp4' length='0'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4008248627112177435&amp;postID=6608540719635613634' title='0 件のコメント'/><link rel='replies' type='application/atom+xml' href='http://www.stbbs.net/blog/atom.xml' title='コメントの投稿'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4008248627112177435/posts/default/6608540719635613634'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/