I use an application on a non-GAE server to backup some data (via a 
Hessian-service implemented on GAE) from my APP engine application 
datastore. The data is loaded from the datastore as objects which are then 
serialized by Hessian and sent to the non-GAE service. The data is then 
stored in an object database. The data is restored (read from the local 
objecd database sent to the GAE application and stored to the datastore) the 
storing step fails with the message:
java.lang.NullPointerException
        at 
com.google.appengine.api.datastore.KeyTranslator.convertToPb(KeyTranslator.java:55)
        at 
com.google.appengine.api.datastore.EntityTranslator.convertToPb(EntityTranslator.java:34)
        at 
com.google.appengine.api.datastore.AsyncDatastoreServiceImpl.put(AsyncDatastoreServiceImpl.java:429)
        at 
com.googlecode.objectify.impl.AsyncObjectifyImpl.put(AsyncObjectifyImpl.java:255)

I analized the decompiled Key code and came to the conclusion that the 
problem lies in the fact that the appId private variable is not properly 
retrieved from the server when the Key instance is serialized by Hessian. In 
fact the appId variable is only set upon Java serialization (the writeObject 
method). So I need to rely on a side effect of the serialization procedure 
to properly send the Key instance to and from the GAE Application.

Another issue is that Java serialization of Key relies on a static object 
being previously initialized. For example you cannot write this:

Key key = KeyFactory.createKey("banana", (5L));

in a non-GAE application if you have not initialized a 
LocalServiceTestHelper instance. It dies in the following manner:
java.lang.NullPointerException: No API environment is registered for this 
thread.
    at 
com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppId(DatastoreApiHelper.java:108)
    at 
com.google.appengine.api.datastore.DatastoreApiHelper.getCurrentAppIdNamespace(DatastoreApiHelper.java:118)
    at com.google.appengine.api.datastore.Key.<init>(Key.java:51)
    at com.google.appengine.api.datastore.Key.<init>(Key.java:37)
    at 
com.google.appengine.api.datastore.KeyFactory.createKey(KeyFactory.java:46)
    at 
com.google.appengine.api.datastore.KeyFactory.createKey(KeyFactory.java:31)

This serialization issue is significant on Android applications that use 
classes containing Key instances which are shared between Activities since 
the transfer of objects between Activities uses Java Serialization. 
In my opinion Key should be refactored so the serialization is made less 
painful. 
I filed an issue here:
http://code.google.com/p/googleappengine/issues/detail?id=4966

Best regards

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine for Java" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/google-appengine-java?hl=en.

Reply via email to