我有一个GWT
网络应用正常运行 - 除非我把它放在Marathon-LB
负载均衡器后面并使用HTTPS
。
失败发生在POST周围。
Marathon-LB
之后时,POST将获得200 OK。 Marathon-LB
时,会出现GWT SerializationException
的内部服务器错误,POST会出现500错误。 对于失败的情况,tomcat的服务器日志中的堆栈跟踪就是这个。请注意,该主题是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容器与运行web Tomcat
的docker容器之间的信任证书。
有关如何调试此问题的任何建议?例如,我如何确定Marathon-LB
容器是否信任webapp容器?
谢谢!
答案 0 :(得分:1)
两种可能的方式(至少)负载均衡器可以破坏应该起作用的GWT-RPC:
无论哪种方式,大多数情况都涉及无法找到正确的序列化策略文件(编译输出中的.gwt.rpc文件),而这又是由com.google.gwt.user.server.rpc.RemoteServiceServlet#loadSerializationPolicy
方法中的某些错误引起的。据我所知,所有这些错误都应该导致记录一些错误,尽管它可能是一个不同的文件。也许检查其他服务器日志文件以查看是否出现问题,或者在负载均衡器后面附加并调试该方法,并确保在您看到错误时它返回实际策略。另请注意,这些策略文件已缓存,因此错误只会发生一次,直到您重新启动服务器Web应用程序。
答案 1 :(得分:0)
我认为你的问题是特定于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:添加了缺少的额外代码行;也忘了提及问题可以在getResourcesAsStream
调用中,也可以在!modulePath.startsWith(contextPath)
比较中。