GAE 端点异常:服务名称不匹配
GAE Endpoints Exception: service name mismatch
我正在尝试为 Google App Engine 上的项目设置 REST API,并且已经部署。但是,调用 API 会导致向客户端返回错误 500,并且在 GAE 的日志中,会显示以下堆栈跟踪。
堆栈跟踪:
com.google.apphosting.runtime.jetty9.JettyLogger warn: /_ah/api/handler/v1/fetchlatest/all (JettyLogger.java:29)
java.lang.IllegalArgumentException: service name mismatch
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
at com.google.api.control.aggregator.CheckRequestAggregator.check(CheckRequestAggregator.java:223)
at com.google.api.control.Client.check(Client.java:177)
at com.google.api.control.ControlFilter.doFilter(ControlFilter.java:249)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.api.control.ConfigFilter.doFilter(ConfigFilter.java:120)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.runtime.jetty9.SaveSessionFilter.doFilter(SaveSessionFilter.java:37)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:297)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:534)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
at com.google.apphosting.runtime.jetty9.RpcConnection.handle(RpcConnection.java:202)
at com.google.apphosting.runtime.jetty9.RpcConnector.serviceRequest(RpcConnector.java:81)
at com.google.apphosting.runtime.jetty9.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:108)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest(JavaRuntime.java:680)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest(JavaRuntime.java:642)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:612)
at com.google.apphosting.runtime.JavaRuntime$NullSandboxRequestRunnable.run(JavaRuntime.java:806)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:274)
at java.lang.Thread.run(Thread.java:745)
我不确定问题出在哪里,但从堆栈跟踪中猜测,可能是由于 web.xml 中 Objectify 过滤器的配置方式所致,因此,所有请求都首先命中 Objectify?虽然我不得不承认,这似乎不太可能,因为其他请求被路由到正确的 servlet。
对象化过滤器:
<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.xml 包含错误的初始参数(endpoint.serviceName 而不是 endpoints.serviceName)。最重要的是,甚至 属性 的参数值也是错误的。不可否认,我们花了比预期更长的时间来弄清楚本应在同行评审中发现的内容。
如果您遵循 https://cloud.google.com/endpoints/docs/frameworks/java/adding-api-management
上的官方文档,就会遇到此问题
有一个部分告诉您将一些代码复制到您的 web.xml,显示:
...
<init-param>
<param-name>endpoints.serviceName</param-name>
<param-value>${endpoints.project.id}.appspot.com</param-value>
</init-param>
...
目前还不清楚该变量是如何解析的。他们不会指示您将其更改为您的实际项目 ID,因此您认为它是由插件或其他东西更新的...
但事实并非如此。结果他们从 https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/appengine-java8/endpoints-v2-backend
的 github 项目中获取了一些代码
但他们忽略了变量实际上是由该项目的 build.gradle 文件中的自定义任务更新的。
// this replaces the ${endpoints.project.id} in appengine-web.xml and web.xml
task replaceProjectId(type: Copy) {
from 'src/main/webapp/WEB-INF/'
include '*.xml'
into "build/exploded-${archivesBaseName}/WEB-INF"
expand(endpoints:[project:[id:projectId]])
filteringCharset = 'UTF-8'
}
assemble.dependsOn replaceProjectId
希望对您有所帮助!
我正在尝试为 Google App Engine 上的项目设置 REST API,并且已经部署。但是,调用 API 会导致向客户端返回错误 500,并且在 GAE 的日志中,会显示以下堆栈跟踪。
堆栈跟踪:
com.google.apphosting.runtime.jetty9.JettyLogger warn: /_ah/api/handler/v1/fetchlatest/all (JettyLogger.java:29)
java.lang.IllegalArgumentException: service name mismatch
at com.google.common.base.Preconditions.checkArgument(Preconditions.java:122)
at com.google.api.control.aggregator.CheckRequestAggregator.check(CheckRequestAggregator.java:223)
at com.google.api.control.Client.check(Client.java:177)
at com.google.api.control.ControlFilter.doFilter(ControlFilter.java:249)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.api.control.ConfigFilter.doFilter(ConfigFilter.java:120)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.googlecode.objectify.ObjectifyFilter.doFilter(ObjectifyFilter.java:48)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:125)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.runtime.jetty9.SaveSessionFilter.doFilter(SaveSessionFilter.java:37)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.utils.servlet.JdbcMySqlConnectionCleanupFilter.doFilter(JdbcMySqlConnectionCleanupFilter.java:60)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:48)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1759)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:582)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:524)
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:226)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1180)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:512)
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1112)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141)
at com.google.apphosting.runtime.jetty9.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:297)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:134)
at org.eclipse.jetty.server.Server.handle(Server.java:534)
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:320)
at com.google.apphosting.runtime.jetty9.RpcConnection.handle(RpcConnection.java:202)
at com.google.apphosting.runtime.jetty9.RpcConnector.serviceRequest(RpcConnector.java:81)
at com.google.apphosting.runtime.jetty9.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:108)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchServletRequest(JavaRuntime.java:680)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.dispatchRequest(JavaRuntime.java:642)
at com.google.apphosting.runtime.JavaRuntime$RequestRunnable.run(JavaRuntime.java:612)
at com.google.apphosting.runtime.JavaRuntime$NullSandboxRequestRunnable.run(JavaRuntime.java:806)
at com.google.apphosting.runtime.ThreadGroupPool$PoolEntry.run(ThreadGroupPool.java:274)
at java.lang.Thread.run(Thread.java:745)
我不确定问题出在哪里,但从堆栈跟踪中猜测,可能是由于 web.xml 中 Objectify 过滤器的配置方式所致,因此,所有请求都首先命中 Objectify?虽然我不得不承认,这似乎不太可能,因为其他请求被路由到正确的 servlet。
对象化过滤器:
<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.xml 包含错误的初始参数(endpoint.serviceName 而不是 endpoints.serviceName)。最重要的是,甚至 属性 的参数值也是错误的。不可否认,我们花了比预期更长的时间来弄清楚本应在同行评审中发现的内容。
如果您遵循 https://cloud.google.com/endpoints/docs/frameworks/java/adding-api-management
上的官方文档,就会遇到此问题有一个部分告诉您将一些代码复制到您的 web.xml,显示:
...
<init-param>
<param-name>endpoints.serviceName</param-name>
<param-value>${endpoints.project.id}.appspot.com</param-value>
</init-param>
...
目前还不清楚该变量是如何解析的。他们不会指示您将其更改为您的实际项目 ID,因此您认为它是由插件或其他东西更新的...
但事实并非如此。结果他们从 https://github.com/GoogleCloudPlatform/java-docs-samples/tree/master/appengine-java8/endpoints-v2-backend
的 github 项目中获取了一些代码但他们忽略了变量实际上是由该项目的 build.gradle 文件中的自定义任务更新的。
// this replaces the ${endpoints.project.id} in appengine-web.xml and web.xml
task replaceProjectId(type: Copy) {
from 'src/main/webapp/WEB-INF/'
include '*.xml'
into "build/exploded-${archivesBaseName}/WEB-INF"
expand(endpoints:[project:[id:projectId]])
filteringCharset = 'UTF-8'
}
assemble.dependsOn replaceProjectId
希望对您有所帮助!