Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make more collections GWT-serializable #828

Closed
gissuebot opened this issue Oct 31, 2014 · 16 comments
Closed

Make more collections GWT-serializable #828

gissuebot opened this issue Oct 31, 2014 · 16 comments

Comments

@gissuebot
Copy link

Original issue created by tomerb on 2011-12-16 at 08:43 PM


Using Guava 10.0.1 and GWT 2.4

It seems that because all fields in AbstractMultimap are transient, the GWT exposure computer decides that the the map values are not exposed, and omits the value type from the serialization policy.

Please see the attached file. I've modified the GWT demo project to show this error.

@gissuebot
Copy link
Author

Original comment posted by cpovirk@google.com on 2011-12-16 at 09:39 PM


We worked around this for (most of?) the immutable classes a long time ago, but we haven't done so for all other classes. The reasoning was that users would declare an RPC interface parameter as Multimap or else Immutable{,Set,List}Multimap but not some non-immutable, non-interface type like ArrayListMultimap. If you do that, I think the problem will go away.

There are two directions we could go from here:

  1. Document this somewhere.

  2. Make it work.

I've been slightly resistant to (2) because it requires us to make some classes that "should" be final non-final and to introduce some more weird code, but maybe we just should. Is it useful for your project to declare a parameter of type ArrayListMultimap instead of Multimap or an immutable type?

(I'll be on vacation shortly, so I may not see your response, but I'll check this bug when I return.)

@gissuebot
Copy link
Author

Original comment posted by tomerb on 2011-12-18 at 04:47 AM


Thanks for the quick response.
Unfortunately, your suggestion didn't work. Both ListMultimap and ImmutableListMultimap cause the same exception as before:

Caused by: com.google.gwt.user.client.rpc.SerializationException: Type 'test.shared.DemoObj' 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 = test.shared.DemoObj@608d5908

@gissuebot
Copy link
Author

Original comment posted by neveue on 2011-12-18 at 10:33 PM


Seems like the problem is that your "DemoObj" is not included in the serialization policy whitelist. I guess that's because your method signature returns a collection of DemoObj, and GWT fails to resolve the DemoObj type from the generic method signature. You need to add a "dummy" method that takes "DemoObj" as a parameter, to force GWT to add it to the whitelist.

More info:
http://stackoverflow.com/questions/4202964/serializationpolicy-error-when-performing-rpc-from-within-gwt-application

@gissuebot
Copy link
Author

Original comment posted by tomerb on 2011-12-19 at 04:43 AM


I'm aware of this workaround, thanks.
However, messing up the interface is hardly the correct solution.

Interestingly, in Guava r09, everything worked. I wonder what changed?

@gissuebot
Copy link
Author

Original comment posted by wasserman.louis on 2011-12-21 at 12:05 PM


(No comment entered for this change.)


Labels: Package-Collect

@gissuebot
Copy link
Author

Original comment posted by cpovirk@google.com on 2012-01-04 at 08:10 PM


We broke serialization of a bunch of collection types in r10 (but only in the public release, so our internal tests didn't see the problem): #791

It's fixed in r11. Please let me know whether that solves the problem for ListMultimap and ImmutableListMultimap.

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2012-01-10 at 11:48 PM


If someone can list all our collection types that can't currently be gwt-serialized, we can evaluate those.


Status: Triaged
Labels: -Type-Defect, -Priority-Medium, Type-Enhancement

@gissuebot
Copy link
Author

Original comment posted by fry@google.com on 2012-02-16 at 07:17 PM


(No comment entered for this change.)


Status: Acknowledged

@gissuebot
Copy link
Author

Original comment posted by tomerb on 2012-04-19 at 04:22 AM


I can verify that version 11.0.2 works with ListMultimap.

@gissuebot
Copy link
Author

Original comment posted by kevinb@google.com on 2012-06-22 at 06:16 PM


(No comment entered for this change.)


Status: Research

@gissuebot
Copy link
Author

Original comment posted by cpovirk@google.com on 2013-01-08 at 04:56 PM


(adding more to this bug because I'm about to direct a StackOverflow questioner here)

You can find the classes that are GWT serializable here:
http://code.google.com/p/guava-libraries/source/browse/#git%2Fguava-gwt%2Fsrc%2Fcom%2Fgoogle%2Fcommon%2Fcollect

In short, that consists of:

  • most of the immutable collections implementations (often with separate Empty, Regular, and Singleton serializers, as required)
  • most of the Table implementations (as we didn't use to have ImmutableTable, so they were the best available choice)
  • most of the Ordering implementations
  • a few others for which there is probably no rhyme or reason (probably some were specifically requested)

We could add more, but there is a downside: Consider an application containing an GWT RPC interface that returns Multimap<Foo, Bar>. Because the client side might receive any serializable Multimap<Foo, Bar>, the GWT compiler must generate client-side code for all such implementations. If only a couple implementations are serializable, that's not so bad. But if every implementation is serializable, that's a lot of bloat in an environment where bloat is a big concern.

The usual solution to this problem is to declare RPC interfaces in terms of a specific type, probably ImmutableMultimap<Foo, Bar>. Then the client needs code only for ImmutableMultimap and any classes used on the client side, not for every Multimap implementation in the classpath. So we certainly can add more serializers, but we're placing a small burden on them. (It can be hard to figure out why GWT download size increases, so the problem, while easy to fix in many cases, can be difficult to track down, especially for someone not familiar with the intricacies of GWT serialization or with the changes in a new version of Guava that he may not even realize he's using.)

Another small concern is that we may want to switch our serializer implementations to implement CustomFieldSerializer: http://google-web-toolkit.googlecode.com/svn/javadoc/latest/com/google/gwt/user/client/rpc/CustomFieldSerializer.html The more implementations we have, the more effort to switch. But this is a minor concern, and it's more of a reason to delay than a reason to never make the change.

One final note: The problem runs deeper than |transient|: GWT, for reasons I'm not familiar with, can't serialize |final| fields, and it requires no-arg constructors. We have plenty of |final| fields and few no-arg constructors, so we need to manually support every class's serialization.

@gissuebot
Copy link
Author

Original comment posted by cpovirk@google.com on 2013-01-08 at 05:16 PM


More on the requirements for GWT serialization: https://developers.google.com/web-toolkit/doc/latest/DevGuideServerCommunication#DevGuideSerializableTypes

@gissuebot
Copy link
Author

Original comment posted by lowasser@google.com on 2013-01-08 at 05:24 PM


StackOverflow had a report that HashBiMap wasn't GWT-serializable...?

@gissuebot
Copy link
Author

Original comment posted by cpovirk@google.com on 2013-01-08 at 05:26 PM


Yes, and I just now told him to consider ImmutableBiMap or, if that's not an option, to post here.

http://stackoverflow.com/questions/14137042/hashbimap-serializationexception-or-how-to-serialize-classes-where-isserializabl

@gissuebot
Copy link
Author

Original comment posted by alex.waters on 2013-02-02 at 02:17 AM


Just thought I'd confirm the problem with HashBiMap - Google brought me here - and from link in #c15 I was able to get it working (implementing a HashBiMap_CustomFieldSerializer).
GWT RPC was throwing a fit about no non-private no-args constructors (using 13.0.1 if that matters).

With regards to the non-serialized final fields mentioned end of #c12, that is thankfully - finally! - fixed (either GWT 2.5.1 or post release):
http://code.google.com/p/google-web-toolkit/issues/detail?id=1054

@cpovirk
Copy link
Member

cpovirk commented Feb 11, 2019

Closing, given our plans to turn down GWT-RPC serialization (though we'll continue to support Guava under GWT in general).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants