我正在为 Google App Engine 实施一个项目。
此时我有以下设置:
- 我有几个 servlet 可以将一些数据返回给客户端应用程序(例如 Android/iOS 客户端)
- 为了测试这个 servlet,我创建了访问这个 servlet 的 junit 测试。
- 在 servlet 内部,有一些逻辑可以确定我们是在运行测试还是从客户端进行实际调用。如果我们在本地机器上运行测试,我们会初始化 LocalServiceTestHelper 以使数据存储、内存缓存等工作。
这一切都很好。
现在问题来了。当我将 AppStats 过滤器添加到我的 web.xml 时,这也适用于在语言环境 junit 测试中使用的 servlet。但是 AppStats 过滤器不起作用。运行测试时,我得到以下堆栈跟踪:
java.lang.NullPointerException
at com.google.appengine.tools.appstats.Recorder.checkNotNull(Recorder.java:378)
at com.google.appengine.tools.appstats.Recorder.<init>(Recorder.java:210)
at com.google.appengine.tools.appstats.Recorder.<init>(Recorder.java:200)
at com.google.appengine.tools.appstats.AppstatsFilter.init(AppstatsFilter.java:183)
at org.mortbay.jetty.servlet.FilterHolder.doStart(FilterHolder.java:97)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:593)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1220)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:513)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:448)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.handler.RequestLogHandler.doStart(RequestLogHandler.java:115)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at org.mortbay.jetty.handler.HandlerWrapper.doStart(HandlerWrapper.java:130)
at org.mortbay.jetty.Server.doStart(Server.java:222)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:39)
at com.google.gwt.dev.shell.jetty.JettyLauncher.start(JettyLauncher.java:672)
at com.google.gwt.dev.DevMode.doStartUpServer(DevMode.java:509)
at com.google.gwt.dev.DevModeBase.startUp(DevModeBase.java:1093)
at com.google.gwt.junit.JUnitShell.getUnitTestShell(JUnitShell.java:707)
at com.google.gwt.junit.JUnitShell.runTest(JUnitShell.java:652)
at com.google.gwt.junit.client.GWTTestCase.runTest(GWTTestCase.java:441)
at junit.framework.TestCase.runBare(TestCase.java:141)
at junit.framework.TestResult$1.protect(TestResult.java:122)
at junit.framework.TestResult.runProtected(TestResult.java:142)
at junit.framework.TestResult.run(TestResult.java:125)
at junit.framework.TestCase.run(TestCase.java:129)
at com.google.gwt.junit.client.GWTTestCase.run(GWTTestCase.java:296)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at junit.framework.TestSuite.runTest(TestSuite.java:255)
at junit.framework.TestSuite.run(TestSuite.java:250)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.run(JUnitTestRunner.java:518)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.launch(JUnitTestRunner.java:1052)
at org.apache.tools.ant.taskdefs.optional.junit.JUnitTestRunner.main(JUnitTestRunner.java:906)
有人知道为什么 AppStats 会出现 NullPointerException 吗?
据我所知,我在这里有两个选择:
- 让 AppStats 过滤器在我当前的 junit 测试中工作。
- 为我的语言环境 junit 测试禁用 AppStats 过滤器,但在正常调用 servlet 时保持它处于活动状态。
两者都很好,但我更喜欢选项 1。
2013 年 4 月 19 日更新:
- 我尝试在过滤器之前初始化 MemCache(如下所述),但这似乎没有解决任何问题。与以前相同的堆栈跟踪。
- 从 Recorder.java 源代码中,我发现构造函数中的 Delegate 参数可能为空,但我不知道为什么。(https://code.google.com/p/googleappengine/source/browse/trunk/java/src/main/com/google/appengine/tools/appstats/Recorder.java)