首页 > 解决方案 > AppEngine + GWT-RPC + Search API 给出错误

问题描述

应用引擎 - 1.9.63

GWT - 2.8.1

客户端到服务器端调用:使用标准 GWT RPC 实现

服务器端代码:

IndexSpec indexSpec = IndexSpec.newBuilder().setName("index").build(); 
Index index = SearchServiceFactory.getSearchService().getIndex(indexSpec);
Document doc = Document.newBuilder()...
try{
    index.put(doc); //Line that results in an exception
}catch(Exception e){
    e.printStackTrace();
}

堆栈跟踪:

com.google.apphosting.api.ApiProxy$CallNotFoundException:无法在既不是原始请求线程也不是由 ThreadManager 创建的线程的线程中进行 API 调用search.IndexDocument 在 com.google.apphosting.api.ApiProxy$CallNotFoundException.foreignThread(ApiProxy.java:800) 在 com.google.apphosting.api.ApiProxy$1.get(ApiProxy.java:175) 在 com.google.apphosting.api。 ApiProxy$1.get(ApiProxy.java:172) 在 com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java:89) 在 com.google.appengine.api.utils.FutureWrapper.get(FutureWrapper.java :89) com.google.appengine.api.search.FutureHelper.getInternal(FutureHelper.java:73) com.google.appengine.api.search.FutureHelper.quietGet(FutureHelper.java:32) com.google。 appengine.api.search.IndexImpl.put(IndexImpl.java:485) 在 com.vehicle.track.server.User.save(User.java:82) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun。反射.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect。com.google.gwt.user.server.rpc.RPC.invokeAndEncodeResponse(RPC.java:587) 上的 java.lang.reflect.Method.invoke(Method.java:498) 上的 DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)在 com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:333) 在 com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:303) 在 com.google .gwt.user.server.rpc.RemoteServiceServlet.processPost(RemoteServiceServlet.java:373) 在 com.google.gwt.user.server.rpc.AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62) 在 javax.servlet.http.HttpServlet .service(HttpServlet.java:707) at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:587) at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) at org.eclipse.jetty.security.SecurityHandler.handle( SecurityHandler.java:577) 在 org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) 在 org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) 在 org .eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) 在 org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) 在 org.eclipse.jetty.server.handler.ContextHandler .doScope(ContextHandler.java:1061) 在 org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) 在 org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97 ) 在组织。eclipse.jetty.server.handler.RequestLogHandler.handle(RequestLogHandler.java:95) 在 org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) 在 org.eclipse.jetty.server.Server。 org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) 的 org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) 的句柄(Server.java:499) .jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) at org.eclipse.jetty.util.thread.QueuedThreadPool$3 .run(QueuedThreadPool.java:555) 在 java.lang.Thread.run(Thread.java:748)97) 在 org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) 在 org.eclipse.jetty.server.HttpConnection 的 org.eclipse.jetty.server.Server.handle(Server.java:499) .onFillable(HttpConnection.java:257) 在 org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) 在 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)在 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) 在 java.lang.Thread.run(Thread.java:748)97) 在 org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) 在 org.eclipse.jetty.server.HttpConnection 的 org.eclipse.jetty.server.Server.handle(Server.java:499) .onFillable(HttpConnection.java:257) 在 org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) 在 org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635)在 org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) 在 java.lang.Thread.run(Thread.java:748)org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) at java.lang.Thread.run(Thread.java:748) 的 QueuedThreadPool.runJob(QueuedThreadPool.java:635)org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) at java.lang.Thread.run(Thread.java:748) 的 QueuedThreadPool.runJob(QueuedThreadPool.java:635)

标签: google-app-enginegwtgoogle-cloud-platform

解决方案


借助 App Engine Java8 运行时环境,您可以使用 App Engine 的ThreadManager API和 Java 的内置 API(例如new Thread(). 但是,如文档中所述:

目前,如果您想调用 App Engine API (com.google.appengine.api.*),您必须从请求线程或使用 ThreadManager API 创建的线程调用这些 API。

我可以在您的 Stacktrace 中看到您确实通过线程池使用了后台线程。您需要使用 ThreadManager API 来实现它。


推荐阅读