Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problems with GWT and Enum

Tags:

java

enums

gwt

I have an enum in the client part of a GWT application and I am getting an exception when I try to run it that is related to serialization problems. Am I doing anything wrong? I read that enums are supported by GWT and I am using the last version.

The enum:

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

}

The exception:

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
like image 638
AntonioJunior Avatar asked Nov 17 '10 18:11

AntonioJunior


People also ask

Should I use enum or string?

Using an enum means you can only have one of those three values or it won't compile. Using strings means your code has to constantly check for equality during runtime - so it becomes bloated, slower and error prone.

Why are enums better than strings?

I would consider Enums to be a better approach than Strings. They are type safe and comparing them is faster than comparing Strings. Show activity on this post. If your set of parameters is limited and known at compile time, use enum .

Can we assign string value to enum in C#?

Since C# doesn't support enum with string value, in this blog post, we'll look at alternatives and examples that you can use in code to make your life easier. The most popular string enum alternatives are: Use a public static readonly string. Custom Enumeration Class.

What is the use of enum in selenium Webdriver?

An Enum in Java is a type which is used to define a collection of constants. For an example – We have fixed number of days in a week. We can use an Enum type in Java to store these days.


5 Answers

Only names of enumeration constants are serialized by GWT's RPC. Field values are not serialized.

GWT:Server Communication:Serializable Types

like image 142
jpleal Avatar answered Nov 15 '22 08:11

jpleal


Add IsSerializable interface, a default scoped no-arg constructor, and make sure its in one of the paths listed in the source tags in your gwt.xml file. <source path="client">

I really think the third suggestion is the issue; I remember having this issue before and it was because I had a dto outside the source paths.

You can have multiple source tags.

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

One pattern is to put persisted objects directly under com.mysite.common, and mashups of persisted items that get transferred over the wire in com.mysite.common.dto, and of course the client gui code is in client.

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

}
like image 41
antony.trupe Avatar answered Nov 15 '22 09:11

antony.trupe


You can try this check list:

  1. Verify that the class has a default constructor (without arguments)
  2. Verify that the class implements Serializable or IsSerializable or implements an Interface that extends Serializable or extends a class that implement Serializable
  3. Verify that the class is in a client.* package or …
  4. Verify, if the class is not in client.* package, that is compiled in your GWT xml module definition. By default is present. If your class is in another package you have to add it to source. For example if your class is under domain.* you should add it to xml as . Be aware that the class cannot belong to server package! More details on GWT page: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideModuleXml
  5. If you are including the class from another GWT project you have to add the inherits to your xml module definition. For example if your class Foo is in the package com.dummy.domain you have to add to the module definition. More details here: http://code.google.com/webtoolkit/doc/latest/DevGuideOrganizingProjects.html#DevGuideInheritingModules
  6. If you are including the class from another GWT project released as a jar verify that the jar contains also the source code because GWT recompile also the Java source for the classes passed to the Client.

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

like image 40
HenioJR Avatar answered Nov 15 '22 09:11

HenioJR


i think you need a no arg constructor.

like image 33
Nick Siderakis Avatar answered Nov 15 '22 10:11

Nick Siderakis


I been studying above to solve some GWT code written in 2008, when upgraded to GWT SDK 2.4.0 (with latest gxt*.jar) gives me:

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

That notorious class is as follows (edited to follow ideas given in this thread):

public class AdempiereGXTUtil {

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

        LoginStage(){
        }
    };

}

Thinking about Andrej's answer to add type to white-list but enum is not some new myType, right? Anyway here is some reference in the codebase (non-relevant fields removed):

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

with:

public interface AdempiereServiceAsync {

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

Originally the AdempiereGXTUtil did not implement IsSerializable, Serializable nor has empty constructor but putting them in above, and cleaning out project in Eclipse does not change the same errors. Eclipse version used is Indigo on Java 1.6 in a Mac Lion environment. Hoping to get more from this thread, which by the way is amazing in its technical depth.

like image 45
Redhuan D. Oon Avatar answered Nov 15 '22 09:11

Redhuan D. Oon