<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:yt="http://gdata.youtube.com/schemas/2007" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">
   <channel>
      <title>Javarants</title>
      <description>Pipes Output</description>
      <link>http://pipes.yahoo.com/pipes/pipe.info?_id=dth0BVnE2xG19PBwrscPhQ</link>
      <pubDate>Tue, 09 Feb 2010 05:03:45 -0800</pubDate>
      <generator>http://pipes.yahoo.com/pipes/</generator>
      <feedburner:info uri="javarants" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><geo:lat>37.353741</geo:lat><geo:long>-122.087172</geo:long><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://www.javarants.com/rss.xml" /><item>
         <title>What I would like to see in the new Apple device (iSlate, iPod Tablet, iTouch, iPad, iTablet, iPhone Max)</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/1YsS3AeCQgg/</link>
         <description>&lt;p&gt;&lt;strong&gt;Update Misses: no cameras, no GPS, no stylus, no SD&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If there is going to be an Apple Tablet there are a few features that I would like to see. These aren&amp;#8217;t really predictions but more my limited view of how you might use such a device:&lt;/p&gt;
&lt;p&gt;Hardware&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Front and rear video camera for killer video conferencing and augmented reality applications&lt;/li&gt;
&lt;li&gt;The standard WiFi, GPS, accelerometer and compass package with optional 3G/wimax connectivity&lt;/li&gt;
&lt;li&gt;Support for all the typical touch gestures along with a stylus for writing&lt;/li&gt;
&lt;li&gt;A low-power mode that is still suitable for reading documents&lt;/li&gt;
&lt;li&gt;A dock suitable for both home plugged in use and on an airplane so you can watch video on it easily&lt;/li&gt;
&lt;li&gt;At least 1080p resolution &amp;#8212; any more than this is overkill&lt;/li&gt;
&lt;li&gt;Some thought to how you would carry it around without destroying it&lt;/li&gt;
&lt;li&gt;Smaller and lighter than a Macbook Air with a longer battery life &amp;#8212; 8 hours?&lt;/li&gt;
&lt;li&gt;Single USB port, Display Port and SD card slot&lt;/li&gt;
&lt;li&gt;At least 64GB of local storage&lt;/li&gt;
&lt;li&gt;Might as well be a conference room quality speakerphone as well&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Software&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support for applications from the iPhone App Store along with new tablet applications&lt;/li&gt;
&lt;li&gt;Strong integration with MobileMe for Back to my Mac, syncing and file sharing&lt;/li&gt;
&lt;li&gt;Tablet versions of Mail.app, iWork, iLife and Dashboard&lt;/li&gt;
&lt;li&gt;Air gestures that use the camera and voice commands for additional remote control&lt;/li&gt;
&lt;li&gt;Broadcast whatever is on the tablet to another Mac or an AppleTV easily&lt;/li&gt;
&lt;li&gt;Run up to 3 applications at the same time&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A device with a bunch of features like that might be nice to have around the house, in meetings and on the road. Could even get some programming done as long as I have a home machine I can connect to as well.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/javarants?a=1YsS3AeCQgg:fEYwmALKeQ8:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/javarants?a=1YsS3AeCQgg:fEYwmALKeQ8:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/1YsS3AeCQgg" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=1253</guid>
         <pubDate>Mon, 04 Jan 2010 14:29:24 -0800</pubDate>
      <feedburner:origLink>http://www.javarants.com/2010/01/04/what-i-would-like-to-see-in-the-new-apple-device-islate-ipod-tablet-itouch-ipad-itablet-iphone-max/</feedburner:origLink></item>
      <item>
         <title>Drastically reducing GC pause times for YQL</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/iIXxzdaAq-4/</link>
         <description>&lt;p&gt;&lt;strong&gt;Update 2: &lt;a rel="nofollow" target="_blank" href="http://www.oracle.com/technology/software/products/jrockit/index.html"&gt;JRockit Real Time 3.1.2&lt;/a&gt;&lt;/strong&gt;&lt;strong&gt; using &lt;code&gt;-XgcPrio:deterministic&lt;/code&gt; performed even better than this configuration in testing though it is not yet an approved VM at Yahoo! we will continue to test with it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update: One issue we still have is that after many hours of deployment with this configuration the heap fragments and we start to get concurrent mode failures. We only saw this though during periods of peak activity.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We were struggling with some long pause times due to GC for YQL that we couldn&amp;#8217;t stomach for our internal property SLAs. The secret turned out to be a collection of parameters for the Java 6 garbage collector:&lt;/p&gt;
&lt;pre&gt;-XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode &amp;#92;
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+CMSIncrementalPacing&lt;/pre&gt;
&lt;p&gt;I have so far been blown away by the results of this combination of parameters. Not only does it work very efficiently under moderate load, under crushing load it rises the occasion and aggressively keeps down the heap in such a way as to never cause the:&lt;/p&gt;
&lt;pre&gt;Concurrent Mode Failure
The concurrent collector uses one or more garbage collector threads that run simultaneously with the
application threads with the goal of completing the collection of the tenured and permanent generations
before either becomes full. As described above, in normal operation, the concurrent collector does most
of its tracing and sweeping work with the application threads still running, so only brief pauses are seen
by the application threads. However, if the concurrent collector is unable to finish reclaiming the
unreachable objects before the tenured generation fills up, or if an allocation cannot be satisfied with
the available free space blocks in the tenured generation, then the application is paused and the
collection is completed with all the application threads stopped. The inability to complete a collection
concurrently is referred to as concurrent mode failure and indicates the need to adjust the concurrent
collector parameters.&lt;/pre&gt;
&lt;p&gt;If you have any other GC secrets for the JVM, leave them here. Just as a heads up I compared it with all the other GC&amp;#8217;s available for Java 6 including the experimental G1 and none of them were as effective.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/javarants?a=iIXxzdaAq-4:7FkCAFz-yho:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/javarants?a=iIXxzdaAq-4:7FkCAFz-yho:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/iIXxzdaAq-4" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=1241</guid>
         <pubDate>Tue, 03 Nov 2009 15:31:36 -0800</pubDate>
      <feedburner:origLink>http://www.javarants.com/2009/11/03/drastically-reducing-gc-pause-times-for-yql/</feedburner:origLink></item>
      <item>
         <title>Building OpenJDK 1.7.0 for Mac OS X 10.6 (Snow Leopard)</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/AJTZmKz1hfk/</link>
         <description>&lt;p&gt;I&amp;#8217;m basing this blog entry on this reference &lt;a rel="nofollow" target="_blank" href="http://confluence.concord.org/display/CCTR/Build+OpenJDK+Java+1.7.0+on+Mac+OS+X+10.5"&gt;page&lt;/a&gt;. There are only a few different things that you need to do so I will spell those out cleanly relative to what was previously needed:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Grab the dependencies except for JIBX, it is no longer needed for the build.&lt;/li&gt;
&lt;li&gt;Checkout the code as described.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;export JAVA_HOME=$SOYLATTE_HOME&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;The build script is somewhat different:&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;env -i PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/bin:/usr/X11/bin &amp;#92; make &amp;#92; CC=gcc-4.0 CXX=g++-4.0 &amp;#92; ALT_BOOTDIR=$SOYLATTE_HOME &amp;#92; JAVA_TOOLS_DIR=$SOYLATTE_HOME/bin &amp;#92; ALT_FREETYPE_HEADERS_PATH=/usr/X11R6/include &amp;#92; ALT_FREETYPE_LIB_PATH=/usr/X11R6/lib &amp;#92; ANT_HOME=/usr/share/ant &amp;#92; NO_DOCS=true &amp;#92; HOTSPOT_BUILD_JOBS=1&lt;/pre&gt;
&lt;p&gt;That should then result in a &lt;em&gt;build/bsd-i586/j2sdk-image&lt;/em&gt; directory containing the JDK.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/javarants?a=AJTZmKz1hfk:94PMImQ1eDw:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/javarants?a=AJTZmKz1hfk:94PMImQ1eDw:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/AJTZmKz1hfk" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=1237</guid>
         <pubDate>Sun, 01 Nov 2009 10:57:26 -0800</pubDate>
      <feedburner:origLink>http://www.javarants.com/2009/11/01/building-openjdk-1-7-0-for-mac-os-x-10-6-snow-leopard/</feedburner:origLink></item>
      <item>
         <title>Update your FireEagle location automatically from any browser</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/7b1GyT4zgz4/</link>
         <description>&lt;div id="attachment_1232" class="wp-caption alignright" style="width:64px;"&gt;&lt;a rel="nofollow" target="_blank" href="http://browfire.com"&gt;&lt;img class="size-full wp-image-1232 " title="BrowFire" src="http://www.javarants.com/wp-content/uploads/2009/07/browfire-54x54.png" alt="The best way to update FireEagle" width="54" height="54"/&gt;&lt;/a&gt;&lt;p class="wp-caption-text"&gt;The best way to update FireEagle&lt;/p&gt;&lt;/div&gt;
&lt;p&gt;With all the talk of geolocation in the browser, I decided this afternoon to go ahead and make it really easy for anyone to automatically update their location in &lt;a rel="nofollow" target="_blank" href="http://fireeagle.yahoo.net/"&gt;FireEagle&lt;/a&gt; by going to a single url from any browser. Depending on the capabilities of your browser it will use various technologies to determine your current location:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Firefox 3.5, iPhone: &lt;a rel="nofollow" target="_blank" href="http://dev.w3.org/geo/api/spec-source.html"&gt;HTML5 Geolocation API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Android and other browsers with Gears: &lt;a rel="nofollow" target="_blank" href="http://code.google.com/apis/gears/api_geolocation.html"&gt;Gears Geolocation API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Other browsers: &lt;a rel="nofollow" target="_blank" href="http://code.google.com/intl/it-IT/apis/ajax/documentation/#ClientLocation"&gt;Google Client Location based on IP address&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span id="more-1228"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Simply go to &lt;a rel="nofollow" target="_blank" href="http://browfire.com"&gt;BrowFire&lt;/a&gt; and it will first get authorization from FireEagle for me to update your location. I only store the OAuth credentials in your own cookies so there is no server-side storage of your location or even the ability to later update or read your location without you revisiting the site. After I get your authorization to update your FireEagle location you need to return to the site and I will either automatically update your location using your IP address or ask you for permission to use more accurate location information from one of the other sources you might have available in your client. It will not ask you again for authorization for 28 days.&lt;/p&gt;
&lt;p&gt;If you are interested in how it all works, you can check out the &lt;a rel="nofollow" target="_blank" href="http://github.com/spullara/firebrowser/tree"&gt;firebrowser&lt;/a&gt; project on &lt;a rel="nofollow" target="_blank" href="http://github.com"&gt;github&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;P.S. If you find some combination that doesn&amp;#8217;t work as you would expect please say so in the comments (and then send me a pull request for your changes &lt;img src='http://www.javarants.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley'/&gt; )&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/javarants?a=7b1GyT4zgz4:58e4TxjUuxA:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/javarants?a=7b1GyT4zgz4:58e4TxjUuxA:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/7b1GyT4zgz4" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=1228</guid>
         <pubDate>Fri, 17 Jul 2009 22:49:35 -0700</pubDate>
      <feedburner:origLink>http://www.javarants.com/2009/07/17/update-your-fireeagle-location-automatically-from-any-browser/</feedburner:origLink></item>
      <item>
         <title>Creating a JSON web service API for Find My iPhone</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/F4i6ttpL8nc/</link>
         <description>&lt;p&gt;One of the really cool features of &lt;a rel="nofollow" target="_blank" href="http://me.com"&gt;MobileMe&lt;/a&gt; and the new iPhone 3.0 OS is the ability for it to &lt;a rel="nofollow" target="_blank" href="http://www.apple.com/mobileme/whats-new/"&gt;reach out and locate your iPhone&lt;/a&gt; at any time if you have that feature enabled. Right now Apple only makes this available on their MobileMe website however and does not offer a programmatic way to get a hold of the information.&lt;/p&gt;
&lt;p&gt;Since the iPhone doesn&amp;#8217;t have background processes to update your location for third party applications I thought that it would be great to have the ability to do this anyway by leveraging their website. The first thing you need to do whenever you are going to scrape a sophisticated service like MobileMe is to collect all the relevant packets going over the wire. Since this service is entirely behind HTTPS the easiest way to do this is within the browser client itself. To that end I found what I believe to be the best Firefox plugin for the job, &lt;a rel="nofollow" target="_blank" href="https://addons.mozilla.org/en-US/firefox/addon/966"&gt;Tamper Data&lt;/a&gt;.&lt;br /&gt;
&lt;span id="more-1216"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;Some critical things that you need to watch for when you are scraping:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Cookies need to be tracked very closely&lt;/li&gt;
&lt;li&gt;URL parameters need to be analyzed to determine which ones are relevant&lt;/li&gt;
&lt;li&gt;Other headers can also have a role in any web based API&lt;/li&gt;
&lt;li&gt;Data may actually be within the page or within an API call of their own&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The Apple MobileMe service has all of these factors:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;MobileMe authentication is transferred via cookies and cross-site redirects&lt;/li&gt;
&lt;li&gt;Destination URLs are BASE64 encoded within the URL for some unknown reason&lt;/li&gt;
&lt;li&gt;The X-Mobileme-Isc header transfers further authentication data&lt;/li&gt;
&lt;li&gt;The device ids owned by the user are within HTML transferred via a JSON request and must be extracted with a regular expression&lt;/li&gt;
&lt;li&gt;Finally Apple has some strange idiosyncratic choices that you need to be aware of like transferring JSON to the server as a form parameter rather than a raw payload&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I chose not to use the standard Java URLConnection but instead to use the latest &lt;a rel="nofollow" target="_blank" href="http://hc.apache.org/"&gt;http-client from Apache&lt;/a&gt;. This library is great and easy to use and it handles things like cookie management. For JSON output I could have just written this myself but wanted to get familiar with &lt;a rel="nofollow" target="_blank" href="http://jackson.codehaus.org/"&gt;Jackson&lt;/a&gt;, a very nice high performance streaming JSON parser and generator from &lt;a rel="nofollow" target="_blank" href="http://codehaus.org"&gt;Codehaus&lt;/a&gt;. All in all, the vast majority of the time was not writing the code but reverse engineering the protocol itself. You can download the source code and contribute changes back to the &lt;a rel="nofollow" target="_blank" href="http://github.com/spullara/findmyiphone/tree/master"&gt;findmyiphone git repository on github&lt;/a&gt;.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/javarants?a=F4i6ttpL8nc:fLpuofIftq0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/javarants?a=F4i6ttpL8nc:fLpuofIftq0:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/F4i6ttpL8nc" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=1216</guid>
         <pubDate>Fri, 03 Jul 2009 12:56:11 -0700</pubDate>
      <feedburner:origLink>http://www.javarants.com/2009/07/03/creating-a-json-web-service-api-for-find-my-iphone/</feedburner:origLink></item>
      <item>
         <title>4hoursearch &amp;#8211; faster, simpler, more powerful using YQL</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/sOV422xNjXk/</link>
         <description>&lt;p&gt;As you know the original &lt;a rel="nofollow" target="_blank" href="http://www.4hoursearch.com"&gt;4hoursearch&lt;/a&gt; was built using &lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/boss"&gt;Yahoo! BOSS&lt;/a&gt;, &lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yui/"&gt;YUI&lt;/a&gt; and Python running on &lt;a rel="nofollow" target="_blank" href="http://code.google.com/appengine/"&gt;Google App Engine&lt;/a&gt;. Although Google App Engine is a very productive environment I was unhappy with it for a few reasons. It doesn&amp;#8217;t feel snappy enough, presumably because of the security enforcement aspects of the system, your code has to be written in Python which is not my favorite environment, and the last is that I was showcasing a great Yahoo! API by leveraging Google infrastructure. The last point is the least valid as Yahoo! doesn&amp;#8217;t offer a truly equivalent environment but I think it will be more compelling as a showcase built entirely on Yahoo! technology. I could have moved it over to this new implementation when YQL launched but I also wanted to wait for BOSS to offer more features so I could significantly enrich the search experience at the same time.&lt;br /&gt;
&lt;span id="more-1187"&gt;&lt;/span&gt;&lt;br /&gt;
I&amp;#8217;ve also recently been experimenting with AJAX over traditional web applications, especially for search, as you can get far more responsive pages by transmitting less information per search result page view. This led me to decide that the UI part of the system should be entirely in the browser using HTML, CSS, and YUI while the backend would be entirely implemented using &lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql"&gt;YQL&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So, in somewhat less than 4 hours, the whole thing has now been rewritten and is live on &lt;a rel="nofollow" target="_blank" href="http://4hoursearch.com"&gt;4hoursearch.com&lt;/a&gt;. The suggestions are actually coming from the same API that grabs them on the frontpage of Yahoo and that uses an &lt;a rel="nofollow" target="_blank" href="http://www.4hoursearch.com/yql/suggest.xml"&gt;Open Data Table to treat that API as a table&lt;/a&gt;. There is also a very small glue layer in &lt;a rel="nofollow" target="_blank" href="http://www.4hoursearch.com/js/yql.js"&gt;js/yql.js&lt;/a&gt; that shows you how to wrap up a YQL query as a YUI DataSource. Finally, in the actual search call you&amp;#8217;ll see that I am now pulling not only the regular search results but also delicious saves &amp;#038; tags, key terms and any search monkey data that appears on the result page.&lt;/p&gt;
&lt;p&gt;The best thing about it is that it is much faster as well though I&amp;#8217;m still getting it to look right in IE &lt;img src='http://www.javarants.com/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley'/&gt; .&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/javarants?a=sOV422xNjXk:nKwDr16ImWk:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/javarants?a=sOV422xNjXk:nKwDr16ImWk:qj6IDK7rITs"&gt;&lt;img src="http://feeds.feedburner.com/~ff/javarants?d=qj6IDK7rITs" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/sOV422xNjXk" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=1187</guid>
         <pubDate>Fri, 17 Apr 2009 14:22:48 -0700</pubDate>
      <feedburner:origLink>http://www.javarants.com/2009/04/17/4hoursearch-faster-simpler-more-powerful-using-yql/</feedburner:origLink></item>
      <item>
         <title>YQL opens up 3rd-party web service table definitions to developers</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/WJ33KX8fo40/</link>
         <description>&lt;p&gt;The &lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql/"&gt;Yahoo! Query Language&lt;/a&gt; aspires to be the last web service API that the normal developer will ever have to learn. By default we implement 50+ tables that grab data both from Yahoo! web services, some 3rd party web services and then the web at large using our dynamic tables that allow you specify a data type and a url. However, those dynamic APIs limit the YQL user to a very flexible but ultimately hard to work with API without the benefit of the structure found in the other tables that we offer.&lt;/p&gt;
&lt;p&gt;Today &lt;a rel="nofollow" target="_blank" href="http://www.yqlblog.net/blog/2009/02/05/open-data-tables-added-to-yql/"&gt;YQL introduced&lt;/a&gt; a new feature that allows 3rd parties to define new tables and then share those table definitions with whomever they like for them to use. For example, let&amp;#8217;s say you are the New York Times or you are a developer that likes the New York Times APIs and would like to make them more accessible to someone using YQL. Yesterday, they released the article search API, so I will use that one among others as an example, to get an api-key to execute these examples go to their &lt;a rel="nofollow" target="_blank" href="http://developer.nytimes.com"&gt;developer site&lt;/a&gt;. This is a pretty sophisticated API that allows you to search using a variety of parameters. If you were to use YQL without modification, you would simply use the dynamic JSON endpoint to parse out the results from their service. The big issue with this though is that you would be unable to easily construct the URLs required and would have to write that code that collected all the parameters and created the URL. If you had a YQL table, those parameters would be defined and how they are expressed in the URL codified and you would be able to individually address the keys.&lt;br /&gt;
&lt;span id="more-1153"&gt;&lt;/span&gt;&lt;br /&gt;
So without this ability you would use something like this:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from json where url='http://api.nytimes.com/svc/search/v1/article?api-key=...&lt;br /&gt;
&amp;amp;query=yahoo&amp;amp;begin_date=19990112&amp;amp;end_date=19993112' and&lt;br /&gt;
itemPath='json.results'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;If we instead defined the API using the &lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql/guide/yql-opentables-chapter.html"&gt;YQL open data tables specification&lt;/a&gt; you would be able to do this (by the way, don&amp;#8217;t read the headlines, you&amp;#8217;ll just be depressed):&lt;/p&gt;
&lt;p&gt;&lt;code&gt;use 'http://www.javarants.com/nyt/nyt.article.search.xml' as articles;&lt;br /&gt;
select * from articles where apikey='...' and query='yahoo' and begin_date='19990112' and&lt;br /&gt;
end_date='19993112'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Why is this superior? For a number of reasons. In the second case not only does it make it easier for anyone to use it, it also brings those keys from the query into columns which allows you to do joins that you cannot do with the first abstraction. Here is an example join:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from bs where apikey='...' and query in ('yahoo', 'google', 'microsoft') and begin_date='19990112' and end_date='20000101'&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;This will actually do 3 searches for you in parallel and then return the combined result. By creating a YQL open table we can really off-load processing that you would normally do on your client or server to the YQL engine. You&amp;#8217;ll note with that query that the user-time spent is actually about half or less than the actual service-time thus drastically decreasing the latency through asynchronous processing.&lt;/p&gt;
&lt;p&gt;One of the really nice APIs out there is &lt;a rel="nofollow" target="_blank" href="http://friendfeed.com/api/"&gt;FriendFeed&amp;#8217;s API&lt;/a&gt;. It really is very well designed and easily works with straight-forward table definitions. Here is an example of how to get the public feed:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;use 'http://www.javarants.com/friendfeed/friendfeed.feeds.xml' as ff;&lt;br /&gt;
select * from ff&lt;/code&gt;&lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql/console/?q=use%20'http%3A%2F%2Fwww.javarants.com%2Ffriendfeed%2Ffriendfeed.feeds.xml'%20as%20ff%3B%0Aselect%20*%20from%20ff"&gt;&lt;small&gt;console&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;By defining different endpoints with the same table definition we will automatically select the correct API based on the keys included in the query. Using that same table we can also get my public entries from twitter:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;select * from ff where nickname='spullara' and service='twitter'&lt;/code&gt;&lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql/console/?q=use%20'http%3A%2F%2Fwww.javarants.com%2Ffriendfeed%2Ffriendfeed.feeds.xml'%20as%20ff%3B%0Aselect%20*%20from%20ff%20where%20nickname%3D'spullara'%20and%20service%3D'twitter'"&gt;&lt;small&gt;console&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This won&amp;#8217;t include my private entries though. However, if you had my remotekey you could generate and pass YQL the authorization header required and it would pass it on to authenticate the API call. Another popular example that has been on the forums is the ability to use &lt;a rel="nofollow" target="_blank" href="http://weather.com"&gt;weather.com&lt;/a&gt;&amp;#8217;s API to tease out international locations. That is actually really easy and you can even use that data to join with their weather forecasts. Here is an example where we pull the weather for all the Moscow&amp;#8217;s of the world:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;use 'http://www.javarants.com/weather/weather.search.xml' as ws;use 'http://www.javarants.com/weather/weather.local.xml' as wl;&lt;br /&gt;
select * from wl where location in (select id from ws where query='moscow')&lt;/code&gt;&lt;a rel="nofollow" target="_blank" href="http://developer.yahoo.com/yql/console/?q=use%20'http%3A%2F%2Fwww.javarants.com%2Fweather%2Fweather.search.xml'%20as%20ws%3Buse%20'http%3A%2F%2Fwww.javarants.com%2Fweather%2Fweather.local.xml'%20as%20wl%3B%0Aselect%20*%20from%20wl%20where%20location%20in%20(select%20id%20from%20ws%20where%20query%3D'moscow')"&gt;&lt;small&gt;console&lt;/small&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve actually started up a project on &lt;a rel="nofollow" target="_blank" href="http://github.com"&gt;github&lt;/a&gt; called &lt;a rel="nofollow" target="_blank" href="http://github.com/spullara/yql-tables/tree/master"&gt;yql-tables&lt;/a&gt; to store useful table definitions and will be taking submissions from the community. You can try them out by &amp;#8216;use&amp;#8217;ing them directly from the git repository or by pulling them onto your own server accessible from the YQL servers.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/javarants?a=4eVGoUza"&gt;&lt;img src="http://feeds.feedburner.com/~f/javarants?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/WJ33KX8fo40" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=1153</guid>
         <pubDate>Thu, 05 Feb 2009 12:55:51 -0800</pubDate>
      <feedburner:origLink>http://www.javarants.com/2009/02/05/yql-opens-up-3rd-party-web-service-table-definitions-to-developers/</feedburner:origLink></item>
      <item>
         <title>Using JAX-RS with Protocol Buffers for high-performance REST APIs</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/tLz3yuLbtBs/</link>
         <description>&lt;p&gt;One of the great things about the &lt;a rel="nofollow" target="_blank" href="http://jcp.org/aboutJava/communityprocess/final/jsr311/index.html"&gt;JAX-RS specification&lt;/a&gt; is that it is very extensible and adding new providers for different mime-types is very easy. One of the interesting binary protocols out there is &lt;a rel="nofollow" target="_blank" href="http://code.google.com/apis/protocolbuffers/docs/overview.html"&gt;Google Protocol Buffers&lt;/a&gt;. They are designed for high-performance systems and drastically reduce the amount of over-the-wire data and also the amount of CPU spent serializing and deserializing that data. There are other similar frameworks out there including &lt;a rel="nofollow" target="_blank" href="http://java.sun.com/developer/technicalArticles/xml/fastinfoset/"&gt;Fast Infoset&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="http://incubator.apache.org/thrift/"&gt;Thrift&lt;/a&gt;. Extending JAX-RS to support those protocols is nearly identical so all of the ideas I&amp;#8217;ll talk about are generally valid for those frameworks as well. The one limitation that we will table for now is that JAX-RS only works over HTTP and will not work for raw socket protocols and the high-performance aspect of protobufs is somewhat reduced by our dependency on the HTTP envelope. My assumption is that you have done your homework and know that message passing is your overriding bottleneck.&lt;br /&gt;
&lt;span id="more-955"&gt;&lt;/span&gt;&lt;br /&gt;
The first thing you will need to do to get started is to download and build Protocol Buffers. You can get the latest stable release from &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/protobuf/"&gt;here&lt;/a&gt;. All the example code you will find in this blog post was developed against protobuf-2.0.3 and the JAX-RS 1.0 specification (using &lt;a rel="nofollow" target="_blank" href="https://jersey.dev.java.net/"&gt;jersey-1.0.1&lt;/a&gt;) though I don&amp;#8217;t expect the API to change very much going forward. Once you have &lt;em&gt;protoc&lt;/em&gt; in your path you are ready to create your first JAX-RS / protobuf project.&lt;/p&gt;
&lt;p&gt;The dependencies you will need to create the application are actually quite small. I use &lt;a rel="nofollow" target="_blank" href="http://maven.apache.org/"&gt;Maven&lt;/a&gt; (and &lt;a rel="nofollow" target="_blank" href="http://www.jetbrains.com/idea/download/"&gt;IntelliJ 8.0&lt;/a&gt;) to do my development so that is how I&amp;#8217;ll describe what you need. For running the application you&amp;#8217;ll need these installed:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;com.sun.jersey&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;jersey-server&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;1.0.1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;com.sun.grizzly&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;grizzly-servlet-webserver&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;1.8.6.3&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;com.google.protobuf&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;protobuf-java&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;2.0.3&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Then to execute the tests that we will create to verify that things are working as expected you&amp;#8217;ll need two additional test-time only dependencies:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;com.sun.jersey&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;jersey-client&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;1.0.1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;scope&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;test&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;scope&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;junit&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;junit&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;4.5&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;scope&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;test&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;scope&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Not a huge set of dependencies on the surface but Maven does hide a lot of the complexity underneath &amp;#8212; total is about 15 jars (mostly grizzly). The next step is to create a Protocol Buffer using their definition language. Instead of making one up myself, I&amp;#8217;ll just use the one from their &lt;a rel="nofollow" target="_blank" href="http://code.google.com/apis/protocolbuffers/docs/javatutorial.html"&gt;example&lt;/a&gt;, addressbook.proto:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(102,0,0);font-weight:bold;font-style:normal;"&gt;package&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; tutorial; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;option&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,102,102);font-weight:bold;font-style:normal;"&gt;java_package&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; = &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"com.sampullara.jaxrsprotobuf.tutorial"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;option&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,102,102);font-weight:bold;font-style:normal;"&gt;java_outer_classname&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; = &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"AddressBookProtos"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; &lt;/span&gt;&lt;span style="color:rgb(102,0,0);font-weight:bold;font-style:normal;"&gt;message&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Person { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;required&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;string&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; name = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;required&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;int32&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; id = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;2&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;optional&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;string&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; email = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;3&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; &lt;/span&gt;&lt;span style="color:rgb(102,0,0);font-weight:bold;font-style:normal;"&gt;enum&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; PhoneType { MOBILE = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;0&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; HOME = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; WORK = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;2&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; } &lt;/span&gt;&lt;span style="color:rgb(102,0,0);font-weight:bold;font-style:normal;"&gt;message&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; PhoneNumber { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;required&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;string&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; number = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;optional&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; PhoneType type = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;2&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; [&lt;/span&gt;&lt;span style="color:rgb(0,102,102);font-weight:bold;font-style:normal;"&gt;default&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; = HOME]; } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;repeated&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; PhoneNumber phone = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;4&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;;
} &lt;/span&gt;&lt;span style="color:rgb(102,0,0);font-weight:bold;font-style:normal;"&gt;message&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; AddressBook { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;repeated&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Person person = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;;
}
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;A fairly simple data description but it does touch on a lot of the features of Protocol Buffers including embedded messages, enums, repeating entries and their type system. Now lets define a simple service that we want to get to work using the &lt;a rel="nofollow" target="_blank" href="https://jsr311.dev.java.net/nonav/javadoc/javax/ws/rs/ext/package-summary.html"&gt;extension SPI&lt;/a&gt; of JAX-RS. This service will have two methods, a GET method for returning a new instance of a &lt;em&gt;Person&lt;/em&gt; and a POST method that just reflects what is passed to it back to the caller unmodified. That will also let us do some round trip testing. Here is the proposed service:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;package&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; com.sampullara.jaxrsprotobuf.tutorial; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;import&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; javax.ws.rs.*; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Path&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"/person"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;)
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; AddressBookService { &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@GET&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Produces&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; AddressBookProtos.Person getPerson() { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; AddressBookProtos.Person.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;newBuilder&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;() .setId(&lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) .setName(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Sam"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) .setEmail(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"sam@sampullara.com"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) .addPhone(AddressBookProtos.Person.PhoneNumber.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;newBuilder&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;() .setNumber(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"415-555-1212"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) .setType(AddressBookProtos.Person.PhoneType.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;MOBILE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) .build()) .build(); } &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@POST&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Consumes&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Produces&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; AddressBookProtos.Person reflect(AddressBookProtos.Person person) { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; person; }
}
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;For each of these methods we&amp;#8217;ve restricted them to either consuming or producing content of type &lt;em&gt;application/x-protobuf&lt;/em&gt;. When JAX-RS sees a request that matches that type or a caller that accepts that type these will be valid endpoints to satisfy those requests. Out of the box, Jersey includes readers and writers for a variety of types including form data, XML and JSON. They also provide a way to register new mime-type readers and writers with a very simple set of annotations on classes that implement either MessageBodyReader or MessageBodyWriter. The class that implements reading is very straight forward, first it calls you back to see if you can read something, then it calls you to actually read it passing you the stream of data. Here is the implementation:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Provider&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Consumes&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;static&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; ProtobufMessageBodyReader &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;implements&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; MessageBodyReader&amp;lt;Message&amp;gt; { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;boolean&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; isReadable(Class&amp;lt;?&amp;gt; type, Type genericType, Annotation[] annotations, MediaType mediaType) { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Message.&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.isAssignableFrom(type); } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Message readFrom(Class&amp;lt;Message&amp;gt; type, Type genericType, Annotation[] annotations,&lt;/span&gt;
&lt;span style="color:rgb(0,0,128);font-weight:normal;font-style:normal;"&gt; MediaType mediaType, MultivaluedMap&amp;lt;String, String&amp;gt; httpHeaders, &lt;/span&gt;
&lt;span style="color:rgb(0,0,128);font-weight:normal;font-style:normal;"&gt; InputStream entityStream) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; IOException, WebApplicationException { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;try&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; { Method newBuilder = type.getMethod(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"newBuilder"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); GeneratedMessage.Builder builder = (GeneratedMessage.Builder) newBuilder.invoke(type); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; builder.mergeFrom(entityStream).build(); } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;catch&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; (Exception e) { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throw&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; WebApplicationException(e); } } }
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;This class either needs to be under a package that is registered to be scanned when the application starts or it could be explicitly registered by extending &lt;em&gt;Application&lt;/em&gt;. You&amp;#8217;ll see in our Main method later we use the former strategy. You&amp;#8217;ll note that in order for us to instantiate a new Protocol Buffer builder we need to use reflection on the type that JAX-RS is expecting. I&amp;#8217;ve convinced myself thats the best way to do it but please comment if you can think of a better way. If there were additional configuration information you needed to pass to the reader you could annotate the methods with that information and receive it here in the annotations array.&lt;/p&gt;
&lt;p&gt;The writer is a bit more complicated because in addition to the &lt;em&gt;isWritable&lt;/em&gt; and &lt;em&gt;writeTo&lt;/em&gt; methods you have to be able to return the size that you are going to write. I was hoping that Protocol Buffers supported a quick way to sum the size of an object but alas they do not so instead I actually do the write in &lt;em&gt;getSize&lt;/em&gt; and temporarily store the result with a weak map. In the future I&amp;#8217;d like to see streaming better supported. Here is how I implemented the writer:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Provider&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Produces&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;static&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; ProtobufMessageBodyWriter &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;implements&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; MessageBodyWriter&amp;lt;Message&amp;gt; { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;boolean&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; isWriteable(Class&amp;lt;?&amp;gt; type, Type genericType, Annotation[] annotations, MediaType mediaType) { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Message.&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.isAssignableFrom(type); } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;private&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Map&amp;lt;Object, &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;byte&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;[]&amp;gt; &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;buffer&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; = &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; WeakHashMap&amp;lt;Object, &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;byte&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;[]&amp;gt;(); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;long&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; getSize(Message m, Class&amp;lt;?&amp;gt; type, Type genericType, Annotation[] annotations, MediaType mediaType) { ByteArrayOutputStream baos = &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; ByteArrayOutputStream(); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;try&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; { m.writeTo(baos); } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;catch&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; (IOException e) { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; -&lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;byte&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;[] bytes = baos.toByteArray(); &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;buffer&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.put(m, bytes); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; bytes.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;length&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;void&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; writeTo(Message m, Class type, Type genericType, Annotation[] annotations, &lt;/span&gt;
&lt;span style="color:rgb(0,0,128);font-weight:normal;font-style:normal;"&gt; MediaType mediaType, MultivaluedMap httpHeaders,&lt;/span&gt;
&lt;span style="color:rgb(0,0,128);font-weight:normal;font-style:normal;"&gt; OutputStream entityStream) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; IOException, WebApplicationException { entityStream.write(&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;buffer&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.remove(m)); } }
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;I&amp;#8217;d love to get around the non-streaming limitation in this integration so if you have any ideas, send them my way. Now we also need to generate the code from the Protocol Buffer definition file. I again use Maven to do that with this additional stanza:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;plugin&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;maven-antrun-plugin&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;executions&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;execution&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;id&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;generate-sources&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;id&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;phase&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;generate-sources&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;phase&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;configuration&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;tasks&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;mkdir&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,255);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dir=&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;&amp;apos;target/generated-sources&amp;apos;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt; /&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;exec&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,255);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;executable=&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;&amp;apos;protoc&amp;apos;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;arg&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,255);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;value=&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;&amp;apos;--java_out=target/generated-sources&amp;apos;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt; /&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;arg&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,255);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;value=&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;&amp;apos;src/main/resources/addressbook.proto&amp;apos;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt; /&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;exec&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;tasks&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;sourceRoot&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;target/generated-sources&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;sourceRoot&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;configuration&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;goals&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;goal&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;run&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;goal&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;goals&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;execution&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;executions&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;plugin&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;That should now be enough to build the service itself along with the message readers and writers. The last thing to do on the production side is to show how you would deploy this using the &lt;a rel="nofollow" target="_blank" href="https://grizzly.dev.java.net/"&gt;Grizzly&lt;/a&gt; container:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Main { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;static&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;final&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; URI &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;BASE_URI&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; = UriBuilder.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;fromUri&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"http://localhost/"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;).port(&lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;9998&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;).build(); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;static&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;void&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; main(String[] args) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; IOException { System.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;out&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.println(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Starting grizzly..."&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); URI uri = &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;BASE_URI&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; SelectorThread threadSelector = &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;createServer&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(uri); System.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;out&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.println(String.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;format&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Try out %sperson&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;n&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;Hit enter to stop it..."&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, uri)); System.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;in&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(246,235,188);font-weight:normal;font-style:normal;"&gt;read&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(); threadSelector.stopEndpoint(); } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;static&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; SelectorThread createServer(URI uri) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; IOException { Map&amp;lt;String, String&amp;gt; initParams = &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; HashMap&amp;lt;String, String&amp;gt;(); initParams.put(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"com.sun.jersey.config.property.packages"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"com.sampullara"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; GrizzlyWebContainerFactory.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;create&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(uri, initParams); }
}
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Jersey+Grizzly makes it very easy instantiate a new servlet container at a particular URI and immediately access the REST services that you have deployed. For testing, it is nice to be able to bring up an actual environment so easily. In our tests we are also going to make use of the REST client that is included with Jersey so that you can see the serialization on both sides of the wire. In order to get the server up and running during the test we need to implement &lt;em&gt;setUp&lt;/em&gt;() and &lt;em&gt;tearDown&lt;/em&gt;():&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;private&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; SelectorThread &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;threadSelector&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;private&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; WebResource &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;r&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Override&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;protected&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;void&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; setUp() &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Exception { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;super&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.setUp(); &lt;/span&gt;&lt;span style="color:rgb(128,128,128);font-weight:normal;font-style:italic;"&gt;//start the Grizzly web container and create the client&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;threadSelector&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; = Main.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;createServer&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(Main.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;BASE_URI&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); ClientConfig cc = &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; DefaultClientConfig(); cc.getClasses().add(ProtobufProviders.ProtobufMessageBodyReader.&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); cc.getClasses().add(ProtobufProviders.ProtobufMessageBodyWriter.&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); Client c = Client.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;create&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(cc); &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;r&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; = c.resource(Main.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;BASE_URI&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); } &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Override&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;protected&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;void&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; tearDown() &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Exception { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;super&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.tearDown(); &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;threadSelector&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.stopEndpoint(); } &lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The client doesn&amp;#8217;t have the special class scanning capability so we directly register our providers with the client and point it at the same URI that the server is running on. Being able to control those in your tests makes integration tests far easier as you don&amp;#8217;t have to worry about mismatched configurations. The first tests we will run will be using the Jersey client:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;void&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; testUsingJerseyClient() { WebResource wr = &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;r&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.path(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"person"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); AddressBookProtos.Person p = wr.get(AddressBookProtos.Person.&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;assertEquals&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Sam"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, p.getName()); AddressBookProtos.Person p2 = wr.type(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;).post(AddressBookProtos.Person.&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, p); &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;assertEquals&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(p, p2); }
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Notice how you can build up a web resource incrementally adding additional constraints or paths to it until ultimately you call one of the HTTP methods on that resource. We also see that using that client API we get typed access to the REST server. Slightly more complicated is another test using direct HTTP connections:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;void&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; testUsingURLConnection() &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; IOException { AddressBookProtos.Person person; { URL url = &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; URL(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"http://localhost:9998/person"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); URLConnection urlc = url.openConnection(); urlc.setDoInput(&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;true&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); urlc.setRequestProperty(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Accept"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); person = AddressBookProtos.Person.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;newBuilder&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;().mergeFrom(urlc.getInputStream()).build(); &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;assertEquals&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Sam"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, person.getName()); } { URL url = &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; URL(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"http://localhost:9998/person"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); HttpURLConnection urlc = (HttpURLConnection) url.openConnection(); urlc.setDoInput(&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;true&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); urlc.setDoOutput(&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;true&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); urlc.setRequestMethod(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"POST"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); urlc.setRequestProperty(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Accept"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); urlc.setRequestProperty(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Content-Type"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/x-protobuf"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); person.writeTo(urlc.getOutputStream()); AddressBookProtos.Person person2 = AddressBookProtos.Person.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;newBuilder&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;().mergeFrom(urlc.getInputStream()).build(); &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;assertEquals&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(person, person2); } }
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;This code looks more like what a non-Java client might do to access your REST service and deserialize the information using their Protocol Buffers. In fact, why don&amp;#8217;t we try this with some Python 2.5 code:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;import&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;urllib&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;import&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; addressbook_pb2 f = &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;urllib&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.urlopen(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"http://localhost:9998/person"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;)
person = addressbook_pb2.Person()
&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(246,235,188);font-weight:normal;font-style:normal;"&gt;person.ParseFromString&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(f.read())
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;print&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(246,235,188);font-weight:normal;font-style:normal;"&gt;person.name&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Works great and outputs &amp;#8220;Sam&amp;#8221; as expected. Very fast but still interoperable between multiple languages in a type-safe way. Once Thrift is further along I will likely make the same sort of interoperability possible.&lt;/p&gt;
&lt;p&gt;For those that just want to open up the final product and see how it all works, here is a &lt;a rel="nofollow" target="_blank" href="http://buildandtest.com/files/jaxrs-protobuf.zip"&gt;link to download it&lt;/a&gt;. You&amp;#8217;ll also note that I actually use &lt;a rel="nofollow" target="_blank" href="http://code.google.com/p/graven/"&gt;graven&lt;/a&gt; under the covers to do my builds as Maven&amp;#8217;s XML is a little too verbose for me.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/javarants?a=zc1Y5S9y"&gt;&lt;img src="http://feeds.feedburner.com/~f/javarants?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/tLz3yuLbtBs" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=955</guid>
         <pubDate>Sat, 27 Dec 2008 19:55:59 -0800</pubDate>
      <feedburner:origLink>http://www.javarants.com/2008/12/27/using-jax-rs-with-protocol-buffers-for-high-performance-rest-apis/</feedburner:origLink></item>
      <item>
         <title>Build your own mail analyzer for Mac Mail.app</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/u1HervfdVLk/</link>
         <description>&lt;p&gt;You&amp;#8217;ve probably read about things like Xoopit and Xobni for analyzing both online mail and your outlook mail. As it turns out, Apple has done something great in this regard that I think has been mostly overlooked. Mail.app stores all of the meta-data for you email in a file called &lt;i&gt;~/Library/Mail/Envelope Index&lt;/i&gt;. You might wonder what the format of this file is&amp;#8230; well it is a SQLite3 database. The contents are pretty easy to see, go to the terminal and type:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;macpro:~ sam$ sqlite3 ~/Library/Mail/Envelope&amp;#92; Index&lt;br /&gt;
SQLite version 3.6.3&lt;br /&gt;
Enter ".help" for instructions&lt;br /&gt;
Enter SQL statements terminated with a ";"&lt;br /&gt;
sqlite&amp;gt;&lt;br /&gt;
&lt;/code&gt;&lt;br /&gt;
&lt;span id="more-943"&gt;&lt;/span&gt;&lt;br /&gt;
Everything about your mailboxes is stored within this database and the structure of the database is normalized so its very easy to navigate. The tables of most interest for mail analysis are:&lt;/p&gt;
&lt;pre&gt;
sqlite&amp;gt; .tables
&lt;strong&gt;addresses&lt;/strong&gt; &lt;strong&gt;mailboxes&lt;/strong&gt; todo_notes
alarms &lt;strong&gt;messages&lt;/strong&gt; todos
associations properties todos_deleted_log
&lt;strong&gt;attachments&lt;/strong&gt; &lt;strong&gt;recipients&lt;/strong&gt; todos_server_snapshot
calendars &lt;strong&gt;subjects&lt;/strong&gt;
feeds &lt;strong&gt;threads&lt;/strong&gt;
&lt;/pre&gt;
&lt;p&gt;Fortunately, accessing a SQLite database is quite easy from just about any language that you decide to use. I&amp;#8217;m just going to do all the queries in straight sqlite3 rather than a language, but they could be embedded in your application. First things first, copy your &lt;em&gt;Envelope Index&lt;/em&gt; to another directory:&lt;/p&gt;
&lt;pre&gt;macpro:tmp sam$ cp ~/Library/Mail/Envelope&amp;#92; Index .&lt;/pre&gt;
&lt;p&gt;Now you can use that database without worrying about messing up the locking or corrupting data while Mail.app is using it. Since we might as well do an example that is interesting rather than merely educational, how about we answer the question: &amp;#8220;Who are my coworkers with whom that I collaborated?&amp;#8221;. This is going to be a multi-query process to extract the information &amp;#8212; there may be more efficient ways to do it &amp;#8212; but think of this as instructive rather than prescriptive. First I need to limit the query to only those mailboxes which contain work email:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;DROP&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes(id);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; INDEX coworkermailboxes_index &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ON&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes(id);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INSERT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INTO&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; mailboxes
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
url &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;like&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;&amp;apos;imap://samp@snv-webmail.corp.yahoo.com/%&amp;apos;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;OR&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
url &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;like&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;&amp;apos;imap://sam@mail.sampullara.com/Yahoo%20Inc%20Archive&amp;apos;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;That gives us a table with several mailboxes that I have in Mail.app including Sent Messages. I would peruse the list of mailboxes to ensure that you are grabbing all the correct information. For me I had to also search my archives. Now I am going to take a series of steps to get to the final out put by iteratively processing successive tables of information. The first table, is a list of those people that you have both sent and received an email with directly (they were the sender and you were a receiver or you were the sender and they were the receiver):&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;DROP&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers(id);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; INDEX coworkers_index &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ON&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers(id);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INSERT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INTO&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; a.rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; addresses a, messages m, recipients r
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
m.sender = a.rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
m.mailbox &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;IN&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; (&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
r.message_id = m.rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; r.address_id = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;4&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INTERSECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; a.rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; addresses a, messages m, recipients r
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
m.sender = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;4&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
m.mailbox &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;IN&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; (&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
r.message_id = m.rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; r.address_id = a.rowid
;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Note I have directly inserted my addresses rowid into this query for the sender on the one hand and the receiver on the other. The next step will be to count the actual number of emails you have received from each of those on the list:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;DROP&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers2;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers2(id, recv);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; INDEX coworkers2_index &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ON&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers2(id);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; "Get the received mail";
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INSERT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INTO&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers2 &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; w.id, &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;COUNT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(*) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; messages m, recipients r, coworkers w
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; m.sender = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;4&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
m.mailbox &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;IN&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; (&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
r.message_id = m.rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; r.address_id = w.id
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;GROUP&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;BY&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; w.id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ORDER&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;BY&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;COUNT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(*)
;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;Finally, we count the number of sent emails and also derive a ratio of sent/received so we can judge how collaborative the exchanges have been:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;DROP&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers3;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;TABLE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers3(id, sent &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;float&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, recv &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;float&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, ratio &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;float&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;CREATE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; INDEX coworkers3_index &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ON&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers3(id);
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; "Get the sent mail";
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INSERT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;INTO&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkers3 &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; w.id, &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;COUNT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(*), w.recv, &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;COUNT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(*)*&lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1.0&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;/w.recv &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; messages m, recipients r, coworkers2 w
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
m.sender = w.id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
m.mailbox &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;IN&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; (&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; coworkermailboxes) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
r.message_id = m.rowid &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; r.address_id = &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;4&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;GROUP&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;BY&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; w.id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ORDER&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;BY&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;COUNT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(*)
;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;You will now have a table named &lt;em&gt;coworkers3&lt;/em&gt; that can be mined for information about your level of correspondence with them. For example, here is way to find relatively equal sends and receives:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; a.comment &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; addresses a, coworkers3 w
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
a.rowid = w.id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
ratio &amp;gt;= &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;.5&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
ratio &amp;lt;=&lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;2&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
sent &amp;gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;10&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ORDER&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;BY&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; sent
LIMIT &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;20&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;When I do this I see the people that either I use to find information or that use me to find information. Every interaction is usually a request and then a response. On the other hand, this query will find those that typically made announcements out to the groups that I also worked with:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; a.comment &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; addresses a, coworkers3 w
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
a.rowid = w.id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
ratio &amp;lt;= &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
sent &amp;gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;10&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;ORDER&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;BY&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; ratio
LIMIT &lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;20&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;;&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;And so on. Adding more filters on top of this you could easily derive your team at work for a particular time period and other insights. With the wealth of information contained in this meta-data store you could figure out all kinds of things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Who sent you an email that you didn&amp;#8217;t reply to yet?&lt;/li&gt;
&lt;li&gt;Who do you respond to the most quickly?&lt;/li&gt;
&lt;li&gt;Who responds to you most quickly?&lt;/li&gt;
&lt;li&gt;What are you and your coworkers approximate working hours?&lt;/li&gt;
&lt;li&gt;What groups of CCs could be made into aliases?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There really is no limit to how far the analysis could go. Ideally, it would be possible to setup a dashboard in Mail.app that let you cut and slice the data in a far more precise way than smart folders currently allow today. Maybe they should come out with super-sql-smart folders!&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/javarants?a=zEnlM7g1"&gt;&lt;img src="http://feeds.feedburner.com/~f/javarants?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/u1HervfdVLk" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=943</guid>
         <pubDate>Fri, 26 Dec 2008 19:46:49 -0800</pubDate>
      <feedburner:origLink>http://www.javarants.com/2008/12/26/build-your-own-mail-analyzer-for-mac-mailapp/</feedburner:origLink></item>
      <item>
         <title>Using JAX-RS (Jersey) to build a JPA/JAXB-backed JSON REST API</title>
         <link>http://feedproxy.google.com/~r/javarants/~3/s4aY-yTtJVA/</link>
         <description>&lt;p&gt;Building applications for deployment to the web has evolved over the last several years to be focused on dynamic behavior, separation of model/view/controller, and simplified but scalable configuration and deployment. From a performance, tools and library perspective I&amp;#8217;m still highly biased to development in Java over more up-and-coming languages. However, much has been learned in the Java community from the better frameworks like Rails and those lessons should not be ignored.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ve been looking for a while though to find that perfect combination of frameworks and libraries that would give me the expressive power that I want for building web applications. There have been many contenders from &lt;a rel="nofollow" target="_blank" href="http://wiki.jruby.org/wiki/JRuby_on_Rails"&gt;JRuby on Rails&lt;/a&gt;, to &lt;a rel="nofollow" target="_blank" href="http://grails.org/"&gt;Grails&lt;/a&gt;, to &lt;a rel="nofollow" target="_blank" href="http://seamframework.org/"&gt;Seam&lt;/a&gt; and even just writing everything myself. Ultimately, I believe in the &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Don't_repeat_yourself"&gt;DRY&lt;/a&gt; principle (like Rails), though I don&amp;#8217;t think many frameworks go far enough when dealing with the database. When you are building a web application it is rare that you are going to change what database you are using. In fact, the majority of your scaling architecture is likely highly dependent on how you store your data. This is why I prefer an application framework that allows me to start with the database and construct my application&amp;#8217;s data object model from it.&lt;br /&gt;
&lt;span id="more-926"&gt;&lt;/span&gt;&lt;br /&gt;
So what are my acceptance criteria for this über-framework?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Great object-relational mapping tool that works well with MySQL + PostgreSQL&lt;/li&gt;
&lt;li&gt;Excellent support for consuming and producing XML and JSON that integrates with the well with the data objects that the ORM tool uses&lt;/li&gt;
&lt;li&gt;Supports writing MVC applications naturally&lt;/li&gt;
&lt;li&gt;Support for building REST APIs with arbitrary URL mapping to service parameters&lt;/li&gt;
&lt;li&gt;High straight-line performance with the ability to scale up servers&lt;/li&gt;
&lt;li&gt;Great defaults that make configuration mostly unnecessary with simple deployment&lt;/li&gt;
&lt;li&gt;&lt;a rel="nofollow" target="_blank" href="http://www.jetbrains.com/idea/"&gt;State-of-the-art IDE support&lt;/a&gt;. I don&amp;#8217;t like to type anymore nor memorize APIs.&lt;/li&gt;
&lt;li&gt;Suitable for quick prototyping and production applications&lt;/li&gt;
&lt;li&gt;Support for templating views of any output type (HTML, XML, etc)&lt;/li&gt;
&lt;li&gt;Easy to unit and integration test&lt;/li&gt;
&lt;li&gt;Open source&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Certainly a high barrier but I think I have finally found one that is a very strong contender. Amazingly, it is even coming out of the JSR standards process with a nice layer of open source on top of it. &lt;a rel="nofollow" target="_blank" href="http://jcp.org/en/jsr/detail?id=311"&gt;JSR-311&lt;/a&gt; was stated to develop an API for providing support for &lt;a rel="nofollow" target="_blank" href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;RESTful&lt;/a&gt; Web Services in the Java Platform. Not only does it do that nicely but it also has the right hooks for simple dependency injection, orthogonal to &lt;a rel="nofollow" target="_blank" href="http://www.jcp.org/en/jsr/detail?id=220"&gt;JPA&lt;/a&gt; (my favorite ORM), support for both XML and JSON natively, and except in unusual circumstances very DRY.&lt;/p&gt;
&lt;p&gt;Because it is in Java and works well with JPA it satisfies a large number of my requirements before we even look at what it offers. Another aspect of it that didn&amp;#8217;t make the above list is that the production quality reference implementation is available as a couple of dependencies in Maven making it very easy to work with. It also works well deployed within lightweight containers like &lt;a rel="nofollow" target="_blank" href="https://grizzly.dev.java.net/"&gt;Grizzly&lt;/a&gt;, heavier ones like &lt;a rel="nofollow" target="_blank" href="http://tomcat.apache.org/"&gt;Tomcat&lt;/a&gt; and &lt;a rel="nofollow" target="_blank" href="https://glassfish.dev.java.net/"&gt;Glassfish&lt;/a&gt;, and the REST APIs it creates can even be directly tested without any container at all. There are some things that Jersey supports that are non-standard that I think are excellent additions to the framework and should likely make it into future versions including support for templating (like JSP and Freemarker) that help it satisfy my requirements.&lt;/p&gt;
&lt;p&gt;To give you an example of how terse the API can be, here is the simplest example that includes deployment as an operating web service:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; Main { &lt;/span&gt;&lt;span style="color:rgb(128,128,0);background-color:rgb(246,235,188);font-weight:normal;font-style:normal;"&gt;@Path&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(246,235,188);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(246,235,188);font-weight:bold;font-style:normal;"&gt;"/helloworld"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(246,235,188);font-weight:normal;font-style:normal;"&gt;)&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;static&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; HelloWorldResource { &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@GET&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Produces&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"text/plain"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; String getClichedMessage() { &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Hello World"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;; } } &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;static&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;void&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; main(String[] args) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;throws&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; IOException { Map&amp;lt;String, String&amp;gt; initParams = &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;new&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; HashMap&amp;lt;String, String&amp;gt;(); initParams.put(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"com.sun.jersey.config.property.packages"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, &lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"com.sun.jersey.samples.helloworld"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); System.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;out&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.println(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Starting grizzly..."&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); URI uri = UriBuilder.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;fromUri&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"http://localhost/"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;).port(&lt;/span&gt;&lt;span style="color:rgb(0,0,255);font-weight:normal;font-style:normal;"&gt;9998&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;).build(); SelectorThread threadSelector = GrizzlyWebContainerFactory.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;create&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(uri, initParams); System.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;out&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.println(String.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:italic;"&gt;format&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"Try out %shelloworld&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;&amp;#92;n&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;Hit enter to stop it..."&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, uri)); System.&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:italic;"&gt;in&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(246,235,188);font-weight:normal;font-style:normal;"&gt;read&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(); threadSelector.stopEndpoint(); }
}
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;The @Path annotation lets you use URI path templates to specify the matching paths and path parameters to your REST service. You can produce any set of content-types and content negotiation will be done for you based on the incoming request. Exceptions can be mapped directly to error responses. Query, Matrix, Path, Header and Cookie parameters are all supported and automatically injected based on annotations. Here is a more sophisticated example from an application I am writing:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@GET&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Produces&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/json"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Path&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"/network/{id: [0-9]+}/{nid}"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; User getUserByNetworkId(&lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@PathParam&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"id"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;int&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; id, &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@PathParam&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"nid"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) String networkId) { Query q = &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;em&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.createQuery(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(255,255,255);font-weight:bold;font-style:normal;"&gt;SELECT&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(237,252,237);font-weight:bold;font-style:normal;"&gt; u &lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(255,255,255);font-weight:bold;font-style:normal;"&gt;FROM&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(237,252,237);font-weight:bold;font-style:normal;"&gt; User u &lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(255,255,255);font-weight:bold;font-style:normal;"&gt;WHERE&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(237,252,237);font-weight:bold;font-style:normal;"&gt; u.networkId = :id &lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(255,255,255);font-weight:bold;font-style:normal;"&gt;AND&lt;/span&gt;&lt;span style="color:rgb(0,128,0);background-color:rgb(237,252,237);font-weight:bold;font-style:normal;"&gt; u.networkUserId = :nid&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;); q.setParameter(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"id"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, id); q.setParameter(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"nid"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, networkId); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; (User) q.getSingleResult(); }&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;In this example we are implementing a GET request with two path parameters, id and uid. They are automatically passed into the method on execution and then I use them in a JPA statement. EntityNotFoundException is actually mapped to a 404 but I don&amp;#8217;t need to deal with that in the method itself. PUTs and POSTs are similarly straight-forward. This method creates a new user:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@PUT&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Consumes&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/json"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Produces&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"application/json"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(128,128,0);font-weight:normal;font-style:normal;"&gt;@Path&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;(&lt;/span&gt;&lt;span style="color:rgb(0,128,0);font-weight:bold;font-style:normal;"&gt;"/create"&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;) &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;public&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; User createUser(User user) { user.setNetwork(&lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;em&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.getReference(Network.&lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;class&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;, user.getNetworkId())); &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;em&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.persist(user); &lt;/span&gt;&lt;span style="color:rgb(102,14,122);font-weight:bold;font-style:normal;"&gt;em&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;.refresh(user); &lt;/span&gt;&lt;span style="color:rgb(0,0,128);font-weight:bold;font-style:normal;"&gt;return&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; user; }&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;All very declarative and readable. And works great with JPA objects that also happen to be JAXB objects. Notice that in those examples I am returning JSON but I don&amp;#8217;t need to explicitly convert my objects. All that is handled by built in message readers and writers (which can be extended if need be). &lt;/p&gt;
&lt;p&gt;One thing that I will note is that after struggling with both &lt;a rel="nofollow" target="_blank" href="http://openjpa.apache.org/"&gt;OpenJPA&lt;/a&gt; (less than ideal support for the standard) and &lt;a rel="nofollow" target="_blank" href="http://hibernate.org"&gt;Hibernate&lt;/a&gt; (some very odd runtime class munging) I settled with &lt;a rel="nofollow" target="_blank" href="http://oss.oracle.com/toplink-essentials-jpa.html"&gt;Toplink-Essentials&lt;/a&gt; (the open-source version of Oracle Toplink). It is much more robust than OpenJPA and is much cleaner at runtime than Hibernate. Finally here is what a typical Maven dependencies look like for creating a Jersey-based web application:&lt;/p&gt;
&lt;pre&gt;
&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;repositories&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;repository&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;id&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;maven2-repository.dev.java.net&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;id&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;name&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;Java.net&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;Repository&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;for&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;Maven&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;name&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;url&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;http://download.java.net/maven/2&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;url&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;repository&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;repository&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;id&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;java.net&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;id&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;url&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;http://download.java.net/maven/1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;url&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;layout&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;legacy&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;layout&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;repository&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;repositories&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependencies&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;com.sun.jersey&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;jersey-server&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;1.0.1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;com.sun.jersey&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;jersey-json&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;1.0.1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;com.sun.jersey&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;jersey-atom&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;1.0.1&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;mysql&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;mysql-connector-java&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;5.1.6&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;toplink.essentials&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;groupId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;toplink-essentials&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;artifactId&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:bold;font-style:normal;"&gt;2.1-60&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;version&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependency&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt; &lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:rgb(0,0,128);background-color:rgb(239,239,239);font-weight:bold;font-style:normal;"&gt;dependencies&lt;/span&gt;&lt;span style="color:rgb(0,0,0);background-color:rgb(239,239,239);font-weight:normal;font-style:normal;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:rgb(0,0,0);font-weight:normal;font-style:normal;"&gt;
&lt;/span&gt;
&lt;/pre&gt;
&lt;p&gt;I was very impressed with how little it took to get going, especially with &lt;a rel="nofollow" target="_blank" href="http://www.jetbrains.com/idea/download/"&gt;IntelliJ 8.0&lt;/a&gt;&amp;#8217;s awesome support for reading pom.xml files. So now I&amp;#8217;m a few days into building the application I set out to build and things are going great. I haven&amp;#8217;t hit any roadblocks so far and I&amp;#8217;ve planned pretty far out already so I don&amp;#8217;t expect to. Though, with Jersey&amp;#8217;s extensibility API, I think that if I do run into anything I have a great escape valve for augmenting the framework. I&amp;#8217;m not associated with Jersey or the JSR-311 specification but I might have to join in the fun. This framework looks like it will have long legs in the Java community.&lt;/p&gt;&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~f/javarants?a=gBUB0V9O"&gt;&lt;img src="http://feeds.feedburner.com/~f/javarants?d=50" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/javarants/~4/s4aY-yTtJVA" height="1" width="1"/&gt;</description>
         <author>Sam Pullara</author>
         <guid isPermaLink="false">http://www.javarants.com/?p=926</guid>
         <pubDate>Thu, 25 Dec 2008 17:38:46 -0800</pubDate>
      <feedburner:origLink>http://www.javarants.com/2008/12/25/using-jax-rs-jersey-to-build-a-jpajaxb-backed-json-rest-api/</feedburner:origLink></item>
   </channel>
</rss><!-- fe1.pipes.re3.yahoo.com uncompressed/chunked Tue Feb  9 05:03:43 PST 2010 -->
