GWT SerializationException,但仅当涉及marathon LB时

GWT SerializationException,但仅当涉及marathon LB时,gwt,mesos,marathon,mesosphere,jsse,Gwt,Mesos,Marathon,Mesosphere,Jsse,我有一个GWTwebapp运行良好——除非我把它放在Marathon LB负载平衡器后面并使用HTTPS 失败发生在一根柱子周围 当webapp没有落后于Marathon LB时,帖子将获得200 OK 但是当它在后面时,会出现内部服务器错误GWTSerializationException,POST会得到500个错误 对于失败案例,tomcat服务器日志中的stacktrace如下所示。请注意,线程是https-jsse-nio-8080-exec-6 01-Feb-2018 18:43:

我有一个
GWT
webapp运行良好——除非我把它放在
Marathon LB
负载平衡器后面并使用
HTTPS

失败发生在一根柱子周围

  • 当webapp没有落后于
    Marathon LB
    时,帖子将获得200 OK
  • 但是当它在
    后面时,会出现内部服务器错误GWT
    SerializationException
    ,POST会得到500个错误
对于失败案例,tomcat服务器日志中的stacktrace如下所示。请注意,线程是https-jsse-nio-8080-exec-6

01-Feb-2018 18:43:39.863 SEVERE [https-jsse-nio-8080-exec-6] org.apache.catalina.core.ApplicationContext.log Exception while dispatching incoming RPC call
com.google.gwt.user.client.rpc.SerializationException: Type 'com.company.SomeGwtSerializableClass' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializ
able' and did not have a custom field serializer.For security purposes, this type will not be serialized.: instance = com.company.SomeGwtSerializableClass@6ce9a6c9
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:667)
        at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:130)
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:153)
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:587)
我怀疑问题在于运行
Marathon LB
的docker容器和运行为webapp服务的
Tomcat
的docker容器之间的信任证书

关于如何调试这个有什么建议吗?例如,我如何确定
容器信任webapp容器

谢谢

负载平衡器有两种可能(至少)破坏GWT-RPC的方法,否则GWT-RPC将无法正常工作:

  • 提供错误的内容:这可能以几种方式发生,例如,如果负载平衡器缓存了某个内容,或者它后面的某个服务器提供了过期的文件,然后该客户端连接到最新的服务器
  • 处理传入呼叫:负载平衡器有几种可能出错或“帮助”并破坏某些东西的方法-删除头,将请求中的moduleBaseUrl重写为其他内容,等等

无论哪种方式,大多数情况都涉及到找不到正确的序列化策略文件(编译输出中的.gwt.rpc文件),而这又是由
com.google.gwt.user.server.rpc.RemoteServiceServlet#loadSerializationPolicy
方法中的某些错误引起的。据我所知,所有这些错误都会导致一些错误也被记录下来,尽管它可能是另一个文件。可能检查其他服务器日志文件以查看是否出现错误,或者在负载平衡器后面附加并调试该方法,并确保在发生错误时该方法返回实际策略。另外请记住,这些策略文件是缓存的,因此在重新启动服务器webapp之前,错误只会发生一次。

我认为您的问题与RPC有关

作为某种验证/保护的一部分,RPC尝试在服务器端通过getServletContext().getResourceAsStream加载这些序列化策略

/*
 * Check that the module path must be in the same web app as the servlet
 * itself. If you need to implement a scheme different than this, override
 * this method.
 */
if (modulePath == null || !modulePath.startsWith(contextPath)) {
  String message = "ERROR: The module path requested, "
      + modulePath
      + ", is not in the same web application as this servlet, "
      + contextPath
      + ".  Your module may not be properly configured or your client and server code maybe out of date.";
  servlet.log(message);
} else {
  // Strip off the context path from the module base URL. It should be a
  // strict prefix.
  String contextRelativePath = modulePath.substring(contextPath.length());

  String serializationPolicyFilePath = SerializationPolicyLoader.getSerializationPolicyFileName(contextRelativePath
      + strongName);

  // Open the RPC resource file and read its contents.
  InputStream is = servlet.getServletContext().getResourceAsStream(
      serializationPolicyFilePath);
您可以在此处看到这一点:

上面的问题是,
serializationPolicyFilePath
是基于客户端路径构建的。因此,如果您的客户机路径和服务器路径不同,您将遇到问题

在这方面我遇到了很多麻烦,最后我通过
RemoteServiceServlet
覆盖了内容,以便能够从不同的位置加载策略文件


Edit1:添加缺少的额外代码行;还忘了提到问题可能在
getResourcesStream
调用中,也可能在
中!modulePath.startsWith(contextPath)
比较。

当您落后于Marathon LB时,您是否通过不同的URL访问应用程序?是的,URL不同。