Using a nested enum in GWT-RPC
Asked Answered
K

3

10

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?

Karlotta answered 18/10, 2011 at 10:37 Comment(12)
Have you tried making it static?Rout
This is really cool! The JLS (section 8.9) explicitly says "Nested enum types are implicitly static. It is permissable to explicitly declare a nested enum type to be static." Does that not apply to enums nested in enums or is it a minor flaw in the GWT compiler?Colonic
...and GWT compiler simply uses the Eclipse compiler (ECJ) to parse source code and build ASTs. So either the Eclipse compiler has a bug in not exposing the enum as being static, or GWT has a bug in not inferring the static flag for a nested enum (I'd go for ECJ, but it really depends what their intent is; it might be by-design).Gauzy
....well I feel stupid.... there was some stuff hanging around from a previous build, turns out making it static doesn't make a difference.... back to the drawing board. Sorry guys!Karlotta
What GWT version are you using? In GWT 2.4.0 your sample works without problems.Rainarainah
Ah that might be the problem i'm on GWT 2.3!!Karlotta
On GWT 2.4.0 it works but I still have the error printedKarlotta
I do not know why it does what it does in your case, but adding IsSerializable might help.Kalvin
I am using java.io.Serializable. code.google.com/webtoolkit/doc/latest/tutorial/RPC.html states that either is acceptableKarlotta
Yeah, I know, but it is a bit tricky and I would try it anyway :)Kalvin
@Kalvin unfortunately, but as expected it didn't work :-(Karlotta
@Karlotta I tried hard, but I cannot reproduce the problem.Epistemic
K
2

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 .

Kriss answered 28/11, 2011 at 22:22 Comment(0)
B
0

This probably has to do with JavaScript. It is possible / probable that in the translation to JavaScript the nested class is being written as non-nested. Therefore if it is private, nothing else has access to it. Workaround is to not make it private, default scope should work fine.

Blackbeard answered 18/10, 2011 at 10:44 Comment(1)
That's a good point, I hadn't thought of that. Ideally I would like it to be private though...Karlotta
C
-2

To be a RPC parameter class type, it must have a empty constructor for serialization. So I think, if you add

private OuterEnum(){
// may be you should give a default value to nestedValue
}

It will work !

Candelariacandelario answered 27/10, 2011 at 23:7 Comment(1)
The problem is with the visibility of the inner enum. It can serialize the outer enum fine. This doesn't answer my question.Karlotta

© 2022 - 2024 — McMap. All rights reserved.