2008-07-22

うそ求人広告

嘘だか本当だか微妙な求人広告
細かいツッコミは無しで。

2008-07-21

PEAR::MDB2で、空文字列が勝手にNULL扱いになってしまう問題について

なんだか知らないがそういう挙動をする。
Oracleがそういう風に動くのは知っているが、使っているのはMySQLだ。

調べたら、MDB2ではデフォルトで「空文字列をNULL扱いにする」という機能が有効になっているらしい。
それを抑制するには connectなりfactoryなりに渡せるオプションビット群から MDB2_PORTABILITY_EMPTY_TO_NULLを外す。
$options = array(
'portability' =>
MDB2_PORTABILITY_ALL ^ MDB2_PORTABILITY_EMPTY_TO_NULL,
);
$mdb2 =& MDB2::factory(
"mysql://{$User}:{$DBpass}@{$host}/${DBname}",
$options);

いくら NULLと空文字列の区別も付かないPHPプログラマが多いからといってこんなデフォルトやめてください。

2008-07-19

Springと一緒に Wicketを使う

我が社は主に Flexと BlazeDSを用いた RIAに注力している。このプラットフォームを用いる場合、サーバ側ではほぼ純粋にビジネスロジックを提供するだけで良いため典型的なMVCタイプの Webアプリケーションよりもさらに分業が容易であるという利点がある。

しかしながら、常にユーザの環境が RIAに適しているとは限らないし、「文書を読ませる」機能に関して言えばそれを Flash Player上に実現した場合あまりユーザにとって快適とは言い難いものになる可能性が高い。

などの理由から、従来通りHTMLで表現される Webアプリケーションを実装する場合も少なからずあるため、近頃先進的な向きに人気の高い Wicketを調べてみた(むろん、同様の目的には Spring MVCや Struts2を使っても良いのだが)。

ここでは、既に Spring Frameworkが Webアプリケーションに導入されていることを前提に Wicketを動作させるために必要な最低限のセットアップを行う手順を示す。
なお、アプリケーションに BlazeDSが既に導入されている場合でも共存が可能であることを確認している。

WEB-INF/lib に設置した jarファイルは下記の通り。

wicket-1.3.4.jar
wicket-ioc-1.3.4.jar
wicket-spring-1.3.4.jar
wicket-spring-annot-1.3.4.jar
slf4j-api-1.5.0.jar
slf4j-jcl-1.5.0.jar

slf4jについては好きな実装を用いて良いと思うが、Springが前提であれば Commons Loggingが存在するはずなのでここでは slf4j-jclを用いている。

必要なライブラリを追加したら、web.xmlに Wicketの設定を追加する。Wicketはサーブレット又はサーブレットフィルタとして適用することが出来るが、後者が推奨されているようだ。


<filter>
<filter-name>wicket</filter-name>
<filter-class>
org.apache.wicket.protocol.http.WicketFilter
</filter-class>
<init-param>
<param-name>applicationFactoryClassName</param-name>
<param-value>
org.apache.wicket.spring.SpringWebApplicationFactory
</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>wicket</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>


典型的な Wicketアプリケーションを構成する要素は、ひとつの WebApplicationクラスと ページ数分の WebPageクラス(とそれぞれに対応するHTMLファイル)である。
applicationFactoryClassNameに SpringWebApplicationFactoryをセットすることで、Wicketは Springの applicationContext.xml内に定義されている Beanの中から WebApplicationのインスタンスを選び出して自動的に用いるようになる。
(そのため、ことSpringを用いる場合は web.xmlにWebApplicationの実装クラス名を直接書き込む必要がない)

この設定では、Webアプリケーションに対する全てのリクエストが Wicketのフィルタに一旦渡されるが、Wicketは自身の守備範囲でない URIへのリクエストをスルーするため、画像などのリソースや他のサーブレット(BlazeDSの通信エンドポイントもそうだ)に対するリクエストを妨害されることはないようだ。

さて、最小限の WebApplicationはこのような実装になる。

package net.stbbs.wicket;

import org.apache.wicket.spring.injection.annot.SpringComponentInjector;

public class WebApplication extends
org.apache.wicket.protocol.http.WebApplication {

@Override
public void init()
{
super.init();
this.addComponentInstantiationListener(new SpringComponentInjector(this));
}

@Override
public Class getHomePage() {
return HomePage.class;
}

}

Springと統合するために、initメソッドに対し addComponentInstantiationListenerの呼び出しを追加している。これによって、WebPageクラスのインスタンスが生成される際にはアノテーションに従って自動的にフィールドインジェクションが行われるようになる。例えばこのように。

public class HomePage extends WebPage {
@SpringBean(name="helloService")
private HelloService helloService;
:
:

上記の例ではアノテーションのパラメータとして name を渡しているが、型の合致するBeanがアプリケーションコンテキスト内にひとつしか無い場合は省略しても良い。

WebPageオブジェクトのライフサイクルは Wicketの管理下にあり Springのそれとは一致しないが、WebPageオブジェクトにフィールドインジェクションされた Beanは実際には適切に自動生成されたプロキシであり、これによりライフサイクルの差異は吸収されるらしい。

インジェクションの対象となるフィールドには初期化の記述をしないように注意すること(例えば private HelloService helloService = null; のように)。インジェクタはフィールドの初期化処理よりも前に走るため、フィールドの初期化を記述するとそれで上書きされてしまうそうだ。

あとは Wicketの作法に従って WebPageクラスと HTMLファイルを必要なだけ作ることで UIを構築していけば良いだろう。

2008-07-13

Windows XP Professionalをマルチユーザー仕様に改造する

ここで紹介するハックはマイクロソフトのEULAに抵触する可能性が高いため、あくまで海外サイトから得た情報を参考までに紹介するに止めるうえ、上級者向けに必要最低限の内容のみ掲載する。情報を利用した結果ついて当方では一切の責任を負うことができないので、各自自己責任のもとで行って頂きたい。
(なおこのネタ自体は 2006年頃から存在するようだが、要点だけまとめた日本語の情報が他に見あたらなかった)

Windows XP Professionalはリモートデスクトップクライアントを用いることで離れた端末からネットワークを通じてログインし、利用できる。しかしながら、同時に利用することが可能なセッションはローカル・リモート合わせてひとつだけである。つまり、誰かがリモートからログインしようとするとその WinXP Proマシンを操作中のユーザはログアウトを迫られる。

複数のユーザが同時にログインしてオペレーティングシステムの機能を利用することは、UNIXやその派生OSでは当たり前に出来ることであるが、Windows(サーバ向け除く)はそのマーケティングにおける性質上、「技術的には出来るけど、出来ないようにしてある」といったところだと思われる。実は以前 Windows XP SP2でこの制限が緩和され同時に2セッションまで利用出来るようになるという噂が流れたのだが、これはガセネタだったようだ。

ここからが本題である。この制限は、termsrv.dll という DLLを3バイト書き換え、いくつかのレジストリ項目を登録し、グループポリシーを修正することで外すことが出来る

termsrv.dllは Windowsフォルダ以下の system32, ServicePackFiles/i386, system32/dllcache にそれぞれ存在している可能性がある(環境によってそれぞれ存在してしていたりしなかったりするようだ)。そこにある全ての termsrv.dllに対し、下記のような書き換えを行う(全て同じ内容のはずなので、1個書き換えてコピーすれば良い)。

0x00022A17
0x74を、0x75に変更
0x00022A69-0x00022A6A
0x7F 0x16を、0x90 0x90に変更

もちろん Windows XP Professionalが通常起動した状態では、このDLLを書き換えることは出来ない。セーフモードをうまく使うか、一旦 Linuxでブートして書き換えるなどの方法があるだろう。ここでは詳しい説明を省くが、セーフモードを使う方法については下記サイトに含まれている。
Enable Multiple Concurrent Remote Desktop Connections or Sessions in Windows XP

DLLを書き換えたら Windows XP Professionalを通常起動し、レジストリに下記のような変更を加える。

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Terminal Server\Licensing Core]
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]

に、それぞれ DWORD値 "EnableConcurrentSessions"を作成し 1にセットする。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]

に、DWORD値 "AllowMultipleTSSessions" を作成し 1にセットする。
(これは環境によっては既にそうなっているかもしれない)

レジストリの書き換えが終わったら、「ファイル名を指定して実行」から gpedit.msc (グループポリシーエディタ)を起動し、「コンピュータの構成」→「管理用テンプレート」→「Windowsコンポーネント」→「ターミナル サービス」まで降りていき、「接続数を制限する」設定を「有効」にし、最大接続数を好きな値にセットする。
次にコントロールパネルから「ユーザー アカウント」→「ユーザのログオンやログオフの方法を変更する」へ降りていき、「ユーザーの簡易切り替えを使用する」をチェックする。

上記で作業はおおかた終了である。リモートデスクトップをまだオンにしていないならば、「システムのプロパティ」→「リモート」からリモートデスクトップを有効にする。これで PCを再起動すれば、Windows XP Professionalが複数ユーザー同時ログイン可能な状態で動作する。
なおコンピュータがドメインに参加している場合、書き換えたレジストリの内容が戻ってしまう問題があるらしい。

関連記事


パスワードなしのアカウントで Windows XP Professionalにリモートデスクトップ接続する ( 推奨はしない )

関連サイト

Remote Desktop Connection Client for Mac

Microsoftが開発・配布している Mac版リモートデスクトップクライアント。Messengerもそうだが、意外と Mac版の存在を知らない人が多い。

rdesktop: A Remote Desktop Protocol Client

オープンソースのリモートデスクトップクライアント

おまけ


Linuxでバイナリファイルを書き換える時は bvi というプログラムが便利だ。操作は viに似ており、: で行番号のかわりにアドレスを16進入力して目的のオフセットへ飛べる。ファイルを開いた時はリードオンリーモードになっているが、:set mm コマンドで書き換えが可能なモードに切り替わるので後は x や i といったように viのような使い方で書き換えを行い、終わったら :wq で上書き終了すると良い。

Xenのハイパバイザ(完全仮想化)モードで運用しているバーチャルマシンの仮想ディスクに含まれているパーティションを Linuxでマウントしたい場合は、multipath-toolsに含まれる kpartxコマンドを使う。
参考記事:ディスクイメージとパーティション