GWT和Enum的问题

时间:2010-11-17 18:49:34

标签: java gwt enums

我在GWT应用程序的客户端部分有一个枚举,当我尝试运行与序列化问题相关的异常时,我得到一个异常。我做错了吗?我读到GWT支持枚举,我使用的是最后一个版本。

枚举:

public enum AnEnum implements Serializable {

    ITEM_A("Item a description"), ITEM_B("Item b description");

    private String description;

    private AnEnum(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

}

例外:

Caused by: java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeWithCustomSerializer(ServerSerializationStreamWriter.java:742)
    ... 47 more
Caused by: com.google.gwt.user.client.rpc.SerializationException: Type '(...).client.(...).AnEnum' was not included in the set of types which can be serialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be serialized.: instance = ITEM_A
    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)
    ... 52 more

8 个答案:

答案 0 :(得分:14)

添加IsSerializable接口,默认的作用域无参数构造函数,并确保它位于gwt.xml文件中源标记中列出的路径之一。 <source path="client">

我真的认为第三个建议就是问题;我记得之前有这个问题,因为我在源路径之外有一个dto。

您可以拥有多个源代码。

<source path="common" />
<source path="client" />

一种模式是将持久化对象直接放在com.mysite.common下,并在com.mysite.common.dto中通过线路传输持久化项目的mashup,当然客户端gui代码也在客户端。< / p>

package com.mysite.client;

import java.io.Serializable;

import com.google.gwt.user.client.rpc.IsSerializable;

public enum AnEnum implements Serializable, IsSerializable {

    ITEM_A("Item a description"), ITEM_B("Item b description");

    private String description;

    AnEnum() {
    }

    AnEnum(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

}

答案 1 :(得分:4)

您可以尝试此检查清单:

  1. 验证该类是否具有默认构造函数(不带参数)
  2. 验证该类是否实现了Serializable或IsSerializable或 实现一个扩展Serializable或扩展类的接口 实现Serializable
  3. 验证该类是否在客户端。*包或...
  4. 验证,如果该类不在客户端。*包中,则编译为 您的GWT xml模块定义。默认情况下 存在。如果您的班级在另一个包中,则必须添加它 源。例如,如果您的课程属于域名。*您应该 将其添加到xml中。要知道这堂课 不能属于服务器包!有关GWT页面的更多详细信息:http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
  5. 如果您要从其他GWT项目中包括该课程,则必须这样做 将继承添加到xml模块定义中。例如,如果你的 class Foo在你必须添加的包com.dummy.domain中  到模块定义。 更多详情:http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
  6. 如果您要将其他GWT项目中的课程包括在内 jar验证jar还包含源代码,因为GWT 重新编译传递给客户端的类的Java源代码。
  7. 字体:http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/

答案 2 :(得分:1)

我认为你需要一个没有arg的构造函数。

答案 3 :(得分:1)

我上面一直在研究解决2008年写的一些GWT代码,升级到GWT SDK 2.4.0(最新的gxt * .jar)给了我:

[WARN] adempiereService: An IncompatibleRemoteServiceException was thrown while processing this call.
com.google.gwt.user.client.rpc.IncompatibleRemoteServiceException: com.google.gwt.user.client.rpc.SerializationException: Type 'org.idempiere.ui.gwt.client.util.AdempiereGXTUtil$LoginStage' was not included in the set of types which can be deserialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be deserialized.
    at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:315)
    at com.google.gwt.user.server.rpc.RemoteServiceServlet.processCall(RemoteServiceServlet.java:206)

...

Caused by: com.google.gwt.user.client.rpc.SerializationException: com.google.gwt.user.client.rpc.SerializationException: Type 'org.idempiere.ui.gwt.client.util.AdempiereGXTUtil$LoginStage' was not included in the set of types which can be deserialized by this SerializationPolicy or its Class object could not be loaded. For security purposes, this type will not be deserialized.
at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.deserialize(ServerSerializationStreamReader.java:581)

臭名昭着的课程如下(编辑以遵循此主题中给出的想法):

public class AdempiereGXTUtil {

    public enum LoginStage implements IsSerializable, Serializable {  
        LOGOUT,
        LOGIN,
        ISLOGGEDIN,
        ROLES,
        WRONGUSER,
        WRONGROLE;

        LoginStage(){
        }
    };

}

考虑到Andrej的answer将类型添加到白名单但枚举不是一些新的myType,对吧?无论如何,这里是代码库中的一些引用(删除了非相关字段):

public interface AdempiereService extends RemoteService {

    public static final String SERVICE_URI = "adempiereService";

    public static class Util {

        public static AdempiereServiceAsync getInstance() {

            AdempiereServiceAsync instance = (AdempiereServiceAsync) GWT
                    .create(AdempiereService.class);
            return instance;
        }
    }

...     
    public LoginStage getLoginStage();

使用:

public interface AdempiereServiceAsync {

...
    public void getLoginStage(AsyncCallback<LoginStage> callback);

最初,AdempiereGXTUtil没有实现IsSerializable,Serializable也没有空构造函数,但将它们放在上面,清理Eclipse中的项目不会改变相同的错误。在Mac Lion环境中使用的Eclipse版本是Java 1.6上的Indigo。希望从这个线程中获得更多,顺便说一下,它的技术深度是惊人的。

答案 4 :(得分:0)

在这种情况下,Enum不能在课堂上。你必须创建一个外部枚举。

答案 5 :(得分:0)

只有枚举常量的名称由GWT的RPC序列化。字段值序列化。

GWT:Server Communication:Serializable Types

答案 6 :(得分:0)

在 Gwt 2.9 中,在包含自定义枚举类的 java.util.EnumSet 类型字段的类上,我也遇到了“未包含在可以序列化的类型集中”错误。 结果证明问题不是我的自定义枚举,而是EnumSet 本身。用 HashSet 或 LinkedHashSet 替换 EnumSet 后,序列化工作。 也许这与这个问题有关:https://github.com/gwtproject/gwt/issues/3319

答案 7 :(得分:-1)

a)你肯定需要一个无操作的构造函数来进行序列化。

b)你可以扩展GWT的'IsSerializable类,或者,如果你想使用Java的Serialization接口,你必须设置一个策略来允许它。在How do I add a type to GWT's Serialization Policy whitelist?有一篇与此相关的帖子。另外,请查看GWT视图以获取有关IsSerializable与Serializable的更多信息。