SiNBLOG

140文字に入らないことを、極稀に書くBlog

GAE/JでGson利用時にjava.lang.VerifyErrorが発生する

Jsonを利用するライブラリとして、Gsonを利用しているのですが、最近Errorが出る。
しかも、それがProduction環境のみという、なかなか辛い状況。
更に原因がよく分からず、デプロイする度に変わるという辛い状況。

Errorが発生しているのは、Gsonのコンストラタ実行時。


Gson gson = new Gson();

普通にコンストクタを実行しているだけのつもり・・・。

環境はSDK 1.6.0, Slim3 1.0.15, gson2.1

Gson gson = new Gson();するだけのプロジェクトを作成して、デプロイしてみたところ
正常に動いているので、必ずしもgsonを使う部分に問題があるとも言い難い感じ・・・。

stackoverflowは以下の通り。


Error for /urlfetch/
java.lang.VerifyError: Cannot inherit from final class
at com.google.appengine.runtime.Request.process-74f4d481c055ff4e(Request.java)
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:634)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:277)
at sun.reflect.GeneratedMethodAccessor5.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at java.lang.ClassLoader.loadClass(ClassLoader.java:266)
at org.sinsandbox.controller.urlfetch.IndexController.buildeTweetList(IndexController.java:66)
at org.sinsandbox.controller.urlfetch.IndexController.run(IndexController.java:36)
at org.slim3.controller.Controller.runBare(Controller.java:111)
at org.slim3.controller.FrontController.processController(FrontController.java:491)
at org.slim3.controller.FrontController.doFilter(FrontController.java:277)
at org.slim3.controller.FrontController.doFilter(FrontController.java:237)
at org.slim3.controller.FrontController.doFilter(FrontController.java:199)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.slim3.datastore.DatastoreFilter.doFilter(DatastoreFilter.java:55)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.slim3.controller.HotReloadingFilter.doFilter(HotReloadingFilter.java:192)
at org.slim3.controller.HotReloadingFilter.doFilter(HotReloadingFilter.java:157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
at org.mortbay.jetty.Server.handle(Server.java:326)
at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:449)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:455)
at com.google.tracing.TraceContext.runInContext(TraceContext.java:695)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:333)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:325)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:453)
at java.lang.Thread.run(Thread.java:679)

IndexController.buildeTweetList(IndexController.java:66)
上の行が、実際にErrorが発生している行で、Gson gson = new Gson();です。

よく分からないので、いじくり回していたのだけど、appengine-web.xmlを変えたら、何故か直った。
しかし、デプロイし直したから、直ったような気もするし、よく分からない。
また、別のAppでも同じErrorが出るのだけど、appengine-web.xmlの設定をコピーしてもダメだった。

appengine-web.xmlのbefore afterは以下の通り。
before



sin4sandbox


1


true





















true


true


after



sin4sandbox


201204191949


true


















true


threadsafeがtrueになっていたからかとも思ったのだけど、コメントアウトしても変わらず・・・。
デプロイ時に何かがしくじっているだけなのか・・・、他に原因があるのか・・・。
今のところ、分からない・・・。

最後にGsonをnewしているControllerのソース


package org.sinsandbox.controller.urlfetch;

import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import org.slim3.controller.Controller;
import org.slim3.controller.Navigation;

import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchService;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;

/**
* UrlFetchIndexController
*
* @author Sinmetal
*
*/
public class IndexController extends Controller {

/**
* Twitter検索APIをFetchする
*/
@Override
public Navigation run() throws Exception {
final String TWITER_SEARCH_URL =
"http://search.twitter.com/search.json?q=gaeja";
String tweetJson = fetchUrl(TWITER_SEARCH_URL, "UTF-8");

List tweetList = buildeTweetList(tweetJson);

requestScope("tweetList", tweetList);
return forward("index.jsp");
}

/**
* 指定したURLをFetchする
*
* @param urlStr
* @param encoding
* @return
* @throws IOException
*/
private String fetchUrl(String urlStr, String encoding) throws IOException {
URLFetchService service = URLFetchServiceFactory.getURLFetchService();
URL url = new URL(urlStr);
HTTPResponse res = service.fetch(url);
return new String(res.getContent(), encoding);
}

/**
* Twitter検索APIの結果から、TweetListを作る
*
* @param searchJson
* @return
*/
private List buildeTweetList(String searchJson) {
List tweetList = new ArrayList();
try {
Gson gson = new Gson();
JsonElement element = gson.fromJson(searchJson, JsonElement.class);
JsonObject json = element.getAsJsonObject();
JsonArray array = json.getAsJsonArray("results");
for (int i = 0; i < array.size(); i++) {
Object obj = array.get(i);
if (obj instanceof JsonObject) {
tweetList.add((JsonObject) obj);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return tweetList;
}
}

何かお心当たりがある方は、是非コメントかtwitterで教えてください。