2010-11-17 18 views
10

Tengo una enumeración en la parte cliente de una aplicación GWT y obtengo una excepción cuando intento ejecutarla relacionada con problemas de serialización. ¿Estoy haciendo algo mal? Leí que las enums son compatibles con GWT y estoy usando la última versión.Problemas con GWT y Enum

La enumeración:

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

} 

La excepción:

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

qué paquete es la enumeración, y qué caminos están listados en las etiquetas de código de gwt.xml? –

+1

¡Definitivamente parece haber un problema/error con las enums y GWTRPC! Probé tu código con GWT 2.0.3, y funciona (ni siquiera se requiere un constructor no-arg). Pero cuando uso 'setDescription (" new value ")' antes de llamar al método de servicio, ese cambio a 'description' está ** perdido ** durante la transferencia al servidor - es decir, el servidor ve' description' como todavía se está configurando a " Artículo una descripción ". No lo he intentado con la última versión de GWT, pero tal vez Google intentó solucionar ese problema para GWT 2.1, pero presentó el problema de la serialización. –

+5

Acabo de encontrar algo en la [documentación] (http://code.google.com/webtoolkit/doc/latest/DevGuideServerCommunication.html) sobre esto: "Las constantes de enumeración se serializan como un nombre único; ninguno de los valores de campo se serializan. " Por lo tanto, probablemente no sea una buena idea usar enumeraciones con campos mutables junto con GWTRPC. –

Respuesta

14

Agregue la interfaz IsSerializable, un constructor no-arg de ámbito predeterminado, y asegúrese de que esté en una de las rutas listadas en las etiquetas fuente en su archivo gwt.xml. <source path="client">

Realmente creo que la tercera sugerencia es el problema; Recuerdo haber tenido este problema antes y fue porque tenía un dto fuera de los caminos de origen.

Puede tener varias etiquetas de origen.

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

Un patrón es poner objetos persistió directamente bajo com.mysite.common, y mashups de artículos persistió que se transfieren a través del cable de com.mysite.common.dto, y por supuesto el código visual se está en el cliente

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

} 
+0

Ya lo hice y no funciona. Lo curioso es que la aplicación siempre funcionó con esa enumeración. Dejó de funcionar cuando cambié el nombre de algunas de las constantes enum, pero no hay nada de malo en ello. – AntonioJunior

+0

Ya no puedo reproducir tu error ... –

+1

¡Gracias! Tu sugerencia resolvió mi problema. Incluso después de que hice lo que sugeriste, no estaba funcionando. Resultó que necesitaba limpiar mi proyecto en Eclipse para que funcionara. – AntonioJunior

1

creo que se necesita un constructor sin arg.

+1

Hola, Nick. Gracias por la pronta respuesta. Lo intenté, pero no funcionó. – AntonioJunior

-1

a) Definitivamente necesita un constructor no operativo para la serialización.

b) Puede ampliar la clase 'IsSerializable' de GWT o, si desea utilizar la interfaz de serialización de Java, debe configurar una política para permitir esto. Hay una publicación relacionada con esto en How do I add a type to GWT's Serialization Policy whitelist?. Además, consulte la vista de GWT para obtener más información sobre IsSerializable frente a Serializable.

+2

a) esto tan mal en caso de enums. – jusio

1

Me estudiado anteriormente para resolver algún código GWT escrito en 2008, cuando se actualiza a GWT SDK 2.4.0 (con el último GXT * .jar) me da:

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

Esa clase notorio es el siguiente (editado a seguir las ideas dadas en este hilo):

public class AdempiereGXTUtil { 

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

     LoginStage(){ 
     } 
    }; 

} 

Pensando en el answer de Andrej para agregar el tipo a la lista blanca pero enum no es un nuevo myType, ¿verdad? De todos modos aquí es alguna referencia en el código base (campos no pertinentes eliminado):

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(); 

con:

public interface AdempiereServiceAsync { 

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

Originalmente, el AdempiereGXTUtil no implementó IsSerializable, Serializable ni tiene constructor vacío, pero su puesta en el anterior y el proyecto de limpieza en Eclipse no cambia los mismos errores. La versión de Eclipse utilizada es Indigo en Java 1.6 en un entorno Mac Lion. Esperando obtener más de este hilo, que por cierto es increíble en su profundidad técnica.

+1

Parece que la solución de Andrej vinculada anteriormente es el camino a seguir. Lo resolví envolviendo el Enum para que se use una clase seriada normal. Entonces ya no pega el error. Le di un +1 en su publicación. Muchas gracias Andrej! Si alguien quiere saber, es su solución ficticia simulada (Dummy d) (segunda publicación allí). Si alguien pregunta, puedo publicar las ediciones que hice en mi código anterior. –

+0

He subido una película de youtube sobre cómo utilicé la idea de Andrej y resolví mi problema anterior. http://youtu.be/gGqvM9pc4mg –

4

Puede probar esta lista de comprobación:

  1. Compruebe que la clase tiene un constructor por defecto (sin argumentos)
  2. Compruebe que la clase implementa Serializable o IsSerializable o implementa una interfaz que se extiende Serializable o se extiende una clase que implementan Serializable
  3. Compruebe que la clase está en un cliente. * paquete o ...
  4. Verify, si la clase no está en cliente. * paquete, que es un borrador iled en su definición de módulo GWT xml. Por defecto está presente. Si su clase está en otro paquete, debe agregarlo a la fuente. Por ejemplo, si su clase está bajo dominio. * Debe agregarlo a xml como. Tenga en cuenta que la clase no puede pertenecer al paquete del servidor. Más detalles en la página GWT: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
  5. Si está incluyendo la clase de otro proyecto GWT, debe agregar las heredades a la definición de su módulo xml a . Por ejemplo, si su clase Foo está en el paquete com.dummy.domain, debe agregar a la definición del módulo. Más detalles aquí: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
  6. Si va a incluir la clase de otro proyecto GWT lanzado como un frasco verificar que el frasco contiene también el código fuente porque GWT recompilación también la fuente de Java para las clases pasa al cliente.

Fuente: http://isolasoftware.it/2011/03/22/gwt-serialization-policy-error/

0

En este caso, enumeración no puede estar en la clase. Tienes que crear un Enum externo.