At the time I thought the issues were connected since they threw the
same exception so I posted them together. So should I post the issue
with exceptions again on the Caucho bug tracker? If this issue is
solved I would recommend Hessian as the best RPC mechanism for GAE at
this time.
Apologies to other readers for the offtopic with bugs.
D.

On Jun 15, 11:24 pm, Jeff Schnitzer <[email protected]> wrote:
> I think you did yourself a disservice by wrapping these two issues
> into a single message - it ends up being way too much text to read and
> otherwise eager volunteers just skip it.
>
> The first issue looks like you're not detaching your entities before
> serializing them.  This is a JDO issue.  I suggest dropping JDO and
> using something simpler like Objectify ;-)
>
> The issue with exceptions looks more serious.  This is something that
> will need to be fixed in Hessian (or your custom serializer).  If you
> cut down your issue to just this, you might get better results from
> Caucho.
>
> Jeff
>
> On Tue, Jun 15, 2010 at 1:55 PM, dilbert <[email protected]> wrote:
> > Hi Jeff. I was hoping to hear from You since I saw that You solved
> > some GAE issues on the hessian-interest list. I already posted the
> > issue on the hessian-interest list here:
> >http://maillist.caucho.com/pipermail/hessian-interest/2010-June/00090...
> > I also posted several forum questions:
> >http://forum.caucho.com/showthread.php?t=9999
> >http://groups.google.com/group/google-appengine-java/browse_thread/th...
> > And a few bug reports:
> >http://bugs.caucho.com/view.php?id=4061
> >http://code.google.com/p/googleappengine/issues/detail?id=3305
> > The posts actually describe two issues one with arraylist
> > serialization and the other with exception serialization. The posts
> > also include test projects with code that reproduces the issues. I
> > also managed to solve the issue today by using a custom serializer.
> > Here is how. First the Serializer:
>
> > public class ThrowableSerializer extends AbstractSerializer {
> >   �...@override
> >    public void writeObject(Object obj, AbstractHessianOutput out)
> > throws IOException {
> >        if (obj != null) {
> >            final Class cl = obj.getClass();
> >            if (out.addRef(obj))
> >                return;
> >            int ref = out.writeObjectBegin(cl.getName());
> >            Throwable tr = (Throwable) obj;
> >            ByteArrayOutputStream bos = new ByteArrayOutputStream();
> >            ObjectOutputStream oos = new ObjectOutputStream(bos);
> >            try {
> >                oos.writeObject(tr);
>
> >                if (ref < -1) {
> >                    out.writeString("value");
> >                    out.writeBytes(bos.toByteArray());
> >                    out.writeMapEnd();
> >                } else {
> >                    if (ref == -1) {
> >                        out.writeInt(1);
> >                        out.writeString("value");
> >                        out.writeObjectBegin(cl.getName());
> >                    }
> >                    out.writeBytes(bos.toByteArray());
> >                }
> >            } finally {
> >                oos.close();
> >                bos.close();
> >            }
> >        } else
> >            out.writeNull();
> >    }
> > }
>
> > The other class we need is the Deserializer:
> > public class ThrowableDeserializer extends AbstractDeserializer {
> >    //private static final Logger l =
> > Logger.getLogger(ThrowableDeserializer.class.getName());
>
> >   �...@override
> >    public Class getType() {
> >        return Throwable.class;
> >    }
>
> >   �...@override
> >    public Object readMap(AbstractHessianInput in) throws IOException
> > {
> >        int ref = in.addRef(null);
> >        byte[] initValue = null;
> >        while (!in.isEnd()) {
> >            String key = in.readString();
>
> >            if (key.equals("value"))
> >                initValue = in.readBytes();
> >            else
> >                in.readString();
> >        }
>
> >        in.readMapEnd();
> >        ByteArrayInputStream bis = new
> > ByteArrayInputStream(initValue);
> >        ObjectInputStream ois = new ObjectInputStream(bis);
> >        try {
> >            Object value = ois.readObject();
> >            in.setRef(ref, value);
> >            return value;
> >        } catch (ClassNotFoundException e) {
> >            throw new RuntimeException(e);
> >        } finally {
> >            ois.close();
> >            bis.close();
> >        }
> >    }
>
> >   �...@override
> >    public Object readObject(AbstractHessianInput in, Object[]
> > fieldNames)
> >            throws IOException {
> >        int ref = in.addRef(null);
> >        byte[] initValue = null;
> >        for (Object o : fieldNames) {
> >            if (o instanceof String) {
> >                final String key = (String) o;
> >                if (key.equals("value"))
> >                    initValue = in.readBytes();
> >                else
> >                    in.readObject();
> >            }
> >        }
> >        ByteArrayInputStream bis = new
> > ByteArrayInputStream(initValue);
> >        ObjectInputStream ois = new ObjectInputStream(bis);
> >        try {
> >            Object value = ois.readObject();
> >            in.setRef(ref, value);
> >            return value;
> >        } catch (ClassNotFoundException e) {
> >            throw new RuntimeException(e);
> >        } finally {
> >            ois.close();
> >            bis.close();
> >        }
> >    }
> > }
> > I'm not sure if the readMap part is actually needed since I rearranged
> > this code from another example. Also, a ThrowableSerializerFactory is
> > needed:
> > public class ThrowableSerializerFactory extends
> > AbstractSerializerFactory {
> >   �...@override
> >    public Serializer getSerializer(Class cl) throws
> > HessianProtocolException {
> >        if (Throwable.class.isAssignableFrom(cl)) {
> >            return new ThrowableSerializer();
> >        }
> >        return null;
> >    }
>
> >   �...@override
> >    public Deserializer getDeserializer(Class cl) throws
> > HessianProtocolException {
> >        if (Throwable.class.isAssignableFrom(cl)) {
> >            return new ThrowableDeserializer();
> >        }
> >        return null;
> >    }
> > }
> > What this code essentially does is take a Throwable (which implements
> > Serializable), serializes it to a byte[] and pushes it over to the
> > other side. This serialization does not use the problematic
> > setAccessible method (like com.caucho.hessian.io.ThrowableSerializer)
> > and works correctly on App engine (I tested it). The only part left to
> > do is to plug all this into the servlet and the client. Here is how to
> > do it on the servlet:
> > public class Service extends HessianServlet implements IService {
> >   �...@override
> >    public void init(ServletConfig config) throws ServletException {
> >        super.init(config);
> >        getSerializerFactory().addFactory(new
> > ThrowableSerializerFactory());
> >    }
> >    // implement IService methods...
> > }
>
> > And here is how to do it on the client:
> > String url = "http://whatever.appspot.com/service";;
> > HessianProxyFactory factory = new HessianProxyFactory();
> > factory.getSerializerFactory().addFactory(new
> > ThrowableSerializerFactory());
> > IService service = (IService) factory.create(IService.class, url);
>
> > I would like to hear your opinion on this solution. Do You see any
> > problems with it? Also, when could we expect to see a solution in
> > Hessian? If You need any other information please ask. Thank You for
> > Your time.
>
> > D.
> > On Jun 15, 7:34 pm, Jeff Schnitzer <[email protected]> wrote:
> >> Perhaps try posting the stacktrace to the hessian-interest list?
> >> Someone (possibly me) might be able to fix this issue.
>
> >> Jeff
>
> >> On Thu, Jun 10, 2010 at 9:13 AM, dilbert <[email protected]> wrote:
> >> > First I'd like to explain what I mean by RPC. I'd like to be able to
> >> > write interfaces like this (simple Java interface):
>
> >> > public interface EchoService {
> >> >  String echo(String message);
> >> > }
>
> >> > The framework would allow the creation of client classes that would
> >> > handle the serialization from/to the RPC service. Of course the
> >> > framework should support the serialization of ArrayLists, HashMaps and
> >> > other collections and should also support the serialization of objects
> >> > marked with the "java.io.Serializable" interface (or some other
> >> > interface).
> >> > We would create the RPC Client this way:
>
> >> > EchoService echoService =
> >> > RpcClientFactory.createInstance(EchoService.class,"http://bla.com/
> >> > smartApp/echo");
>
> >> > And of course use it this way:
>
> >> > String echoMessage = echoService.echo("The message !!!");
>
> >> > The server side servlet would implement the previously mentioned
> >> > interface.
> >> > public class Service extends WhateverServlet implements EchoService {
> >> >   �...@override
> >> >    String echo(String message) {
> >> >        return "server sends:" + message;
> >> >    }
> >> > }
>
> >> > A few additional nice features to have would be:
> >> > -support for asynchronous calls (where the developer would provide a
> >> > callback for handling the result, similar to GWT RPC)
> >> > -the developers should be able to access the RPC client somehow to be
> >> > able to handle Cookies or other http headers.
> >> > -the client side should be usable from Android.
>
> >> > After a long search I have found that the framework that most closely
> >> > matches these requirements is Hessian (http://hessian.caucho.com/). It
> >> > uses a binary protocol so it should be very fast and it works on
> >> > Android. AFAIK it does not support async calls. However, not all is
> >> > well. The current Hessian implementation does not handle exceptions
> >> > well. It throws a SecurityException like this:
>
> >> > java.lang.SecurityException: java.lang.IllegalAccessException:
> >> > Reflection is not allowed on private java.lang.Throwable
> >> > java.lang.Throwable.cause
>
> >> > I considered GWT RPC for a while but it does not have a proper Java
> >> > client or I could not find one.
>
> ...
>
> read more »

-- 
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