App Engine(突然间)告诉我,我的Objectify设置不正确。它之前正在工作,我做在我的web.xml中有Objectify Filter。
这是我日志中的完整堆栈跟踪:
javax.servlet.ServletContext log: unavailable
java.lang.IllegalStateException: You have not started an Objectify context.
You are probably missing the ObjectifyFilter.
If you are not running in the context of an http request, see the ObjectifyService.run() method.
at com.googlecode.objectify.ObjectifyService.ofy(ObjectifyService.java:44)
at com.mydomain.gae.defaultmodule.MyObject.loadEverything(MyObject.java:21)
at com.mydomain.gae.defaultmodule.MyServlet.init(MyServlet.java:40)
at javax.servlet.GenericServlet.init(GenericServlet.java:212)
at org.mortbay.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:440)
at org.mortbay.jetty.servlet.ServletHolder.doStart(ServletHolder.java:263)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at org.mortbay.jetty.servlet.ServletHandler.initialize(ServletHandler.java:685)
at org.mortbay.jetty.servlet.Context.startContext(Context.java:140)
at org.mortbay.jetty.webapp.WebAppContext.startContext(WebAppContext.java:1250)
at org.mortbay.jetty.handler.ContextHandler.doStart(ContextHandler.java:517)
at org.mortbay.jetty.webapp.WebAppContext.doStart(WebAppContext.java:467)
at org.mortbay.component.AbstractLifeCycle.start(AbstractLifeCycle.java:50)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.createHandler(AppVersionHandlerMap.java:206)
at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.getHandler(AppVersionHandlerMap.java:179)
at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:136)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:469)
at com.google.tracing.TraceContext$TraceContextRunnable.runInContext(TraceContext.java:437)
at com.google.tracing.TraceContext$TraceContextRunnable$1.run(TraceContext.java:444)
at com.google.tracing.CurrentContext.runInContext(CurrentContext.java:256)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContextNoUnref(TraceContext.java:308)
at com.google.tracing.TraceContext$AbstractTraceContextCallback.runInInheritedContext(TraceContext.java:300)
at com.google.tracing.TraceContext$TraceContextRunnable.run(TraceContext.java:441)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:235)
at java.lang.Thread.run(Thread.java:745)
这是我的web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1">
<listener>
<listener-class>
com.mydomain.gae.defaultmodule.Initializer
</listener-class>
</listener>
<servlet>
<servlet-name>MyServlet</servlet-name>
<servlet-class>com.mydomain.gae.defaultmodule.MyServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>MyServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
</web-app>
...然后是代码:
public class Initializer implements ServletContextListener {
@Override
public void contextInitialized(@Nonnull final ServletContextEvent SCE) {
ObjectifyFactory oFactory = ObjectifyService.factory();
oFactory.register(MyEntity.class);
oFactory.register(MyOtherEntity.class);
oFactory.begin();
}
}
public final class MyServlet extends HttpServlet {
private MyObject = myObj;
@Override
public void init() throws ServletException {
myObj = new MyObject();
myObj.loadEverything();
}
}
public class MyObject extends MyOtherObject {
public void loadEverything() {
for (MyEntity me : ofy().load().type(MyEntity.class).list()) {
// Do very important things.
}
}
}
IllegalStateException
一旦到达ofy().load().type(MyEntity.class).list()
,就会被抛出。此代码以前有效。我不知道为什么这个突然爆炸在我脸上,因为这里所分享的代码都没有被改变。
如果有人有任何想法可能让我朝着正确的方向前进,我对听到他们100%有兴趣。
答案 0 :(得分:5)
过滤器适用于请求。您的servlet init方法未在请求的上下文中调用,因此ObjectifyFilter未运行 - 请注意它不在您的堆栈跟踪中。
摆脱oFactory.begin()
中的contextInitialized()
,这不正确使用该方法。
如果您想在servlet init()
中使用Objectify,请在ObjectifyService.run()
内运行代码:
ObjectifyService.run(new VoidWork() {
public void vrun() {
myObj = new MyObject();
myObj.loadEverything();
}
});
这将设置&amp;以与过滤器相同的方式拆除Objectify上下文。
答案 1 :(得分:0)
对我来说,问题出在web.xml文件中。我必须添加过滤器和过滤器映射...
<filter>
<filter-name>ObjectifyFilter</filter-name>
<filter-class>com.googlecode.objectify.ObjectifyFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>ObjectifyFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
但是,我在ServletContextListener中使用了ObjectifyFactory。像这样:
ObjectifyService.init(new ObjectifyFactory(
DatastoreOptions.newBuilder()
.setProjectId("PROJECT_ID")
.build()
.getService()
));