Search code examples
herokuclassloaderembedded-jetty

jetty nosql MongoSessionManager usage on heroku


I have grails application on heroku. I use MongoSessionManager which allows, to share session data between heroku cluster nodes. I also use a custom bootstrap class to configure jetty instance, for grails application.

The problem with MongoSessionManager, that when jetty tries to deserialize object from Mondodb, it throws ClassNotFoundException:

2012-01-30T15:23:56+00:00 app[web.2]: 2012-01-30 15:23:56.121:WARN:oejnm.MongoSessionManager: 2012-01-30T15:23:56+00:00 app[web.2]: at java.net.URLClassLoader$1.run(URLClassLoader.java:217) 2012-01-30T15:23:56+00:00 app[web.2]: at java.security.AccessController.doPrivileged(Native Method) 2012-01-30T15:23:56+00:00 app[web.2]: at java.net.URLClassLoader.findClass(URLClassLoader.java:205) 2012-01-30T15:23:56+00:00 app[web.2]: at java.lang.ClassLoader.loadClass(ClassLoader.java:321) 2012-01-30T15:23:56+00:00 app[web.2]: at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294) 2012-01-30T15:23:56+00:00 app[web.2]: java.lang.ClassNotFoundException: org.codehaus.groovy.grails.web.servlet.GrailsFlashScope 2012-01-30T15:23:56+00:00 app[web.2]: at java.io.ObjectInputStream.resolveClass(ObjectInputStream.java:621) 2012-01-30T15:23:56+00:00 app[web.2]: at java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1592) 2012-01-30T15:23:56+00:00 app[web.2]: at java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1513) 2012-01-30T15:23:56+00:00 app[web.2]: at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1749) 2012-01-30T15:23:56+00:00 app[web.2]: at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1346) 2012-01-30T15:23:56+00:00 app[web.2]: at org.eclipse.jetty.nosql.mongodb.MongoSessionManager.decodeValue(MongoSessionManager.java:447) 2012-01-30T15:23:56+00:00 app[web.2]: at java.lang.ClassLoader.loadClass(ClassLoader.java:266) 2012-01-30T15:23:56+00:00 app[web.2]: at java.lang.Class.forName0(Native Method)

It seems that jetty uses other classloader, which can't find class specific for my web application. Is there the way to configure jetty instance, that it could find all classes, which my application uses?


Solution

  • If you only want to deploy your libraries in the webapp then not easily. Normally you could put it under $jetty.home/lib/ext or the like and get it in the larger scoped classloader. In this embedded mode you could muck with the system and server classes methods on the WebAppContext but then I don't know for a fact how the heroku jetty instance is setup so I can promise that would work.

    Thanks to David though who opened an issue in bugzilla (bugs.eclipse.org under RT/Jetty) on this issue (with a fix even, we like that), I'll apply the fix and it should be available in 7.6.1 and 8.1.1 releases in a few weeks or on master and jetty-8 branches later today.

    cheers

    [edit] fix for this has been applied to master and jetty-8 and will appear in 7.6.1 and 8.1.1 releases of jetty