Wednesday, December 28, 2011

Embedded Jetty, Atmosphere & Jersey

Backstory
So, my final major project for my bachelors degree's is software in nature, though it still has it's roots in hardware.  My project is to build a compiler / translator for my own custom HDL titled Silk. The compiler (named Weave) will output a Verilog file for import into a standard synthesis tool. Written in a mix of Java & Scala it is hoped to eventually integrate with Eclipse.

14.7 PSI
Atmosphere is an abstraction layer for bidirectional communication in web applications. You are probably thinking, Weave is a compiler not a webapp... You would be correct.  However, with more and more moving to the web it would be extremely convenient to have a websocket api for the compiler. At this point I haven't exactly figured out what atmosphere gives me over using the Jetty API directly.  The documentation for atmosphere is non-existent at best and outdated / wrong at worst.  It seems to have a lot of hype / people swearing by it so I will give it a shot.
To get started however I spent the last few days getting it compiling and running.  At this point I now have an embedded jetty server and atmosphere accepting websocket connections. I am unsure as to what the protocol is and will begin looking into that next as well as setting up connecting to the server on the other side.
So without further ado...

The Code
So first off here is the code that I had when I wrote this blog post:
https://github.com/Deathbobomega/Weave/tree/9a77f3d2b688a906f8ecc2c5dcd68452fb272018
For those who are also interested in continuous integration here is the build server:
http://ci.codingwell.net/job/Weave/12/

I do believe I would have never figured this out (or would have required several back and forth posts on the mailing list) if it wasn't for Charles Brown. He posted some example code to github that I found extremely helpful.
https://github.com/charlesbrown/Jersey-Atmosphere-with-Embedded-Jetty

I however ended up chasing my tail for hours/days trying to figure out why I had the same problem he did:
http://markmail.org/message/6wxzztdwbgfgxmp3

But his solution only sort-of worked for me. This also made me wonder why the github code (which was newer) did not include this "fix".  The wierd part was, the "sort-of" was that it worked in eclipse but not when I ran it from the command line using Gradle.

After much searching and head banging I found that it was a classpath issue.  The atmosphere-compat-jetty artifact was conflicting with the jetty implementation and depending on the order jars got loaded is whether it would work. Further searching indicated that I should exclude the compat-jetty artifact since I am embedding jetty and leave the other compat-* artifacts alone.
The exception:
java.lang.UnsupportedOperationException: Please remove the atmosphere-compat-jetty from your classpath
Should have pointed me to this, but I wasn't sure why it was included and why I needed to remove it.  After realizing the artifact existed as a placeholder until the app was loaded into a servlet container and only conflicted because I was embedding the container it was a simple matter to correct.

In Gradle this is simply:

configurations {
   all*.exclude group: 'org.atmosphere', module: 'atmosphere-compat-jetty'
}

Another useful tool in my experimentation is the following page that lets me connect to an arbitrary websocket:
http://websocket.org/echo.html

If you have any questions or comments drop me a line or post in the comments.

1 comment:

bumbu pecel bali said...
This comment has been removed by a blog administrator.