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.