Проблемы с GWT и Enum

У меня есть перечисление в клиентской части приложения 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

Ответ 1

Добавьте интерфейс IsSerializable, конструктор no-arg по умолчанию и убедитесь, что он находится на одном из путей, перечисленных в исходных тегах в файле gwt.xml. <source path="client">

Я действительно думаю, что это третья идея; Я помню эту проблему раньше, и это было потому, что у меня было dto вне исходных путей.

У вас может быть несколько исходных тегов.

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

Один шаблон состоит в том, чтобы поместить сохраненные объекты непосредственно в com.mysite.common и mashups сохраненных элементов, которые передаются по проводке в com.mysite.common.dto, и, конечно, клиентский gui-код находится в клиенте.

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

}

Ответ 2

Вы можете попробовать этот контрольный список:

  • Убедитесь, что класс имеет конструктор по умолчанию (без аргументов)
  • Убедитесь, что класс реализует Serializable или IsSerializable или реализует интерфейс, который расширяет Serializable или расширяет класс которые реализуют Serializable
  • Убедитесь, что класс находится в клиенте. * package или...
  • Проверить, если класс не находится в клиенте. * package, который скомпилирован в ваше определение модуля XML GWT. По умолчанию настоящее. Если ваш класс находится в другом пакете, вы должны добавить его к источнику. Например, если ваш класс находится в домене. * Вы должны добавьте его в xml as. Имейте в виду, что класс не может принадлежать серверу! Подробнее на странице GWT: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
  • Если вы включаете класс из другого проекта GWT, вы должны добавьте наследования к вашему определению модуля xml. Например, если класс Foo находится в пакете com.dummy.domain, который вы должны добавить  к определению модуля. Подробнее здесь: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
  • Если вы включили класс из другого проекта GWT, выпущенного как банку проверить, что в банке также содержится исходный код, потому что GWT перекомпилируйте также источник Java для классов, переданных клиенту.

Шрифт: http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/

Ответ 3

Я думаю, вам нужен конструктор no arg.

Ответ 4

Я изучил выше, чтобы решить какой-то код GWT, написанный в 2008 году, при обновлении до 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 не меняет те же ошибки. Используемая версия Eclipse - Indigo на Java 1.6 в среде Mac Lion. Надеюсь получить больше от этой темы, которая, кстати, удивительна по своей технической глубине.

Ответ 5

В этом случае Enum не может быть в классе. Вы должны создать внешний Enum.

Ответ 7

a) Вам определенно нужен конструктор no-op для сериализации.

b) Вы можете либо расширить класс GWT IsSerializable, либо, если вы хотите использовать интерфейс Java Serialization, вы должны настроить политику, чтобы разрешить это. Там есть сообщение, связанное с этим в Как добавить тип в белый список GWT "Сериализация политики" ?. Кроме того, проверьте изображение GWT для получения дополнительной информации о IsSerializable или Serializable.