2011-08-12 56 views
7

的當運行在託管模式下我的GWT應用程序(GWT 2.0.4),調用遠程Tomcat上運行RPC方法,我得到GWT序列化異常:GWT序列化政策託管模式不同步

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 = [email protected] 
.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 

託管模式產生使用不同的md5序列化策略文件(* .gwt.rpc),這些是在GWT編譯過程中創建的 - 這些部署在我的服務器上。 GWT缺少託管模式客戶端需要的序列化策略文件。

當在非託管模式下運行時,一切都很好。

我試圖通過Ant或Eclipse調試配置啓動託管模式,結果相同。 GWT編譯類路徑和託管模式類路徑(包括)是相同的。

GWT編譯Ant腳本:

<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> 

託管模式啓動 - Ant腳本:

<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方法簽名:

public List<MyData> getSmpeWorkDddefZonesData(String processId); 

MyData定義(在ProjectE宣稱是非-GWT項目 - 數據層):

package com.mypackage.data; 

import java.io.Serializable; 

public interface MyData extends Serializable {... 

邁德特從其他GWT模塊繼承模塊鏈接: com.mypackage.Data.gwt.xml

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

主要模塊com.myapp.Main.gwt.xml

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

如何使託管產生相同的序列化策略文件?

回答

3

我一直有同樣的問題。我看到的唯一解決方案是確保您在兩側都具有相同的.gwt.rpc文件。

這意味着,每次啓動或重新加載開發模式時,都必須用新生成的文件替換部署在您的Web服務器上的舊文件.gwt.rpc

或者您將開發模式戰爭輸出目錄指向Web服務器上下文。並確保Web服務器已啓用自動部署。所以每次Dev模式更改文件時,Web服務器都會自動重新加載文件。

+2

感謝,它幫助!只需添加更多細節:我必須使用-war/path/to/my/built/war選項啓動託管模式,而不是默認路徑。 – foch

0

根據我在com.google.gwt.user.rebind.rpc.ProxyCreator中看到的內容,GWT通過其內容(md5)生成序列化策略.gwt.rpc文件的名稱。

因此,出於某種原因,超級開發模式下的序列化策略與正常構建期間生成的不同。

下面的方法解決了這個問題對我來說:

  1. 打開系列化政策.gwt.rpc的常規構建
  2. 打開系列化策略生成.gwt.rpc文件生成的文件爲超級開發模式。您可以通過查看Super Dev Mode啓動時打印的工作目錄來找到它的位置。例如。在我的情況下,它是:「workDir:C:\ Users \ your_user \ AppData \ Local \ Temp \ gwt-codeserver-5658052675265790575.tmp」
  3. 比較2個文件 - 這可以給你一個很好的提示,可能。在我的情況下,2個不需要的類型被添加到序列化策略中,我可以完全將它們從項目中刪除。
  4. 固定不符的.gwt.rpc文件名後應該再是相同的,問題將是固定的:)