gwt serialization policy hosted mode out of sync

2019-02-13 11:58发布

When running my GWT application (gwt 2.0.4) in hosted mode, calling RPC methods running on remote Tomcat, I get GWT serialization exception:

INFO: GwtRpcEventSrvc: ERROR: The serialization policy file '/84EC7BA65AF8175BAA99B47877FDE163.gwt.rpc' was not found; did you forget to include it in this deployment?

SEVERE: GwtRpcEventSrvc: WARNING: Failed to get the SerializationPolicy '84EC7BA65AF8175BAA99B47877FDE163' for module 'http://host:19980/MYAPP/'; a legacy, 1.3.3 compatible, serialization policy will be used.  Youmay experience SerializationExceptions as a result.

SEVERE: Exception while dispatching incoming RPC call
Throwable occurred: com.google.gwt.user.client.rpc.SerializationException: java.lang.reflect.InvocationTargetException
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeWithCustomSerializer(ServerSerializationStreamWriter.java:760)
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeImpl(ServerSerializationStreamWriter.java:723)
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:612)
.at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129)
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:152)
...
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'com.mypackage.data.MyData' was not assignable to 'com.google.gwt.user.client.rpc.IsSerializable' and did not have a custom field serializer.For security purposes, this type will not be serialized.: instance = com.mypackage.data.MyData@1b061b06
.at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:610)
.at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:129)
.at com.google.gwt.user.client.rpc.core.java.util.Collection_CustomFieldSerializerBase.serialize(Collection_CustomFieldSerializerBase.java:43)
.at com.google.gwt.user.client.rpc.core.java.util.LinkedList_CustomFieldSerializer.serialize(LinkedList_CustomFieldSerializer.java:36)
.... 33 more

Hosted mode generates serializations policy files (*.gwt.rpc) with different md5 that those that were created during GWT compilation - these are deployed on my server. GWT is missing serialization policy file that hosted mode client wants.

When running in non-hosted mode everything is fine.

I tried to launch hosted mode via Ant or Eclipse debug configuration with the same results. GWT compilation classpath and hosted mode classpath (including) are the same.

GWT Compilation Ant script:

<java failonerror="true" fork="true" classname="com.google.gwt.dev.Compiler">
  <classpath>
    <pathelement location="${basedir}/src" />
    <pathelement location="${dir.build.root}/ProjectA/src" />
    <pathelement location="${dir.build.root}/ProjectB/src" />
    <pathelement location="${dir.build.root}/ProjectC/src" />
    <pathelement location="${dir.build.root}/ProjectD/src" />
    <pathelement location="${dir.build.root}/ProjectE/src" />
    <pathelement location="${dir.root}/ProjectD/src" />
    <pathelement location="${dir.root}/THIRDPARTY/build/athirdparty.jar" />
    <pathelement location="${dir.commons.gwtcompiler}/gwt-user.jar" />
    <pathelement location="${dir.commons.gwtcompiler}/gwt-dev.jar" />
    <pathelement location="../ExternalLibs/libs/gwt-log-3.0.0.jar" />
<!-- JAXB API sources needed for GWT compilation of JAXB annotated classes -->
    <pathelement location="../ExternalLibs/nonshipjars/jaxb-api-src.zip" />
  </classpath>
  <jvmarg value="-Xmx1g" />
  <jvmarg value="-Dgwt.nowarn.metadata" />
  <arg line="-localWorkers 2 -style OBF" />
  <arg line="-war ${basedir}/www" />
  <arg line="-extra ${basedir}/build" />
  <arg value="com.myapp.Main" />
</java>

Hosted mode launch - Ant script:

<target name="hosted" description="Run hosted mode">
  <java failonerror="true" fork="true" classname="com.google.gwt.dev.HostedMode">
    <classpath>
        <pathelement location="${basedir}/src" />
        <pathelement location="${dir.build.root}/ProjectA/src" />
        <pathelement location="${dir.build.root}/ProjectB/src" />
        <pathelement location="${dir.build.root}/ProjectC/src" />
        <pathelement location="${dir.build.root}/ProjectD/src" />
        <pathelement location="${dir.build.root}/ProjectE/src" />
        <pathelement location="${dir.root}/ProjectD/src" />
        <pathelement location="${dir.root}/THIRDPARTY/build/athirdparty.jar" />
        <pathelement location="${dir.commons.gwtcompiler}/gwt-user.jar" />
        <pathelement location="${dir.commons.gwtcompiler}/gwt-dev.jar" />
        <pathelement location="../ExternalLibs/libs/gwt-log-3.0.0.jar" />
    <!-- JAXB API sources needed for GWT compilation of JAXB annotated classes -->
        <pathelement location="../ExternalLibs/nonshipjars/jaxb-api-src.zip" />
    </classpath>
    <jvmarg value="-Xmx1g" />
    <jvmarg value="-Dgwt.nowarn.metadata" />
    <arg line="com.myapp.Main" />
    <arg line="-startupUrl" />
    <arg line=" http://host:19980/MYAPP/Main.html" />
    <arg line="-whitelist" />
    <arg line="^http[:][/][/]host[:]19980" />
    <arg line="-whitelist" />
    <arg line=" ^http[:][/][/]localhost" />
    <arg line="-whitelist" />
    <arg line="^http[:][/][/]127.0.0.1" />
    <arg line="-port" />
    <arg line="8080" />
    <arg line="-noserver" />
    <arg line="-logLevel" />
    <arg line="DEBUG" />
  </java>
</target>

RPC method signature:

public List<MyData> getSmpeWorkDddefZonesData(String processId);

MyData definition (declared in ProjectE that is non-GWT project - data tier):

package com.mypackage.data;

import java.io.Serializable;

public interface MyData extends Serializable {...

MyData is linked in module inherited from another GWT module: com.mypackage.Data.gwt.xml:

<module>
  <source path="data" />
</module>

Main module com.myapp.Main.gwt.xml:

...
  <inherits name="com.mypackage.Data" />
...

How to make hosted generate the same serialization policy files?

2条回答
神经病院院长
2楼-- · 2019-02-13 12:13

Based on what I see in com.google.gwt.user.rebind.rpc.ProxyCreator GWT generates the names of the serialization policy .gwt.rpc files by their content (md5).

So for some reason the serialization policy in the Super Dev Mode is different than the one generated during the normal build.

The following approach fixed the problem for me:

  1. Open the serialization policy .gwt.rpc file generated for the regular build
  2. Open the serialization policy .gwt.rpc file generated for the Super Dev Mode. You can find where it is by looking into the work directory printed at Super Dev Mode startup. E.g. in my case it was: "workDir: C:\Users\your_user\AppData\Local\Temp\gwt-codeserver-5658052675265790575.tmp"
  3. Compare the 2 files - this could give you a pretty good hint regarding where the problem might be. In my case 2 unneeded types were getting added to the serialization policy and I could simply remove them from the project completely.
  4. After fixing the discrepancies the .gwt.rpc files name should be identical again and the problem will be fixed :)
查看更多
闹够了就滚
3楼-- · 2019-02-13 12:17

I've been having the same problem. The only solution I see, is to make sure you have the same .gwt.rpc files on both sides.

That means, everytime you start or reload Dev Mode, you have to replace the old .gwt.rpc files deployed on your web server with the newly generated ones.

Or you point the Dev Mode war output directory to the web server context. And make sure the web server has auto-deploy turned on. So every time the files are changed by Dev Mode, the web server automatically reloads the files.

查看更多
登录 后发表回答