PDA

View Full Version : SecurityException with Hessian on google app engine


dilbert
06-02-2010, 07:15 AM
I am having trouble with Hessian on Google App Engine. First I will describe the setup. I have a persistent class MessageDb declared as (It contains a String and an arraylist of strings):

@PersistenceCapable
public class MessageDb {
@PrimaryKey
private String user;

@Persistent
private ArrayList<String> words = new ArrayList<String>();
/* getters and setters ...*/
}

I have the following service interface:
public interface IService {
ArrayList<String> testMessage();
/* Some other methods ... */
}

The Service is implemented on App engine in the following way:
public class Service extends HessianServlet implements IService {
private static final PersistenceManagerFactory pmfInstance = JDOHelper.getPersistenceManagerFactory("transactions-optional");

@Override
public ArrayList<String> testMessage() {
PersistenceManager pm = null;
try {
pm = pmfInstance.getPersistenceManager();

MessageDb messageDb;
try {
messageDb = pm.getObjectById(MessageDb.class, "testMessage");
} catch (JDOObjectNotFoundException e) {
return null;
}
return messageDb.getWords();
//return new ArrayList<String>(messageDb.getWords());
} finally {
if (pm != null)
pm.close();
}
}
}

The service simply retrieves an MessageDb object by key and returns the object's ArrayList<String>. This code works fine on the local development server but it fails when deployed on remote Google servers with the following exception:

java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private int java.util.ArrayList.size
at com.google.appengine.runtime.Request.process-0c4ab611241850c6(Request.java)
at java.lang.reflect.Field.setAccessible(Field.java:1 66)
at com.caucho.hessian.io.JavaSerializer.introspect(Ja vaSerializer.java:122)
at com.caucho.hessian.io.JavaSerializer.<init>(JavaSerializer.java:81)
at com.caucho.hessian.io.JavaSerializer.create(JavaSe rializer.java:95)
at com.caucho.hessian.io.SerializerFactory.getDefault Serializer(SerializerFactory.java:348)
at com.caucho.hessian.io.SerializerFactory.loadSerial izer(SerializerFactory.java:278)
at com.caucho.hessian.io.SerializerFactory.getSeriali zer(SerializerFactory.java:224)
at com.caucho.hessian.io.SerializerFactory.getObjectS erializer(SerializerFactory.java:197)
at com.caucho.hessian.io.Hessian2Output.writeObject(H essian2Output.java:418)
at com.caucho.hessian.io.AbstractHessianOutput.writeR eply(AbstractHessianOutput.java:558)
at com.caucho.hessian.server.HessianSkeleton.invoke(H essianSkeleton.java:323)
at com.caucho.hessian.server.HessianSkeleton.invoke(H essianSkeleton.java:202)
at com.caucho.hessian.server.HessianServlet.invoke(He ssianServlet.java:389)
at com.caucho.hessian.server.HessianServlet.service(H essianServlet.java:369)
at org.mortbay.jetty.servlet.ServletHolder.handle(Ser vletHolder.java:511)
...
at com.google.apphosting.runtime.JavaRuntime$RpcRunna ble.run(JavaRuntime.java:413)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalAccessException: Reflection is not allowed on private int java.util.ArrayList.size
... 55 more

I am not sure if this security exception is a bug in Hessian (for using an "forbidden" API) or In App engine (too tight security check) so I would like to hear what You think about it. I think this is perhaps connected with the datanucleus enhancements of the persistent class MessageDb. When the arrayList elements are copied in a new arrayList (like so: return new ArrayList<String>(messageDb.getWords()); ) then the exception does not occur.

Another problem that I ran into is similar but it has to do with exceptions. I will start with an example. First the exception declaration:
public class TestException extends RuntimeException {
}
Next the service declaration:
public interface IService {
void testException();
}
And finally the service implementation:
public class Service extends HessianServlet implements IService {
public void testException() {
throw new TestException();
}
}
As You can see this is a trivial implementation to test the exception. When executed on Google servers it dies like this:

java.lang.SecurityException: java.lang.IllegalAccessException: Reflection is not allowed on private java.lang.Throwable java.lang.Throwable.cause
at com.google.appengine.runtime.Request.process-9880ff155b30e983(Request.java)
at java.lang.reflect.Field.setAccessible(Field.java:1 66)
at com.caucho.hessian.io.JavaSerializer.introspect(Ja vaSerializer.java:122)
at com.caucho.hessian.io.JavaSerializer.<init>(JavaSerializer.java:81)
at com.caucho.hessian.io.ThrowableSerializer.<init>(ThrowableSerializer.java:59)
at com.caucho.hessian.io.SerializerFactory.loadSerial izer(SerializerFactory.java:301)
at com.caucho.hessian.io.SerializerFactory.getSeriali zer(SerializerFactory.java:224)
at com.caucho.hessian.io.SerializerFactory.getObjectS erializer(SerializerFactory.java:197)
at com.caucho.hessian.io.Hessian2Output.writeObject(H essian2Output.java:418)
at com.caucho.hessian.io.Hessian2Output.writeFault(He ssian2Output.java:400)
at com.caucho.hessian.server.HessianSkeleton.invoke(H essianSkeleton.java:314)
at com.caucho.hessian.server.HessianSkeleton.invoke(H essianSkeleton.java:202)
at com.caucho.hessian.server.HessianServlet.invoke(He ssianServlet.java:389)
at com.caucho.hessian.server.HessianServlet.service(H essianServlet.java:369)
at org.mortbay.jetty.servlet.ServletHolder.handle(Ser vletHolder.java:511)
...
at com.google.apphosting.runtime.JavaRuntime$RpcRunna ble.run(JavaRuntime.java:413)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalAccessException: Reflection is not allowed on private java.lang.Throwable java.lang.Throwable.cause
... 54 more

On the client I get something like this:
java.lang.reflect.UndeclaredThrowableException
at $Proxy0.testException(Unknown Source)
at com.noveideje.testHessian.client.Main.main(Main.ja va:37)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Nativ e Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Native MethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(De legatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at com.intellij.rt.execution.application.AppMain.main (AppMain.java:110)
Caused by: java.io.EOFException: readObject: unexpected end of file
at com.caucho.hessian.io.Hessian2Input.readObject(Hes sian2Input.java:2133)
at com.caucho.hessian.io.MapDeserializer.readMap(MapD eserializer.java:114)
at com.caucho.hessian.io.Hessian2Input.readObject(Hes sian2Input.java:1653)
at com.caucho.hessian.io.Hessian2Input.readReply(Hess ian2Input.java:348)
at com.caucho.hessian.client.HessianProxy.invoke(Hess ianProxy.java:194)
... 7 more

The ArrayList case also ends in an java.io.EOFException on the client.
Tell me what do You think about this issue. If you have any additional questions do not hesitate to ask. Thank you for your time.

P.S. The following link contains a test project which contains the code needed to reproduce the errors. The project uses GAE 1.3.2 and Hessian 4.0.6
https://docs.google.com/leaf?id=0BzRGFZP1yPUwMzFmNjZiM2YtMzExYi00NDdiLWJlM DgtMmJkMDJiMDhkN2Yx&hl=en

dilbert
06-16-2010, 09:05 AM
There is a bug report with a workaround here: http://bugs.caucho.com/view.php?id=4080

dilbert
06-23-2010, 12:15 PM
The problem also manifests itself on GAE 1.3.4. This severely disables sending exceptions over Hessian on GAE.

yaohua
09-19-2011, 09:01 AM
I think that good information, so I can get a lot of ideas.



house md seasons 1-6 dvd boxset (http://www.wholesalecheapdvd.com/House-MD-Seasons-1-6-DVD-Boxset-FREE-SHIPPING-451.html)
how i met your mother seasons 1-6 dvd boxset (http://www.wholesalecheapdvd.com/How-I-Met-Your-Mother-Seasons-1-6-DVD-Boxset-FREE-SHIPPING-508.html)

JohnGreen
10-15-2011, 10:18 AM
I am having the same error. Can some one please help.