‎appengine上でWicketを使う際のポイント主にwicket-1.4-RC6をベースに作業した内容になっています。HttpSessionStore(this);」とする。セッションオブジェクトの保存をファイルではなく、HttpSessionに入れる事でAppEngine上ではDatastoreに保存される事になる。いう事で、セッションオブジェクトもスケールの対象となるのでとてもありがたい。appengine-web.xml内に「<sessions-enabled>true</sessions-enabled>」を追加し、セッションを利用可能に設定する。リソースの更新チェック関連リソースのチェックの為にModificationWatcherがThreadを生成していしまい、これがAppEngineの制限に引っかかってしまう。これを止めるには以下の方法のいずれかを使用する。WicketApplication#init()内で「getResourceSettings().setResourcePollFrequency(null);」する必要がある。リソースの更新チェックは行われなくなる。Application.DEPLOYMENT;」とする。この件について、wicket-1.4-RC6以降で適用できるという条件でおもしろい記事があった。この方法を使うと開発時にDEVELOPMENTモードで起動しつつ、setSecurityManager(null)せずに済むかもしれない。Engine/1.2.2"とか)を返された場合はAppEngine上、と判断ができるので、ローカルで動作しているときのみ上記の方法で自前のModificationWatcherを適用し、AppEngine上ではDEPLOYMENTモードで動作させる、とするのが良さそう。上記サイトのMyModificationWatcherクラスをAppEngineModificationWatcherとして、以下のようにすればおk。super.newWebRequest(servletRequest);}NotSerializableExceptionjavax.jdo.Query#execute()で返されたクエリ結果をWebPageに保持していると、ローカルでは問題無く動作するがAppEngine上ではNotSerializeExceptionが発生する事がある。これをローカルで簡単に気づくにはWebPage#onDetach()をオーバライドして、WebPage自身をシリアライズするコードを書いて、ローカルでの実行時のみそれを走らせるようにおくとAppEngineにデプロイ後にNotSerializeExceptionが発生しないかをチェックできて便利かも。ついでに、onDetach()時には上記に加え、getSession()したオブジェクトのシリアライズも試しておくと便利。ListDataProviderや、Repeater系のコンポーネントでList#subList()を使っている場合は要注意。subList()した結果、シリアライズ不可なRandomAccessSubListのインスタンスが返って来てしまう可能性がある。ファイルのアップロードorg.apache.wicket.markup.html.form.upload.FileUploadFieldクラスを使用した、Wicket標準のファイルアップロードはそのままでは動作しない。org.apache.wicket.util.upload.DiskFileItemが、ファイルのサイズに関わらずDiskFileItem#getTempFile()経由でorg.apache.wicket.util.file.FileCleanerにアクセス(track()メソッドを実行)してしまい、その際のFileCreanerのstaticフィールドの初期化でThreadを生成してしまうため。DiskFileItemFactory();」という風に生成されている。((WebRequest)getRequest()).newMultipartWebRequest(getMaxSize());」という風に生成されている。DiskFileItemFactoryクラス内で、メモリ上で処理するかテンポラリファイルで処理するかを判断するしきい値となるサイズ(デフォルトでは10KB)が用意されているが、それとは関係無しにFileCleanerにアクセスしてしまうため、その値を触ってもダメ。いうわけで、次のようにすればAppEngine上でもWicketのFileUploadFieldを使ったファイルアップロードが可能になる。DiskFileItemクラスを継承し、絶対にファイルアクセスしないようにする。サイズに関係無くbyte[]とByteArrayOutputStreamを保持するようにして、以下のメソッドをオーバーライドして動作確認した。→常にtrueを返す。UnsupportedOperationException()するDiskFileItemFactoryクラスを継承し、上記で作成したオリジナルのFileItemクラスのインスタンスを返すようにする。DiskFileItemFactory()している一行だけを、上記で作成したオリジナルのFileItemFactoryの生成に書き換える。ファイルアップロードで使用するFormクラスの、handleMultiPart()メソッドをオーバーライドして、上記で作成したオリジナルのMultipartServletWebRequestクラスをgetRequestCycle().setRequest()するようにする。Engineのリクエスト処理の仕組み的に、静的ファイルとして応答できるものは極力そちらで処理し、アプリケーションノードで処理したくない。その際に問題になるのがWicketのリソースファイル。デフォルトの状態だとこれらのリソースファイルへのリクエストが全てアプリケーションノードでさばかれることになり、SpinUpに出くわしたりした場合にアプリケーションがもっさりしたカンジになってしまう。fileとして定義してデプロイすると良い。