Search code examples
javagwtenumsgwt-rpc

Using a nested enum in GWT-RPC


I have an enum with a nested enum (which I want to make private), but when I do so GWT tells me that the nested enum is not visible and throws an exception.

public enum OuterEnum {
    A(NestedEnum.X),
    B(NestedEnum.Y),
    C(NestedEnum.X);

    NestedEnum nestedValue;
    private OuterEnum(NestedEnum nv) { nestedValue = nv; }

    private enum NestedEnum {
        X, Y;
    }
}

If I remove the private modifier from the nested enum then the code works. Why does GWT not allow the private modifier for nested enums? Is there a workaround?


Solution

  • Serialization works just fine, at least with example you have provided. All enums a getting serialized/deserialized in following way(GWT 2.4, 2.3, 2.2):

        public static OuterEnum instantiate(SerializationStreamReader streamReader) throws SerializationException {
                int ordinal = streamReader.readInt();
                OuterEnum[] values = OuterEnum.values();
                assert (ordinal >= 0 && ordinal < values.length);
                return values[ordinal];
    }
    
        public static void serialize(SerializationStreamWriter streamWriter, OuterEnum instance) throws SerializationException {
                assert (instance != null);
                streamWriter.writeInt(instance.ordinal());
    }
    

    E.g. i doesn't matter what is used inside. Only ordinal is passed over the network. It means there is a problem in some other place, GWT simply doesn't care what is inside of enum, because it is not transferred over the network (enum's should be immutable there is no need to transfer its state). I think your problem might be something like this:

    public class OuterClass implements Serializable{
    
        private OuterEnum.NestedEnum nested;
        private OuterEnum outer;
    
        public enum OuterEnum {
            A(NestedEnum.X), B(NestedEnum.Y), C(NestedEnum.X);
    
            NestedEnum nestedValue;
    
            private OuterEnum(NestedEnum nv) {
                nestedValue = nv;
            }
    
    
            private enum NestedEnum {
                X, Y;
            }
        }
    }
    

    This example is VERY different from previous one. Let's assume that OuterClass is used in GWT-RPC service. Since NestedEnum used as field of OuterClass, GWT needs to create a TypeSerializer for it. But since a TypeSerializer is a separate class, it doesn't have ANY access to the NestedEnum (since it is private). So the compilation fails.

    This basically the only case when your example will not work. There might be some bugs in some specific GWT versions, but i'm 100% sure that your example works in gwt 2.2-2.4 .