Google App Engineでマジでセッションが効かない | sola's note

sola's note

日ごろのメモを書いていきます。何か新しいものを作るために。

そう。Google App Engine for JavaでHttpSessionが効かないのである。

これは相当ハマった。
深夜にしかやってないけど、数日は浪費…。
なんというか、情報が少なすぎる。

他の人はGAEでセッション情報使わないのかな…??

とか思いかけたくらい。

とまあ前置きはいいとして、本題に。
とりあえず、結論から書くと

HttpSessionが効かない。

Googleの本家の紹介ページ や、
その他有志者等のサイトの紹介でも大体次のように書いてある。

☆以下GAEのドキュメント引用☆
セッションを有効にする
App Engine には、サーブレット セッション インターフェースによるセッションの実装が含まれています。この実装では、App Engine のデータストアと memcache を使用してセッション データを保管します。

この機能は、デフォルトでは無効になっています。有効にするには、appengine-web.xml に次の行を追加します:

<sessions-enabled>true</sessions-enabled>

この実装により、種類が _ah_SESSION のデータストア エンティティが作成され、接頭辞 _ahs のキーで memcache が作成されます。
☆引用終わり☆

Google本家はまだmemcacheという何か匂わせる記述がある。
しかし、大抵の紹介サイトはかなりの率で「セッション」という言葉以外は触れていない。

触れていても細かく実装に触れていない事が多い。

んで(二度目になるけど)結論から言うと、
Javaで馴染みがあるHttpSessionは効いてこない。
HttpSessionは定義が出来るし、使用する事もできるのだけれど


リクエストが発生する度にセッションオブジェクト内の値がnullになる


もう意味不明だった。
セッションIDは変わらないのに、オブジェクトが消えている。

しかもこれ、


 ロ ー カ ル 環 境 で は 使 え て し ま う


これが諸悪の根源
ローカルで色々実装して、

さあデプロイするぞ

なんてデプロイすると、
ことごとくセッション情報が消える

結論から言うと…なんて書いといて、全然結論に至って無くて申し訳ない…w

じゃあどうすればいいか

ということになるよね。
今現在で

sessionに一番近い挙動を得ることが出ると感じたのが

「memcache」

パッケージは

com.google.appengine.api.memcache

はっきり言おう。

memcacheの仕様は、


 キ ャ ッ シ ュ に 類 似 す る 機 能


って事くらいしかわかってないw

ダメじゃんて?w



だってさっき仕事から帰ってきて試してわかったばっかなんだもんorz



参考になるのは
低レベルAPIドキュメントの

ここ

memcacheの使い方は

1.まず呼び出す
MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();

2.セットする(存在はMapに近い)
memcacheService.put("hoge",hoge);

3.取得する
Hoge hoge = (Hoge)memcacheService.get("hoge");

以上。

ServletとJSPでやりとりする場合は

まずServletで

MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
memcacheService.put("hoge",hoge);

をやる。(インポート忘れずに)

次にJSPで

MemcacheService memcacheService = MemcacheServiceFactory.getMemcacheService();
Hoge hoge = (Hoge)memcacheService.get("hoge");

をやる。

これで取得できるよ。
話は戻るけど、Google App Engineのドキュメントに合ったように、
memcacheを使う場合は

appengine-web.xml



<sessions-enabled>true</sessions-enabled>

を書いておかないとだめかもしれない。
そこまでは検証してないです。(soraは書いています)

気を付けることは、
putする時に、データが無いと

java.lang.IllegalArgumentException: Cannot use as value: '[]'



java.io.NotSerializableException: org.datanucleus.store.appengine.query.LazyResult

という警告がでます。
どういうチェックが適切かわかりませんが、気をつけて。

あと気になるのが、
未調査なんだけど

・Serializableとの関係
 →memcacheはデータストアにうんたらかんたらとかセッションレプリケーションと関係する記述を見かけたので。
・タイムアウト(有効時間)
 →セッションにタイムアウト時間があるので、何かしらあるはず。

かな。
すぐ思いつくのはこの程度。