<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
	<title>codahale.com</title>
	<subtitle>
		Coda Hale lives in Berkeley, CA, where he writes about programming, web
		development, and the occasional bit about bicycles.
	</subtitle>
	
	<link href="http://codahale.com/" />
	<updated>2009-09-24T17:51:00-07:00</updated>
	<id>http://codahale.com/</id>
	<author>
		<name>Coda Hale</name>
		<email>coda.hale@gmail.com</email>
	</author>
	
	<link rel="self" href="http://feeds.feedburner.com/codahale" type="application/atom+xml" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com" /><entry>
		<title>FOSS and Male Privilege</title>
		<link href="http://feedproxy.google.com/~r/codahale/~3/gjqUa5dav4k/" />
		<updated>2009-08-27T00:00:00-07:00</updated>
		<id>http://codahale.com/foss-and-male-privilege</id>
		<content type="html">
			&lt;p&gt;From the comments on the LWN thread,
&lt;a href="http://lwn.net/Articles/348459/"&gt;FSF to host a mini-summit on Women in Free Software&lt;/a&gt;:&lt;/p&gt;

&lt;h2&gt;Bruce Perens&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;Can we say that women aren&amp;rsquo;t joining because they, as a population rather than
as individuals, are not interested? The other alternative would be to say that
men in the field had established mechanisms which were astonishingly effective
at keeping them out even though they really were interested, and which still
stood today.&lt;/p&gt;

&lt;p&gt;…&lt;/p&gt;

&lt;p&gt;I'd be a lot more comfortable if I heard it from them, and if they explained
what the mechanisms were and how they were so effective that even people who
were interested were barred from participating with almost total
effectiveness. And why this was not so for a number of other fields.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;Skud&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;Bruce, I started using Linux in 1993 with slackware installed off a stack of
floppies. I ran X with fvwm and kermit for dialup Internet. I learnt Perl a
couple of years later and have worked professionally and full time with Open
Source (mostly LAMP stack) since 1996. I've done all-nighters and
adrenaline-fuelled hacking runs and totally fscked my PC with broken kernel
recompiles. I have founded user groups, hosted mailing lists, launched open
source projects, etc. I have contributed to major and minor projects all over
the damn place; I regularly get email thanking me for writing one of the best
known Perl manpages. I have spoken at conferences all over the world. I am
well known by certain segments of USENET, IRC, and mailing lists, and geeks
all over the world recognise my name when I travel; friends of mine threaten
to get tshirts printed saying &amp;ldquo;Yes, I know Skud&amp;rdquo; because of this. I have been
chewing people&amp;rsquo;s ears off about why open source/free software is awesome and
world-changing since I was 18 years old. And most of the above information is
readily available online. About half the first page of Google results (from
where I'm sitting right now) for &amp;ldquo;women in open source&amp;rdquo; mention me.&lt;/p&gt;

&lt;p&gt;Recently, I have also been documenting issues that women face in open source,
linking and discussing and synthesising and summarising and KEYNOTING OSCON.
(I started doing this a bit in 1998, but stepped back from it for a while, so
most of my women-in-open-source work is more recent.)&lt;/p&gt;

&lt;p&gt;And then I look at this thread and see that a) &amp;ldquo;women are just less passionate
about open source than men&amp;rdquo; and b) that nobody seems to believe us when we say
there is a problem.&lt;/p&gt;

&lt;p&gt;Fuck that. Follow some of those funny little blue underlined words and DO SOME
READING.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;Bruce Perens&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;OK, I'm going to guess that you might be Yuwei Lin, and that you are a woman.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;Skud&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;Bruce, I am Kirrily Robert, as a &lt;a href="http://lmgtfy.com/?q=skud"&gt;&lt;em&gt;trivial&lt;/em&gt; search&lt;/a&gt;
would have told you, if we hadn&amp;rsquo;t met in person on multiple occasions.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;Bruce Perens&lt;/h2&gt;

&lt;blockquote&gt;&lt;p&gt;Oh, sorry. I just went by who came up in the first half page of google
searches for
&lt;a href="http://lmgtfy.com/?q=women+in+Open+Source"&gt;women in Open Source&lt;/a&gt;. Lyn comes
up first here.&lt;/p&gt;&lt;/blockquote&gt;

&lt;h2&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;Bruce Perens demonstrates one of the &amp;ldquo;established mechanisms which [are]
astonishingly effective at keeping [women] out&amp;rdquo; of the FOSS community. The irony
of his inability to recognize the existence of the mechanisms of which he is an
active part is lost on him and depresses the rest of us.&lt;/p&gt;

			&lt;p&gt;(This was posted at &lt;a href="http://codahale.com/foss-and-male-privilege/"&gt;codahale.com&lt;/a&gt;.)&lt;/p&gt;
		&lt;img src="http://feeds.feedburner.com/~r/codahale/~4/gjqUa5dav4k" height="1" width="1"/&gt;</content>
	<feedburner:origLink>http://codahale.com/foss-and-male-privilege/</feedburner:origLink></entry>
	
	<entry>
		<title>A Lesson In Timing Attacks (or, Don't use MessageDigest.isEquals)</title>
		<link href="http://feedproxy.google.com/~r/codahale/~3/HxW3-pDTAcY/" />
		<updated>2009-08-13T00:00:00-07:00</updated>
		<id>http://codahale.com/a-lesson-in-timing-attacks</id>
		<content type="html">
			&lt;p&gt;&lt;a href="http://crypto.stanford.edu/~dabo/papers/ssl-timing.pdf"&gt;Timing attacks&lt;/a&gt;
are pretty horrible from the perspective of someone trying to write a secure
cryptosystem. They work against a programmer&amp;rsquo;s best instincts—don&amp;rsquo;t do extra
work—to give an attacker with access to a Statistics 101 textbook a good solid
grip on your application&amp;rsquo;s guts.&lt;/p&gt;

&lt;h2&gt;How the hell does that work?&lt;/h2&gt;

&lt;p&gt;In short, a timing attack uses statistical analysis of how long it takes your
application to do something in order to learn something about the data it&amp;rsquo;s
operating on. For &lt;a href="http://en.wikipedia.org/wiki/HMAC"&gt;HMACs&lt;/a&gt;, this means using
the amount of time your application takes to compare a given value with a
calculated value to learn information about the calculated value.&lt;/p&gt;

&lt;p&gt;Take &lt;a href="http://rdist.root.org/2009/05/28/timing-attack-in-google-keyczar-library/"&gt;the recent Keyczar vulnerability that Nate Lawson found&lt;/a&gt;.
He was able to take the fact that Keyczar used a simple break-on-inequality
algorithm to compare a candidate HMAC digest with the calculated digest.&lt;/p&gt;

&lt;p&gt;This is the offending code in Python:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Sign&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;sig_bytes&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;and in Java:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Arrays&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;hmac&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;doFinal&lt;/span&gt;&lt;span class="o"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;sigBytes&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;A value which shares no bytes in common with the secret digest will return
immediately; a value which shares the first 15 bytes will return 15 compares
later. That&amp;rsquo;s a difference of perhaps microseconds, but given enough
attempts—which is usually easy to arrange in web applications (how many of you
throttle requests with bad session cookies?)—the random noise becomes a very
predictable, normally distributed skew, leaving only the signal.&lt;/p&gt;

&lt;h2&gt;Well that doesn&amp;rsquo;t seem that bad&lt;/h2&gt;

&lt;p&gt;Oh, but it is.&lt;/p&gt;

&lt;p&gt;I can choose what message I want to be authenticated—let&amp;rsquo;s say a session cookie
with a specific user ID—and then calculate 256 possible values:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;0000000000000000000000000000000000000000
0100000000000000000000000000000000000000
0200000000000000000000000000000000000000
... snip 250 ...
FD00000000000000000000000000000000000000
FE00000000000000000000000000000000000000
FF00000000000000000000000000000000000000
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I go through each of these values until I find one—
&lt;code&gt;A100000000000000000000000000000000000000&lt;/code&gt;—that takes a fraction of a
millisecond &lt;em&gt;longer&lt;/em&gt; than the others. I now know that the first byte of what the
HMAC for that message &lt;em&gt;should be&lt;/em&gt; is &lt;code&gt;A1&lt;/code&gt;. Repeat the process for the remaining
19 bytes, and all of a sudden I'm logged in as you.&lt;/p&gt;

&lt;h2&gt;You can&amp;rsquo;t possibly measure that, can you?&lt;/h2&gt;

&lt;p&gt;Right about now, most people are thinking about the improbability of measuring
the difference between two array comparisons in a web application, given all the
routers, parsers, servers, proxies, etc. in the way.&lt;/p&gt;

&lt;p&gt;According to Crosby et al.&amp;rsquo;s &lt;a href="http://www.cs.rice.edu/~dwallach/pub/crosby-timing2009.pdf"&gt;Opportunities And Limits Of Remote Timing Attacks&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;We have shown that, even though the Internet induces significant timing
jitter, we can reliably distinguish remote timing differences as low as 20µs.
A LAN environment has lower timing jitter, allowing us to reliably distinguish
remote timing differences as small as 100ns (possibly even smaller). These
precise timing differences can be distinguished with only hundreds or possibly
thousands of measurements.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;So. Almost microsecond resolution with hundreds to thousands of measurements.
Who wants to bet that network jitter compensation models get worse instead of
better?&lt;/p&gt;

&lt;p&gt;A worst-case scenario for guessing an HMAC would require 20 × 256 × &lt;code&gt;n&lt;/code&gt;
measurements, where &lt;code&gt;n&lt;/code&gt; is the number of measurements required to pin down a
single byte. So—around 5,000,000 requests. You could do that in less than a week
at a barely-perceptible 10 req/s.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s an attack which takes some planning and analysis, but it&amp;rsquo;s viable.&lt;/p&gt;

&lt;h2&gt;Well crap. Now what?&lt;/h2&gt;

&lt;p&gt;Instead of using a variable-time algorithm for comparing secrets, you should be
using constant-time algorithms. Lawson recommends something like the following
in Python:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;is_equal&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;False&lt;/span&gt;
    
    &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;zip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
        &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In Java, that would look like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isEqual&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt;&lt;span class="o"&gt;[]&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    
    &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;|=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;^&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Yay! Problem solved, right?&lt;/h2&gt;

&lt;p&gt;Oh, if only.&lt;/p&gt;

&lt;p&gt;Check out what&amp;rsquo;s inside of &lt;code&gt;java.security.MessageDigest&lt;/code&gt; as recently as Java
6.0 Update 15:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cm"&gt;/**&lt;/span&gt;
&lt;span class="cm"&gt;  * Compares two digests for equality. Does a simple byte compare.&lt;/span&gt;
&lt;span class="cm"&gt;  * &lt;/span&gt;
&lt;span class="cm"&gt;  * @param digesta one of the digests to compare.&lt;/span&gt;
&lt;span class="cm"&gt;  * &lt;/span&gt;
&lt;span class="cm"&gt;  * @param digestb the other digest to compare.    &lt;/span&gt;
&lt;span class="cm"&gt;  *&lt;/span&gt;
&lt;span class="cm"&gt;  * @return true if the digests are equal, false otherwise.&lt;/span&gt;
&lt;span class="cm"&gt;  */&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;boolean&lt;/span&gt; &lt;span class="nf"&gt;isEqual&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;digesta&lt;/span&gt;&lt;span class="o"&gt;[],&lt;/span&gt; &lt;span class="kt"&gt;byte&lt;/span&gt; &lt;span class="n"&gt;digestb&lt;/span&gt;&lt;span class="o"&gt;[])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digesta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;digestb&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;digesta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;digesta&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;digestb&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;])&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;Wait What&lt;/h2&gt;

&lt;p&gt;Yep. Byte-by-byte comparison; returns on first inequality. Just what we don&amp;rsquo;t
need.&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ll be blunt here: &lt;strong&gt;any Java application which compares client-provided data
to a secret value using &lt;code&gt;MessageDigest.isEqual&lt;/code&gt; is vulnerable to timing
attacks&lt;/strong&gt;. This includes HMACs, decryption results, etc.&lt;/p&gt;

&lt;p&gt;I reported this to Sun on July 22nd, 2009. It&amp;rsquo;s
&lt;a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6863503"&gt;Bug # 6863503&lt;/a&gt;,
which isn&amp;rsquo;t publicly viewable due to the security concerns. Besides the
automated email with the ticket number, I haven&amp;rsquo;t heard anything from Sun since
then. In my bug report, I was explicit about my intent to follow through
according to the &lt;a href="http://www.wiretrip.net/rfp/policy.html"&gt;RFPolicy&lt;/a&gt;, which says&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;D. If the MAINTAINER goes beyond 5 working days without any communication to
the ORIGINATOR, the ORIGINATOR may choose to disclose the ISSUE. The
MAINTAINER is responsible for providing regular status updates (regarding the
resolution of the ISSUE) at least once every 5 working days.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;So here I am, fully disclosing a rather large cryptographic vulnerability in one
of the largest programming platforms there is. I can&amp;rsquo;t tell if that&amp;rsquo;s terrible
or awesome.&lt;/p&gt;

&lt;h2&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;Replace your usage of &lt;code&gt;MessageDigest.isEqual&lt;/code&gt; with a constant-time algorithm,
like the one above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Every time you compare two values, ask yourself: what could someone do if
they knew either of these values?&lt;/strong&gt; If the answer is at all meaningful, use a
constant-time algorithm to compare them.&lt;/p&gt;

&lt;h2&gt;A Side Note&lt;/h2&gt;

&lt;p&gt;This would be substantially less of an issue if more cryptographic libraries had
better encapsulation. An HMAC is &lt;em&gt;not&lt;/em&gt; just a series of characters or bytes—why
treat it as such? Why have such a crucial piece of cryptography squirt out its
state for others to man-handle?&lt;/p&gt;

&lt;h2&gt;Thanks&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://www.root.org/~nate/"&gt;Nate Lawson&lt;/a&gt;&amp;rsquo;s Keyczar find got me thinking about
timing attacks in my own code. His
&lt;a href="http://www.youtube.com/watch?v=ySQl0NhW1J0"&gt;When Crypto Attacks&lt;/a&gt; talk should be
required watching for everyone with access to a compiler.&lt;/p&gt;

&lt;h2&gt;Updated August 13, 2009&lt;/h2&gt;

&lt;p&gt;As &lt;a href="http://news.ycombinator.com/item?id=761059"&gt;sophacles on Hacker News&lt;/a&gt;
pointed out, I had overly refactored the suggested constant-time algorithms and
introduced a more subtle timing attack vulnerability via the return
statement&amp;rsquo;s boolean expression short-circuit. The algorithm has been updated to
fix this.&lt;/p&gt;

			&lt;p&gt;(This was posted at &lt;a href="http://codahale.com/a-lesson-in-timing-attacks/"&gt;codahale.com&lt;/a&gt;.)&lt;/p&gt;
		&lt;img src="http://feeds.feedburner.com/~r/codahale/~4/HxW3-pDTAcY" height="1" width="1"/&gt;</content>
	<feedburner:origLink>http://codahale.com/a-lesson-in-timing-attacks/</feedburner:origLink></entry>
	
	<entry>
		<title>How Not To Fix A Security Bug</title>
		<link href="http://feedproxy.google.com/~r/codahale/~3/iiOVKX2Op54/" />
		<updated>2009-06-14T00:00:00-07:00</updated>
		<id>http://codahale.com/how-not-to-fix-a-security-bug</id>
		<content type="html">
			&lt;h2&gt;November 25th, 2008&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Tadayoshi Funaba opens &lt;a href="http://redmine.ruby-lang.org/issues/show/794"&gt;Bug #794&lt;/a&gt;
in the Ruby Issue Tracking System describing a segmentation fault when huge
decimal strings are converted into &lt;code&gt;BigDecimal&lt;/code&gt; instances.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;November 26th, 2008&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Matz closes Bug #794 with &lt;a href="http://redmine.ruby-lang.org/repositories/revision/ruby-19?rev=20359"&gt;r20359&lt;/a&gt;
to Ruby 1.9&amp;rsquo;s trunk.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;November 27th, 2008 to June 2nd, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Every site running Ruby 1.8.x which creates BigDecimal instances from
client-provided data is vulnerable to a Denial-of-Service attack which Ruby
Core developers have already fixed but not backported.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 3rd, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-1904"&gt;CVE-2009-1904&lt;/a&gt;
is assigned.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 7th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;ruby-core notifies the &lt;a href="http://en.wikipedia.org/wiki/Vendor-sec"&gt;vendor-sec&lt;/a&gt;
mailing list of the vulnerability.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 8th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://bugs.gentoo.org/show_bug.cgi?id=273213"&gt;Bug 273213&lt;/a&gt; is created in
the Gentoo bug tracker to address CVE-2009-1904. Like most tickets for
as-yet-undisclosed security vulnerabilities, the ticket was marked
confidential and that &amp;ldquo;no information should be disclosed until [the
vulnerability] is made public.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Michael Koziarski creates a private GitHub project, &lt;a href="http://github.com/NZKoz/bigdecimal-segfault-fix/tree/master"&gt;bigdecimal-segfault-fix&lt;/a&gt;
with a workaround for the bug.&lt;/li&gt;
&lt;li&gt;Kirk Haines &lt;a href="http://github.com/rubyspec/rubyspec/commit/95c0abbe07bf350f83d2454eb080b0bd315d59d4"&gt;commits a change&lt;/a&gt;
to the RubySpec project which adds a test to ensure Ruby implementations
don&amp;rsquo;t &amp;ldquo;segfault when using a very large string to build [a BigDecimal].&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 9th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;The vulnerability &lt;a href="http://www.ruby-lang.org/en/news/2009/06/09/dos-vulnerability-in-bigdecimal/"&gt;is announced&lt;/a&gt; as well as the release of Ruby 1.8.7-p173.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.vuxml.org/freebsd/62e0fbe5-5798-11de-bb78-001cc0377035.html"&gt;A ticket is added&lt;/a&gt;
to FreeBSD&amp;rsquo;s security bug tracker to address CVE-2009-1904.&lt;/li&gt;
&lt;li&gt;Michael Koziarski &lt;a href="http://groups.google.com/group/rubyonrails-security/msg/fad60751e2b9b4f6?"&gt;announces the vulnerability&lt;/a&gt;
to the rails-security mailing list.&lt;/li&gt;
&lt;li&gt;Kirk Haines &lt;a href="http://redmine.ruby-lang.org/issues/show/1589"&gt;adds Backport #1589&lt;/a&gt;
to the Ruby Issue Tracking System describing a patch which &amp;ldquo;eliminate[s] some
BigDecimal bugs.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Kirk Haines &lt;a href="http://groups.google.com/group/comp.lang.ruby/browse_thread/thread/3106062ee1df078a/0625d1bd36da13db?lnk=raot&amp;amp;fwc=2"&gt;announces the release of Ruby 1.8.6-p369&lt;/a&gt;, which includes a fix for CVE-2009-1904.&lt;/li&gt;
&lt;li&gt;Michael Koziarski makes the bigdecimal-segfault-fix project public on GitHub.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 10th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Barry Hess finds a bug introduced in 1.8.7-p173 &lt;a href="http://www.getharvest.com/blog/2009/06/ruby-denial-of-service-patch-breaks-bigdecimal-to_f-method/"&gt;breaks BigDecimal#to_f&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugzilla.redhat.com/show_bug.cgi?id=504958"&gt;A ticket is added&lt;/a&gt; to
the Red Hat bug tracker to address CVE-2009-1904.&lt;/li&gt;
&lt;li&gt;The vulnerability &lt;a href="http://weblog.rubyonrails.org/2009/6/10/dos-vulnerability-in-ruby/"&gt;is announced&lt;/a&gt;
on the Ruby On Rails blog.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bugs.launchpad.net/ubuntu/+source/ruby1.8/+bug/385436"&gt;A ticket is added&lt;/a&gt; to
the Ubuntu bug tracker to address CVE-2009-1904.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=532689"&gt;A ticket is added&lt;/a&gt;
to the Debian bug tracker to address CVE-2009-1904.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 12th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.freshports.org/commit.php?category=lang&amp;amp;port=ruby18&amp;amp;files=yes&amp;amp;message_id=200906122244.n5CMiug0080745@repoman.freebsd.org"&gt;A fix is released&lt;/a&gt; for FreeBSD.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 13th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=532689#20"&gt;A fix is released&lt;/a&gt; for Debian Unstable. This fix contains the bug that Barry Hess found.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 14th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;No fix has been released for Ubuntu.&lt;/li&gt;
&lt;li&gt;No fix has been released for Red Hat.&lt;/li&gt;
&lt;li&gt;No fix has been released for Fedora Core.&lt;/li&gt;
&lt;li&gt;No fix has been released for Gentoo.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;June 15th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Ruby 1.8.7-p174 &lt;a href="http://www.ruby-forum.com/topic/189053#827091"&gt;is released&lt;/a&gt;
without the &lt;code&gt;BigDecimal#to_f&lt;/code&gt; bug.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;This is not a coordinated disclosure. This is a clusterfuck. If you are
responsible for running a secure MRI/Ruby installation, your only hope is to pay
attention to all changes made to Ruby&amp;rsquo;s trunk and backport any fixes yourself.
Depending on your operating system vendor is not a viable strategy, as
downstream vendors are not given sufficient advance warning and are presented
with fixes which introduce other bugs or do not apply cleanly to the last
released version.&lt;/p&gt;

&lt;h2&gt;Updated June 16th, 2009&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.koziarski.net/"&gt;Michael Koziarski&lt;/a&gt; dropped me a note to clarify a
few things. First, his GitHub project was private and was only opened to the
public &lt;em&gt;after&lt;/em&gt; the vulnerability was announced. Second, ruby-core sent an
email to the &lt;a href="http://en.wikipedia.org/wiki/Vendor-sec"&gt;vendor-sec&lt;/a&gt; mailing
list 48 hours before the disclosure. I've updated the timeline to reflect
these changes.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://twitter.com/jdludlow"&gt;James Ludlow&lt;/a&gt; &lt;a href="http://twitter.com/jdludlow/status/2166873415"&gt;let me know about&lt;/a&gt;
a bug introduced in 1.8.7-p173 and fixed in 1.8.7-p174.&lt;/li&gt;
&lt;li&gt;Updated my conclusions based on the new information. Still not happy, but more
accurate in what I'm unhappy about.&lt;/li&gt;
&lt;/ul&gt;


			&lt;p&gt;(This was posted at &lt;a href="http://codahale.com/how-not-to-fix-a-security-bug/"&gt;codahale.com&lt;/a&gt;.)&lt;/p&gt;
		&lt;img src="http://feeds.feedburner.com/~r/codahale/~4/iiOVKX2Op54" height="1" width="1"/&gt;</content>
	<feedburner:origLink>http://codahale.com/how-not-to-fix-a-security-bug/</feedburner:origLink></entry>
	
	<entry>
		<title>What Makes Jersey Interesting: Injection Providers</title>
		<link href="http://feedproxy.google.com/~r/codahale/~3/JVFLr_UjNO0/" />
		<updated>2009-05-16T00:00:00-07:00</updated>
		<id>http://codahale.com/what-makes-jersey-interesting-injection-providers</id>
		<content type="html">
			&lt;p&gt;&lt;em&gt;Ok, let&amp;rsquo;s get back to the geeky stuff.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Another interesting thing about Jersey (in addition to
&lt;a href="http://codahale.com/what-makes-jersey-interesting-parameter-classes"&gt;parameter classes&lt;/a&gt;)
is the way it uses dependency injection.&lt;/p&gt;

&lt;p&gt;Jersey doesn&amp;rsquo;t have an abstract base class for resources, like Rails'
&lt;code&gt;ActionController::Base&lt;/code&gt; or Restlet&amp;rsquo;s &lt;code&gt;Resource&lt;/code&gt;. This removes the obvious way
of retrieving information about the incoming request: from the base class.&lt;/p&gt;

&lt;p&gt;Take this Rails controller action, for example:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;
  &lt;span class="n"&gt;render&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:text&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;&amp;quot;You asked for &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;request&lt;/code&gt; is a method defined on &lt;code&gt;ActionController::Base&lt;/code&gt; which returns an
object encapsulating the information about the current HTTP request.&lt;/p&gt;

&lt;p&gt;But how would you test this action in isolation? Hopefully the base class
provides an easy way of passing in a mock request object, or else you&amp;rsquo;re stuck
modifying instance variables or partially mocking the class you&amp;rsquo;re trying to
test.&lt;/p&gt;

&lt;h2&gt;So what&amp;rsquo;s a better way of doing that?&lt;/h2&gt;

&lt;p&gt;Jersey avoids this situation by injecting the required information into the
resource class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;show&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Context&lt;/span&gt; &lt;span class="n"&gt;UriInfo&lt;/span&gt; &lt;span class="n"&gt;uriInfo&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;You asked for &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;uriInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAbsolutePath&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Jersey detects the &lt;code&gt;@Context&lt;/code&gt; annotation and automatically injects a &lt;code&gt;UriInfo&lt;/code&gt;
with the current request&amp;rsquo;s data into the method. You can do this for
&lt;code&gt;HttpHeaders&lt;/code&gt;, &lt;code&gt;SecurityContext&lt;/code&gt;, and a few other Jersey classes.&lt;/p&gt;

&lt;p&gt;When it comes time to test this class, it&amp;rsquo;s a simple matter of making a mock
&lt;code&gt;UriInfo&lt;/code&gt; and passing it in:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;itReturnsTheRequestURI&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;MyResource&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MyResource&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;UriInfo&lt;/span&gt; &lt;span class="n"&gt;uriInfo&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;mock&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UriInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="n"&gt;when&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uriInfo&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAbsolutePath&lt;/span&gt;&lt;span class="o"&gt;()).&lt;/span&gt;&lt;span class="na"&gt;thenReturn&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/wooooo&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    
    &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;show&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;uriInfo&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;You asked for /wooooo&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Because the resource class doesn&amp;rsquo;t go out and get the &lt;code&gt;UriInfo&lt;/code&gt; itself, it&amp;rsquo;s
much easier to test.&lt;/p&gt;

&lt;p&gt;What takes this feature from Neat to Indispensable is the fact that Jersey opens
this infrastructure to you: it&amp;rsquo;s easy to write your own injection providers to
peel arbitrary bits of an HTTP request off and inject them into your resources.&lt;/p&gt;

&lt;h2&gt;1.. 2.. 3.. Example time!&lt;/h2&gt;

&lt;p&gt;As an easy example, let&amp;rsquo;s take the request&amp;rsquo;s locale, as determined by its
&lt;code&gt;Accept-Language&lt;/code&gt; header. Out of the box, Jersey gives us access to this via
&lt;code&gt;HttpHeaders#getAcceptableLanguages()&lt;/code&gt;, which returns a list of &lt;code&gt;Locale&lt;/code&gt;
instances in order of preference.&lt;/p&gt;

&lt;p&gt;But it&amp;rsquo;s a tedious thing to have our resource class have an &lt;code&gt;HttpHeaders&lt;/code&gt;
instance injected and then get the first item from the
&lt;code&gt;getAcceptableLanguages()&lt;/code&gt; results:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Context&lt;/span&gt; &lt;span class="n"&gt;HttpHeaders&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;this is lowercase&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUppercase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAcceptableLanguages&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;In order to test that, we&amp;rsquo;ll have to come up with an &lt;code&gt;HttpHeaders&lt;/code&gt; mock and stub
its &lt;code&gt;getAcceptableLanguages()&lt;/code&gt; to return a list of locales. Bleagh.&lt;/p&gt;

&lt;p&gt;&lt;ins&gt;
&lt;strong&gt;Update:&lt;/strong&gt; If you&amp;rsquo;re wondering why you'd need a &lt;code&gt;Locale&lt;/code&gt; to convert a string to
uppercase, check out the Turkish language. The uppercase version of &lt;strong&gt;i&lt;/strong&gt;
(U+0069) is &lt;strong&gt;İ&lt;/strong&gt; (U+0130), and the lowercase version of &lt;strong&gt;I&lt;/strong&gt; (U+0049) is &lt;strong&gt;ı&lt;/strong&gt;
(U+0131). It matters.
&lt;/ins&gt;&lt;/p&gt;

&lt;h2&gt;Now make it uglier&lt;/h2&gt;

&lt;p&gt;In keeping with my &amp;ldquo;so what if it looks good on a slide&amp;rdquo; motif here, I'm also
going to throw in error handling: what if the user doesn&amp;rsquo;t specify a locale?&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Context&lt;/span&gt; &lt;span class="n"&gt;HttpHeaders&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;locales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;headers&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getAcceptableLanguages&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt; &lt;span class="n"&gt;selectedLocale&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;selectedLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;US&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;selectedLocale&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;locales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;this is lowercase&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUppercase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;selectedLocale&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;That&amp;rsquo;s goddamn horrible&amp;mdash;we&amp;rsquo;ll have to test that logic all over the place,
lest we end up throwing an &lt;code&gt;IndexOutOfBoundsException&lt;/code&gt; because someone&amp;rsquo;s HTTP
client has funny ideas about valid locales are.&lt;/p&gt;

&lt;p&gt;It would be nice to have the locale-selecting code in its own class, and to do
that in the same way that our &lt;code&gt;HttpHeaders&lt;/code&gt; instance was injected.&lt;/p&gt;

&lt;h2&gt;I assume you have some kind of plan&lt;/h2&gt;

&lt;p&gt;In order to do that we&amp;rsquo;ll need to write two things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A class implementing &lt;code&gt;Injectable&amp;lt;Locale&amp;gt;&lt;/code&gt;, which will be responsible for
extracting a &lt;code&gt;Locale&lt;/code&gt; from an HTTP request context.&lt;/li&gt;
&lt;li&gt;A class implementing &lt;code&gt;InjectableProvider&amp;lt;Locale&amp;gt;&lt;/code&gt;, which will be responsible
for injecting instances of #1.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Jersey has a specific class to handle the first responsibility:
&lt;code&gt;AbstractHttpContextInjectable&lt;/code&gt; which is used to inject information from the
HTTP context into resource classes. The second responsibility is simple enough
to not require a template base class.&lt;/p&gt;

&lt;h2&gt;Ok, let&amp;rsquo;s do it&lt;/h2&gt;

&lt;p&gt;Luckily for us, we can kill two birds with one stone and implement both
complimentary responsibilities in a single class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Provider&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LocaleProvider&lt;/span&gt;
      &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AbstractHttpContextInjectable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;InjectableProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Injectable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getInjectable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ComponentContext&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ComponentScope&lt;/span&gt; &lt;span class="nf"&gt;getScope&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ComponentScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PerRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
    
    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt; &lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Locales&lt;/span&gt; &lt;span class="n"&gt;locales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRequest&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAcceptableLanguages&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;US&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;locales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This is kind of a complicated class. Let&amp;rsquo;s cover a few things.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;@Provider&lt;/code&gt; annotation marks it so that Jersey will add it as an injection
provider.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;getInjectable&lt;/code&gt; method checks to see that &lt;code&gt;c&lt;/code&gt; is &lt;code&gt;Locale&lt;/code&gt;&amp;mdash;that is, if
  Jersey is asking this provider if it can  inject a &lt;code&gt;Locale&lt;/code&gt;. If so, it
  returns itself to do the injection.  Otherwise, it returns &lt;code&gt;null&lt;/code&gt; to
  indicate there&amp;rsquo;s nothing it can inject.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;getScope&lt;/code&gt; method indicates that the returned injectable is only
meaningful on a per-request basis.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;getValue&lt;/code&gt; method is where the real logic happens. Once the
&lt;code&gt;LocaleProvider&lt;/code&gt; instance has been returned from &lt;code&gt;getInjectable&lt;/code&gt;, Jersey
passes it an &lt;code&gt;HttpContext&lt;/code&gt;, which contains all the relevant information about
the HTTP  request. It returns the most-preferred locale, including error
handling.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;When we put &lt;code&gt;LocaleProvider&lt;/code&gt; in a package that Jersey&amp;rsquo;s configured to scan, we
can reduce our resource class logic to this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;uppercase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@Context&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt; &lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;this is lowercase&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toUppercase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locale&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Then our test looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Test&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;itReturnsAnUppercaseString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;MyResource&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;MyResource&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
    
    &lt;span class="n"&gt;assertThat&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;uppercase&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;CANADA&lt;/span&gt;&lt;span class="o"&gt;),&lt;/span&gt;
        &lt;span class="n"&gt;is&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;THIS IS LOWERCASE&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;);&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;But I don&amp;rsquo;t think we&amp;rsquo;re done yet.&lt;/p&gt;

&lt;h2&gt;How many times you wanna write this thing&lt;/h2&gt;

&lt;p&gt;Much like &lt;a href="/what-makes-jersey-interesting-parameter-classes"&gt;parameter classes&lt;/a&gt;,
our code gets cleaner the more injection providers we write, so we need to
extract out the guts into a base class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AbstractInjectableProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AbstractHttpContextInjectable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kd"&gt;implements&lt;/span&gt; &lt;span class="n"&gt;InjectableProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Context&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;

    &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AbstractInjectableProvider&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Injectable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getInjectable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ComponentContext&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Type&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;equals&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;t&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nf"&gt;getInjectable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;

        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Injectable&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;E&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;getInjectable&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ComponentContext&lt;/span&gt; &lt;span class="n"&gt;ic&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Context&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;ComponentScope&lt;/span&gt; &lt;span class="nf"&gt;getScope&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ComponentScope&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;PerRequest&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now our provider is sleek and shiny:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Provider&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LocaleProvider&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AbstractInjectableProvider&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;LocaleProvider&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;class&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;

    &lt;span class="nd"&gt;@Override&lt;/span&gt;
    &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt; &lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;HttpContext&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;Locales&lt;/span&gt; &lt;span class="n"&gt;locales&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getRequest&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAcceptableLanguages&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;locales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;isEmpty&lt;/span&gt;&lt;span class="o"&gt;())&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Locale&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;US&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
        &lt;span class="o"&gt;}&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;locales&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;get&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now both our resource class and our &lt;code&gt;LocaleProvider&lt;/code&gt; are composed and testable.&lt;/p&gt;

&lt;p&gt;I love it when a plan comes together.&lt;/p&gt;

&lt;h2&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;Jersey has an internal dependency injection system which allows you to write
small, focused classes to extract aspects of an HTTP request&amp;mdash;in our case, the
request&amp;rsquo;s locale&amp;mdash;and inject them into your resource classes as an object of
an appropriate type. This makes for smaller, more composed, more testable
resource classes, which in turn makes for an application which is easier to
change.&lt;/p&gt;

			&lt;p&gt;(This was posted at &lt;a href="http://codahale.com/what-makes-jersey-interesting-injection-providers/"&gt;codahale.com&lt;/a&gt;.)&lt;/p&gt;
		&lt;img src="http://feeds.feedburner.com/~r/codahale/~4/JVFLr_UjNO0" height="1" width="1"/&gt;</content>
	<feedburner:origLink>http://codahale.com/what-makes-jersey-interesting-injection-providers/</feedburner:origLink></entry>
	
	<entry>
		<title>Ruby and Male Privilege</title>
		<link href="http://feedproxy.google.com/~r/codahale/~3/K7JJk9BUWio/" />
		<updated>2009-05-10T00:00:00-07:00</updated>
		<id>http://codahale.com/ruby-and-male-privilege</id>
		<content type="html">
			&lt;h2&gt;Act One&lt;/h2&gt;

&lt;p&gt;I read this today:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;A female computer science professor wrote:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;[A]t a conference in France, a male speaker (French), who was speaking about
the importance of testing, showed an overhead slide of a naked woman with a
caption of the sort&amp;mdash;&amp;lsquo;Would you buy this product without testing it
first?&amp;rsquo; There were only 2 or 3 women in the audience (of about 150), but I
had fleeting feelings of having accidentally walked into a stag party and
wondering if he had either not expected any women to be there or had
discounted the importance of directing his remarks to the women in the
audience.&lt;/p&gt;&lt;/blockquote&gt;&lt;/blockquote&gt;

&lt;p&gt;&amp;mdash;Ellen Spertus, &lt;em&gt;&lt;a href="http://people.mills.edu/spertus/Gender/pap/pap.html"&gt;Why are There so Few Female Computer Scientists?&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Dr. Spertus wrote that paper in 1991.&lt;/p&gt;

&lt;p&gt;In 1991, I used a gift certificate I won in a junior high car-washing fundraiser
content to purchase a tape of Pearl Jam&amp;rsquo;s &lt;em&gt;Ten&lt;/em&gt; from the local record store.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Pearl Jam.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Junior High.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;A tape.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Act Two&lt;/h2&gt;

&lt;p&gt;On April 18th, 2009, Matt Aimonetti gave a presentation on CouchDB entitled
&lt;em&gt;CouchDB: Perform Like A Pr0n Star&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/couch-db.png" title="The first slide from Matt Aimonetti&amp;rsquo;s presentation" alt="The first slide from Matt Aimonetti&amp;rsquo;s presentation, featuring a woman&amp;rsquo;s rear in lingerie." /&gt;&lt;/p&gt;

&lt;p&gt;You can &lt;a href="http://www.slideshare.net/mattetti/couchdb-perform-like-a-pr0n-star"&gt;see the rest of the slides here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Intermission&lt;/h2&gt;

&lt;p&gt;In the &lt;strong&gt;eighteen&lt;/strong&gt; intervening years, what&amp;rsquo;s changed?&lt;/p&gt;

&lt;p&gt;Let me rephrase: &lt;strong&gt;in the lifetime of this year&amp;rsquo;s college freshman&lt;/strong&gt;, what&amp;rsquo;s
changed?&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s a depressing question.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s another one: when she graduates in 2013, what will have changed for that
freshman?&lt;/p&gt;

&lt;h2&gt;Act Three&lt;/h2&gt;

&lt;p&gt;A few days ago, I noticed this exchange on Twitter:&lt;/p&gt;

&lt;p&gt;&lt;img src="/images/staying-classy.png" title="An online exchange after the dust had cleared." alt="blah" /&gt;&lt;/p&gt;

&lt;p&gt;And &lt;a href="http://twitter.com/dhh/status/1631342976"&gt;this gem&lt;/a&gt; from David Heinemeier
Hansson, creator of Rails:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;I do think the spheres of the female body gives life wonder. Suppressing all
our animal instincts is futile.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Ladies and gentlemen, the leading lights of the Ruby community.&lt;/p&gt;

&lt;h2&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;Read &lt;a href="http://people.mills.edu/spertus/Gender/pap/pap.html"&gt;Why Are There So Few Female Computer Scientists&lt;/a&gt; and
&lt;a href="http://www.tldp.org/HOWTO/Encourage-Women-Linux-HOWTO/"&gt;HOWTO Encourage Women In Linux&lt;/a&gt;. And honestly,
I'm beginning to wonder if the women who aren&amp;rsquo;t joining the Ruby community
aren&amp;rsquo;t making the right choice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Also be sure to read
&lt;a href="http://lafalafu.com/krc/privilege.html"&gt;The Male Programmer Privilege Checklist&lt;/a&gt;
for examples of the subtle privileges that male programmers enjoy, almost always
without knowing it.&lt;/p&gt;

			&lt;p&gt;(This was posted at &lt;a href="http://codahale.com/ruby-and-male-privilege/"&gt;codahale.com&lt;/a&gt;.)&lt;/p&gt;
		&lt;img src="http://feeds.feedburner.com/~r/codahale/~4/K7JJk9BUWio" height="1" width="1"/&gt;</content>
	<feedburner:origLink>http://codahale.com/ruby-and-male-privilege/</feedburner:origLink></entry>
	
	<entry>
		<title>When Formality Works</title>
		<link href="http://feedproxy.google.com/~r/codahale/~3/Wnp8aBuGXeA/" />
		<updated>2009-05-07T00:00:00-07:00</updated>
		<id>http://codahale.com/when-formality-works</id>
		<content type="html">
			&lt;p&gt;&lt;a href="http://yehudakatz.com/2009/05/02/incentivizing-innovation/"&gt;On his blog, Yehuda Katz writes&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;One of the things I love the most about the Ruby community is how easy it is
to try out small mutations in practices, which leads to very rapid evolution
in best practices. Rather than having the community look toward authority to
design, plan, and implement &amp;ldquo;best practices&amp;rdquo; (a la the JSR model), members of
the Ruby community try different things, and have rapidly made refinements to
the practices over time.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;In general, I agree with Yehuda about &lt;a href="http://obiefernandez.com"&gt;Obie&lt;/a&gt;&amp;rsquo;s
&lt;a href="http://railsmaturitymodel.com/"&gt;current advertising campaign&lt;/a&gt;: playing
hot-or-not with the bullet points in a HashRocket sales brochure does not make
for a compelling discussion of what makes good software, nor does it actually
help the community. (But then, I don&amp;rsquo;t think helping the community is the
intent behind RMM&amp;mdash;I think it&amp;rsquo;s about drumming up business by being
thoughtleaders.)&lt;/p&gt;

&lt;p&gt;But I have an important nit to pick.&lt;/p&gt;

&lt;h2&gt;That&amp;rsquo;s not how the JSR model works.&lt;/h2&gt;

&lt;p&gt;Java programmers don&amp;rsquo;t sit around feeling helpless waiting for &lt;em&gt;JSR-9918: Doing
That Thing You Get Paid To Do&lt;/em&gt; to be finalized. Instead, they haul off and
implement &lt;a href="http://functionaljava.org/"&gt;crazy experiments&lt;/a&gt; and
&lt;a href="http://www.thimbleware.com/projects/jrel"&gt;solve their problems&lt;/a&gt; in new and
unique ways &lt;em&gt;just like every other programming community&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the &lt;a href="http://jcp.org/en/procedures/jcp2"&gt;Java Community Process&lt;/a&gt;, you write
a JSR proposal describing what you'd like to standardize and why. &lt;a href="http://www.jcp.org/en/jsr/detail?id=311#orig"&gt;Here&amp;rsquo;s the original proposal for JSR-311, about RESTful web services for Java&lt;/a&gt;.
Then you assemble an expert group&amp;mdash;a group of people who are both
knowledgeable and interested in the subject&amp;mdash;and write a bunch of drafts, go
through a bunch of reviews, and finally end up with both a free reference
implementation of the standard and a test suite to verify API compliance with
the standard.&lt;/p&gt;

&lt;p&gt;Horrible, I know.&lt;/p&gt;

&lt;p&gt;It is incredibly bureaucratic, yes. But it&amp;rsquo;s a standardization process. It&amp;rsquo;s not
where innovation starts, it&amp;rsquo;s where it ends. And that&amp;rsquo;s as it should be.&lt;/p&gt;

&lt;p&gt;The whole point of a standard is to describe a fixed set of practices that
people can take for granted. Once they can take it for granted, they can begin
to focus on other things.&lt;/p&gt;

&lt;h2&gt;For example, Rack.&lt;/h2&gt;

&lt;p&gt;One of the more exciting things to have happened in the Ruby web development
community is &lt;a href="http://rack.rubyforge.org/"&gt;Rack&lt;/a&gt;. It&amp;rsquo;s not a very sexy project &amp;mdash;
one can&amp;rsquo;t claim to be a web framework middleware ninja&amp;mdash;but it has an
incredible amount of utility: it&amp;rsquo;s standardized the interface between web
application containers&amp;mdash;&lt;a href="http://mongrel.rubyforge.org/"&gt;Mongrel&lt;/a&gt;,
&lt;a href="http://code.macournoyer.com/thin/"&gt;Thin&lt;/a&gt;, &lt;a href="http://ebb.rubyforge.org/"&gt;Ebb&lt;/a&gt;,
&lt;a href="http://www.modrails.com/"&gt;Passenger&lt;/a&gt;, &lt;a href="http://kenai.com/projects/jruby-rack/pages/Home"&gt;Glassfish, Jetty, Tomcat, JBoss, SpringSource, Google App Engine&lt;/a&gt;,
&lt;a href="http://github.com/chneukirchen/rack/blob/d221938a6401d956ac6cfdc892f9b1c11b1fa31a/lib/rack/handler/webrick.rb"&gt;WEBrick&lt;/a&gt;, &lt;a href="http://litespeedtech.com/"&gt;LiteSpeed&lt;/a&gt;, &lt;a href="http://github.com/KirinDave/fuzed/tree/master"&gt;Fuzed&lt;/a&gt;, &lt;a href="http://github.com/chneukirchen/rack/blob/d221938a6401d956ac6cfdc892f9b1c11b1fa31a/lib/rack/handler/cgi.rb"&gt;CGI&lt;/a&gt;, &lt;a href="http://github.com/chneukirchen/rack/blob/d221938a6401d956ac6cfdc892f9b1c11b1fa31a/lib/rack/handler/fastcgi.rb"&gt;FastCGI&lt;/a&gt;, &lt;a href="http://github.com/chneukirchen/rack/blob/d221938a6401d956ac6cfdc892f9b1c11b1fa31a/lib/rack/handler/scgi.rb"&gt;SCGI&lt;/a&gt;, &lt;a href="http://swiftiply.swiftcore.org/mongrel.html"&gt;EventedMongrel, SwiftipliedMongrel&lt;/a&gt;
&amp;mdash; and Ruby web applications.&lt;/p&gt;

&lt;p&gt;Thanks to Rack&amp;rsquo;s acceptance, you write a web application to work with a minimal
interface and deploy it on a wide variety of infrastructure without needing to
write your own adapter code. You no longer need to care about the glue code
between your web server and your web application. You can then spend time doing
other things, &lt;em&gt;like caring about your actual web application.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;Why did Rack succeed?&lt;/h2&gt;

&lt;p&gt;Rack succeeded because it has a &lt;a href="http://rack.rubyforge.org/doc/SPEC.html"&gt;spec&lt;/a&gt;,
a &lt;a href="http://github.com/rack/rack/tree/master"&gt;reference implementation&lt;/a&gt; and even
a &lt;a href="http://github.com/rack/rack/blob/815342a8e15db564b766f209ffb1e340233f064f/lib/rack/lint.rb"&gt;test suite&lt;/a&gt;
to ensure spec compatibility.&lt;/p&gt;

&lt;p&gt;It doesn&amp;rsquo;t matter if Christian Neukirchen&amp;mdash;not that he would&amp;mdash;hauls off and
destroys Rack as a library; the spec still exists, and implementations of it can
be written again and again.&lt;/p&gt;

&lt;p&gt;But a spec is not sufficient, obviously. You can&amp;rsquo;t just crack open Word and
start writing fiction in order to make your project gain traction. You need to
extract from existing projects a common pattern, round off rough edges, and
resolve long-standing issues. Rack did that. It took the various Rails dispatch
glue code and other half-assed Ruby middleware implementations, looked at what
worked for the &lt;a href="http://www.python.org/dev/peps/pep-0333"&gt;Python community&lt;/a&gt;, came
up with some iterations, got an &lt;em&gt;astounding&lt;/em&gt; amount of feedback from concerned,
knowledgeable people in the Ruby community, and ended up producing something
which has seen widespread adoption in a short period of time.&lt;/p&gt;

&lt;p&gt;I'm not sure why Yehuda feels compelled to bring out the scare quotes when
referring to these as &amp;ldquo;best practices.&amp;rdquo; It&amp;rsquo;s a good process and it obviously
works.&lt;/p&gt;

&lt;h2&gt;Ruby needs more of this.&lt;/h2&gt;

&lt;p&gt;The Ruby community has not had a great history of doing this.
&lt;a href="http://rcrchive.net/"&gt;Ruby Change Requests&lt;/a&gt;, a mechanism for proposed changes
to the Ruby language, were mothballed because ruby-core simply didn&amp;rsquo;t want to
deal with it. It&amp;rsquo;s much easier just making changes and having everyone else run
around fixing the ways in which the latest patch release of Ruby totally breaks
their code. It was discontent with this process which produced the
&lt;a href="http://www.rubyspec.org"&gt;RubySpec project&lt;/a&gt; which, say, &lt;em&gt;looked toward authority
to design, plan, and implement &amp;ldquo;best practices&amp;rdquo;&lt;/em&gt; regarding the Ruby language.&lt;/p&gt;

&lt;p&gt;Why?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Because trying to build a business on top of a Ruby interpreter in which
ruby-core is constantly trying out &amp;ldquo;small mutations&amp;rdquo; is really goddamn
annoying.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Not everything needs a spec&amp;mdash;actually, &lt;em&gt;very few things need a spec.&lt;/em&gt; But
trying to build the fundamentals of interoperability without a spec and an open
process is&amp;mdash;like Ruby 1.8.7&amp;mdash;bound to fail.&lt;/p&gt;

&lt;h2&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;The path to success for a Ruby library and a JSR are the same: pick a problem
where diversity of interface poses a problem, extract a common solution, get a
bunch of feedback from &lt;del&gt;stakeholders&lt;/del&gt;interested people in the
community who are working in the area, build a solid reference implementation
which people can easily use, build a test suite so implementers can red/green
their projects, and write a well-defined, simple spec.&lt;/p&gt;

&lt;p&gt;It worked for &lt;a href="http://jcp.org/en/jsr/detail?id=315"&gt;servlets&lt;/a&gt;,
it worked for &lt;a href="http://jcp.org/en/jsr/detail?id=220"&gt;Hibernate&lt;/a&gt;,
it&amp;rsquo;s working for &lt;a href="http://jcp.org/en/jsr/detail?id=311"&gt;Restlet&lt;/a&gt;,
it&amp;rsquo;s working for &lt;a href="http://jcp.org/en/jsr/detail?id=315"&gt;Joda Time&lt;/a&gt;,
it&amp;rsquo;ll work for &lt;a href="http://docs.google.com/Doc?id=dd2fhx4z_13cw24s7dj"&gt;Spring and Guice&lt;/a&gt;,
and it worked for Rack.&lt;/p&gt;

			&lt;p&gt;(This was posted at &lt;a href="http://codahale.com/when-formality-works/"&gt;codahale.com&lt;/a&gt;.)&lt;/p&gt;
		&lt;img src="http://feeds.feedburner.com/~r/codahale/~4/Wnp8aBuGXeA" height="1" width="1"/&gt;</content>
	<feedburner:origLink>http://codahale.com/when-formality-works/</feedburner:origLink></entry>
	
	<entry>
		<title>What Makes Jersey Interesting: Parameter Classes</title>
		<link href="http://feedproxy.google.com/~r/codahale/~3/pnL1YBIAM5E/" />
		<updated>2009-05-02T00:00:00-07:00</updated>
		<id>http://codahale.com/what-makes-jersey-interesting-parameter-classes</id>
		<content type="html">
			&lt;p&gt;For folks who have known me for a while, this may come as a bit of a shock:
these days I'm spending a &lt;em&gt;lot&lt;/em&gt; of time working with Java. And I'm having a
&lt;em&gt;lot&lt;/em&gt; of fun.&lt;/p&gt;

&lt;h2&gt;lol wut&lt;/h2&gt;

&lt;p&gt;No really.&lt;/p&gt;

&lt;p&gt;This is due in no small part to the fact that I'm working on writing RESTful
web services using a really neat framework:
&lt;a href="https://jersey.dev.java.net/"&gt;Jersey&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;What Is This Jersey You Speak Of&lt;/h2&gt;

&lt;p&gt;Jersey is the reference implementation  of
&lt;a href="https://jsr311.dev.java.net/"&gt;JSR311&lt;/a&gt;, which is the Java community&amp;rsquo;s incredibly
bureaucratic way of coming up with a decent API for writing RESTful web
services. Despite the gray-flannel-suit feel to it, it&amp;rsquo;s actually a delight to
work with.&lt;/p&gt;

&lt;p&gt;Broadly speaking, Jersey maps resources to classes, and HTTP verbs to methods.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s an example resource class:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/helloworld&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_PLAIN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;HelloWorldResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@GET&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;sayHello&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Hello, world!&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The &lt;code&gt;@Path&lt;/code&gt; annotation marks the class as a resource class and tells Jersey what
URIs the resource is responsible for. When a request comes in for &lt;code&gt;/helloworld&lt;/code&gt;,
Jersey routes that to a &lt;code&gt;HelloWorldResource&lt;/code&gt; instance.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@Produces&lt;/code&gt; annotation allows Jersey to perform content negotiation. If a
request comes in with a &lt;code&gt;Accept: image/jpeg&lt;/code&gt; header, Jersey will respond with a
&lt;code&gt;406 Not Acceptable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;@GET&lt;/code&gt; annotation tells Jersey that the &lt;code&gt;sayHello()&lt;/code&gt; method is responsible
for handling &lt;code&gt;GET&lt;/code&gt; requests. If a resource class doesn&amp;rsquo;t have a method to handle
an HTTP verb, Jersey will respond with a &lt;code&gt;405 Method Not Allowed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;When a &lt;code&gt;GET&lt;/code&gt; request comes in, Jersey calls &lt;code&gt;sayHello()&lt;/code&gt;. The &lt;code&gt;String&lt;/code&gt; that&amp;rsquo;s
returned gets turned into an HTTP response entity, and you&amp;rsquo;re off to the races.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s a lot more to it, but that&amp;rsquo;s Jersey and JSR311 in a nutshell.&lt;/p&gt;

&lt;p&gt;What this article is about is how a Jersey application handles change&amp;mdash;you can
find anything about a framework which will look good on a slide but end up
sucking horribly in real life (see: Rails' &lt;code&gt;respond_to&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;For this article, I'm going to write a weekday calculator. You give it a date,
and it tells you what day of the week the day was (or will be) on. Not
super-useful, sure, but my boss won&amp;rsquo;t let me paste huge chunks of our source
code here; you&amp;rsquo;ll have to settle for a contrived example.&lt;/p&gt;

&lt;h2&gt;Round One: The Simplest Thing Possible&lt;/h2&gt;

&lt;p&gt;The first thing I&amp;rsquo;ll do is sketch out a skeleton resource class. Here&amp;rsquo;s a first
swing:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/v1/weekday/{date}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_PLAIN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SkeletonWeekdayResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@GET&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getWeekday&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; is on a ???.&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;You&amp;rsquo;ll notice that the &lt;code&gt;getWeekday&lt;/code&gt; method takes an argument, &lt;code&gt;date&lt;/code&gt;, which is
annotated with &lt;code&gt;@PathParam&lt;/code&gt;. The &lt;code&gt;@PathParam&lt;/code&gt; annotation pulls the &lt;code&gt;date&lt;/code&gt;
variable from the resource&amp;rsquo;s URI template (&lt;code&gt;/v1/weekday/{date}&lt;/code&gt;), turns it into
a &lt;code&gt;String&lt;/code&gt;, and passes it to the &lt;code&gt;getWeekday&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s a sample request/response:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GET /v1/weekday/20060714 HTTP/1.1
Host: localhost:8080
Accept: */*
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And our resource class responds with:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: text/plain

20060714 is on a ???.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This isn&amp;rsquo;t much more complicated than &lt;code&gt;HelloWorldResource&lt;/code&gt;; we&amp;rsquo;re still in
could-be-crap-but-looks-good-on-a-slice territory. So let&amp;rsquo;s add the guts of the
resource&amp;mdash;date parsing and weekday calculation. Because Java&amp;rsquo;s &lt;code&gt;Calendar&lt;/code&gt; and
&lt;code&gt;Date&lt;/code&gt; classes are &lt;em&gt;hilariously&lt;/em&gt; bad, I'm going to use
&lt;a href="http://joda-time.sourceforge.net/"&gt;Joda Time&lt;/a&gt;, which kicks ass.&lt;/p&gt;

&lt;h2&gt;Round Two: Now Make It Work&lt;/h2&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/v2/weekday/{date}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_PLAIN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;NaiveWeekdayResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DateTimeFormatter&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISODateTimeFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basicDate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  
  &lt;span class="nd"&gt;@GET&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getWeekday&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dateAsString&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseDateTime&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dateAsString&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dateAsString&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; is on a &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dayOfWeek&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAsText&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;The changes here are obvious: we use &lt;code&gt;ISO_BASIC&lt;/code&gt;, a parser and formatter, to
turn &lt;code&gt;dateAsString&lt;/code&gt; into a &lt;code&gt;DateTime&lt;/code&gt;, &lt;code&gt;date&lt;/code&gt;. &lt;code&gt;date.dayOfWeek()&lt;/code&gt; returns a
property which we turn into text and send back to the client.&lt;/p&gt;

&lt;p&gt;Now it does what we want:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GET /v2/weekday/20060714 HTTP/1.1
Host: localhost:8080
Accept: */*
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;And then:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 200 OK
Content-Type: text/plain

20060714 is on a Friday.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;But this could still be a Potemkin application. So let&amp;rsquo;s do something you
rarely see in slide shows. Let&amp;rsquo;s throw some bad input at it.&lt;/p&gt;

&lt;h2&gt;Round Three: Oh Yeah, Error Handling&lt;/h2&gt;

&lt;p&gt;What happens when someone asks for an invalid date?&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GET /v2/weekday/200607f14 HTTP/1.1
Host: localhost:8080
Accept: */*
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Oh geez:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 500 Invalid format: "200607f14" is malformed at "f14"
Content-Type: text/html; charset=iso-8859-1

&amp;lt;big-ass stack trace complaining about the date&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;rsquo;s not terrible, but it needs to change.&lt;/p&gt;

&lt;p&gt;First, &lt;code&gt;500 Internal Server Error&lt;/code&gt;is the wrong response. The problem isn&amp;rsquo;t with
the server&amp;rsquo;s state, it&amp;rsquo;s with the request. A better response would be &lt;code&gt;400 Bad
Request&lt;/code&gt;&amp;mdash;that way the client knows not to retry the request, and we can add
an explanation of what about the request needs to change before it will be
acceptable.&lt;/p&gt;

&lt;p&gt;Second, unloading a stack trace on random passers-by is bad form. They don&amp;rsquo;t
care, and they probably shouldn&amp;rsquo;t know what kind of magic is behind the scenes.&lt;/p&gt;

&lt;p&gt;So let&amp;rsquo;s add some error handling:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/v3/weekday/{date}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_PLAIN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BetterWeekdayResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DateTimeFormatter&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISODateTimeFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basicDate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  
  &lt;span class="nd"&gt;@GET&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getWeekday&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;dateAsString&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseDateTime&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dateAsString&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dateAsString&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; is on a &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;dayOfWeek&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAsText&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IllegalArgumentException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebApplicationException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Response&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Couldn&amp;#39;t parse date: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dateAsString&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; (&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This is a pretty simple approach&amp;mdash;catch the exception, and throw a
&lt;code&gt;WebApplicationException&lt;/code&gt; with an HTTP response explaining the problem. Jersey
catches the &lt;code&gt;WebApplicationException&lt;/code&gt; and sends the attached &lt;code&gt;Response&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s try that again:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;GET /v2/weekday/200607f14 HTTP/1.1
Host: localhost:8080
Accept: */*
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Yay!&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;HTTP/1.1 400 Bad Request
Content-Type: text/plain

Couldn't parse date: 200607f14 (Invalid format: "200607f14" is malformed at "f14")
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ok, so our code is now correct and handles errors, but its readability has
suffered&amp;mdash;for two lines of domain-specific code, we have nine lines of error
handling. &lt;em&gt;Ruh-roh.&lt;/em&gt; If we continue with this approach, every date parsing
resource in the application will have its own error handling, which means a lot
of copying and pasting and testing the error handling and bugs, bugs, bugs.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s where Jersey starts to shine&amp;mdash;separation of concerns.&lt;/p&gt;

&lt;h2&gt;Round Four: Time To Clean&lt;/h2&gt;

&lt;p&gt;The trick here is to stop accepting &lt;code&gt;String&lt;/code&gt;s and start dealing with
domain-specific objects. We can do that easily due to the way that Jersey
handles the &lt;code&gt;@PathParam&lt;/code&gt; annotation.&lt;/p&gt;

&lt;p&gt;From the Jersey docs:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The type of the annotated parameter, field or property must either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&amp;hellip;&lt;/li&gt;
&lt;li&gt;Be a primitive type.&lt;/li&gt;
&lt;li&gt;Have a constructor that accepts a single &lt;code&gt;String&lt;/code&gt; argument.&lt;/li&gt;
&lt;li&gt;Have a static method named &lt;code&gt;valueOf&lt;/code&gt; that accepts a single &lt;code&gt;String&lt;/code&gt;
argument (see, for example, &lt;code&gt;Integer#valueOf(String)&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we can just write a class which takes a single &lt;code&gt;String&lt;/code&gt; argument, eh?&lt;/p&gt;

&lt;p&gt;Like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SimpleDateParam&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DateTimeFormatter&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISODateTimeFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basicDate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;originalValue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;SimpleDateParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;WebApplicationException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;originalValue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;date&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseDateTime&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;IllegalArgumentException&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebApplicationException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;Response&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;Couldn&amp;#39;t parse date: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; (&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
          &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
      &lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="nf"&gt;getDate&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;date&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getOriginalValue&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;originalValue&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;This is a pretty straight-forward class which takes a string, parses it, and
either throws a &lt;code&gt;WebApplicationException&lt;/code&gt; or returns an object with a &lt;code&gt;DateTime&lt;/code&gt;
and the original parameter.&lt;/p&gt;

&lt;p&gt;We can change our resource class to accept a &lt;code&gt;SimpleDateParam&lt;/code&gt; argument instead
of a &lt;code&gt;String&lt;/code&gt;, which ends up looking like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/v4/weekday/{date}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_PLAIN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AwesomeWeekdayResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@GET&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getWeekday&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;SimpleDateParam&lt;/span&gt; &lt;span class="n"&gt;dateParam&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dateParam&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOriginalValue&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; is on a &amp;quot;&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dateParam&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getDate&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;dayOfWeek&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAsText&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Now that&amp;rsquo;s nice.&lt;/p&gt;

&lt;p&gt;In between our first working resource and this one, we've done a few things
worth noting:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We extracted date parsing and HTTP-specific error handling into a simple,
testable, reusable class.&lt;/li&gt;
&lt;li&gt;We made our resource classes more testable. Instead of banging &lt;code&gt;String&lt;/code&gt;s
together and testing error handling, we can pass in &lt;code&gt;SimpleDateParam&lt;/code&gt; stubs
test the actual resource logic, safe in the knowledge that a malformed
&lt;code&gt;SimpleDateParam&lt;/code&gt; &lt;strong&gt;cannot exist&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;We made our web service a better HTTP citizen. Instead of freaking out with a
&lt;code&gt;500 THE BEES THEY'RE IN MY EYES&lt;/code&gt; mystery response, we provide clients and
intermediaries with specific, usable information.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;But wait! We&amp;rsquo;re not done yet!&lt;/p&gt;

&lt;h2&gt;Round Five: And &lt;em&gt;Stay&lt;/em&gt; Solved, Damnit&lt;/h2&gt;

&lt;p&gt;We can safely assume we&amp;rsquo;ll be writing a &lt;em&gt;lot&lt;/em&gt; of these param classes for any
given project&amp;mdash;in fact, the more of these we write, the cleaner and more
testable our resources are.&lt;/p&gt;

&lt;p&gt;Think about it&amp;mdash;does your web service accept any of the following things?&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;URIs&lt;/li&gt;
&lt;li&gt;Numbers&lt;/li&gt;
&lt;li&gt;Enums (e.g., &lt;code&gt;/posts?status=1&lt;/code&gt; ends up being &lt;code&gt;PostStatus.ACTIVE&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Booleans&lt;/li&gt;
&lt;li&gt;Timestamps&lt;/li&gt;
&lt;li&gt;IDs with a specific format&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Duh. Of course it does. Now how many times do want to write that code? Once. So
it behooves us to streamline the param-writing process as much as possible.&lt;/p&gt;

&lt;p&gt;Thus:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;AbstractParam&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;V&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;originalParam&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;AbstractParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;WebApplicationException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;originalParam&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;throw&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nf"&gt;WebApplicationException&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;onError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;));&lt;/span&gt;
    &lt;span class="o"&gt;}&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt; &lt;span class="nf"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getOriginalParam&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;originalParam&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  
  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;toString&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;abstract&lt;/span&gt; &lt;span class="n"&gt;V&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;Throwable&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt; &lt;span class="nf"&gt;onError&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;Response&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Status&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;BAD_REQUEST&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;entity&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;getErrorMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;))&lt;/span&gt;
        &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
  
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getErrorMessage&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Throwable&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Invalid parameter: &amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; (&amp;quot;&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getMessage&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;)&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;Which means our param class ends up look like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;DateParam&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="n"&gt;AbstractParam&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DateTime&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;final&lt;/span&gt; &lt;span class="n"&gt;DateTimeFormatter&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ISODateTimeFormat&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;basicDate&lt;/span&gt;&lt;span class="o"&gt;();&lt;/span&gt;
  
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="nf"&gt;DateParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;WebApplicationException&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;super&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;

  &lt;span class="nd"&gt;@Override&lt;/span&gt;
  &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="n"&gt;DateTime&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="kd"&gt;throws&lt;/span&gt; &lt;span class="n"&gt;Throwable&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;ISO_BASIC&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;parseDateTime&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;param&lt;/span&gt;&lt;span class="o"&gt;);&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;p&gt;And our resource class looks like this:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nd"&gt;@Path&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;/v5/weekday/{date}&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="nd"&gt;@Produces&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="n"&gt;MediaType&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;TEXT_PLAIN&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;FinalWeekdayResource&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nd"&gt;@GET&lt;/span&gt;
  &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;String&lt;/span&gt; &lt;span class="nf"&gt;getWeekday&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;@PathParam&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;quot;date&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="n"&gt;DateParam&lt;/span&gt; &lt;span class="n"&gt;dateParam&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dateParam&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getOriginalParam&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot; is on a &amp;quot;&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;dateParam&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="na"&gt;getValue&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;dayOfWeek&lt;/span&gt;&lt;span class="o"&gt;().&lt;/span&gt;&lt;span class="na"&gt;getAsText&lt;/span&gt;&lt;span class="o"&gt;()&lt;/span&gt;
        &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;.&amp;quot;&lt;/span&gt;&lt;span class="o"&gt;;&lt;/span&gt;
  &lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;


&lt;h2&gt;tl;dr&lt;/h2&gt;

&lt;p&gt;Jersey&amp;rsquo;s approach to handling input is graceful in the face of ugly error
handling and edge cases, allowing separation of concerns, encapsulation, and
reuse. We started out with a simple resource class, added some functionality,
added some ugly error handling, then extracted that into a small, composed,
testable class. Any other resource class which needs to parse an ISO 8601 basic
date? &lt;em&gt;Solved.&lt;/em&gt; The end result is testable and readable.&lt;/p&gt;

&lt;p&gt;All this despite the fact that it&amp;rsquo;s in Java.&lt;/p&gt;

&lt;p&gt;You can download all the source code for this project
&lt;a href="/downloads/jersey-parameter-example.zip"&gt;here&lt;/a&gt;.&lt;/p&gt;

			&lt;p&gt;(This was posted at &lt;a href="http://codahale.com/what-makes-jersey-interesting-parameter-classes/"&gt;codahale.com&lt;/a&gt;.)&lt;/p&gt;
		&lt;img src="http://feeds.feedburner.com/~r/codahale/~4/pnL1YBIAM5E" height="1" width="1"/&gt;</content>
	<feedburner:origLink>http://codahale.com/what-makes-jersey-interesting-parameter-classes/</feedburner:origLink></entry>
	
</feed>
