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.
