I would close the old issue and create a new one cut down to just the
exception issue.

*Are* there any serious RPC alternatives right now?  Sounds like
gwt-syncproxy isn't quite ready for prime time (and makes me nervous
since it's not using a published protocol), the *-WS stuff is a
trainwreck, and *-RS is not really convenient as an RPC layer.  I
would like alternatives.

Jeff

On Tue, Jun 15, 2010 at 2:41 PM, dilbert <[email protected]> wrote:
> 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.
>
>

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