2010/10/15
Google App Engine for Java 本番環境で NoClassDefFoundError
開発環境でさくさくっと開発して鼻歌交じりにデプロイ&画面確認したら 500 ERROR …
java.lang.NoClassDefFoundError: com/google/apphosting/runtime/security/shared/stub/java/net/InetAddress
NoClassDefFoundError って? と思ったら、クラス名を見るにホワイトリストにない(使用が禁止されている)クラスっぽい。
でもログが指し示す箇所を見る限り、前回デプロイ時と変えてない…っていうかこれライブラリだし!
というわけで該当のコードを見てみました。ちなみにライブラリは JSONIC という POJO <-> json のデコード/エンコードができる素敵ライブラリです。
Seasar.org の Maven リポジトリから取得しているので、バージョンは1.2.0。
net.arnx.jsonic.JSON#preformat
protected Object preformat(Context context, Object value) throws Exception { Object data = null; JSONHint hint = context.getHint(); if (value == null || value instanceof CharSequence || value instanceof Character || value instanceof Boolean || value instanceof Map<?, ?> || value.getClass().isArray() || value instanceof Iterable<?> || value instanceof Iterator<?> || value instanceof Enumeration<?> || value instanceof Element ) { data = value; /* 中略 */ } else if (value instanceof InetAddress) { // ここ(★)で NoClassDefFoundError data = ((InetAddress)value).getHostAddress(); } else if (value instanceof Charset) { /* 中略 */ } else { data = value; } return data; }
見た感じ、value をひたすら instanceof 比較して型ごとに処理してるみたいですね。
で、実際に開発環境で実行して、該当箇所(★)にブレークポイントを指定してみたところ、そこに達した時の value の型が com.google.appengine.api.datastore.Key でした…
つまり、★以前の instanceof 比較 で引っかからなかったのでここに達した結果、NoClassDefFoundError が吐かれたってことですね。
というか、ホワイトリストにない型でも、import しただけでは NoClassDefFoundError って吐かれないんですね…
参考 via / @nekop
JSONIC は appengine に特化されたライブラリではないので、ホワイトリストにないクラスを使ってるのはしょうがない、ということで JSON#encode に渡す POJO の中身を気をつけるしかないのかなー
ちなみに、slim3 のモデルは POJO なので最初はそのまま渡してたのですが、ModelRef なんかがあると JSON#encode にやたら時間がかかったり、OutOfMemoryError になったりするので、ぼくはこんな風にしてます。
// Foo model; com.google.appengine.api.datastore.Entity e = FooMeta.get().modelToEntity(model); Map<String, Object> result = e.getProperties(); /* * Entity#getProperties で返ってくる Map は UnmodifiableMap なので、 * 上記のKeyとかをMap#removeしたりするとき、UnsupportedOperationException が発生するため… */ result = new HashMap<String, Object>(result); // 以下略
- 43 http://drillbits.jp/
- 26 http://longurl.org
- 21 http://twitter.com/
- 19 http://ms2.seesaa.net/article/165939546.html
- 15 http://friendfeed.com/shin1ogawa/4420bdd9/google-app-engine-for-java
- 15 http://www.google.co.jp/search?hl=ja&lr=lang_ja&tbs=lr:lang_1ja&q=javascript+タイムゾーン+変換&aq=2&aqi=g3g-c1&aql=&oq=javascript+タイムゾーン&gs_rfai=
- 9 http://d.hatena.ne.jp/keyword/jsonic
- 9 http://hootsuite.com/dashboard
- 9 http://search.minakoe.jp/rsss/rsss.asp?pgsz=100&qry=java¬wit=1&twit=0&debug=1&multi=1
- 9 http://www.google.co.jp/search?sourceid=navclient&hl=ja&ie=UTF-8&rlz=1T4GGLL_jaJP351JP351&q=java+Outputter
