asolfre / objectify-appengine

Automatically exported from code.google.com/p/objectify-appengine
MIT License
0 stars 0 forks source link

com.google.gwt.user.client.rpc.SerializationException in GWT RPC #135

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. To load an object from AppEngine to GWT using 

What is the expected output? What do you see instead?
GWT should be able to deserialize the object.
But instead GWT is will complain:
com.google.gwt.user.client.rpc.SerializationException: Type ... 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 = ...

What version of the product are you using? On what operating system?
4.0a4, Mac 10.7.5

Please provide any additional information below.
Almost the same code (need to adjust to use 4.0.a4) works just fine with 3.1

Lemme know if further info is needed.

Original issue reported on code.google.com by azur...@gmail.com on 30 Sep 2012 at 4:44

GoogleCodeExporter commented 9 years ago
Any updates, guys?

This still happens with
4.0b1, Mac 10.8.2

Original comment by azur...@gmail.com on 15 Nov 2012 at 4:33

GoogleCodeExporter commented 9 years ago
Also 4.0b1 on Windows i get:

No source code is available for type com.googlecode.objectify.Ref<T>; did you 
forget to inherit a required module?

Original comment by jens.sch...@gmail.com on 16 Nov 2012 at 9:31

GoogleCodeExporter commented 9 years ago
GWT serialization will be fixed Real Soon Now!

Original comment by lhori...@gmail.com on 16 Nov 2012 at 4:21

GoogleCodeExporter commented 9 years ago
It looks like this can be fixed using <super-source path="path" />. Ref needs 
to be added and Key needs to be updated so it matches the ‘real’ Key class.
I will try to fix it soon as it is a showstopper for my GWT project now.

Original comment by jens.sch...@gmail.com on 18 Dec 2012 at 1:44

GoogleCodeExporter commented 9 years ago
Yeah Super source looks like the solution. I started working on trying a super 
source but haven't had time to try it completely. When I do it I have to copy 
quite a few classes to make it work :)

Original comment by brandon....@arcbees.com on 18 Dec 2012 at 2:43

GoogleCodeExporter commented 9 years ago
I see what you mean by the Key class. B/c I'm wondering how to super source the 
Key<T> class when it has the com.google.appengine.api.datastore.Key.

{{{
public class Key<T> implements Serializable, Comparable<Key<?>>
{
    private static final long serialVersionUID = 2L;

    /** Key.create(key) is easier to type than new Key<Blah>(key) */
    public static <T> Key<T> create(com.google.appengine.api.datastore.Key raw) {
        if (raw == null)
            throw new NullPointerException("Cannot create a Key<?> from a null datastore Key");

        return new Key<T>(raw);
    }
}}}

Original comment by brandon....@arcbees.com on 18 Dec 2012 at 8:45

GoogleCodeExporter commented 9 years ago
super sourcing this objectify package with this class in it gets rid of my 
source error during compile, but the rpc serializer is still complaining. So if 
Rev<Entity> field is added to the entity, the serializer won't put it in the 
white list. So I don't think the super source is the whole story. 

package com.sceneverse.shozon.client.objectify;

import com.google.gwt.user.client.rpc.IsSerializable;
import com.googlecode.objectify.Key;

/**
 * <p>
 * Ref associates a Key<?> with an entity value.
 * </p>
 * 
 * <p>
 * Note that the methods might or might not throw runtime exceptions related to
 * datastore operations; ConcurrentModificationException,
 * DatastoreTimeoutException, DatastoreFailureException, and
 * DatastoreNeedIndexException. Some Refs hide asynchronous operations that
 * could throw these exceptions.
 * </p>
 * 
 * @author Jeff Schnitzer <jeff@infohazard.org>
 */
public class Ref<T> implements IsSerializable {

    private Key<T> key;
    private T value;

    public Ref(Key<T> key) {
        this.key = key;
    }

    /**
     * @return the key associated with this Ref
     */
    public Key<T> key() {
        return key;
    }

    /**
     * Obtain the entity value associated with the key.
     * 
     * @return the entity referenced, or null if the entity was not found
     * @throws IllegalStateException
     *             if the value has not been initialized
     */
    public T get() {
        return value;
    }

    /**
     * Nearly identical to get() but conforms to JavaBean conventions and
     * returns null instead of throwing IllegalStateException if uninitialized.
     * This is convenient for use in a JSON converter or an expression language.
     * 
     * @return the entity referenced, or null if either the entity was not found
     *         or this Ref is uninitialized
     */
    public T getValue() {
        return value;
    }

    /**
     * Explicitly sets (or resets) the value of this Ref.
     */
    public void set(T value) {
        this.value = value;
    }

    /**
     * Same as key() but conforms to JavaBeans conventions in case this is being
     * processed by a JSON converter or expression language.
     */
    final public Key<T> getKey() {
        return key();
    }

    /** Renders some info about the key */
    @Override
    public String toString() {
        return "(" + key() + ")";
    }
}

Original comment by brandon....@arcbees.com on 18 Dec 2012 at 9:52

GoogleCodeExporter commented 9 years ago
Maybe I could write a custom serializer too. 

Original comment by brandon....@arcbees.com on 18 Dec 2012 at 10:00

GoogleCodeExporter commented 9 years ago
Yes you probably have to serialize/deserialize the key or raw key. I have not 
had time to look at it myself but it looks like you are close to solving it. 
Keep us updated.

There is a nice guide here: 
http://concentricsky.com/blog/2011/mar/emulating-jre-classes-gwt

Original comment by jens.sch...@gmail.com on 19 Dec 2012 at 2:04

GoogleCodeExporter commented 9 years ago
Thanks for the guide link. I was reading that yesterday an thought that was 
good tutorial. I noticed you did a few  serializers in your source too. I'm 
looking at building the serializer this weekend. :)

Original comment by brandon....@arcbees.com on 19 Dec 2012 at 5:55

GoogleCodeExporter commented 9 years ago
Back from holiday... I cant take credit for the serializers as I am just a 
regular user. Not a commiter yet :-)

Did you have any luck with the key/ref serializers?

Original comment by jens.sch...@gmail.com on 19 Jan 2013 at 6:10

GoogleCodeExporter commented 9 years ago
does anyone have a work around for this issue yet? Or an approximate fix date? 
I spent a day upgrading to 4.0b1 but now have to roll back the changes to 3.1. 
Would love to upgrade because the API changes look great! 

Original comment by berton.j...@gmail.com on 20 Jan 2013 at 12:44

GoogleCodeExporter commented 9 years ago
I would love being able to use Ref in my client-side GWT application too.

Original comment by freddy.b...@gmail.com on 25 Jan 2013 at 3:44

GoogleCodeExporter commented 9 years ago
This should be fixed in trunk. Also, Ref should now be implemented in client 
emulation.

Original comment by lhori...@gmail.com on 14 Feb 2013 at 11:05

GoogleCodeExporter commented 9 years ago
Hi, I build from trunk, but I get this error when I use the jar in my 
project... am I using/building it wrong?
I dont see the equivalent() method in the GWT Key serializer....? Could it be 
that I transfer a Set of Refs?

    [DEBUG] [pageloader] - Checking rule <generate-with class='com.google.gwt.user.rebind.rpc.ServiceInterfaceProxyGenerator'/>
        [ERROR] [pageloader] - Errors in 'jar:file:/C:/Projects/Git/labbirdapps/labbirdapps/Common/lib/objectify-4.0b1.jar!/com/googlecode/objectify/Ref.java'
            [ERROR] [pageloader] - Line 119: The method equivalent(Key<T>) is undefined for the type Key<T>
            [ERROR] [pageloader] - Line 131: The method getSimpleName() is undefined for the type Class<capture#2-of ? extends Ref>

Original comment by jens.sch...@gmail.com on 19 Feb 2013 at 11:03

GoogleCodeExporter commented 9 years ago
When do you plan to update the version with this fix in Maven ?
THX

Original comment by freddy.b...@gmail.com on 3 Mar 2013 at 9:30

GoogleCodeExporter commented 9 years ago
"Real Soon Now" - sorry, racing under some other deadlines at the moment.

Original comment by lhori...@gmail.com on 3 Mar 2013 at 10:43

GoogleCodeExporter commented 9 years ago
This is a really good news.
THX

Original comment by freddy.b...@gmail.com on 4 Mar 2013 at 6:22

GoogleCodeExporter commented 9 years ago
Hi.

Running into the same issue with current git (2013-05-21) and a very simple 
class:

EVERE: javax.servlet.ServletContext log: Exception while dispatching incoming 
RPC call
com.google.gwt.user.client.rpc.SerializationException: Type '$Proxy44' 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 = 
[dk.madsdydensborg.daddybank.client.AccountEntity@1fec8cf1, 
dk.madsdydensborg.daddybank.client.AccountEntity@63193296]
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serialize(ServerSerializationStreamWriter.java:665)
    at com.google.gwt.user.client.rpc.impl.AbstractSerializationStreamWriter.writeObject(AbstractSerializationStreamWriter.java:126)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter$ValueWriter$8.write(ServerSerializationStreamWriter.java:153)
    at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamWriter.serializeValue(ServerSerializationStreamWriter.java:585)
    at com.google.gwt.user.server.rpc.RPC.encodeResponse(RPC.java:605)

Class is very simple, something like:

@Entity
public class AccountEntity implements IsSerializable {
    @Id 
    private Long id;
    private String name;
    private Double balance;

Any clues? 

Original comment by madsdy...@gmail.com on 21 May 2013 at 7:43

GoogleCodeExporter commented 9 years ago
@madsdy - I ran into the same problem when I was trying to serialize a .list() 
from a load action. I resolved it by tossing the .list() result into a loop on 
each item in the list. If your method's returning something similar, I bet it's 
having the same problem I was. I'm betting there's a better way to get those 
items converted to a serializable form (as opposed to the loadgenerator proxy 
that's being seen, $Proxy44 in your instance), but I haven't dug deep into it 
yet. This has resolved my issue for now.

Ex. List<MyItem> items = 
ofy().load().type(MyItem.class).filter("name",name).list();
ArrayList<MyItem> convertedItems = new ArrayList<MyItem>();
for(MyItem item:items){
convertedItems.add(item);
}
return convertedItems;

Original comment by p.pr...@blueesoteric.com on 21 May 2013 at 8:33

GoogleCodeExporter commented 9 years ago
@p.pr - Instead of looping over the list, you can use the addAll() convenience 
method.

http://docs.oracle.com/javase/6/docs/api/java/util/List.html#addAll(java.util.Co
llection)

Original comment by ccrvinc...@gmail.com on 21 May 2013 at 9:49

GoogleCodeExporter commented 9 years ago
To use GWT, Objectify and lists you need the workaround presented here. Very 
hard to figure out just from an error log. Thanks guys.

However, quite inconvenient to do this every time you need a list over GWT. Not 
sure where the problem lays but it would be nice to have it fixed.

Original comment by c...@rahmstrom.com on 15 May 2014 at 8:42

GoogleCodeExporter commented 9 years ago
The root issue is a shortcoming of GWT which cannot be worked around by 
Objectify. Please star this GWT issue:

https://code.google.com/p/google-web-toolkit/issues/detail?id=3303

If you need convenience, you could subclass enough of Objectify's command 
objects such that the List Objectify returns is a materialized ArrayList. This 
will eliminate the performance benefits of asynchronous processing.

You could propose a feature like ofy().forceSynchronous(true).load() which 
would force immediate materialization of every collection. I'm not thrilled 
about the idea though.

Really, this needs to be fixed in GWT.

Original comment by lhori...@gmail.com on 15 May 2014 at 9:17