Mantis - Hessian
Viewing Issue Advanced Details
4061 major always 06-02-10 00:06 06-16-10 01:13
dilbert  
 
normal  
new 4.0.6  
open  
none    
none  
0004061: Security exceptions with Hessian on google app engine
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:166)
    at com.caucho.hessian.io.JavaSerializer.introspect(JavaSerializer.java:122)
    at com.caucho.hessian.io.JavaSerializer.<init>(JavaSerializer.java:81)
    at com.caucho.hessian.io.JavaSerializer.create(JavaSerializer.java:95)
    at com.caucho.hessian.io.SerializerFactory.getDefaultSerializer(SerializerFactory.java:348)
    at com.caucho.hessian.io.SerializerFactory.loadSerializer(SerializerFactory.java:278)
    at com.caucho.hessian.io.SerializerFactory.getSerializer(SerializerFactory.java:224)
    at com.caucho.hessian.io.SerializerFactory.getObjectSerializer(SerializerFactory.java:197)
    at com.caucho.hessian.io.Hessian2Output.writeObject(Hessian2Output.java:418)
    at com.caucho.hessian.io.AbstractHessianOutput.writeReply(AbstractHessianOutput.java:558)
    at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:323)
    at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:202)
    at com.caucho.hessian.server.HessianServlet.invoke(HessianServlet.java:389)
    at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:369)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:97)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:238)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:135)
    at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:250)
    at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5838)
    at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5836)
    at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
    at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:398)
    at com.google.net.rpc.impl.Server$2.run(Server.java:852)
    at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
    at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:576)
    at com.google.net.rpc.impl.Server.startRpc(Server.java:807)
    at com.google.net.rpc.impl.Server.processRequest(Server.java:369)
    at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:442)
    at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)
    at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)
    at com.google.net.async.Connection.handleReadEvent(Connection.java:474)
    at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:831)
    at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
    at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:103)
    at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
    at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.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:166)
    at com.caucho.hessian.io.JavaSerializer.introspect(JavaSerializer.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.loadSerializer(SerializerFactory.java:301)
    at com.caucho.hessian.io.SerializerFactory.getSerializer(SerializerFactory.java:224)
    at com.caucho.hessian.io.SerializerFactory.getObjectSerializer(SerializerFactory.java:197)
    at com.caucho.hessian.io.Hessian2Output.writeObject(Hessian2Output.java:418)
    at com.caucho.hessian.io.Hessian2Output.writeFault(Hessian2Output.java:400)
    at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:314)
    at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:202)
    at com.caucho.hessian.server.HessianServlet.invoke(HessianServlet.java:389)
    at com.caucho.hessian.server.HessianServlet.service(HessianServlet.java:369)
    at org.mortbay.jetty.servlet.ServletHolder.handle(ServletHolder.java:511)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1166)
    at com.google.apphosting.utils.servlet.ParseBlobUploadFilter.doFilter(ParseBlobUploadFilter.java:97)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.runtime.jetty.SaveSessionFilter.doFilter(SaveSessionFilter.java:35)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at com.google.apphosting.utils.servlet.TransactionCleanupFilter.doFilter(TransactionCleanupFilter.java:43)
    at org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1157)
    at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:388)
    at org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
    at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:182)
    at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:765)
    at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:418)
    at com.google.apphosting.runtime.jetty.AppVersionHandlerMap.handle(AppVersionHandlerMap.java:238)
    at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:152)
    at org.mortbay.jetty.Server.handle(Server.java:326)
    at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:542)
    at org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnection.java:923)
    at com.google.apphosting.runtime.jetty.RpcRequestParser.parseAvailable(RpcRequestParser.java:76)
    at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:404)
    at com.google.apphosting.runtime.jetty.JettyServletEngineAdapter.serviceRequest(JettyServletEngineAdapter.java:135)
    at com.google.apphosting.runtime.JavaRuntime.handleRequest(JavaRuntime.java:250)
    at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5838)
    at com.google.apphosting.base.RuntimePb$EvaluationRuntime$6.handleBlockingRequest(RuntimePb.java:5836)
    at com.google.net.rpc.impl.BlockingApplicationHandler.handleRequest(BlockingApplicationHandler.java:24)
    at com.google.net.rpc.impl.RpcUtil.runRpcInApplication(RpcUtil.java:398)
    at com.google.net.rpc.impl.Server$2.run(Server.java:852)
    at com.google.tracing.LocalTraceSpanRunnable.run(LocalTraceSpanRunnable.java:56)
    at com.google.tracing.LocalTraceSpanBuilder.internalContinueSpan(LocalTraceSpanBuilder.java:576)
    at com.google.net.rpc.impl.Server.startRpc(Server.java:807)
    at com.google.net.rpc.impl.Server.processRequest(Server.java:369)
    at com.google.net.rpc.impl.ServerConnection.messageReceived(ServerConnection.java:442)
    at com.google.net.rpc.impl.RpcConnection.parseMessages(RpcConnection.java:319)
    at com.google.net.rpc.impl.RpcConnection.dataReceived(RpcConnection.java:290)
    at com.google.net.async.Connection.handleReadEvent(Connection.java:474)
    at com.google.net.async.EventDispatcher.processNetworkEvents(EventDispatcher.java:831)
    at com.google.net.async.EventDispatcher.internalLoop(EventDispatcher.java:207)
    at com.google.net.async.EventDispatcher.loop(EventDispatcher.java:103)
    at com.google.net.rpc.RpcService.runUntilServerShutdown(RpcService.java:251)
    at com.google.apphosting.runtime.JavaRuntime$RpcRunnable.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.java:37)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.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(Hessian2Input.java:2133)
    at com.caucho.hessian.io.MapDeserializer.readMap(MapDeserializer.java:114)
    at com.caucho.hessian.io.Hessian2Input.readObject(Hessian2Input.java:1653)
    at com.caucho.hessian.io.Hessian2Input.readReply(Hessian2Input.java:348)
    at com.caucho.hessian.client.HessianProxy.invoke(HessianProxy.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 attachment 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
 testHessian.zip [^] (23,038 bytes) 06-02-10 00:06

Notes
(0004640)
dilbert   
06-16-10 01:13   
Ignore this bug. A new report is posted: http://bugs.caucho.com/view.php?id=4080 [^]