<?xml version="1.0"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Terse Systems</title>
    <link>http://tersesystems.com/</link>
    <atom:link href="http://tersesystems.com/rss.xml" rel="self" type="application/rss+xml" />
    <description>Terse Systems</description>
    <language>en-us</language>
    <pubDate>Fri, 21 Mar 2014 21:48:21 -0700</pubDate>
    <lastBuildDate>Fri, 21 Mar 2014 21:48:21 -0700</lastBuildDate>

    
    <item>
      <title>Fixing X.509 Certificates</title>
      <link>http://tersesystems.com/2014/03/20/fixing-x509-certificates</link>
      <pubDate>Thu, 20 Mar 2014 09:32:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2014/03/20/fixing-x509-certificates</guid>
      <description>&lt;p&gt;This is a continuation in a series of posts about how to &lt;a href=&quot;/2014/01/13/fixing-the-most-dangerous-code-in-the-world/&quot;&gt;correctly configure a TLS client&lt;/a&gt; using JSSE, using &lt;a href=&quot;https://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf&quot;&gt;The Most Dangerous Code in the World&lt;/a&gt; as a guide.   This post is about X.509 certificates in TLS, and has some videos to show both what the vulnerabilities are, and how to fix them.  I highly recommend the videos, as they do an excellent job of describing problems that TLS faces in general.&lt;/p&gt;

&lt;p&gt;Also, JDK 1.8 just came out and has &lt;a href=&quot;http://blog.ivanristic.com/2014/03/ssl-tls-improvements-in-java-8.html&quot;&gt;much better encryption&lt;/a&gt;.  Now would be a good time to &lt;a href=&quot;http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html&quot;&gt;upgrade&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Table of Contents&lt;/h2&gt;

&lt;p&gt;Part One: we talk about how to correctly use and verify X.509 certificates.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What X.509 Certificates Do&lt;/li&gt;
&lt;li&gt;Understanding Chain of Trust&lt;/li&gt;
&lt;li&gt;Understanding Certificate Signature Forgery&lt;/li&gt;
&lt;li&gt;Understanding Signature Public Key Cracking&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Part Two: We discuss how to check X.509 certificates.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validating a X.509 Certificate in JSSE&lt;/li&gt;
&lt;li&gt;Validating Key Size and Signature Algorithm&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;What X.509 Certificates Do&lt;/h2&gt;

&lt;p&gt;The previous post talked about using secure ciphers and algorithms.  This alone is enough to set up a secure connection, but there&amp;rsquo;s no guarantee that you are talking to the server that you think you are talking to.&lt;/p&gt;

&lt;p&gt;Without some means to verify the identity of a remote server, an attacker could still present itself as the remote server and then forward the secure connection onto the remote server.&lt;/p&gt;

&lt;p&gt;This is the problem that Netscape had.  As it turned out, some &lt;a href=&quot;https://en.wikipedia.org/wiki/X.500&quot;&gt;directory services&lt;/a&gt; that needed authentication had a system that looked like it might solve the problem.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;https://en.wikipedia.org/wiki/ITU-T&quot;&gt;ITU-T&lt;/a&gt; had a system of &lt;a href=&quot;https://en.wikipedia.org/wiki/Public_key_certificate&quot;&gt;public key certificates&lt;/a&gt; in a format called &lt;a href=&quot;http://en.wikipedia.org/wiki/X.509&quot;&gt;X.509&lt;/a&gt; in a binary encoding known as &lt;a href=&quot;http://en.wikipedia.org/wiki/ASN.1&quot;&gt;ASN.1 DER&lt;/a&gt;.  The entire system was copied wholesale for use in &lt;a href=&quot;https://en.wikipedia.org/wiki/Secure_Sockets_Layer#SSL_1.0.2C_2.0_and_3.0&quot;&gt;SSL&lt;/a&gt;, and X.509 certificates became the way to verify the identity of a server.&lt;/p&gt;

&lt;p&gt;The best way to think about public key certificates is as a passport system.  Certificates are used to establish information about the bearer of that information in a way that is difficult to forge.  This is why certificate verification is so important: accepting any certificate means that an attacker&amp;rsquo;s certificate will be blindly accepted.&lt;/p&gt;

&lt;p&gt;X.509 certificates contain a public key (typically RSA based), and a digest algorithm (typically in the SHA-2 family, i.e. SHA512) which provides a cryptographic hash.  Together these are known as the &lt;a href=&quot;https://en.wikipedia.org/wiki/Signature_Algorithm&quot;&gt;signature algorithm&lt;/a&gt; (i.e. &amp;ldquo;RSAWithSHA512&amp;rdquo;). One certificate can sign another certificate by taking all the DER encoded bits of a new certificate (basically everything except &amp;ldquo;SignatureAlgorithm&amp;rdquo;) and passing it through the digest algorithm to create a cryptographic hash.  That hash is then signed by the private key of the organization owning the issuing certificate, and the result is stuck onto the end of the new certificate in a &amp;ldquo;SignatureValue&amp;rdquo; field.  Because the issuer&amp;rsquo;s public key is available, and the hash could have only been generated by the certificate that was given as input, we can treat it as &amp;ldquo;signed&amp;rdquo; by the issuer.&lt;/p&gt;

&lt;p&gt;So far, so good.  Unfortunately, X.509 certificates are complex.  Very few people understand (or agree on) the various fields that can be involved in X.509 certificates, and even fewer understand ASN.1 DER, the binary format that X.509 is encoded in (which has led to some interesting attacks on the format).  So much of the original X.509 specification was vague that &lt;a href=&quot;http://www.ietf.org/rfc/rfc5280.txt&quot;&gt;PKIX&lt;/a&gt; was created to nail down some of the extensions.  Currently, these seem to be the important ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &amp;ldquo;&lt;a href=&quot;http://tools.ietf.org/search/rfc5280#section-4.1&quot;&gt;basic fields&lt;/a&gt;&amp;rdquo; that every certificate has.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tools.ietf.org/html/rfc3280#section-4.2.1.7&quot;&gt;&lt;code&gt;subjectAltName&lt;/code&gt;&lt;/a&gt;, where &amp;lsquo;dNSName&amp;rsquo; is the official hostname of the server.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tools.ietf.org/html/rfc5280#section-4.2.1.9&quot;&gt;&lt;code&gt;basicConstraints&lt;/code&gt;&lt;/a&gt; used to establish chain of trust.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tools.ietf.org/search/rfc5280#section-4.2.1.3&quot;&gt;&lt;code&gt;keyUsage&lt;/code&gt;&lt;/a&gt;.  Used to define a CA certificate.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;There are other fields in X.509, but in practice, X.509 compatibility is so broken that few of them matter.  For example, &lt;a href=&quot;http://tools.ietf.org/search/rfc5280#section-4.2.1.10&quot;&gt;&lt;code&gt;nameConstraints&lt;/code&gt;&lt;/a&gt; is considered &lt;a href=&quot;http://middleware.internet2.edu/pki06/proceedings/chadwick-name_constraints_hole.pdf&quot;&gt;near&lt;/a&gt; &lt;a href=&quot;http://conferences.sigcomm.org/imc/2013/papers/imc257-durumericAemb.pdf&quot;&gt;useless&lt;/a&gt; and &lt;a href=&quot;http://tools.ietf.org/search/rfc5280#section-4.2.1.11&quot;&gt;&lt;code&gt;policyConstraints&lt;/code&gt;&lt;/a&gt; has been misunderstood and &lt;a href=&quot;http://www.blackhat.com/presentations/bh-dc-09/Marlinspike/BlackHat-DC-09-Marlinspike-Defeating-SSL.pdf&quot;&gt;exploited&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;So if you want to do the minimum amount of work, all you need is some
approximation to a DN, maybe a &lt;code&gt;basicConstraints&lt;/code&gt;, and if you&amp;rsquo;re feeling really
enthusiastic, &lt;code&gt;keyUsage&lt;/code&gt; (although this is often ignored by implementations, see
the part 2a slides for examples.  Even &lt;code&gt;basicConstraints&lt;/code&gt;, the single most
fundamental extension in a certificate, and in most cases just a single
boolean value, was widely ignored until not too long ago).&lt;/p&gt;

&lt;p&gt;&amp;mdash; &lt;a href=&quot;http://permalink.gmane.org/gmane.comp.encryption.general/10869&quot;&gt;Peter Gutmann&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;&lt;a href=&quot;https://www.cs.auckland.ac.nz/~pgut001/&quot;&gt;Peter Gutmann&lt;/a&gt; is an excellent resource on X.509 certificates (although he does have a &lt;a href=&quot;https://twitter.com/will_sargent/status/432761901294964736&quot;&gt;tendency to rant&lt;/a&gt;. Read the &lt;a href=&quot;https://www.cs.auckland.ac.nz/~pgut001/pubs/x509guide.txt&quot;&gt;X.509 Style Guide&lt;/a&gt;, check out the X.509 bits of &lt;a href=&quot;https://www.cs.auckland.ac.nz/~pgut001/tutorial/index.html&quot;&gt;Godzilla Crypto Tutorial&lt;/a&gt;, and buy &lt;a href=&quot;https://www.cs.auckland.ac.nz/~pgut001/pubs/book.pdf&quot;&gt;Engineering Security&lt;/a&gt; when it comes out of draft.&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;re not up for plowing through hundreds of pages of lovingly (or not so lovingly) described X.509 brokenness, the best overall reference is &lt;a href=&quot;http://www.zytrax.com/tech/survival/ssl.html#x509-overview&quot;&gt;Zytrax&amp;rsquo;s SSL Survival Guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;And for an entertaining overview of X.509 brokenness, watch this video on CCC 26&amp;rsquo;s &amp;ldquo;&lt;a href=&quot;http://blog.ivanristic.com/2009/08/black-hat-2009-ssl-review-black-ops-of-pki-dan-kaminsky.html&quot;&gt;Black Ops of PKI&lt;/a&gt;&amp;rdquo; by &lt;a href=&quot;http://dankaminsky.com/&quot;&gt;Dan Kaminsky&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;video src=&quot;http://mirror.fem-net.de/CCC/26C3/mp4/26c3-3658-en-black_ops_of_pki.mp4&quot; controls&gt;&lt;/video&gt;&lt;/p&gt;

&lt;h3&gt;Understanding Chain of Trust&lt;/h3&gt;

&lt;p&gt;In TLS, the server not only sends its own certificate (known as an &amp;ldquo;end entity certificate&amp;rdquo; or EE), but also sends a &lt;a href=&quot;http://www.zytrax.com/tech/survival/ssl.html#x509-chaining&quot;&gt;chain of certificates&lt;/a&gt; that lead up to (but not including) a root CA certificate issued by a certificate authority (CA for short).  Each of these certificates is signed by the one above them, so that they are known to be authentic.  Certificate validation in TLS goes through a &lt;a href=&quot;https://en.wikipedia.org/wiki/Certification_path_validation_algorithm&quot;&gt;specific algorithm&lt;/a&gt; to validate each individual certificate, then match signatures with each one in the chain to establish a chain of trust.&lt;/p&gt;

&lt;p&gt;Bad things can happen if the chain of trust only checks the signature, and does not also check the &lt;code&gt;keyUsage&lt;/code&gt; and the &lt;code&gt;basicConstraints&lt;/code&gt; fields in X.509.  Moxie Marlinspike has an excellent presentation at DEFCON 17 on defeating TLS, starting off with subverting the chain of trust:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/ibF36Yyeehw&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;h2&gt;Understanding Certificate Signature Forgery&lt;/h2&gt;

&lt;p&gt;As previously mentioned, certificates are needed because they can say &amp;ldquo;this certificate is good because it has been signed by someone I trust.&amp;rdquo;  If you can &lt;a href=&quot;http://www.win.tue.nl/hashclash/rogue-ca/&quot;&gt;forge a signature&lt;/a&gt;, then you can represent yourself as a certificate authority:&lt;/p&gt;

&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/T12BAz3dC90&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Since the original paper, an MD5 based attack like this has been seen in the wild.  A virus called &lt;a href=&quot;http://arstechnica.com/security/2012/06/flame-crypto-breakthrough/&quot;&gt;Flame&lt;/a&gt; forged a signature (jumping through a series of &lt;a href=&quot;http://trailofbits.files.wordpress.com/2012/06/flame-md5.pdf&quot;&gt;extremely difficult technical hurdles&lt;/a&gt;), and used it to hijack the Windows Update mechanism used by Microsoft to patch machines, completely compromising almost 200 servers.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/MD2_(cryptography)&quot;&gt;MD2&lt;/a&gt; was broken in &lt;a href=&quot;https://www.cosic.esat.kuleuven.be/publications/article-1432.pdf&quot;&gt;this paper&lt;/a&gt;, and is no longer considered a secure hash algorithm.  MD4 is out.  As shown in the video, &lt;a href=&quot;https://en.wikipedia.org/wiki/MD5_(cryptography)&quot;&gt;MD5&lt;/a&gt; is out, and the current advice is to &lt;a href=&quot;http://www.kb.cert.org/vuls/id/836068&quot;&gt;avoid using the MD5 algorithm in any capacity&lt;/a&gt;.  Mozilla is even more explicit about not using &lt;a href=&quot;https://wiki.mozilla.org/CA:MD5and1024&quot;&gt;MD5&lt;/a&gt; as a hash algorithm for intermediate and end entity certificates.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://en.wikipedia.org/wiki/SHA1&quot;&gt;SHA1&lt;/a&gt; has not been completely broken yet, but it is starting to look very weak.  The current advice is to &lt;a href=&quot;http://sim.ivi.co/2009/06/tls-and-nists-policy-on-hash-functions.html&quot;&gt;stop using SHA-1 as soon as practical&lt;/a&gt; and it has been &lt;a href=&quot;http://technet.microsoft.com/en-us/security/advisory/2880823&quot;&gt;deprecated by Microsoft&lt;/a&gt;.  Using SHA-1 is still allowed by NIST on existing certificates though.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;Federal agencies may use SHA-1 for the following applications: verifying old digital signatures and time stamps, generating and verifying hash-based message authentication codes (HMACs), key derivation functions (KDFs), and random bit/number generation. Further guidance on the use of SHA-1 is provided in SP 800-131A.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://csrc.nist.gov/groups/ST/hash/policy.html&quot;&gt;NIST&amp;rsquo;s Policy on hash functions&lt;/a&gt;, September 28, 2012&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Even the JSSE documentation itself says that SHA-2 is required, although it leaves this as an exercise for the reader:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;&amp;ldquo;The strict profile suggest all certificates should be signed with SHA-2 or stronger hash functions. In JSSE, the processes to choose a certificate for the remote peer and validate the certificate received from remote peer are controlled by KeyManager/X509KeyManager and TrustManager/X509TrustManager. By default, the SunJSSE provider does not set any limit on the certificate&amp;rsquo;s hash functions. Considering the above strict profile, the coder should customize the KeyManager and TrustManager, and limit that only those certificate signed with SHA-2 or stronger hash functions are available or trusted.&amp;rdquo;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The short version is that certificates should be signed with an algorithm from the SHA-2 library (i.e. at least SHA-256).  And indeed, most public certificates (over 95%) are signed this way.&lt;/p&gt;

&lt;h2&gt;Understanding Signature Public Key Cracking&lt;/h2&gt;

&lt;p&gt;An X.509 certificate has an embedded public key, almost universally RSA.  RSA has a modulus component (also known as key size or key length), which is intended to be difficult to factor out.  Some of these public keys were created at a time when computers were smaller and weaker than they are now: their key size is too small.  Those public keys may still be valid, but the security they provide doesn&amp;rsquo;t provide adequate protection against today&amp;rsquo;s technology.&lt;/p&gt;

&lt;p&gt;The Mozilla Wiki brings the point home in three paragraphs:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The other concern that needs to be addressed is that of RSA1024 being too small a modulus to be robust against faster computers. Unlike a signature algorithm, where only intermediate and end-entity certificates are impacted, fast math means we have to disable or remove all instances of 1024-bit moduli, including the root certificates.&lt;/p&gt;

&lt;p&gt;The NIST recommendation is to discontinue 1024-bit RSA certificates by December 31, 2010. Therefore, CAs have been advised that they should not sign any more certificates under their 1024-bit roots by the end of this year.&lt;/p&gt;

&lt;p&gt;The date for disabling/removing 1024-bit root certificates will be dependent on the state of the art in public key cryptography, but under no circumstances should any party expect continued support for this modulus size past December 31, 2013. As mentioned above, this date could get moved up substantially if new attacks are discovered. We recommend all parties involved in secure transactions on the web move away from 1024-bit moduli as soon as possible.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://wiki.mozilla.org/CA:MD5and1024&quot;&gt;Dates for Phasing out MD5-based signatures and 1024-bit moduli&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;This needs the all caps treatment:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KEY SIZE MUST BE CHECKED ON EVERY SIGNATURE IN THE CERTIFICATE, INCLUDING THE ROOT CERTIFICATE.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;UNDER NO CIRCUMSTANCES SHOULD &lt;em&gt;ANY PARTY&lt;/em&gt; EXPECT SUPPORT FOR 1024 BIT RSA KEYS IN 2014.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;1024 bit certificates are dead, dead, dead.  They cannot be considered secure.  NIST has recommended at least &lt;a href=&quot;http://news.netcraft.com/archives/2012/09/10/minimum-rsa-public-key-lengths-guidelines-or-rules.html&quot;&gt;2048 bits in 2013&lt;/a&gt;, there&amp;rsquo;s a website entirely devoted to &lt;a href=&quot;http://www.keylength.com/en/&quot;&gt;appropriate key lengths&lt;/a&gt; and it&amp;rsquo;s covered extensively in &lt;a href=&quot;http://csrc.nist.gov/publications/nistpubs/800-57/sp800-57_PART3_key-management_Dec2009.pdf&quot;&gt;key management solutions&lt;/a&gt;  The certificate authorities have stopped issuing them for a while, and &lt;a href=&quot;http://csrc.nist.gov/publications/nistpubs/800-131A/sp800-131A.pdf&quot;&gt;over 95% of trusted leaf certificates`1qa and 95% of trusted signing certificates use NIST recommended key sizes&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The same caveats apply to DSA and ECC key sizes: &lt;a href=&quot;http://www.keylength.com/en/&quot;&gt;keylength.com&lt;/a&gt; has the details.&lt;/p&gt;

&lt;h2&gt;Part Two: Implementation&lt;/h2&gt;

&lt;p&gt;The relevant documentation is the Certificate Path Programmer Guide, also known as Java PKI API Programmer&amp;rsquo;s Guide:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html&quot;&gt;Java PKI API Programmer&amp;rsquo;s Guide, 1.8&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/certpath/CertPathProgGuide.html&quot;&gt;Java PKI API Programmer&amp;rsquo;s Guide, 1.7&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.oracle.com/javase/6/docs/technotes/guides/security/certpath/CertPathProgGuide.html&quot;&gt;Java PKI API Programmer&amp;rsquo;s Guide, 1.6&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Despite listing problems in verification above, I&amp;rsquo;m going to assume that JSSE checks certificates and certificate chains correctly, and doesn&amp;rsquo;t have horrible bugs in the implementation.  I am concerned that JSSE may have vulnerabilities, but part of the problem is knowing exactly what the correct behaviour should be and TLS does not come with a reference implementation or a reference suite.  As far as I know, JSSE has not been subject to the X.509 test suite from CPNI, and CPNI &lt;a href=&quot;http://marc.info/?l=openssl-dev&amp;amp;m=106821942719227&amp;amp;w=2&quot;&gt;doesn&amp;rsquo;t release their test suite to the public&lt;/a&gt;.  I am also unaware of any publically available X.509 certificate fuzzing tools.&lt;/p&gt;

&lt;p&gt;With that in mind, the most I can do is make sure that the existing code is at least being called, and that the bits that should be configured and tweaked are indeed tweaked out of the box.&lt;/p&gt;

&lt;h3&gt;Validating a Certificate in JSSE&lt;/h3&gt;

&lt;p&gt;Validating a certificate is easy.  Certificate validation is done by &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/api/java/security/cert/package-summary.html&quot;&gt;&lt;code&gt;java.security.cert&lt;/code&gt;&lt;/a&gt; and basic certificate validation (including expiration checking) is done using &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/security/cert/X509Certificate.java#X509Certificate&quot;&gt;&lt;code&gt;X509Certificate&lt;/code&gt;&lt;/a&gt; :&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;certificate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checkValidity&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;An interesting side note is that although a trust store contains certificates, the fact that they are X.509 certificates is a detail &amp;mdash; trust anchors are just subject distinguished name and public key bindings.  This means they don&amp;rsquo;t have to be signed, and don&amp;rsquo;t really have an expiration date.  This tripped me up initially (and a &lt;a href=&quot;http://stackoverflow.com/questions/22253862/what-if-truststore-certificate-expires/22324010#22324010&quot;&gt;few&lt;/a&gt; &lt;a href=&quot;http://stackoverflow.com/questions/5206859/java-trustmanager-behavior-on-expired-certificates&quot;&gt;others&lt;/a&gt;), but &lt;a href=&quot;http://tools.ietf.org/search/rfc3280#section-6.1.1&quot;&gt;RFC 3280&lt;/a&gt; and &lt;a href=&quot;http://tools.ietf.org/search/rfc5280#section-6.1.1&quot;&gt;RFC 5280&lt;/a&gt; are quite clear that expiration doesn&amp;rsquo;t apply to trust anchors or trust stores.&lt;/p&gt;

&lt;p&gt;Unfortunately, the chain validation is far more complex.&lt;/p&gt;

&lt;h3&gt;Validating Key Size and Signature Algorithm&lt;/h3&gt;

&lt;p&gt;We need to make sure that JSSE is not accepting weak certificates.  In particular, we want to check that the X.509 certificates have a decent signature algorithm and a decent key size.&lt;/p&gt;

&lt;p&gt;Now, there is a &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#DisabledAlgorithms&quot;&gt;&lt;code&gt;jdk.certpath.disabledAlgorithms&lt;/code&gt;&lt;/a&gt; feature in JDK 1.7 that looks &lt;a href=&quot;http://sim.ivi.co/2013/11/harness-ssl-and-jsse-key-size-control.html&quot;&gt;very close&lt;/a&gt; to doing what we want.  (There&amp;rsquo;s also a &lt;code&gt;jdk.tls.disabledAlgorithms&lt;/code&gt; security setting which handles server handshakes and is covered &lt;a href=&quot;/2014/01/13/fixing-the-most-dangerous-code-in-the-world/&quot;&gt;elsewhere&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;But &lt;code&gt;jdk.certpath.disabledAlgorithms&lt;/code&gt;  is only in 1.7 and is global across the JVM.  We need to support JDK 1.6 and make it local to the SSLContext.  We can do better.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s what an example configuration looks like:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ssl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;disabledSignatureAlgorithms&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;MD2, MD4, MD5&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;disabledKeyAlgorithms&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;RSA keySize &amp;lt;= 1024, DSA keySize &amp;lt;= 1024, EC &amp;lt; 224&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;I&amp;rsquo;ll skip over the details of how parsing and algorithm decomposition is done, except to say Scala contains a &lt;a href=&quot;http://www.scala-lang.org/api/2.10.2/index.html#scala.util.parsing.combinator.package&quot;&gt;parser combinator&lt;/a&gt; library which makes writing small parsers very easy.  On configuration, each of the statements parses out into an &lt;code&gt;AlgorithmConstraint&lt;/code&gt; that is checks to see if the certificate&amp;rsquo;s key size or algorithm matches.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s an &lt;code&gt;AlgorithmChecker&lt;/code&gt; that checks for signature and key algorithms (note that the signature algorithm skips the root):&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;21&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;22&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;23&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;24&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlgorithmChecker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signatureConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PKIXCertPathChecker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;check&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Certificate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unresolvedCritExts&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;java.util.Collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;cert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x509Cert&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;X509Certificate&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;commonName&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;getCommonName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x509Cert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;subAltNames&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x509Cert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getSubjectAlternativeNames&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;check: checking certificate commonName = $commonName, subjAltName = $subAltNames&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isRootCert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;checkSignatureAlgorithms: skipping signature checks on trusted root certificate $commonName&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;isRootCert&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;checkSignatureAlgorithms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x509Cert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;checkKeyAlgorithms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x509Cert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UnsupportedOperationException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;check only works with x509 certificates!&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and finally:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;21&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlgorithmChecker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;signatureConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PKIXCertPathChecker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checkSignatureAlgorithms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;x509Cert&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;X509Certificate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sigAlgName&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x509Cert&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getSigAlgName&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sigAlgorithms&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Algorithms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decomposes&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sigAlgName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;checkSignatureAlgorithms: sigAlgName = $sigAlgName, sigAlgName = $sigAlgName, sigAlgorithms = $sigAlgorithms&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sigAlgorithms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;findSignatureConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;constraint&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;constraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;matches&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;checkSignatureAlgorithms: x509Cert = $x509Cert failed on constraint $constraint&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Certificate failed: $a matched constraint $constraint&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CertPathValidatorException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now we have an algorithm checker, we need to put it into the chain.&lt;/p&gt;

&lt;p&gt;Note that are two ways of validating a chain in JSSE.  The first is using &lt;a href=&quot;http://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html#CertPathValidator&quot;&gt;&lt;code&gt;CertPathValidator&lt;/code&gt;&lt;/a&gt;, which validates a certificate chain according to &lt;a href=&quot;http://tools.ietf.org/html/rfc3280#section-6&quot;&gt;RFC 3280&lt;/a&gt;.  The second is &lt;a href=&quot;http://docs.oracle.com/javase/8/docs/technotes/guides/security/certpath/CertPathProgGuide.html#CertPathBuilder&quot;&gt;&lt;code&gt;CertPathBuilder&lt;/code&gt;&lt;/a&gt;, which &amp;ldquo;builds&amp;rdquo; a certificate chain according to &lt;a href=&quot;http://tools.ietf.org/html/rfc4158.html&quot;&gt;RFC 4158&lt;/a&gt;.  I&amp;rsquo;ve been told by informed experts that &lt;code&gt;CertPathBuilder&lt;/code&gt; is actually closer to the behavior of modern browsers, but in this case, we&amp;rsquo;re just adding onto the chain of &lt;code&gt;PKIXCertPathChecker&lt;/code&gt;.  There are several layers of configuration to go through, but eventually we pass this through to the TrustManager.&lt;/p&gt;

&lt;p&gt;To do this, we have to create a &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/java/security/cert/PKIXBuilderParameters.java#PKIXBuilderParameters&quot;&gt;&lt;code&gt;PKIXBuilderParameters&lt;/code&gt;&lt;/a&gt; object and then attach the &lt;code&gt;AlgorithmChecker&lt;/code&gt; to it, then stick that inside ANOTHER parameters object called &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/javax/net/ssl/CertPathTrustManagerParameters.java&quot;&gt;&lt;code&gt;CertPathTrustManagerParameters&lt;/code&gt;&lt;/a&gt; and then pass that into the &lt;code&gt;factory.init&lt;/code&gt; method:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;21&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;22&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;23&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;24&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;25&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;26&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;27&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;28&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;29&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;30&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;31&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;32&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;33&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;34&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;35&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;36&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;37&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;38&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;39&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;40&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;41&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;42&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ConfigSSLContextBuilder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buildTrustManagerParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trustStore&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;KeyStore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;signatureConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;keyConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CertPathTrustManagerParameters&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.collection.JavaConverters._&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;certSelect&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;X509CertSelector&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X509CertSelector&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pkixParameters&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PKIXBuilderParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trustStore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;certSelect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;c1&quot;&gt;// Add the algorithm checker in here&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checkers&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;PKIXCertPathChecker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AlgorithmChecker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;signatureConstraints&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyConstraints&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;c1&quot;&gt;// Use the custom cert path checkers we defined&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;pkixParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setCertPathCheckers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checkers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;asJava&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CertPathTrustManagerParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pkixParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buildTrustManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tsc&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;TrustStoreConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;signatureConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;keyConstraints&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;AlgorithmConstraint&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;X509TrustManager&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trustManagerFactory&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trustStore&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trustStoreBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tsc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trustManagerParameters&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buildTrustManagerParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;trustStore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;signatureConstraints&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;keyConstraints&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trustManagerParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trustManagers&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;factory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getTrustManagers&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trustManagers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Cannot create trust manager with configuration $tsc&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;c1&quot;&gt;// The JSSE implementation only sends back ONE trust manager, X509TrustManager&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;trustManagers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;head&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;asInstanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;X509TrustManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;And we&amp;rsquo;re done.  Now we can check for bad X.509 algorithms out of the box, and have it be local to the SSLContext.&lt;/p&gt;

&lt;p&gt;X.509 certificates are one of the moving pieces of TLS that have many, many ways of going wrong.  Be prepared to find &lt;a href=&quot;http://sim.ivi.co/2009/06/jsse-troubleshooting-certificates-order.html&quot;&gt;out of order certificates&lt;/a&gt;, &lt;a href=&quot;http://sim.ivi.co/2011/06/best-practice-to-include-compelete.html&quot;&gt;missing intermediate certificates&lt;/a&gt;, and other &lt;a href=&quot;http://unmitigatedrisk.com/?p=397&quot;&gt;things you can&amp;rsquo;t identify&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Certificate path debugging can be turned on using the &lt;code&gt;-Djava.security.debug=certpath&lt;/code&gt; and &lt;code&gt;-Djavax.net.debug=&quot;ssl trustmanager&quot;&lt;/code&gt; settings.  &lt;a href=&quot;http://www.smartjava.org/content/how-analyze-java-ssl-errors&quot;&gt;How to analyze Java SSL errors&lt;/a&gt; is a good example of tracking down bugs, and you may also like &lt;a href=&quot;http://portecle.sourceforge.net/&quot;&gt;Portecle&lt;/a&gt;, a GUI tool for certificates.&lt;/p&gt;

&lt;h3&gt;Next&lt;/h3&gt;

&lt;p&gt;Certificate Revocation!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Monkeypatching Java Classes</title>
      <link>http://tersesystems.com/2014/03/02/monkeypatching-java-classes</link>
      <pubDate>Sun, 02 Mar 2014 14:56:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2014/03/02/monkeypatching-java-classes</guid>
      <description>&lt;p&gt;So, remember that thing I said last post about adding some &lt;a href=&quot;/2014/01/13/fixing-the-most-dangerous-code-in-the-world&quot;&gt;debug features to JSSE&lt;/a&gt;?  Turns out that didn&amp;rsquo;t work.&lt;/p&gt;

&lt;p&gt;Sometimes debugging would work.  Sometimes it wouldn&amp;rsquo;t.  I couldn&amp;rsquo;t get it to work reliably.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html&quot;&gt;debugging feature in JSSE&lt;/a&gt; is defined by calling &lt;code&gt;-Djavax.net.debug=ssl&lt;/code&gt; on the command line.   The class that reads from the system property is &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/ssl/Debug.java#Debug&quot;&gt;&lt;code&gt;sun.security.ssl.Debug&lt;/code&gt;&lt;/a&gt; and reading it explained everything:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;21&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;22&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;23&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;24&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;25&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;26&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;27&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;28&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;29&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;30&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;31&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;32&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;33&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;34&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;35&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;36&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;37&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;38&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;39&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;40&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;41&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;42&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;43&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;44&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;45&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;46&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;47&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;48&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;49&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;50&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;51&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;52&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;53&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;54&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Debug&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;AccessController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;doPrivileged&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;GetPropertyAction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;javax.net.debug&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Locale&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ENGLISH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;help&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;Help&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isOn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;prefix&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;prefix&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;d&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;boolean&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isOn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toLowerCase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Locale&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ENGLISH&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;all&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;n&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ssl&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;sslctx&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;n&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                    &lt;span class=&quot;c1&quot;&gt;// don&amp;#39;t enable data and plaintext options by default&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;data&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                        &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;packet&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                        &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;equals&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;plaintext&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;indexOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This explained why I was seeing problems with my debug code.  The &lt;code&gt;args&lt;/code&gt; field of &lt;code&gt;Debug&lt;/code&gt; was being set in a static initialization block, when the class was first loaded into the JVM.  Due to some race conditions, my code could call &lt;code&gt;System.setProperty(&quot;java.net.debug&quot;, options)&lt;/code&gt; before &lt;code&gt;Debug&lt;/code&gt; was loaded, but there was no way of ensuring that.  And of course, the &lt;code&gt;args&lt;/code&gt; file was marked as &lt;code&gt;private static final&lt;/code&gt; so there was no way to modify it outside of the class after that point.&lt;/p&gt;

&lt;p&gt;But it was even worse than that.  The static methods &lt;code&gt;isOn&lt;/code&gt; and &lt;code&gt;getInstance&lt;/code&gt; were used by the JSSE internal classes to determine whether debug information should be logged or not, and those fields were also marked &lt;code&gt;private static final&lt;/code&gt;, i.e. in  &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/ssl/SSLContextImpl.java#42&quot;&gt;&lt;code&gt;sun.security.ssl.SSLContextImpl&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SSLContextImpl&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;SSLContextSpi&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;static&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;final&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ssl&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;X509ExtendedKeyManager&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;chooseKeyManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;KeyManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;KeyManagementException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;int&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kms&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;kms&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isOn&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;sslctx&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                &lt;span class=&quot;n&quot;&gt;System&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;out&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                    &lt;span class=&quot;s&quot;&gt;&amp;quot;X509KeyManager passed to &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                    &lt;span class=&quot;s&quot;&gt;&amp;quot;SSLContext.init():  need an &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;                    &lt;span class=&quot;s&quot;&gt;&amp;quot;X509ExtendedKeyManager for SSLEngine use&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;AbstractKeyManagerWrapper&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;X509KeyManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;km&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;DummyX509KeyManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;INSTANCE&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;In order to turn debugging on, I not only needed to change the &lt;code&gt;args&lt;/code&gt; field in &lt;code&gt;sun.security.ssl.Debug&lt;/code&gt; after it had been initialized, but I also needed to change every class that used &lt;code&gt;private static final Debug debug = Debug.getInstance(&quot;ssl&quot;);&lt;/code&gt; so that it would no longer be null.&lt;/p&gt;

&lt;p&gt;The first idea I came up with was to change &lt;code&gt;Debug.getInstance()&lt;/code&gt; and &lt;code&gt;Debug.isOn&lt;/code&gt;.  Now, there are ways to change method definitions in the JVM.  The package &lt;code&gt;java.lang.instrument&lt;/code&gt; defines java agents that can swap out code at run time (&amp;ldquo;hot reloading&amp;rdquo;), there&amp;rsquo;s &amp;ldquo;HotSwap&amp;rdquo; the JVM debug option, and there&amp;rsquo;s the disposable classloader option.  None of them are really applicable in this case &amp;mdash; JSSE is a system level package, Play does not require a java agent, and HotSwap is&amp;hellip; well, it would probably work fine.  But we don&amp;rsquo;t actually need to change the method definition.  We just need to swap out private static final field references at run time.&lt;/p&gt;

&lt;p&gt;The language tells you that you can&amp;rsquo;t touch &lt;code&gt;final&lt;/code&gt; fields and it tells you that you absolutely can&amp;rsquo;t touch &lt;code&gt;private&lt;/code&gt; fields from outside the class.  It&amp;rsquo;s lying.  If you own the JVM, you can &lt;a href=&quot;https://en.wikipedia.org/wiki/Monkey_patch&quot;&gt;monkey patch&lt;/a&gt; any field reference.&lt;/p&gt;

&lt;p&gt;The key is a method called &lt;a href=&quot;http://mishadoff.github.io/blog/java-magic-part-4-sun-dot-misc-dot-unsafe/&quot;&gt;&lt;code&gt;sun.misc.Unsafe#putObject&lt;/code&gt;&lt;/a&gt;.  It looks like this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MonkeyPatcher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;kd&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;unsafe:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sun&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;misc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Unsafe&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;forName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;sun.misc.Unsafe&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDeclaredField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;theUnsafe&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;setAccessible&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asInstanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sun&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;misc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Unsafe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;cm&quot;&gt;/**&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;cm&quot;&gt;   * Monkeypatches any given static field.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;cm&quot;&gt;   *&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;cm&quot;&gt;   * @param field the field to change&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;cm&quot;&gt;   * @param newObject the new object to place in the field.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;cm&quot;&gt;   */&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;monkeyPatchField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;field:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;newObject:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AnyRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;staticFieldBase&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;staticFieldOffset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;unsafe&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;putObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;base&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offset&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newObject&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;So, we&amp;rsquo;ve got the means to swap out any given field.  Now we need to find all the classes that have a Debug field defined.  This is a little trickier, as the class loader only knows about the fields in classes that have already been loaded.  We need to go through the JAR file, load all the classes in that JAR into memory, and then quiz them about whether they have that field or not.&lt;/p&gt;

&lt;p&gt;So, we add a class finder trait:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;21&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;22&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;23&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;24&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;25&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;26&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;27&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;28&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;29&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;30&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;31&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;32&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;33&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;34&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;35&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;36&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;37&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;38&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;39&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;40&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;41&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;42&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;43&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ClassFinder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;logger:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;org&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;slf4j&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Logger&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;initialResource:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isValidClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;className:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Boolean&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;findClasses:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;findClasses: using initialResource = ${initialResource}&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classSet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;collection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;mutable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;Set&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;classLoader:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ClassLoader&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currentThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getContextClassLoader&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;urlToSource:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initialResource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;findClasses: urlToSource = ${urlToSource}&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;parts:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;urlToSource&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;!&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;jarURLString:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parts&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;jar:&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;findClasses: Loading from ${jarURLString}&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;jar:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jarURLString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;jarConnection:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;URLConnection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;openConnection&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;jis:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JarInputStream&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JarInputStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jarConnection&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getInputStream&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;je:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;JarEntry&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getNextJarEntry&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;je&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;je&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;isDirectory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;className:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;je&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;substring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;je&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;className&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;replace&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sc&quot;&gt;&amp;#39;/&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&amp;#39;.&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isValidClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;findClasses: adding valid class ${className}&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;c:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;loadClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;classSet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;c&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;je&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;jis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getNextJarEntry&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;jis&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;classSet&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;toSet&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;And then we&amp;rsquo;re going to set up something that will do &lt;code&gt;Debug&lt;/code&gt; and &lt;code&gt;args&lt;/code&gt; swapping specifically.  There are a couple of wrinkles to this: we need to have  &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/api/java/security/AccessController.html&quot;&gt;&lt;code&gt;AccessController&lt;/code&gt;&lt;/a&gt; give us privileged conditions, and between 1.6 and 1.7 the package name of &lt;code&gt;Debug&lt;/code&gt; changed from &lt;code&gt;com.sun.net.ssl.internal.ssl.Debug&lt;/code&gt; to &lt;code&gt;sun.security.ssl.Debug&lt;/code&gt;, so we have to get the class we want at runtime as well.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;21&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;22&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;23&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;24&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;25&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;26&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;27&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;28&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;29&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;30&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;31&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;32&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;33&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;34&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;35&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;36&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;37&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;38&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;39&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;40&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;41&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;42&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;43&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;44&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;45&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;46&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;47&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;48&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;49&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;50&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;51&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;52&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;53&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;54&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;55&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;56&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;kd&quot;&gt;abstract&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FixLoggingAction&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;PrivilegedExceptionAction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MonkeyPatcher&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ClassFinder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;newOptions:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isValidField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;field:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;definedType:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;java.lang.reflect.Modifier._&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;modifiers:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Int&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getModifiers&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;field&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;definedType&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isStatic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;isFinal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modifiers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FixInternalDebugLogging&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;kd&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MonkeyPatchInternalSslDebugAction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;newOptions:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FixLoggingAction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initialResource&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;/javax/net/ssl/SSLContext.class&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;isValidClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;className:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;):&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Boolean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;com.sun.net.ssl.internal.ssl&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;startsWith&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;sun.security.ssl&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;debugType:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Class&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debugClassName&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foldVersion&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;run16&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;com.sun.net.ssl.internal.ssl.Debug&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;runHigher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;sun.security.ssl.Debug&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;Thread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;currentThread&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getContextClassLoader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;loadClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugClassName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;nl&quot;&gt;newDebug:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;AnyRef&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debugType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;newInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;asInstanceOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;AnyRef&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;c1&quot;&gt;// Switch out all the classes with a static final field&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugClass&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;findClasses&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugField&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debugClass&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDeclaredFields&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isValidField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debugType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;            &lt;span class=&quot;n&quot;&gt;monkeyPatchField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debugField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newDebug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;c1&quot;&gt;// Switch out the Debug.args field.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;argsField&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;debugType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;getDeclaredField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;args&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;monkeyPatchField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;argsField&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newOptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;newOptions:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;MonkeyPatchInternalSslDebugAction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;newOptions&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;AccessController&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;doPrivileged&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;NonFatal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;IllegalStateException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;InternalDebug configuration error&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;That&amp;rsquo;s it!  Just call &lt;code&gt;FixInternalDebugLogging(&quot;ssl&quot;)&lt;/code&gt; and you can turn on debug information in TLS dynamically, at runtime.  This is tremendously useful when you are in the Play console or running a couple of tests to a specific client.&lt;/p&gt;

&lt;p&gt;This is a technique that works best on initialization code where the original codebase just needs to be tweaked a bit, but monkey patching can be applied to any accessible field.  It&amp;rsquo;s obviously unsafe, but it&amp;rsquo;s effective.  Evil, sure.  But effective.&lt;/p&gt;

&lt;p&gt;Mua ha ha.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Fixing The Most Dangerous Code In The World</title>
      <link>http://tersesystems.com/2014/01/13/fixing-the-most-dangerous-code-in-the-world</link>
      <pubDate>Mon, 13 Jan 2014 14:44:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2014/01/13/fixing-the-most-dangerous-code-in-the-world</guid>
      <description>&lt;h2&gt;TL;DR&lt;/h2&gt;

&lt;p&gt;Most non-browser HTTP clients do SSL / TLS wrong.  Part of why clients do TLS wrong is because crypto libraries have unintuitive APIs.  In this post, I&amp;rsquo;m going to write about my experience extending an HTTP client to configure Java&amp;rsquo;s Secure Socket library correctly, and what to look for when implementing your own client.&lt;/p&gt;

&lt;h2&gt;Introduction&lt;/h2&gt;

&lt;p&gt;I volunteered to implement a configurable TLS solution for &lt;a href=&quot;http://www.playframework.com&quot;&gt;Play&amp;rsquo;s&lt;/a&gt; &lt;a href=&quot;http://www.playframework.com/documentation/2.2.x/ScalaWS&quot;&gt;web services client&lt;/a&gt; (aka WS).  WS is a Scala based wrapper on top of &lt;a href=&quot;https://github.com/AsyncHttpClient/async-http-client&quot;&gt;AsyncHttpClient&lt;/a&gt; that provides &lt;a href=&quot;http://www.playframework.com/documentation/2.2.x/ScalaAsync&quot;&gt;asynchronous mechanisms&lt;/a&gt; like &lt;a href=&quot;http://docs.scala-lang.org/overviews/core/futures.html&quot;&gt;Future&lt;/a&gt; and &lt;a href=&quot;http://www.playframework.com/documentation/2.2.x/Iteratees&quot;&gt;Iteratee&lt;/a&gt; on top of AsyncHttpClient and allows a developer to make GET and POST calls to a web service in just a couple of lines of code.&lt;/p&gt;

&lt;p&gt;However, WS did not contain any way to configure TLS.  It was technically possible to configure TLS through the use of system properties (i.e. &amp;ldquo;javax.net.ssl.keyStore&amp;rdquo;) but that brought up more messiness &amp;mdash; what if you wanted more than one keystore?  What if you needed clients with different ciphers?  Sadly, WS isn&amp;rsquo;t alone in this: most frameworks don&amp;rsquo;t provide configuration for the &lt;a href=&quot;http://davidvaleri.wordpress.com/2011/07/26/simplified-tls-configuration-in-apache-camel/&quot;&gt;finer points of TLS&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Added to that was the awareness that SSL client libraries have been dubbed &lt;a href=&quot;http://www.cs.utexas.edu/~shmat/shmat_ccs12.pdf&quot;&gt;The Most Dangerous Code in the World&lt;/a&gt; (&lt;a href=&quot;https://docs.google.com/document/pub?id=1roBIeSJsYq3Ntpf6N0PIeeAAvu4ddn7mGo6Qb7aL7ewa&quot;&gt;FAQ&lt;/a&gt;).  The problem is &lt;a href=&quot;https://security.stackexchange.com/questions/22965/what-is-the-potential-impact-of-these-ssl-certificate-validation-vulnerabilities&quot;&gt;real and serious&lt;/a&gt;, and I want to fix it.&lt;/p&gt;

&lt;p&gt;There is also a long and well known gulf between the security community and the developer community about the &lt;a href=&quot;https://wiki.thc.org/ssl&quot;&gt;level of knowledge about TLS&lt;/a&gt; and the current state of the &lt;a href=&quot;http://conferences.sigcomm.org/imc/2013/papers/imc257-durumericAemb.pdf&quot;&gt;HTTPS certificate ecosystem&lt;/a&gt;.  I want to fix that as well, and this blog post should be a good start.&lt;/p&gt;

&lt;p&gt;So.  Here&amp;rsquo;s what I did.&lt;/p&gt;

&lt;h2&gt;Table of Contents&lt;/h2&gt;

&lt;p&gt;For the sake of readability (i.e. avoiding TL;DR), I&amp;rsquo;m breaking this across several blog posts.&lt;/p&gt;

&lt;p&gt;The pull request is &lt;a href=&quot;https://github.com/playframework/playframework/pull/2229&quot;&gt;on Github&lt;/a&gt; and you are invited to review the code and comment as you see fit.&lt;/p&gt;

&lt;p&gt;In this blog post, I&amp;rsquo;m just going to cover the setup.&lt;/p&gt;

&lt;p&gt;First, the problems that make TLS necessary.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The First Problem: Programmers do not get security&lt;/li&gt;
&lt;li&gt;The Second Problem: Wifi / Ethernet is not secure&lt;/li&gt;
&lt;li&gt;The Third Problem: Man In the Middle&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Then, the implementation in WS.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Use Cases for WS&lt;/li&gt;
&lt;li&gt;Understanding TLS&lt;/li&gt;
&lt;li&gt;Understanding JSSE&lt;/li&gt;
&lt;li&gt;Configuring a client&lt;/li&gt;
&lt;li&gt;Debugging a client&lt;/li&gt;
&lt;li&gt;Choosing a protocol&lt;/li&gt;
&lt;li&gt;Choosing a cipher suite&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Future posts will discuss certificates in more detail, but this gives us somewhere to start.&lt;/p&gt;

&lt;h2&gt;Problems&lt;/h2&gt;

&lt;h3&gt;The First Problem: Programmers do not get security&lt;/h3&gt;

&lt;p&gt;The first problem is the assumption that TLS is overkill, built by researchers to protect against an abstract threat.&lt;/p&gt;

&lt;p&gt;Unfortunately, this is not the case.  TLS has real attacks against it, and they exist in the wild.  Even worse, there are very serious, real world implications to breaking a TLS connection.  Some people trust TLS in situations which could mean imprisonment or death.&lt;/p&gt;

&lt;p&gt;But. Programmers work with bugs.  Programmers get bugs.  Programmers do not get security.&lt;/p&gt;

&lt;p&gt;Programmers understand how bad input can ruin a programmer&amp;rsquo;s day.  Programmers understand how corrupt data can completely ruin any hope of a functioning program.  Programmers know that working with concurrency is so dangerous that it should only be done with special concurrency primitives and rules.  Human users may be incompetent, but they are mostly benevolent: the forces working against the programmer are entropy and loose requirements.&lt;/p&gt;

&lt;p&gt;Programmers don&amp;rsquo;t usually write programs that have to defend against an attacker.  Most programmers have never even seen an attacker. Even the concept of a human deliberately trying to break or subvert a program is foreign.  QA usually tests for successful cases, and maybe for some negative test cases&amp;hellip; but QA typically doesn&amp;rsquo;t submit specially crafted XML documents that poke at the filesystem or chew up gigabytes of memory with character entities.&lt;/p&gt;

&lt;p&gt;If programming is like driving a car, then the difference between working with QA versus working against an attacker is the difference between driving in rush hour versus driving with someone determined to run you off the road. TLS, and people using TLS based clients, have to assume that someone is going to try to run them off the road.&lt;/p&gt;

&lt;p&gt;It also helps to see what an attack is like.  For most programmers, an attack is theoretical, even a bad joke in poor taste.  It doesn&amp;rsquo;t really become real until an actual attack is demonstrated by a security researcher in front of the programmer in question.&lt;/p&gt;

&lt;p&gt;With that in mind, I&amp;rsquo;ve included several videos from real live security professionals in this blog post.  You don&amp;rsquo;t have to watch them all at once, but you should watch them all eventually and see how they think.&lt;/p&gt;

&lt;h3&gt;The Second Problem: Wifi / Ethernet is not secure&lt;/h3&gt;

&lt;p&gt;TLS has a specific problem that most programmers do not have to deal with.  TLS has to assume an attacker has access to the TCP/IP stream between client and server.  This is commonly called packet snooping.&lt;/p&gt;

&lt;p&gt;It is trivial to snoop on other computers in your network using tools like &lt;a href=&quot;https://www.wireshark.org/&quot;&gt;Wireshark&lt;/a&gt;.  This is doubly true when using wireless networks, such as a coffee shop.  People are often surprised that every single website they visit is being broadcast in the clear, in the same way as radio, but it&amp;rsquo;s true, and it&amp;rsquo;s easy to pick up those radio transmissions.&lt;/p&gt;

&lt;p&gt;But don&amp;rsquo;t take my word for it.  Here&amp;rsquo;s the &lt;a href=&quot;https://wifipineapple.com/&quot;&gt;Wifi Pineapple&lt;/a&gt;:&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/P9Q0SWVo8Bo?t=1m47s&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;You can buy a Wifi Pineapple for &lt;a href=&quot;https://hakshop.myshopify.com/products/wifi-pineapple&quot;&gt;$100 plus shipping&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It picks up all traffic sent over a wifi network.  It&amp;rsquo;s so good at intercepting traffic that people have turned it on and started &lt;a href=&quot;http://www.troyhunt.com/2013/04/the-beginners-guide-to-breaking-website.html&quot;&gt;intercepting traffic accidentally&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can plug it into an ethernet adapter, or there&amp;rsquo;s an &lt;a href=&quot;http://hakshop.myshopify.com/collections/wifi-pineapple-kits/products/wifi-pineapple-mark-v-ultra-bundle&quot;&gt;ultra bundle&lt;/a&gt; that provides a huge antenna and an &lt;a href=&quot;http://hakshop.myshopify.com/collections/wifi-pineapple-kits/products/wifi-pineapple-mk5-elite&quot;&gt;elite version&lt;/a&gt; that lets it run off a battery for 72 hours.&lt;/p&gt;

&lt;p&gt;Don&amp;rsquo;t think that WPA protects you from this.  WPA2 is vulnerable to &lt;a href=&quot;http://www.aircrack-ng.org/doku.php?id=cracking_wpa&quot;&gt;bruteforcing&lt;/a&gt; and most people choose passwords with extremely low entropy, partly because wifi passwords are shared so often.&lt;/p&gt;

&lt;h3&gt;The Third Problem: Man In the Middle&lt;/h3&gt;

&lt;p&gt;Not only can an attacker sniff packets on the network, but the attacker can also substitute traffic.  Here&amp;rsquo;s a video of &lt;a href=&quot;http://www.oxid.it/cain.html&quot;&gt;Cain &amp;amp; Abel&lt;/a&gt; at work:&lt;/p&gt;

&lt;iframe width=&quot;420&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/pfHsRscy540&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;Note that it takes less than 20 seconds to impersonate the server, after which the attacker can modify any URL coming from the server to point somewhere else.  This is why rendering a login page in HTTP is essentially no protection at all: by the time the page is rendered, the attacker can make the HTML form send to a completely different URL.&lt;/p&gt;

&lt;p&gt;This attack is called &lt;a href=&quot;https://sites.google.com/site/cse825maninthemiddle/&quot;&gt;Man in the Middle&lt;/a&gt;.  (For an in depth demonstration of MITM attacks, checkout the presentation &lt;a href=&quot;http://2012.video.sector.ca/page/6&quot;&gt;Hey, I just middled you, and this is crazy&lt;/a&gt;.)&lt;/p&gt;

&lt;p&gt;This is not a theoretical attack.  It has been automated to the point where rewriting web pages on the fly is fairly trivial &amp;mdash; if you go down to your local &lt;a href=&quot;https://noisebridge.net&quot;&gt;hackerspace&lt;/a&gt; and browse the Internet without &lt;a href=&quot;http://torrentfreak.com/vpn-services-that-take-your-anonymity-seriously-2013-edition/&quot;&gt;using a VPN&lt;/a&gt;, at some point you will find all your images URLs are pointing to Goatse.&lt;/p&gt;

&lt;p&gt;Google has been subject to a host of attacks, from &lt;a href=&quot;https://www.eff.org/deeplinks/2011/08/iranian-man-middle-attack-against-google&quot;&gt;Iran&lt;/a&gt;.  Note that the attack happened at the backbone, not at a particular coffee shop.  Advanced persistent threats (APT) can include large nation states as well as script kiddies.&lt;/p&gt;

&lt;p&gt;Encrypting data ensures that an attacker cannot read plaintext over the network, using public key encryption.  However, the client still doesn&amp;rsquo;t know the identity of the server it&amp;rsquo;s trying to connect to.  This is a problem.  If you don&amp;rsquo;t verify the identity of the machine you&amp;rsquo;re talking to, then you could be talking to anyone.&lt;/p&gt;

&lt;h2&gt;The Use Cases&lt;/h2&gt;

&lt;p&gt;So that&amp;rsquo;s the threat model.  Now the use cases for WS.&lt;/p&gt;

&lt;p&gt;WS is a web services client, intended for asynchronous, non-blocking programmatic access to services using HTTP.  Most clients will be RESTful with either a small (4k) XML or JSON payload or continously streaming data.  Clients will only connect to a few well-known servers.  Use of WS for general browsing or indexing a website is possible, but not the focus.&lt;/p&gt;

&lt;h3&gt;Client connects to internal WS service&lt;/h3&gt;

&lt;p&gt;In this use case, the client is talking to a service which is not publically available.  The client and server will use private certificates (the &amp;ldquo;&lt;a href=&quot;http://www.thoughtcrime.org/blog/authenticity-is-broken-in-ssl-but-your-app-ha/&quot;&gt;moxie option&lt;/a&gt;&amp;rdquo;), use a PKI management solution like DigiCert or OpenCA, or use an internal root CA.&lt;/p&gt;

&lt;p&gt;The client may use mTLS / client authentication to connect to the internal service as an additional security measure.&lt;/p&gt;

&lt;p&gt;The server will most likely support TLSv1.0.  TLSv1.2 support is unlikely given that it does not come out of the box with ngnix and other clients.  It is likely that the server supports RC4 ciphers.&lt;/p&gt;

&lt;h3&gt;Client connects to external WS service&lt;/h3&gt;

&lt;p&gt;In this use case, the client is talking to an external WS service, which is not owned by the organization and exists on the public Internet.  The server may have a self-signed certificate, but is more likely to have a public certificate signed by a certificate authority.&lt;/p&gt;

&lt;p&gt;Public facing &amp;ldquo;webscale&amp;rdquo; services using HTTPS are likely to support TLSv1.2 and support good ECC ciphers.&lt;/p&gt;

&lt;h3&gt;Client connects to public internets&lt;/h3&gt;

&lt;p&gt;In this use case, the client is calling up random URLs given to it by the web service and storing the content.  This is a  behavior of RSS feed web applications, which require connections to scrape and process data but do not typically analyse the contents.&lt;/p&gt;

&lt;p&gt;The server could be anything.  This is not the primary use case, and so the defaults will not be tuned for maximum compatbility with unknown or misconfigured servers.&lt;/p&gt;

&lt;h2&gt;Understanding TLS&lt;/h2&gt;

&lt;p&gt;This is going to be extremely abbreviated, but let&amp;rsquo;s give a refresher anyway.  Adapted from Zytrax&amp;rsquo;s &lt;a href=&quot;http://www.zytrax.com/tech/survival/ssl.html&quot;&gt;SSL Survival Guide&lt;/a&gt; (which also has some excellent sections on X.509 certificates):&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;TLS has four components: authentication, message integrity, key negotiation and encryption.&lt;/p&gt;

&lt;p&gt;The client and the server begin a &lt;a href=&quot;http://en.wikipedia.org/wiki/Transport_Layer_Security#TLS_handshake&quot;&gt;handshake&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;   The server sends a certificate and the chain of certificates leading back to a root certificate authority.
   The client should perform certificate and chain validation, making sure the chain terminates to a root CA trusted by the client.&lt;/p&gt;

&lt;p&gt;In mutual TLS or client authentication, the client also sends a certificate to the server.  This is rare, and most communication just authenticates the server to the client.&lt;/p&gt;

&lt;p&gt;Because a server hands out the public key certificate and has the private key certificate, the client can encrypt all HTTP information using the public key and the server can decrypt it using the private key.&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Thomas Porrin&amp;rsquo;s explanation of &lt;a href=&quot;http://security.stackexchange.com/a/20833/6714&quot;&gt;how SSL works&lt;/a&gt; is also excellent.  For details, &lt;a href=&quot;http://en.wikipedia.org/wiki/Transport_Layer_Security&quot;&gt;Wikipedia&lt;/a&gt; is comprehensive as always.&lt;/p&gt;

&lt;p&gt;So far, so good.  Next is JSSE.&lt;/p&gt;

&lt;h2&gt;Understanding JSSE&lt;/h2&gt;

&lt;p&gt;JSSE is &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#ClassRelationship&quot;&gt;complex&lt;/a&gt;.  The reference guide and the crypto spec are surprisingly helpful (once I started to understand it), but it wasn&amp;rsquo;t until I had the source code handy and could look at the internal Sun JSSE classes that I felt I had a handle on it:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JSSE 1.7: &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#SSLOverview&quot;&gt;Reference Guide&lt;/a&gt;, &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/crypto/CryptoSpec.html#SSLTLS&quot;&gt;Crypto Spec&lt;/a&gt;, &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider&quot;&gt;Sun Providers&lt;/a&gt;, &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/certpath/CertPathProgGuide.html&quot;&gt;Cert Path&lt;/a&gt;, &lt;a href=&quot;http://grepcode.com/snapshot/repository.grepcode.com/java/root/jdk/openjdk/7-b147/&quot;&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;JSSE 1.6: &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#SSLOverview&quot;&gt;Reference Guide&lt;/a&gt;, &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/technotes/guides/security/crypto/CryptoSpec.html#SSLTLS&quot;&gt;Crypto Spec&lt;/a&gt;, &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/technotes/guides/security/SunProviders.html#SunJSSEProvider&quot;&gt;Sun Providers&lt;/a&gt;, &lt;a href=&quot;http://docs.oracle.com/javase/6/docs/technotes/guides/security/certpath/CertPathProgGuide.html&quot;&gt;Cert Path&lt;/a&gt;, &lt;a href=&quot;http://grepcode.com/snapshot/repository.grepcode.com/java/root/jdk/openjdk/6-b14/&quot;&gt;Source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In addition, the following best practices guides were very helpful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://docs.fedoraproject.org/en-US/Fedora_Security_Team//html/Defensive_Coding/sect-Defensive_Coding-TLS-Client-OpenJDK.html&quot;&gt;Fedora Security TLS Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://developer.android.com/training/articles/security-ssl.html&quot;&gt;Android Security Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;It&amp;rsquo;s important to note that Play supports JDK 1.6. and 1.6 came out in &lt;a href=&quot;https://en.wikipedia.org/wiki/Java_version_history#Java_SE_6_.28December_11.2C_2006.29&quot;&gt;December 2006&lt;/a&gt;.  That&amp;rsquo;s over eight years ago.  Since then, TLS (and the attacks on TLS) have evolved.  Where possible, I wanted to bring 1.6 up to the 1.7 level of functionality, or at least note where it lags.&lt;/p&gt;

&lt;p&gt;There are several parts to the JSSE, but it all starts with &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#SSLContext&quot;&gt;SSLContext&lt;/a&gt;(&lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/javax/net/ssl/SSLContext.java#SSLContext&quot;&gt;source&lt;/a&gt;, &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/ssl/SSLContextImpl.java#74&quot;&gt;impl&lt;/a&gt;).  Without a correctly configured &lt;code&gt;SSLContext&lt;/code&gt;, you have nothing.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SSLContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyManagers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trustManagers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secureRandom&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// correctly configured ssl context.&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Wait, what?  What&amp;rsquo;s a &lt;code&gt;TrustManager&lt;/code&gt;?  What&amp;rsquo;s a &lt;code&gt;KeyManager&lt;/code&gt;?  Well, from the &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html&quot;&gt;JSSE Reference Guide&lt;/a&gt; (which is the first, last and frequently only word on the subject):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#TrustManager&quot;&gt;TrustManager&lt;/a&gt;&lt;/em&gt;: Determines whether the remote authentication credentials (and thus the connection) should be trusted.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;&lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#KeyManager&quot;&gt;KeyManager&lt;/a&gt;&lt;/em&gt;: Determines which authentication credentials to send to the remote host.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Most of the time, you&amp;rsquo;ll be working with a trust manager.  You only need to worry about a key manager if you&amp;rsquo;re doing client authentication.&lt;/p&gt;

&lt;p&gt;The interesting thing with this API, right off the bat, is that &lt;code&gt;init()&lt;/code&gt; takes null parameters for defaults, and it takes an array of managers.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;What the JSSE Reference Guide says is &amp;ldquo;&lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#SSLContext&quot;&gt;installed security providers will be searched for the highest priority implementation of the appropriate factory&lt;/a&gt;&amp;rdquo;.   What &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/ssl/SSLContextImpl.java#74&quot;&gt;actually happens&lt;/a&gt; is that you get an empty key manager and a default &lt;code&gt;X509TrustManagerImpl&lt;/code&gt; that points to &lt;code&gt;cacerts&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Likewise, the API takes an array of key managers, so you would expect this to work:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyManager1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;keyManager2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// what could go wrong?&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;The problem here is that &lt;code&gt;init()&lt;/code&gt; doesn&amp;rsquo;t compose or aggregate managers together.  As &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/SSLContext.html#init(javax.net.ssl.KeyManager[],%20javax.net.ssl.TrustManager[],%20java.security.SecureRandom&quot;&gt;the Javadoc says&lt;/a&gt;, &amp;ldquo;only the first instance of a particular key and/or trust manager implementation type in the array is used. (For example, only the first &lt;code&gt;javax.net.ssl.X509KeyManager&lt;/code&gt; in the array will be used.)&amp;rdquo;&lt;/p&gt;

&lt;p&gt;There is similar fineprint and tricksy assumptions throughout the JSSE API.  If you don&amp;rsquo;t have the source code available, you will be utterly confused.&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;re not using &lt;code&gt;SSLContext&lt;/code&gt;, then changes are done by setting &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#Customization&quot;&gt;system properties&lt;/a&gt;.  This isn&amp;rsquo;t a bad way per se, but it&amp;rsquo;s global and opaque to the API.&lt;/p&gt;

&lt;p&gt;Direct unit testing is painful as half the classes are defined as final, or use static methods.  The internal logic is frustratingly and needlessly tightly coupled.&lt;/p&gt;

&lt;p&gt;Despite all of this, and despite having interfaces temptingly near, you should NEVER replace the underlying JSSE functionality.  Augment it, sure.  Subclass away.  Filter out weak points.  But doing a straight up rewrite is a mistake.  As per Moxie Marlinspike:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;If you’re interested in writing a more restrictive TrustManager implementation for Android, my recommendation is to have your implementation call through to the system’s default TrustManager implementation as the very first thing it does.  . That way you can ensure you at least won’t be doing any worse than the default, even if there are vulnerabilities in the additional checks you do.&lt;/p&gt;

&lt;p&gt;&amp;mdash;&lt;a href=&quot;http://www.thoughtcrime.org/blog/strongtrustmanager-mitm/&quot;&gt;Guardian&amp;rsquo;s StrongTrustManager Vulnerabilities&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Having read through TLS and JSSE, we&amp;rsquo;re now ready to check out how to configure the client.&lt;/p&gt;

&lt;h2&gt;Configuring a client&lt;/h2&gt;

&lt;p&gt;So, with the source code in hand, the first question was: how is WS?&lt;/p&gt;

&lt;p&gt;It turns out that WS does the right thing.  If you want to disable certificate validation, you have explicitly set the following in &lt;code&gt;application.conf&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;acceptAnyCertificate&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;which will let you accept a self-signed certificate that has not been added to your trust store.&lt;/p&gt;

&lt;p&gt;However, the way &lt;code&gt;ws.acceptAnyCertificate&lt;/code&gt; is interesting.  In Play 2.2.x, it looks like this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;playConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;flatMap&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getBoolean&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;ws.acceptAnyCertificate&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getOrElse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;asyncHttpConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setSSLContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;SSLContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getDefault&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&lt;/p&gt;

&lt;p&gt;That&amp;rsquo;s it.  There&amp;rsquo;s no other logic that involves telling AsyncHttpClient to accept any certificate anywhere else in Play.&lt;/p&gt;

&lt;p&gt;It turns out that accepting any certificate is the &lt;em&gt;default&lt;/em&gt; behavior in AsyncHttpClient.  If you are making HTTPS calls in Java using AsyncHTTPClient 1.7.x directly, you are &lt;a href=&quot;https://github.com/AsyncHttpClient/async-http-client/issues/352&quot;&gt;vulnerable to a MITM attack&lt;/a&gt;.&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The SSLContext class is central to the SSL implementation in Java in general and in AsyncHttpClient in particular. The default SSLContext for AsyncHttpClient is dependent on whether the javax.net.ssl.keyStore system property is set. If this property is set, AsyncHttpClient will create a TLS SSLContext with a KeyManager based on the specified key store (and configured based on the values of many other javax.net.ssl properties as described in the JSSE Reference Guide linked above). Otherwise, it will create a TLS SSLContext with no KeyManager and a TrustManager which accepts everything. In effect, if javax.net.ssl.keyStore is unspecified, any ol’ SSL certificate will do.&lt;/p&gt;

&lt;p&gt;&amp;mdash; &lt;a href=&quot;http://kevinlocke.name/bits/2012/10/03/ssl-certificate-verification-in-dispatch-and-asynchttpclient/&quot;&gt;SSL Certificate Verification in Dispatch and AsyncHttpClient&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The first step in implementing HTTPS is to set up certificate verification to avoid &lt;a href=&quot;https://github.com/AsyncHttpClient/async-http-client/issues/352&quot;&gt;issue 352&lt;/a&gt;.  This, in itself, is fairly easy: just create an &lt;code&gt;SSLContext&lt;/code&gt; instance, then init with null values.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AsyncHttpConfig&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SSLContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;protocol&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;init&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;setSSLContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;asyncHttpClientConfig&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;But, of course, that was only the beginning.&lt;/p&gt;

&lt;p&gt;The essential problem with &lt;code&gt;ws.acceptAnyCertificate&lt;/code&gt; is while it&amp;rsquo;s wrong, it&amp;rsquo;s also a one line configuration setting.  It&amp;rsquo;s obvious what it does.  Meanwhile, the experience of adding a self signed certificate to the trust manager is downright painful.  By default, the root CA certificates are in &lt;code&gt;$JAVA_HOME/lib/security/cacerts&lt;/code&gt; and so if you want to add an extra certificate (rather than replace all the existing CA certs), you have to know the exact &lt;a href=&quot;https://www.sslshopper.com/article-most-common-java-keytool-keystore-commands.html&quot;&gt;keystore&lt;/a&gt; command for it:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;keytool&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;nn&quot;&gt;trustcacerts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;path&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ca&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ca&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pem&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CA_ALIAS&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keystore&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;$JAVA_HOME&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;jre&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;lib&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cacerts&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Just from a deployment and maintenance perspective, this is a huge hassle.  And it&amp;rsquo;s not like trust stores and keystores are all that complicated: there&amp;rsquo;s an list of certificates tied to aliases, with an optional password attached.&lt;/p&gt;

&lt;p&gt;The simplest thing to do, from a programmer perspective, would be to have a list of stores that were pulled into a single manager.  Then, instead of having to run a keytool command, you could just add a line saying where your store was, and you&amp;rsquo;d be done.&lt;/p&gt;

&lt;p&gt;This involved creating a key manager and a trust manager that could take multiple stores.   After looking through the source code, I determined that there was no API problem with using multiple stores inside a single manager&amp;hellip; but then ran into the implementation again. In the X.509 implementation of JSSE, there&amp;rsquo;s a one to one correspondence between a manager and a store.   I ended creating managers from the &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/api/javax/net/ssl/TrustManagerFactory.html&quot;&gt;factories&lt;/a&gt; and then using a composite manager pattern based off &lt;a href=&quot;http://codyaray.com/2013/04/java-ssl-with-multiple-keystores&quot;&gt;Cody A. Ray&amp;rsquo;s blog post&lt;/a&gt;, and using the &lt;a href=&quot;http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/security/ssl/X509TrustManagerImpl.java#X509TrustManagerImpl&quot;&gt;&lt;code&gt;X509TrustManagerImpl&lt;/code&gt;&lt;/a&gt; implementation and the
 &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#X509ExtendedTrustManager&quot;&gt;&lt;code&gt;X509ExtendedTrustManager&lt;/code&gt; example&lt;/a&gt; as references.&lt;/p&gt;

&lt;p&gt;The composite trust manager has a list of &lt;code&gt;X509TrustManagerImpl&lt;/code&gt;, and iterates through each one until it finds one that doesn&amp;rsquo;t throw an exception.  If all of them throw exceptions, then it rethrows the exception with the entire list (so that no exceptions are swallowed), otherwise, it returns the first good result.  This extends the &lt;code&gt;TrustManager&lt;/code&gt; functionality while safely keeping all of the existing logic in place.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;21&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;22&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;23&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;24&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;25&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;26&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;27&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;28&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;29&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;30&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;31&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;32&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;33&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;34&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;checkServerTrusted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;X509Certificate&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;authType&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trusted&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exceptionList&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;withTrustManagers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;trustManager&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;trustManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;checkServerTrusted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;chain&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;authType&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;n&quot;&gt;trusted&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trusted&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;No trust manager was able to validate this certificate chain: # of exceptions = ${exceptionList.size}&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;CompositeCertificateException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exceptionList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;private&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;withTrustManagers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;X509TrustManager&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exceptionList&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ArrayBuffer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;trustManagers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;trustManager&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;trustManager&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;CertPathBuilderException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;No path found to certificate: this usually means the CA is not in the trust store&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;exceptionList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;GeneralSecurityException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;General security exception&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;exceptionList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NonFatal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Unexpected exception!&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;          &lt;span class=&quot;n&quot;&gt;exceptionList&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;append&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;exceptionList&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Now you can now configure multiple key stores and trust stores directly in &lt;code&gt;application.conf&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ssl&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;keyManager&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;stores&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;PKCS12&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;path:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;keys/client.p12&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;password:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;changeit2&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;PEM&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;path:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;keys/client.pem&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;trustManager&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;stores&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;path:&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;keys/mystore.jks&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;path:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;$&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;java.home&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;/lib/security/cacerts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and end up with a properly configured key manager and trust manager that contain all the keys from the various stores.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s a lot more to key stores and trust stores than I&amp;rsquo;ve mentioned here.  For more details (including how to resolve improperly configured certificate chains), see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.palominolabs.com/2011/10/18/java-2-way-tlsssl-client-certificates-and-pkcs12-vs-jks-keystores/&quot;&gt;Java 2-way TLS/SSL (Client Certificates) and PKCS12 vs JKS KeyStores&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.chariotsolutions.com/2013/01/https-with-client-certificates-on.html&quot;&gt;HTTPS with Client Certificates on Android&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;And to muck with certificates inside a keystore, I recommend &lt;a href=&quot;http://portecle.sourceforge.net/&quot;&gt;Portacle&lt;/a&gt;, a GUI key management system.&lt;/p&gt;

&lt;h2&gt;Configuring multiple clients&lt;/h2&gt;

&lt;p&gt;So now we have a configuration.  But there&amp;rsquo;s another problem.  There&amp;rsquo;s only one &lt;code&gt;application.conf&lt;/code&gt; file, and all the WS methods are on the companion object:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;nc&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;https://google.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This meant that if you have several web services, say &amp;ldquo;secure.com&amp;rdquo; and &amp;ldquo;loose.com&amp;rdquo;, you cannot set up different configuration profiles for them, or set up a client dynamically, or do isolated testing.  Everything had to be handled when the Play configuration loads.&lt;/p&gt;

&lt;p&gt;I broke apart the &lt;code&gt;WS.client&lt;/code&gt; and added a &lt;code&gt;WSClient&lt;/code&gt; trait that could call &lt;code&gt;url&lt;/code&gt; in the same way.  Now you can do this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;com.typesafe.config.ConfigFactory&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;play.api.libs.ws._&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;play.api.libs.ws.ning._&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configuration&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Configuration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;ConfigFactory&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;s&quot;&gt;    |ws.ssl.trustManager = &#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;s&quot;&gt;  &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stripMargin&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;DefaultWSConfigParser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;configuration&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NingAsyncHttpClientConfigBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secureClient&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WSClient&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NingWSClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;response&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;secureClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;https://secure.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and have much finer grained control over the TLS configuration.&lt;/p&gt;

&lt;p&gt;Unfortunately, getting a client passed as an implicit parameter to &lt;code&gt;WS.url&lt;/code&gt; is harder.  I added a &lt;a href=&quot;http://spray.io/blog/2012-12-13-the-magnet-pattern/&quot;&gt;magnet pattern&lt;/a&gt; so you can do this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;PairMagnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fromPair&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pair&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Pair&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;WSClient&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;java.net.URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WSRequestHolderMagnet&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;WSRequestHolder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;netUrl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pair&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;netUrl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.language.implicitConversions&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exampleURL&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;net&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;URL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://example.com&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;nc&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;client&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;exampleURL&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and added another method &lt;code&gt;WS.clientUrl&lt;/code&gt; that takes an implicit client:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sslClient&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;play&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;api&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;libs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ning&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;NingWSClient&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sslBuilder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;nc&quot;&gt;WS&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clientUrl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;http://example.com/feed&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Debugging a client&lt;/h2&gt;

&lt;p&gt;While I was going through the client, I figured I may as well make it easier to turn on and off debugging as well.&lt;/p&gt;

&lt;p&gt;Debugging is done by setting a system property, i.e. &lt;code&gt;-Djavax.net.debug=&quot;ssl&quot;&lt;/code&gt;.  Debugging output is written directly to &lt;code&gt;System.out.println()&lt;/code&gt;, and the recommended way to change this is to &lt;a href=&quot;http://sim.ivi.co/search/label/Debug%20Logging&quot;&gt;change System.out&lt;/a&gt;.  I can only hope this changes in JDK 1.8 &amp;mdash; at the very least it should use &lt;code&gt;java.util.logging&lt;/code&gt; &amp;mdash; but it&amp;rsquo;s what there is for now.&lt;/p&gt;

&lt;p&gt;I had the &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/ReadDebug.html&quot;&gt;JSSE debug page&lt;/a&gt; and the &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/jsse/JSSERefGuide.html#Debug&quot;&gt;debug section of the reference guide&lt;/a&gt; handy, so it was fairly simple to provide that in configuration rather than futz with system properties.  I added &lt;a href=&quot;http://download.java.net/jdk8/docs/technotes/guides/security/troubleshooting-security.html&quot;&gt;certpath&lt;/a&gt; and &amp;ldquo;ocsp&amp;rdquo; (an undocumented debug property) as well, while I was checking for certificate validation.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;16&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;17&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;18&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;19&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;20&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;certpath&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;, &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ocsp&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;k&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;  &lt;span class=&quot;k&quot;&gt;#&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;defines&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;all&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;of&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;below&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;defaultctx&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;handshake&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;verbose&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;keygen&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;keymanager&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;pluggability&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;record&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;packet&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;plaintext&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;sessioncache&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;sslctx&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;,
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt; &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;trustmanager&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This is not a perfect solution, because system properties are global across all clients.  But it&amp;rsquo;s better.&lt;/p&gt;

&lt;p&gt;ADDENDUM: this only worked intermittently and eventually I figured out why and fixed it.  The more sensitive among you may wish to avoid &lt;a href=&quot;http://tersesystems.com/2014/03/02/monkeypatching-java-classes&quot;&gt;this link&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Next, it was time to figure out what went into the client.  The most important thing is the protocol.&lt;/p&gt;

&lt;h2&gt;Choosing a protocol&lt;/h2&gt;

&lt;p&gt;TLS comes in different versions.  In JSSE, the list is available &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#jssenames&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are two calls that refer directly to the protocol names, the getInstance call:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SSLContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getInstance&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;TLS&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// or &amp;quot;TLSv1.2&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and the enabledProtocols list, which shows what the SSL context is willing to accept:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;enabledProtocols&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sslContext&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getDefaultParameters&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;().&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getEnabledProtocols&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;SSLv2 and SSLv2Hello (there is no v1) are obsolete and usage in the field is &lt;a href=&quot;https://www.trustworthyinternet.org/ssl-pulse/&quot;&gt;down to 25% on the public Internet&lt;/a&gt;.  SSLv3 is known to have security issues and is still out in the field with 100% support.  Virtually all HTTPS servers support it, and Mozilla Firefox still uses SSLv3 by default.   They have a number of &lt;a href=&quot;http://www.yaksman.org/~lweith/ssl.pdf&quot;&gt;security issues&lt;/a&gt; compared to TLS.&lt;/p&gt;

&lt;p&gt;TLSv1.2 is the current version, but early implementations of TLS 1.2 were prone to misconfiguration, which resulted in TLS 1.2 being &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/SunProviders.html#tlsprotonote&quot;&gt;disabled for the client by default in 1.7&lt;/a&gt;.  Mozilla Firefox also has &lt;a href=&quot;https://support.mozilla.org/en-US/questions/959936&quot;&gt;TLSv1.2 disabled&lt;/a&gt;, as of January 2014, and is only enabling it in the next version.&lt;/p&gt;

&lt;p&gt;However, virtually all servers support &lt;a href=&quot;https://www.trustworthyinternet.org/ssl-pulse/&quot;&gt;TLS v1.0&lt;/a&gt;, and given our use cases, we expect that web services will have TLSv1.2 configured correctly.  TLS 1.0 has been described as &lt;a href=&quot;http://blog.cryptographyengineering.com/2011/09/brief-diversion-beast-attack-on-tlsssl.html&quot;&gt;broken from the BEAST attack&lt;/a&gt;, but the attack seems to apply only to CBC ciphers, which we&amp;rsquo;re not obliged to use.&lt;/p&gt;

&lt;p&gt;We want people to use the highest possible version of TLS.  So we specify &amp;ldquo;TLSv1.2&amp;rdquo;, &amp;ldquo;TLSv1.1&amp;rdquo;, &amp;ldquo;TLSv1&amp;rdquo; in that order for JDK 1.7.  For JDK 1.6, only &amp;ldquo;TLSv1&amp;rdquo; is available, so that&amp;rsquo;s what we have.  We throw an exception on &amp;ldquo;SSLv3&amp;rdquo;, &amp;ldquo;SSLv2&amp;rdquo; and &amp;ldquo;SSLv2Hello&amp;rdquo;.  If you don&amp;rsquo;t want that, then you have to explicitly set a &lt;code&gt;ws.ssl.loose.allowWeakProtocols&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;You can also specify the default protocol and the protocols list explicitly, i.e. if you want to configure JSSE for &lt;a href=&quot;http://www.nsa.gov/ia/programs/suiteb_cryptography/index.shtml&quot;&gt;Suite B&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;protocol&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;TLSv1.2&amp;quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// passed into SSLContext.getInstance()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;c1&quot;&gt;// passed into sslContext.getDefaultParameters().setEnabledProtocols()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enabledProtocols&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;TLSv1.&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;2&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Next, it&amp;rsquo;s time to figure out what cipher suite to pick.&lt;/p&gt;

&lt;h2&gt;Choosing a cipher suite&lt;/h2&gt;

&lt;p&gt;A &lt;a href=&quot;https://en.wikipedia.org/wiki/Cipher_suite&quot;&gt;cipher suite&lt;/a&gt; is really four different ciphers in one, describing the key exchange, bulk encryption, message authentication and random number function.  In this particular case, we&amp;rsquo;re focusing on the bulk encryption cipher.&lt;/p&gt;

&lt;p&gt;The JSSE list of cipher suites is &lt;a href=&quot;http://docs.oracle.com/javase/7/docs/technotes/guides/security/StandardNames.html#ciphersuites&quot;&gt;here&lt;/a&gt; and there is an extensive &lt;a href=&quot;http://sim.ivi.co/search/label/Cipher%20Suite&quot;&gt;comparison list&lt;/a&gt;.  There&amp;rsquo;s a number of different ciphers available, and the list has changed substantially between JDK 1.7 and JDK 1.6.&lt;/p&gt;

&lt;p&gt;In 1.7, the default cipher list is reportedly &lt;a href=&quot;http://sim.ivi.co/2011/07/jsse-oracle-provider-preference-of-tls.html&quot;&gt;pretty good&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In 1.6, the default list is &lt;a href=&quot;http://op-co.de/blog/posts/android_ssl_downgrade/&quot;&gt;out of order&lt;/a&gt; &amp;mdash; some of the weaker ciphers show up before the stronger ciphers do.  Not only that, but 1.6 has no support for Elliptic Curve cryptography (ECC) ciphers, which are much stronger and allow for perfect forward secrecy.&lt;/p&gt;

&lt;p&gt;Now, the client doesn&amp;rsquo;t control what cipher will eventually be used.  The server does.  As a client, there are two things that you can do:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You can present a list of ciphers which you are willing to accept.&lt;/li&gt;
&lt;li&gt;You can refuse a cipher which you know to be weak.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;In 1.7, we use the default cipher list.&lt;/p&gt;

&lt;p&gt;For 1.6, the client provides a truncated cipher list based off &lt;a href=&quot;https://briansmith.org/browser-ciphersuites-01.html&quot;&gt;Brian Smith&amp;rsquo;s list&lt;/a&gt;, with the ECC ciphers taken out and the 3DES cipher removed.  Roughly 55% of the Internet uses RC4, and given that WS is a web services client, it will probably be talking to only a few services which are current.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java16RecommendedCiphers&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;TLS_DHE_RSA_WITH_AES_256_CBC_SHA&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;TLS_DHE_RSA_WITH_AES_128_CBC_SHA&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;TLS_DHE_DSS_WITH_AES_128_CBC_SHA&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;TLS_RSA_WITH_AES_256_CBC_SHA&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;TLS_RSA_WITH_AES_128_CBC_SHA&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;SSL_RSA_WITH_RC4_128_SHA&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;SSL_RSA_WITH_RC4_128_MD5&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;s&quot;&gt;&amp;quot;TLS_EMPTY_RENEGOTIATION_INFO_SCSV&amp;quot;&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// per RFC 5746&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;There are some ciphers which everyone agrees are bad though, and should never be used.  NULL.  Export Suite.  DES.  Anon.  They are disabled by default, and the JSSE team says &lt;a href=&quot;http://sim.ivi.co/2011/08/jsse-oracle-provider-default-disabled.html&quot;&gt;You are NOT supposed to use these cipher suites&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This brings up the next question: should WS consider RC4 and MD5 based ciphers to be weak?   Surprisingly, probably not.&lt;/p&gt;

&lt;p&gt;If you are setting up a server, you shouldn&amp;rsquo;t use RC4 and MD5 in your cipher suites, certainly.  But if you&amp;rsquo;re a client, you&amp;rsquo;re probably fine talking to a server that is using RC4 or MD5.&lt;/p&gt;

&lt;p&gt;In the case of RC4:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;RC4 is horribly broken, and is horribly broken in ways that are meaningful to TLS. But the magnitude of RC4&amp;rsquo;s brokenness wasn&amp;rsquo;t appreciated until last year, and up until then, RC4 was a common recommendation for resolving both the SSL3/TLS1.0 BEAST attack and the TLS &amp;ldquo;Lucky 13&amp;rdquo; M-t-E attack. That&amp;rsquo;s because RC4 is the only widely-supported stream cipher in TLS. Moreover, RC4 was considered the most computationally efficient way to get TLS deployed, which 5-6 years ago might have been make-or-break for some TLS deployments.
You should worry about RC4 in TLS &amp;mdash;&amp;ndash; but not that much: the attack is noisy and extremely time consuming. You should not be alarmed by MD5 in TLS, although getting rid of it is one of many good reasons to drive adoption of TLS 1.2.&lt;/p&gt;

&lt;p&gt;&amp;mdash; &lt;a href=&quot;https://news.ycombinator.com/item?id=6548545&quot;&gt;Thomas H. Ptacek&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The best, known attack against using RC4 with HTTPS involves causing a browser to transmit many HTTP requests &amp;mdash; each with the same cookie &amp;mdash; and exploiting known biases in RC4 to build an increasingly precise probability distribution for each byte in a cookie. However, the attack needs to see on the order of 10 billion copies of the cookie in order to make a good guess. This involves the browser sending ~7TB of data. In ideal situations, this requires nearly three months to complete.&lt;/p&gt;

&lt;p&gt;&amp;mdash; &lt;a href=&quot;http://googleonlinesecurity.blogspot.com/2013/11/a-roster-of-tls-cipher-suites-weaknesses.html&quot;&gt;A roster of TLS cipher suites weaknesses&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;The case of MD5:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The MD5 hash function is broken, that is true. However, TLS doesn&amp;rsquo;t use MD5 in its raw form; it uses variants of HMAC-MD5, which applies the hash function twice, with two different padding constants with high Hamming distances (put differently, it tries to synthesize two distinct hash functions, MD5-IPAD and MD5-OPAD, and apply them both). Nobody would recommend HMAC-MD5 for use in a new system, but it has not been broken.&lt;/p&gt;

&lt;p&gt;&amp;mdash; &lt;a href=&quot;https://news.ycombinator.com/item?id=6548545&quot;&gt;Thomas H. Ptacek&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;and:&lt;/p&gt;

&lt;blockquote&gt;&lt;p&gt;The attacks on HMAC-MD5 do not seem to indicate a practical vulnerability when used as a message authentication code.&lt;/p&gt;

&lt;p&gt;&amp;mdash; &lt;a href=&quot;http://tools.ietf.org/search/rfc6151#section-2.3&quot;&gt;RFC 6151, section 2.3&lt;/a&gt;&lt;/p&gt;&lt;/blockquote&gt;

&lt;p&gt;Note that we are talking about use of MD5 in a cipher here &amp;mdash; as a client, accepting an MD5 signed certificate is a &lt;a href=&quot;/2014/03/20/fixing-x509-certificates/&quot;&gt;different kettle of fish&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://sim.ivi.co/2011/07/java-se-7-release-security-enhancements.html&quot;&gt;&lt;code&gt;jdk.tls.disabledAlgorithms&lt;/code&gt;&lt;/a&gt; constraint in 1.7 works fine to exclude bad or weak ciphers, and can also check small key sizes.  In particular, before 1.8, ephemeral DH parameters were &lt;a href=&quot;http://bugs.java.com/bugdatabase/view_bug.do?bug_id=6521495&quot;&gt;limited to 1024 bits&lt;/a&gt;, which is considered weak these days.  The solution is to set &lt;code&gt;jdk.tls.disabledAlgorithms=&quot;DHE keySize &amp;lt;= 1024, ECDHE keySize &amp;lt;= 1024&quot;&lt;/code&gt;.  You may also need to do this if you&amp;rsquo;re on 1.7, as there&amp;rsquo;s a &lt;a href=&quot;http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8013059&quot;&gt;nasty bug in 1.7&lt;/a&gt; that causes connections to fail &lt;a href=&quot;https://groups.google.com/forum/#!topic/play-framework/ECee_w2wlrU&quot;&gt;0.05% of the time&lt;/a&gt; &amp;mdash; although frankly, upgrading to 1.8 is a much &lt;a href=&quot;http://docs.oracle.com/javase/8/docs/technotes/guides/install/install_overview.html&quot;&gt;better solution&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Note that &lt;code&gt;jdk.tls.disabledAlgorithms&lt;/code&gt; is a security property, not a system property, and it&amp;rsquo;s null by default:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;scala&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;java&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Security&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;getProperty&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;jdk.tls.disabledAlgorithms&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;res9&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Also note that, as the author says, &amp;ldquo;&lt;a href=&quot;http://sim.ivi.co/2013/11/harness-ssl-and-jsse-key-size-control.html&quot;&gt;There is no such handy approach in JDK 6 and 5.0&lt;/a&gt;&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;Play supports 1.6, so we make our own &amp;ldquo;handy approach&amp;rdquo;: we check the cipher list at configuration time, and throw an exception if we find that there is a weak cipher in the list.  If you want to turn off the check, you have to configure the &lt;code&gt;ws.ssl.loose.acceptWeakCiphers&lt;/code&gt; flag.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t think that ciphers need to be checked at run time, as I don&amp;rsquo;t think that the client will accept a cipher from the server that is not already in the client list.  However, if you&amp;rsquo;re going to be paranoid, you probably want to set &lt;code&gt;jdk.tls.disabledAlgorithms&lt;/code&gt; anyway.&lt;/p&gt;

&lt;p&gt;As with protocols, you can configure the cipher list by hand:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;ws&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ssl&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enabledCiphers&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;  
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;And that about wraps things up for cipher suites.&lt;/p&gt;

&lt;h2&gt;Next&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;/2014/03/20/fixing-x509-certificates/&quot;&gt;X.509 Certificates&lt;/a&gt;!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Building a Development Environment with Docker</title>
      <link>http://tersesystems.com/2013/11/20/building-a-development-environment-with-docker</link>
      <pubDate>Wed, 20 Nov 2013 22:22:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2013/11/20/building-a-development-environment-with-docker</guid>
      <description>&lt;h2&gt;TL;DR&lt;/h2&gt;

&lt;p&gt;I&amp;rsquo;ve written a &lt;a href=&quot;https://gist.github.com/wsargent/7049221&quot;&gt;cheat sheet for Docker&lt;/a&gt;, and I have a &lt;a href=&quot;https://github.com/wsargent/docker-devenv&quot;&gt;github project&lt;/a&gt; for it.  Here&amp;rsquo;s the thinking that went into why Docker, and how best to use it.&lt;/p&gt;

&lt;h2&gt;The problem&lt;/h2&gt;

&lt;p&gt;You want to build your own development environment from scratch, and you want it to be as close to a production environment as possible.&lt;/p&gt;

&lt;h2&gt;Solutions&lt;/h2&gt;

&lt;p&gt;Development environments usually just&amp;hellip; evolve.  There&amp;rsquo;s a bunch of tries at producing a consistent development environment, even between developers.  Eventually, through trial and error, a common set of configuration files and install instructions turns into something that resembles a scaled down and testable version of the production environment, managed through version control and a set of bash scripts.&lt;/p&gt;

&lt;p&gt;But even when it gets to that point, it&amp;rsquo;s not over, because modern environments can involve dozens of different components, all with their own configuration, often times communicating with each other through TCP/IP or even worse, talking to a third party API like S3.  To replicate the production environment, these lines of communication must be drawn &amp;mdash; but they can&amp;rsquo;t be squashed into one single machine.  Something has to give.&lt;/p&gt;

&lt;h3&gt;Solution #1: Shared dev environment&lt;/h3&gt;

&lt;p&gt;The first solution is to set up a environment with exactly the same machines in the same way as production, only scaled down for development.  Then, everyone uses it.&lt;/p&gt;

&lt;p&gt;This works only if there is no conflict between developers, and resource use and contention is not a problem.  Oh, and you don&amp;rsquo;t want to swap out one of those components for a particular team.&lt;/p&gt;

&lt;p&gt;If you need to access the environment from outside the office, you&amp;rsquo;ll need a VPN.  And if you&amp;rsquo;re on a flaky network or on a plane, you&amp;rsquo;re out of luck.&lt;/p&gt;

&lt;h3&gt;Solution #2: Virtual Machines&lt;/h3&gt;

&lt;p&gt;The second solution is to put as much of the environment as possible onto the developer&amp;rsquo;s laptop.&lt;/p&gt;

&lt;p&gt;Virtual Machines such as VirtualBox will allow you to create an isolated dev environment.  You can package VMs into boxes with Vagrant, and create fresh VMs from template as needed.  They each have their own IP address, and you can get them to share filesystems.&lt;/p&gt;

&lt;p&gt;However, VMs are not small.  You can chew up gigabytes very easily providing the OS and packages for each VM, and those VMs do not share CPU or memory when running together.  If you have a complex environment, you will run into a point where you either run out of disk space or memory, or you break down and start packaging multiple components inside a single VM, producing an environment which may not reflect production and is far more fragile and prone to complexities.&lt;/p&gt;

&lt;h3&gt;Solution #3: Docker&lt;/h3&gt;

&lt;p&gt;Docker solves the isolation problem.  Docker provides (consistent, reproducible, disposable) containers that make components appear to be running on different machines, while sharing CPU and memory underneath, and provides TCP/IP forwarding and filesystems that can be shared between containers.&lt;/p&gt;

&lt;p&gt;So, here&amp;rsquo;s how you build a development environment in Docker.&lt;/p&gt;

&lt;h2&gt;Docker Best Practices&lt;/h2&gt;

&lt;h3&gt;Build from Dockerfile&lt;/h3&gt;

&lt;p&gt;The only sane way to put together a dev environment in Docker is to use raw Dockerfile and a private repository.  Pull from the central docker registry only if you must, and keep everything local.&lt;/p&gt;

&lt;h3&gt;Chef recipes are slow&lt;/h3&gt;

&lt;p&gt;You might think to yourself, &amp;ldquo;self, I don&amp;rsquo;t feel like reinventing the wheel.  Let&amp;rsquo;s just use chef recipes for everything.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;The problem is that creating new containers is something that you&amp;rsquo;ll do lots.  Every time you create a container, seconds will count, and minutes will be totally unacceptable.  It turns out that calling &lt;code&gt;apt-get update&lt;/code&gt; is a great way to watch nothing happen for a while.&lt;/p&gt;

&lt;h3&gt;Use raw Dockerfile&lt;/h3&gt;

&lt;p&gt;Docker uses a versioned file system called AUFS, which identifies commands it can run from layers (aka cached fs) and pulls out the appropriate version.  You want to keep the cache happy.  You want to put all the mutable stuff at the very end of the Dockerfile, so you can leverage cache as much as possible.  Chef recipes are a black box to Docker.&lt;/p&gt;

&lt;p&gt;The way this breaks down is:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Cache wins.&lt;/li&gt;
&lt;li&gt;Chef, ansible, etc, does not use cache.&lt;/li&gt;
&lt;li&gt;Raw Dockerfile uses cache.&lt;/li&gt;
&lt;li&gt;Raw Dockerfile wins.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;There&amp;rsquo;s another way to leverage Docker, and that&amp;rsquo;s to use an image that doesn&amp;rsquo;t start off from &lt;code&gt;ubuntu&lt;/code&gt; or &lt;code&gt;basebox&lt;/code&gt;.  You can use your own base image.&lt;/p&gt;

&lt;h2&gt;The Basics&lt;/h2&gt;

&lt;h3&gt;Install a internal docker registry&lt;/h3&gt;

&lt;p&gt;Install an internal registry (&lt;a href=&quot;https://github.com/dotcloud/docker-registry&quot;&gt;the fast way&lt;/a&gt;) and run it as a daemon:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;docker run -name internal_registry -d -p 5000:5000 samalba/docker-registry&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Alias server to localhost:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;echo &quot;127.0.0.1      internal_registry&quot; &amp;gt;&amp;gt; /etc/hosts&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Check internal_registry exists and is running on port 5000:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;apt-get install -y curl
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;curl &#8211;get &#8211;verbose http://internal_registry:5000/v1/_ping&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h3&gt;Install Shipyard&lt;/h3&gt;

&lt;p&gt;Shipyard is a web application that provides an easy to use interface for seeing what Docker is doing.&lt;/p&gt;

&lt;p&gt;Open up a port in your &lt;code&gt;Vagrantfile&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;config.vm.network :forwarded_port, :host =&amp;gt; 8005, :guest =&amp;gt; 8005&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Install shipyard from the central index:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;SHIPYARD=$(docker run \
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    -name shipyard \
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  -p 8005:8000 \
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  -d \
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  shipyard/shipyard)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You will also need to replace &lt;code&gt;/etc/init/docker.conf&lt;/code&gt; with the following:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;description &quot;Docker daemon&quot;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;start on filesystem and started lxc-net
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;stop on runlevel [!2345]
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;respawn
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;script
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        /usr/bin/docker -d -H tcp://0.0.0.0:4243 -H unix:///var/run/docker.sock
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;end script&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;THen reboot the VM.&lt;/p&gt;

&lt;p&gt;Once the server has rebooted and you&amp;rsquo;ve waited for a bit, you should have shipyard up.  The credentials are &amp;ldquo;shipyard/admin&amp;rdquo;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Go to &lt;a href=&quot;http://localhost:8005/hosts/&quot;&gt;http://localhost:8005/hosts/&lt;/a&gt; to see Shipyard&amp;rsquo;s hosts.&lt;/li&gt;
&lt;li&gt;In the vagrant VM, &lt;code&gt;ifconfig eth0&lt;/code&gt; and look for &amp;ldquo;inet addr:10.0.2.15&amp;rdquo; &amp;mdash; enter the IP address.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Create base image&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Create a Dockerfile with initialization code such as `apt-get update / apt-get install&amp;#8217; etc: this is your base.&lt;/li&gt;
&lt;li&gt;Build your base image, then push it to the internal registry with &lt;code&gt;docker build -t internal_registry:5000/base .&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Build from your base image&lt;/h3&gt;

&lt;p&gt;Build all of your other Dockerfile pull from &amp;ldquo;base&amp;rdquo; instead of ubuntu.&lt;/p&gt;

&lt;p&gt;Keep playing around until you have your images working.&lt;/p&gt;

&lt;h3&gt;Push your images&lt;/h3&gt;

&lt;p&gt;Push all of your images into the internal registry.&lt;/p&gt;

&lt;h3&gt;Save off your registry&lt;/h3&gt;

&lt;p&gt;if you need to blow away your Vagrant or set someone else up, it&amp;rsquo;s much faster to do it with all the images still intact:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;docker export internal_registry &amp;gt; internal_registry.tar
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;gzip internal_registry.tar
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;mv internal_registry.tar.gz /vagrant&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Tips&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;docker add&lt;/code&gt; blows away the cache, don&amp;rsquo;t use it (bug, possibly fixed).&lt;/li&gt;
&lt;li&gt;There&amp;rsquo;s a limit to the number of layers you can have, pack your apt-get onto a single line.&lt;/li&gt;
&lt;li&gt;Keep common instructions at the top of the Dockerfile to leverage the cache as long as possible.&lt;/li&gt;
&lt;li&gt;Use tags when building (Always pass the -t option to &lt;code&gt;docker build&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Never map the public port in a Dockerfile.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Exposing Services&lt;/h3&gt;

&lt;p&gt;If you are running a bunch of services in Docker and want to expose them through Virtualbox to the host OS, you need to do something like this in your Vagrant:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;(49000..49900).each do |port|
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  config.vm.network :forwarded_port, :host =&amp;gt; port, :guest =&amp;gt; port
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Let&amp;rsquo;s start up Redis:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;docker pull johncosta/redis
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;docker run -p 6379 -d johncosta/redis&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Then find the port:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;docker ps
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;docker port &amp;lt;redis_container_id&amp;gt; 6379&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Then connect to the &lt;code&gt;49xxx&lt;/code&gt; port that Virtualbox exposes.&lt;/p&gt;

&lt;h3&gt;Cleanup&lt;/h3&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;docker ps -a | grep &#39;weeks ago&#39; | awk &#39;{print $1}&#39; | xargs docker rm&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h3&gt;eliminate:&lt;/h3&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;docker rm `docker ps -a -q`&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h3&gt;Running from an existing volume&lt;/h3&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;&#39;&gt;&lt;span class=&#39;line&#39;&gt;docker run -i -t -volumes-from 5ad9f1d9d6dc mytag /bin/bash&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Sources&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/phusion/baseimage-docker&quot;&gt;Phusion Base Image&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://crosbymichael.com/dockerfile-best-practices.html&quot;&gt;Dockerfile Best Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.rackspace.com/blog/how-mailgun-uses-docker-and-contributes-back/&quot;&gt;How Mailgun uses Docker&lt;/a&gt; (video is more complete than the blog post).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.relateiq.com/a-docker-dev-environment-in-24-hours-part-2-of-2/&quot;&gt;Docker Dev Environment in 24 Hours&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      <title>Play in Practice</title>
      <link>http://tersesystems.com/2013/04/20/play-in-practice</link>
      <pubDate>Sat, 20 Apr 2013 14:20:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2013/04/20/play-in-practice</guid>
      <description>&lt;p&gt;I gave a talk on Play in Practice at the &lt;a href=&quot;http://www.meetup.com/SF-Scala/events/111419142/&quot;&gt;SF Scala meetup&lt;/a&gt; recently.
Thanks to &lt;a href=&quot;http://stackmob.com&quot;&gt;Stackmob&lt;/a&gt; for hosting us and providing pizza.&lt;/p&gt;

&lt;p&gt;I went into describing how to implementing &lt;a href=&quot;http://martinfowler.com/bliki/CQRS.html&quot;&gt;CQRS&lt;/a&gt;
in &lt;a href=&quot;http://www.playframework.com/&quot;&gt;Play&lt;/a&gt;, but there was a fairly long question and answer section about Play as well.
I couldn&amp;rsquo;t go into detail on some of the answers and missed some others, so I&amp;rsquo;ll fill in the details here.&lt;/p&gt;

&lt;h2&gt;Video&lt;/h2&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/s2GOZpzBwVE?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;h2&gt;Slides&lt;/h2&gt;

&lt;iframe src=&quot;http://www.slideshare.net/slideshow/embed_code/19312123&quot; width=&quot;597&quot; height=&quot;486&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px&quot; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;


&lt;h2&gt;Core API&lt;/h2&gt;

&lt;p&gt;The core API is &lt;a href=&quot;http://www.playframework.com/documentation/2.1.1/ScalaActions&quot;&gt;Action&lt;/a&gt;, which take in a
&lt;code&gt;Request&lt;/code&gt; and return a &lt;code&gt;Result&lt;/code&gt;.  The &lt;code&gt;Request&lt;/code&gt; is immutable, but you can
&lt;a href=&quot;http://stackoverflow.com/questions/9629250/how-to-avoid-passing-parameters-everywhere-in-play2&quot;&gt;wrap it&lt;/a&gt; with extra
information, which you&amp;rsquo;ll typically do with &lt;a href=&quot;http://www.playframework.com/documentation/2.1.1/ScalaActionsComposition&quot;&gt;action composition&lt;/a&gt;.
2.1.1 introduced EssentialAction, which uses &lt;code&gt;(RequestHeader =&amp;gt; Iteratee[Array[Byte], Result])&lt;/code&gt; instead of Action&amp;rsquo;s
&lt;code&gt;(Request =&amp;gt; Result)&lt;/code&gt; and makes building &lt;code&gt;Filters&lt;/code&gt; easier.&lt;/p&gt;

&lt;p&gt;Again, Play&amp;rsquo;s core is simple.  &lt;a href=&quot;http://sadache.tumblr%0A.com/post/26258782102/bitsbout-play2-architecture&quot;&gt;About as simple as you can get&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Streaming&lt;/h2&gt;

&lt;p&gt;Streaming is handled by &lt;a href=&quot;http://www.playframework.com/documentation/2.1.1/Iteratees&quot;&gt;Iteratees&lt;/a&gt;, which can be a
confusing topic for many people.  There are good writeups
&lt;a href=&quot;http://mandubian.com/2012/08/27/understanding-play2-iteratees-for-normal-humans/&quot;&gt;here&lt;/a&gt;
and &lt;a href=&quot;http://jazzy.id.au/default/2012/11/06/iteratees_for_imperative_programmers.html&quot;&gt;here&lt;/a&gt;.  &lt;a href=&quot;https://github.com/ornicar/lila&quot;&gt;lila&lt;/a&gt;
is the best application to look at for streaming, especially for sockets and hubs.&lt;/p&gt;

&lt;p&gt;Having good streaming primitives is something that I didn&amp;rsquo;t get into that much in the talk, but is still vitally
important to &amp;ldquo;&lt;a href=&quot;http://arstechnica.com/business/2012/05/say-hello-to-the-real-real-time-web/&quot;&gt;real time web&lt;/a&gt;&amp;rdquo; stuff.&lt;/p&gt;

&lt;h2&gt;Filters&lt;/h2&gt;

&lt;p&gt;If you want to do anything that you&amp;rsquo;d consider as part of a &amp;ldquo;servlet pipeline&amp;rdquo;, you use &lt;a href=&quot;http://jazzy.id.au/default/2013/02/16/understanding_the_play_filter_api.html&quot;&gt;Filters&lt;/a&gt;, which are designed to work with streams.&lt;/p&gt;

&lt;p&gt;An example of a good Filter is to automatically uncompress an asset &amp;mdash; here&amp;rsquo;s an example that uses an Enumeratee:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;GunzipFilter&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EssentialFilter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;EssentialAction&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EssentialAction&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RequestHeader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;headers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Content-Encoding&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exists&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&amp;quot;gzip&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;nc&quot;&gt;Gzip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;gunzip&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;        &lt;span class=&quot;n&quot;&gt;next&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Note that this only does uncompression: Automatic streaming gzip compression of templates is &lt;a href=&quot;https://github.com/playframework/Play20/commit/0023ab6815c0f9db4836314b0696889a0b8c6055&quot;&gt;not available&lt;/a&gt; &amp;ldquo;out of the box&amp;rdquo; in 2.1.2, but it should be available in Play 2.2.&lt;/p&gt;

&lt;h2&gt;Templating&lt;/h2&gt;

&lt;p&gt;Play comes packaged with its own template language, &lt;a href=&quot;https://github.com/spray/twirl&quot;&gt;Twirl&lt;/a&gt;, but you&amp;rsquo;re not required to
use it.  There is an integration into &lt;a href=&quot;https://github.com/adetante/play2-scalate&quot;&gt;Scalate&lt;/a&gt; that gives you Mustache,
Jade, Scaml and SSP.  There&amp;rsquo;s also an &lt;a href=&quot;https://github.com/guillaumebort/play2-freemarker-demo&quot;&gt;example project&lt;/a&gt; that
shows how to integrate Play with Freemarker.&lt;/p&gt;

&lt;p&gt;One thing that Play doesn&amp;rsquo;t address directly is how to set up a structure for page layouts.  Play provides you with index.scala.html and main.scala.html, but
doesn&amp;rsquo;t provide you with any more structure than that.  If you set up a header and footer and allow for subdirectories to use their own templates, you can minimize the amount of confusion in the views.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s an example in &lt;a href=&quot;https://github.com/wsargent/play20-rememberme/tree/master/app/views/base&quot;&gt;RememberMe&lt;/a&gt;, and this is the approach that &lt;a href=&quot;https://github.com/ornicar/lila&quot;&gt;lila&lt;/a&gt; takes as well.&lt;/p&gt;

&lt;p&gt;Another thing is that Play&amp;rsquo;s default project template is intentionally minimal.  If you use Backbone and HTML5 templates,
then a custom &lt;a href=&quot;https://github.com/n8han/giter8&quot;&gt;giter8&lt;/a&gt; template like
&lt;a href=&quot;http://prihoda.net/blog/2012/6/17/play-scala-template-with-html5-boilerplate-and-backbonejs.html&quot;&gt;mprihoda/play-scala&lt;/a&gt; may suit you better.&lt;/p&gt;

&lt;h2&gt;JSON&lt;/h2&gt;

&lt;p&gt;Play&amp;rsquo;s JSON API is very well done, and is a great way to pass data around without getting into the weeds or having to
resort to XML.  It goes very well with case classes.&lt;/p&gt;

&lt;p&gt;The documentation isn&amp;rsquo;t bad, but Pascal Voitot (the author of play-json) has a series of blog posts that go
the extra mile: &lt;a href=&quot;http://mandubian%0A.com/2012/09/08/unveiling-play-2-dot-1-json-api-part1-jspath-reads%0A-combinators/&quot;&gt;reading JSON with JsPath&lt;/a&gt;, &lt;a href=&quot;http://mandubian%0A.com/2012/10/01/unveiling-play-2-dot-1-json-api-part2-writes-format-combinators/&quot;&gt;writing JSON formats&lt;/a&gt;,
&lt;a href=&quot;http://mandubian.com/2012/10/29/unveiling-play-2-dot-1-json-api-part3-json-transformers/&quot;&gt;transforming JSON&lt;/a&gt;, and
even defining &lt;a href=&quot;http://mandubian.com/2012/11/11/JSON-inception/&quot;&gt;JSON macros&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Forms&lt;/h2&gt;

&lt;p&gt;Form handling is one of those things that is never intuitive for me.  The documentation helps, but really if you want to know how to do validation, using the &lt;a href=&quot;https://github.com/playframework/Play20/tree/master/samples/scala/forms&quot;&gt;sample forms application&lt;/a&gt; is the best way to pick things up.  There are many useful nuggets that aren&amp;rsquo;t explicitly discussed in the documentation.  In particular, the ability to make custom constraints is &lt;a href=&quot;https://github.com/wsargent/play20-rememberme/blob/master/app/controllers/BaseConstraints.scala&quot;&gt;extremely useful&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Routing&lt;/h2&gt;

&lt;p&gt;There&amp;rsquo;s only one routing API replacement that I know of, &lt;a href=&quot;https://github.com/teamon/play-navigator&quot;&gt;Play Navigator&lt;/a&gt;, a
routing DSL for &lt;a href=&quot;http://codetunes.com/2012/scala-dsl-tutorial-writing-web-framework-router&quot;&gt;REST services&lt;/a&gt;.  However, you can use
custom data types in the routing table using &lt;a href=&quot;http://www.playframework.com/documentation/api/2.1.0/scala/index.html#play.api.mvc.QueryStringBindable&quot;&gt;QueryStringBindable&lt;/a&gt; and &lt;a href=&quot;http://julien.richard-foy.fr/blog/2012/04/09/how-to-implement-a-custom-pathbindable-with-play-2/&quot;&gt;PathBindable&lt;/a&gt;, and save yourself some &amp;ldquo;string2foo&amp;rdquo; conversion.&lt;/p&gt;

&lt;h2&gt;Asynchronous Operation&lt;/h2&gt;

&lt;p&gt;Talking about Akka (and the other async code) in Play is tricky for a couple of reasons.&lt;/p&gt;

&lt;p&gt;The first reason is that &amp;ldquo;async&amp;rdquo; involves a number of different concepts, all of which are complex and worthy of blog posts in themselves.  Sadek Drobi gives a nice
&lt;a href=&quot;http://sadache.tumblr.com/post/42351000773/async-reactive-nonblocking-threads-futures-executioncont&quot;&gt;overview&lt;/a&gt;,
and there&amp;rsquo;s an exhaustive &lt;a href=&quot;https://groups.google.com/d/topic/play-framework-dev/30MqnKDp0Fs/discussion&quot;&gt;mailing list discussion&lt;/a&gt; about the asynchronous code in Play works.&lt;/p&gt;

&lt;p&gt;The second bit of trickiness is that Play 2.0 and Play 2.1 async features do not work in the quite the same way.&lt;/p&gt;

&lt;p&gt;Play 2.0 uses Akka for &lt;a href=&quot;http://www.playframework.com/documentation/2.0/AkkaCore&quot;&gt;almost everything&lt;/a&gt; internally.&lt;/p&gt;

&lt;p&gt;Play 2.1 does &lt;em&gt;not&lt;/em&gt; use Akka to handle incoming requests, or iteratees, or internal code.  It uses &lt;code&gt;scala.concurrent.Future&lt;/code&gt; instead with its own &lt;a href=&quot;http://www.playframework.com/documentation/2.1.0/ThreadPools&quot;&gt;thread pools&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Play 2.1 also uses a default thread pool, which &lt;em&gt;is&lt;/em&gt; Akka backed &amp;mdash; &lt;code&gt;ActorSystem(&quot;play&quot;)&lt;/code&gt; &amp;mdash;
and is used for the application code, i.e. the stuff inside &lt;code&gt;Action&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is important, because blog posts like James Ward&amp;rsquo;s &lt;a href=&quot;http://www.jamesward.com/2012/06/25/optimizing-play-2-for-database-driven-apps&quot;&gt;Optimizing Play 2 for Database Driven Apps&lt;/a&gt; are &lt;em&gt;only&lt;/em&gt; applicable to Play 2.0,
not 2.1.  For 2.1, use the &lt;a href=&quot;http://www.playframework.com/documentation/2.1.0/ThreadPools&quot;&gt;thread pools&lt;/a&gt; documentation.&lt;/p&gt;

&lt;p&gt;In addition to the &amp;ldquo;play&amp;rdquo; actor system, there&amp;rsquo;s a Play Akka plugin.  The Akka plugin is actually packaged with
Play itself, and you can find it under &lt;code&gt;play.api.libs.concurrent.Akka&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, if Play already uses Akka under the hood, then why define an Akka plugin?&lt;/p&gt;

&lt;p&gt;I believe it&amp;rsquo;s because the Akka plugin defines a distinct &lt;code&gt;ActorSystem(&quot;application&quot;)&lt;/code&gt; that can be used for backend
tasks like sending email, and can be configured without impacting the &amp;ldquo;play&amp;rdquo; ActorSystem.  The Akka plugin provides a
useful default and enforces seperation between Play&amp;rsquo;s actors and the application&amp;rsquo;s actors.&lt;/p&gt;

&lt;h2&gt;CQRS&lt;/h2&gt;

&lt;p&gt;Given that most of the CQRS talks I&amp;rsquo;ve read have been from the enterprise perspective, it was nice to talk about CQRS
in the context of functional programming and statelessness.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Message_passing&quot;&gt;Message passing&lt;/a&gt;
is something that is typically mentioned in inter process communication, or in message oriented middleware.
Akka &amp;mdash; a message passing architecture on the thread level &amp;mdash; allows us to build &amp;ldquo;zero coupling&amp;rdquo; systems
.  As message passing patterns, CQRS and DDD are a good set of idioms to think about domain logic together,
especially since they already assume eventual consistency and indeterminate time.&lt;/p&gt;

&lt;h2&gt;Authentication&lt;/h2&gt;

&lt;p&gt;If you&amp;rsquo;re using Scala, there are two good authentication options, &lt;a href=&quot;https://github.com/wsargent/play20-rememberme&quot;&gt;RememberMe&lt;/a&gt;
(ahem) and &lt;a href=&quot;https://github.com/jaliss/securesocial&quot;&gt;SecureSocial&lt;/a&gt;.  SecureSocial has better documentation and has been
around longer, but RememberMe has better security resistance to some attacks.  I&amp;rsquo;m working to integrate RememberMe&amp;rsquo;s
functionality into SecureSocial, but you&amp;rsquo;ll want to check out both of them.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s also a pure Java authentication option: &lt;a href=&quot;http://joscha.github.io/play-authenticate/&quot;&gt;Play Authenticate&lt;/a&gt;.  I haven&amp;rsquo;t used this, but the code looks reasonable.&lt;/p&gt;

&lt;p&gt;If you&amp;rsquo;d rather go it alone or need a basic starter application, you may find &lt;a href=&quot;https://github.com/yesnault/Play20StartApp&quot;&gt;Play20StartApp&lt;/a&gt; useful (password reset, account confirmation, etc.)&lt;/p&gt;

&lt;h2&gt;Authorization&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/schaloner/deadbolt-2&quot;&gt;Deadbolt 2&lt;/a&gt; is the best known authorization framework.  You can use things like &lt;a href=&quot;https://github.com/wsargent/play-shiro/&quot;&gt;Shiro&lt;/a&gt;, but you&amp;rsquo;re better off with something specifically designed for Play.&lt;/p&gt;

&lt;h2&gt;Security&lt;/h2&gt;

&lt;p&gt;Play does fairly well on security compared to other frameworks.  For example, it will set a &lt;a href=&quot;https://github.com/playframework/Play20/pull/336&quot;&gt;CORS header&lt;/a&gt; to protect against &lt;a href=&quot;http://webapp-hardening.heroku.com/clickjacking&quot;&gt;clickjacking&lt;/a&gt;, will sign the session cookie with an HMAC to protect against &lt;a href=&quot;http://webapp-hardening.heroku.com/broken_auth&quot;&gt;broken authentication&lt;/a&gt;, supports SSL, etc.&lt;/p&gt;

&lt;p&gt;However, there are some things that Play doesn&amp;rsquo;t do.&lt;/p&gt;

&lt;p&gt;Play doesn&amp;rsquo;t encrypt the session cookie, so you shouldn&amp;rsquo;t store any sensitive information in there.&lt;/p&gt;

&lt;p&gt;Play won&amp;rsquo;t protect you from &lt;a href=&quot;http://en.wikipedia.org/wiki/Replay_attack&quot;&gt;replay attacks&lt;/a&gt;, as Play is stateless by default.  You can specify a nonce or request counter to counteract this, and &lt;a href=&quot;https://github.com/wsargent/play20-rememberme&quot;&gt;RememberMe&lt;/a&gt; uses a &lt;a href=&quot;http://atyantik.com/blog/improved-persistent-login-cookie-best-practice/&quot;&gt;token based&lt;/a&gt; approach for persistent login cookies.&lt;/p&gt;

&lt;p&gt;Play won&amp;rsquo;t protect you against &lt;a href=&quot;http://www.troyhunt.com/2010/05/owasp-top-10-for-net-developers-part-1.html&quot;&gt;injection attacks&lt;/a&gt;.  You can specify &lt;a href=&quot;http://tersesystems.com/2012/12/16/problems-scala-fixes&quot;&gt;value classes&lt;/a&gt; to validate your input against raw strings.&lt;/p&gt;

&lt;p&gt;Play won&amp;rsquo;t protect you against &lt;a href=&quot;http://webapp-hardening.heroku.com/security_misconfig&quot;&gt;security misconfiguration&lt;/a&gt;.  You should have a &lt;a href=&quot;http://webdevchecklist.com/play-framework/&quot;&gt;release checklist&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Play won&amp;rsquo;t protect you from &lt;a href=&quot;http://webapp-hardening.heroku.com/insecure_crypto&quot;&gt;insecure cryptography practices&lt;/a&gt;.  Education helps, but there&amp;rsquo;s a lot of misinformation out there as well; watch &lt;a href=&quot;https://www.youtube.com/watch?v=ySQl0NhW1J0&quot;&gt;this video&lt;/a&gt; (and &lt;a href=&quot;http://rdist.root.org/2009/06/10/when-crypto-attacks-slides-posted/&quot;&gt;slides&lt;/a&gt;) and be wary of things you read on Stack Overflow and Hacker News.&lt;/p&gt;

&lt;p&gt;Play won&amp;rsquo;t protect you from &lt;a href=&quot;http://webapp-hardening.heroku.com/unrestricted_access&quot;&gt;failure to restrict URL access&lt;/a&gt;; that&amp;rsquo;s up to the authorization framework.&lt;/p&gt;

&lt;p&gt;Play does have &lt;a href=&quot;http://webapp-hardening.heroku.com/csrf&quot;&gt;cross site request forgery&lt;/a&gt;
protection, but it will only be effective if you enable the filter and explicitly pass the CSRF helper function in through
&lt;a href=&quot;http://nickcarroll.me/2013/02/11/protect-your-play-application-with-the-csrf-filter/&quot;&gt;every single form&lt;/a&gt;.  There is an &lt;a href=&quot;https://github.com/orefalo/play2-authenticitytoken&quot;&gt;authenticity token&lt;/a&gt; approach as well, though I haven&amp;rsquo;t used it.&lt;/p&gt;

&lt;p&gt;Most importantly, Play won&amp;rsquo;t tell you about how web application security fails.  I recommend &lt;a href=&quot;http://www.amazon.com/Tangled-Web-Securing-Modern-Applications/dp/1593273886&quot;&gt;The Tangled Web&lt;/a&gt; as an excellent overview on how web applications are stitched together out of different technologies, and how to secure them.&lt;/p&gt;

&lt;h2&gt;Logging&lt;/h2&gt;

&lt;p&gt;The underlying logger for Play is &lt;a href=&quot;http://logback.qos.ch/&quot;&gt;Logback&lt;/a&gt;. Logback is one of the few hardcoded dependencies
 in Play, which has caused some &lt;a href=&quot;https://github.com/typesafehub/play2-mini/issues/7&quot;&gt;issues&lt;/a&gt;.  Fortunately, Play uses
Logback through the SLF4J logging API, but there&amp;rsquo;s no option built into Play to allow Logback to be swapped out easily.
There are reports of people swapping out Logback for &lt;a href=&quot;http://osdir.com/ml/play-framework/2013-02/msg00881.html&quot;&gt;other logging frameworks&lt;/a&gt;, but I haven&amp;rsquo;t tried them.&lt;/p&gt;

&lt;p&gt;There have also been issues with the logging configuration conflicting in places or being unclear.  One thing that has
tripped people up repeatedly is that all the logging configuration
&lt;a href=&quot;http://blog.mograbi.info/2013/03/setting-logback-with-playframework-20.html&quot;&gt;must be done in one place&lt;/a&gt;.  You can&amp;rsquo;t
have some logging configuration in &lt;code&gt;application.conf&lt;/code&gt; and some configuration in logger.xml.&lt;/p&gt;

&lt;p&gt;While Play uses SLF4J under the hood, it doesn&amp;rsquo;t expose SLF4J functionality in &lt;code&gt;play.api.Logger&lt;/code&gt;.  In fact,
there are only two method signatures for logging:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This doesn&amp;rsquo;t really cover the way I like to log, and it doesn&amp;rsquo;t provide even the features that are available in
SLF4J, such as parameterized logging.  My own answer was to ignore the Play logging API entirely and write a
Logging wrapper directly against SLF4J (with
&lt;a href=&quot;http://debasishg.blogspot.com/2009/09/side-effects-with-kestrel-in-scala.html&quot;&gt;kestrel combinators&lt;/a&gt;, natch), but you
may want to use something out of the box.&lt;/p&gt;

&lt;p&gt;For example, &lt;a href=&quot;https://github.com/typesafehub/scalalogging&quot;&gt;Typesafe Logging&lt;/a&gt;, uses SLF4J and provides you with this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AnyRef*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;marker&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Marker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;marker&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Marker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;AnyRef*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;marker&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Marker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Or you can use &lt;a href=&quot;https://github.com/dln/loglady/&quot;&gt;loglady&lt;/a&gt;, which uses the Python API style with printf syntax:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Any*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thrown&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Throwable&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Any*&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;WAR packaging&lt;/h2&gt;

&lt;p&gt;I said in the Q&amp;amp;A that I didn&amp;rsquo;t think you could package Play 2 applications as WAR files.  Well, it turns out that
there is a &lt;a href=&quot;https://github.com/dlecan/play2-war-plugin&quot;&gt;plugin available&lt;/a&gt;, and it works with Servlet 3.0 and 2.5
containers (Tomcat 6/7, Jetty 7/8/9, JBoss 5/6/7, etc).  You may need to
&lt;a href=&quot;https://github.com/dlecan/redirect-playlogger&quot;&gt;tweak the logger&lt;/a&gt; to work in the container correctly.&lt;/p&gt;

&lt;p&gt;I don&amp;rsquo;t know how Play&amp;rsquo;s performance is affected by running inside a servlet container; let me know if it works for you.&lt;/p&gt;

&lt;h2&gt;Asset Packaging&lt;/h2&gt;

&lt;p&gt;Javascript assets in Play are minified using &lt;a href=&quot;http://www.playframework.com/documentation/2.1.x/AssetsGoogleClosureCompiler&quot;&gt;Google Closure&lt;/a&gt; &amp;mdash; this happens automatically on &lt;code&gt;play dist&lt;/code&gt;.  They also can be gzipped using a &lt;a href=&quot;https://groups.google.com/forum/#!msg/play-framework/dSJEKhYiMDE/u-N50plw6hwJ&quot;&gt;custom SBT script&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This makes a good enough solution for most people.  If you are really intent on minimizing your asset overhead, you should consider putting your assets on a static file server backed by HAProxy, or putting them on CDN.&lt;/p&gt;

&lt;h2&gt;Email&lt;/h2&gt;

&lt;p&gt;Email is one of those things that I think should be divorced as much as possible from Play.  It&amp;rsquo;s backend and async by
nature, and this makes it something that is best handled through Akka.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://blog.eigengo.com/blog_posts/akka-extras-email&quot;&gt;akka-email&lt;/a&gt; is available on &lt;a href=&quot;https://github.com/eigengo/akka-extras/tree/master/javamail&quot;&gt;Github&lt;/a&gt; and
gives you a starting place to build up a message passing infrastructure for email.&lt;/p&gt;

&lt;h2&gt;Metrics&lt;/h2&gt;

&lt;p&gt;Instrumenting applications is important.  Sadly, every metrics solution has its own API, so you can&amp;rsquo;t easily switch between them.  However, there&amp;rsquo;s no shortage of options.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.newrelic.com/2013/06/05/play-2/&quot;&gt;New Relic&lt;/a&gt; recently came out with support for Play 2.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/twitter/ostrich&quot;&gt;Ostrich&lt;/a&gt;, the Twitter metrics library.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://metrics.codahale.com/&quot;&gt;Metrics&lt;/a&gt;, with the &lt;a href=&quot;https://github.com/erikvanoosten/metrics-scala&quot;&gt;metrics-scala&lt;/a&gt; from
Erik Van Oosten, cross-compiled for multiple versions.  This is what I use.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Ticketfly/pillage&quot;&gt;Pillage&lt;/a&gt;, which has a Scala option (I have not tried this).&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/typesafehub/play-plugins/tree/master/statsd&quot;&gt;statsd&lt;/a&gt; module for Play 2.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The
&lt;a href=&quot;http://typesafe.com/products/console&quot;&gt;Typesafe Console&lt;/a&gt; is the best monitoring tool to use if you are using Akka, but that depends on having a &lt;a href=&quot;http://typesafe.com/products/typesafe-subscription&quot;&gt;Typesafe subscription&lt;/a&gt; if you want to use it in production.&lt;/p&gt;

&lt;h2&gt;Load and Stress Testing&lt;/h2&gt;

&lt;p&gt;Determining a load plan is hard, and involves some amount of educated guessing.  Fortunately, most applications simply don&amp;rsquo;t get that much load, even ones you&amp;rsquo;d &lt;a href=&quot;https://vimeo.com/12814529&quot;&gt;think would be busy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://gatling-tool.org/&quot;&gt;Gatling&lt;/a&gt; and &lt;a href=&quot;https://github.com/wg/wrk&quot;&gt;wrk&lt;/a&gt; are good ways of stressing a system, but they don&amp;rsquo;t reflect normal user behavior.  Apache JMeter is very good at modelling random user behavior, but is clunky.  A good and arguably the most realistic load test is to hire a couple of hundred users from Mechanical Turk to pound on the site at once, but this may not be very convenient.&lt;/p&gt;

&lt;h2&gt;Deployment&lt;/h2&gt;

&lt;p&gt;There are a number of different ways to deploy Play projects.  Using &lt;code&gt;play dist&lt;/code&gt; gets you most of the way, but you may want to deploy with &lt;a href=&quot;http://www.perevillega.com/post/2013/04/01/28/using-ansible-to-deploy-play-framework-apps-in-ec2-instances#.UYBlNyt4YkZ&quot;&gt;Ansible&lt;/a&gt; or &lt;a href=&quot;https://github.com/njin-fr/application_play2&quot;&gt;Chef&lt;/a&gt; or &lt;a href=&quot;https://groups.google.com/d/msg/play-framework/iIbKXtBlo9k/mjxp5ZWYZ6AJ&quot;&gt;Fabric&lt;/a&gt;.  Or you can use &lt;a href=&quot;http://agileand.me/content/deploying-play-application-rackspace-cloud-vps&quot;&gt;upstart&lt;/a&gt; or even &lt;a href=&quot;http://justinholmes.co.uk/50cbc7281223262b001ca08e&quot;&gt;git hooks&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you just want to push changes to a staging server as they happen, you can do this with &lt;code&gt;rsync -avz &#8211;delete -e ssh $deployed_code staging:/opt/play-app&lt;/code&gt;, although this isn&amp;rsquo;t so great for production.&lt;/p&gt;

&lt;h2&gt;Java Support&lt;/h2&gt;

&lt;p&gt;The Java and Scala APIs are very similar.  However, there are a couple of notable differences, which come out of Java&amp;rsquo;s lack of closure support:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Java API does not support Iteratees.&lt;/li&gt;
&lt;li&gt;The Java API does not have an implicit execution context.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The &lt;code&gt;play.libs.F&lt;/code&gt; library goes a fair way to providing Scala&amp;rsquo;s functional programming constructs in Java.&lt;/p&gt;

&lt;h2&gt;More?&lt;/h2&gt;

&lt;p&gt;If you have suggestions or want to point something out, please email me at &lt;a href=&quot;mailto:will.sargent@gmail.com&quot; title=&quot;Play in Practice&quot;&gt;will.sargent@gmail.com&lt;/a&gt;, and I&amp;rsquo;ll fill out this post with more details.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Error Handling in Scala</title>
      <link>http://tersesystems.com/2012/12/27/error-handling-in-scala</link>
      <pubDate>Thu, 27 Dec 2012 15:38:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/12/27/error-handling-in-scala</guid>
      <description>&lt;p&gt;The &lt;a href=&quot;http://tersesystems.com/2012/12/16/problems-scala-fixes&quot;&gt;previous post&lt;/a&gt; was mostly about programming &amp;ldquo;in the small&amp;rdquo; where the primary concern is making sure the body of code in the method does what it&amp;rsquo;s supposed to and doesn&amp;rsquo;t do anything else.  This blog post is about what to do when code doesn&amp;rsquo;t work &amp;mdash; how Scala signals failure and how to recover from it, based on &lt;a href=&quot;http://aboutwhichmorelater.tumblr.com/post/30409572482/scala-util-try&quot;&gt;some&lt;/a&gt; &lt;a href=&quot;http://grokbase.com/t/gg/scala-debate/128ssy8tkd/design-improvement-for-success-failure/128svrykfq#128svrykfq&quot;&gt;insightful&lt;/a&gt; &lt;a href=&quot;http://grokbase.com/t/gg/scala-user/129w1rkfar/more-about-try-catching-handling&quot;&gt;discussions&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, let&amp;rsquo;s define what we mean by failure.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Unexpected internal failure&lt;/em&gt;: the operation fails as the result of an unfulfilled expectation, such as a null pointer reference, violated assertions, or simply bad state.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Expected internal failure&lt;/em&gt;: the operation fails deliberately as a result of internal state, i.e. a blacklist or &lt;a href=&quot;https://github.com/erikvanoosten/sentries&quot;&gt;circuit breaker&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Expected external failure&lt;/em&gt;: the operation fails because it is told to process some raw input, and will fail if the raw input cannot be processed.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Unexpected external failure&lt;/em&gt;: the operation fails because a resource that the system depends on is not there: there&amp;rsquo;s a loose file handle, the database connection fails, or the network is down.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Java has one explicit construct for handling failure: &lt;code&gt;Exception&lt;/code&gt;.  There&amp;rsquo;s some difference of usage in Java throughout the years &amp;mdash; IO and JDBC use checked exceptions throughout, while other API like &lt;code&gt;org.w3c.dom&lt;/code&gt; rely on unchecked exceptions.  According to &lt;a href=&quot;http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882&quot;&gt;Clean Code&lt;/a&gt;, the best practice is to use unchecked exceptions in preference to checked exceptions, but there&amp;rsquo;s &lt;a href=&quot;http://www.ibm.com/developerworks/java/library/j-jtp05254/index.html&quot;&gt;still debate&lt;/a&gt; over whether unchecked exceptions are always appropriate.&lt;/p&gt;

&lt;h2&gt;Exceptions&lt;/h2&gt;

&lt;p&gt;Scala makes &amp;ldquo;checked vs unchecked&amp;rdquo; very simple: it doesn&amp;rsquo;t have checked exceptions.  All exceptions are unchecked in Scala, even &lt;code&gt;SQLException&lt;/code&gt; and &lt;code&gt;IOException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The way you catch an exception in Scala is by defining a &lt;code&gt;PartialFunction&lt;/code&gt; on it:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BufferedReader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileReader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continually&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takeWhile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;nc&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;IOException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Or you can use &lt;a href=&quot;http://www.scala-lang.org/api/current/scala/util/control/Exception$.html&quot;&gt;control.Exception&lt;/a&gt;, which provides &lt;a href=&quot;http://stackoverflow.com/questions/2903481/using-scala-util-control-exception&quot;&gt;some interesting building blocks&lt;/a&gt;.  The docs say &amp;ldquo;focuses on composing exception handlers&amp;rdquo;, which means that this set of classes supplies most of the logic you would put into a catch or finally block.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;nc&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;handling&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;RuntimeException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;classOf&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;IOException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;by&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apply&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IOException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;foo&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Using the &lt;code&gt;control.Exception&lt;/code&gt; methods is fun and you can string together exception handling logic to create &lt;a href=&quot;http://stackoverflow.com/a/1646480/5266&quot;&gt;automatic resource management&lt;/a&gt;, or an automated exception logger.  On the other hand, it&amp;rsquo;s full of sharp things like &lt;code&gt;allCatch&lt;/code&gt;.  Leave it alone unless you really need it.&lt;/p&gt;

&lt;p&gt;Another important caveat is to make sure that you are catching the exceptions that you think you&amp;rsquo;re catching.  A common mistake (mentioned in &lt;a href=&quot;http://twitter.github.io/effectivescala/#Error%20handling-Handling%20exceptions&quot;&gt;Effective Scala&lt;/a&gt;) is to use a default case in the partial function:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This will catch absolutely everything, including OutOfMemoryError and other errors that would normally terminate the JVM.&lt;/p&gt;

&lt;p&gt;If you want to catch &amp;ldquo;everything&amp;rdquo; that would normally happen, then use &lt;a href=&quot;http://www.scala-lang.org/api/2.10.1/index.html#scala.util.control.NonFatal$&quot;&gt;&lt;code&gt;NonFatal&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;scala.util.control.NonFatal&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;operation&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;NonFatal&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;exc&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Exceptions don&amp;rsquo;t get mentioned very much in Scala, but they&amp;rsquo;re still the bedrock for dealing with unexpected failure.  For unexpected internal failure, there&amp;rsquo;s a set of &lt;a href=&quot;http://daily-scala.blogspot.com/2010/03/assert-require-assume.html&quot;&gt;assertion methods&lt;/a&gt; called &lt;code&gt;require&lt;/code&gt;, &lt;code&gt;assert&lt;/code&gt;, and &lt;code&gt;assume&lt;/code&gt;, which all use throwables under the hood.&lt;/p&gt;

&lt;h2&gt;Option&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.scala-lang.org/api/current/scala/Option.html&quot;&gt;Option&lt;/a&gt; represents optional values, returning an instance of &lt;code&gt;Some(A)&lt;/code&gt; if A exists, or &lt;code&gt;None&lt;/code&gt; if it does not.  It&amp;rsquo;s ubiquitous in Scala code, to the point where it fades into invisibility.  The &lt;a href=&quot;http://blog.tmorris.net/scalaoption-cheat-sheet/&quot;&gt;cheat sheet&lt;/a&gt; is the best way to get a handle on it.&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s almost impossible to use &lt;code&gt;Option&lt;/code&gt; incorrectly, but there is one caveat: &lt;code&gt;Some(null)&lt;/code&gt; is valid.  If you have code that returns null, wrap it in &lt;code&gt;Option()&lt;/code&gt; to convert it:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;optionResult&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// optionResult is None.&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;Either&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.scala-lang.org/api/rc/index.html#scala.util.Either&quot;&gt;Either&lt;/a&gt; is a disjoint union construct.  It returns either an instance of &lt;code&gt;Left[L]&lt;/code&gt; or an instance of &lt;code&gt;Right[R]&lt;/code&gt;.  It&amp;rsquo;s commonly used for error handling, where by convention &lt;code&gt;Left&lt;/code&gt; is used to represent failure and &lt;code&gt;Right&lt;/code&gt; is used to represent success.  It&amp;rsquo;s perfect for dealing with expected external failures such as parsing or validation.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FailResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reason&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Either&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FailResult&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;StringTokenizer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;countTokens&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;nc&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;nextToken&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;nc&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;FailResult&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Could not parse string: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&lt;code&gt;Either&lt;/code&gt; is like &lt;code&gt;Option&lt;/code&gt; in that it makes an abstract idea explicit by introducing an intermediate object.  Unlike &lt;code&gt;Option&lt;/code&gt;, it does not have a &lt;code&gt;flatMap&lt;/code&gt; method, so you can&amp;rsquo;t use it in &lt;a href=&quot;http://www.scala-lang.org/node/111&quot;&gt;for comprehensions&lt;/a&gt; &amp;mdash; not safely at any rate. You can use a left or right projection if you&amp;rsquo;re not interested in handling failure:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rightFoo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;outputFoo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outputFoo&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;More typically, you&amp;rsquo;ll use &lt;code&gt;fold&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;parse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;success&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&#8230;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You&amp;rsquo;re not limited to using &lt;code&gt;Either&lt;/code&gt; for parsing or validation, of course.  You can use it for &lt;a href=&quot;http://martinfowler.com/bliki/CQRS.html&quot;&gt;CQRS&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserFault&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;UserCreatedEvent&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;createUser&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Either&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;UserFault&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;UserCreatedEvent&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;or arbitary binary choices:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;whatShape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;shape&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Shape&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Either&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Square&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;Circle&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&lt;code&gt;Either&lt;/code&gt; is powerful, but it&amp;rsquo;s trickier than &lt;code&gt;Option&lt;/code&gt;.  In particular, it can lead to &lt;a href=&quot;http://stackoverflow.com/questions/13105020/calling-external-services-in-scala-code-with-dependencies&quot;&gt;deeply nested code&lt;/a&gt;.  It can also be misunderstood.  Take the following Java lookup method:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;java&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;kd&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Foo&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;throws&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;FooException&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// throw if not found or db exception&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Scala has &lt;code&gt;Option&lt;/code&gt;, so we can use that.  But what if the database goes down?  Using the error reporting convention of &lt;code&gt;Either&lt;/code&gt; might suggest the following:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Either&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FooException&lt;/span&gt;,&lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;But this is awkward.  If you return &lt;code&gt;Either&lt;/code&gt; because something might fail unexpectedly, then immediately half your API becomes littered with &lt;code&gt;Either[Throwable, T]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ah, but what if you&amp;rsquo;re modifying a new object?&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inputFoo&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Either&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;FooException&lt;/span&gt;,&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;If you&amp;rsquo;re dealing with expected failure and there&amp;rsquo;s good odds that the operation will fail, then returning &lt;code&gt;Either&lt;/code&gt; is fine: create a case class representing failure &lt;code&gt;FailResult&lt;/code&gt; and use &lt;code&gt;Either[FailResult,Foo]&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Don&amp;rsquo;t return exceptions through Either.  If you want a construct to return exceptions, use Try.&lt;/p&gt;

&lt;h2&gt;Try&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.scala-lang.org/api/rc/index.html#scala.util.Try&quot;&gt;Try&lt;/a&gt; is similar to &lt;code&gt;Either&lt;/code&gt;, but instead of returning any class in a &lt;code&gt;Left&lt;/code&gt; or &lt;code&gt;Right&lt;/code&gt; wrapper, it returns &lt;code&gt;Failure[Throwable]&lt;/code&gt; or &lt;code&gt;Success[T]&lt;/code&gt;.  It&amp;rsquo;s an analogue for the try-catch block: it replaces try-catch&amp;rsquo;s stack based error handling with heap based error handling.  Instead of having an exception thrown and having to deal with it immediately in the same thread, it disconnects the error handling and recovery.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Try&lt;/code&gt; can be used in for comprehensions: unlike &lt;code&gt;Either&lt;/code&gt;, it implements &lt;code&gt;flatMap&lt;/code&gt;.  This means you can do the following:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sumTry&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and if there&amp;rsquo;s an exception returned from the first &lt;code&gt;Try&lt;/code&gt;, then the for comprehension will terminate early and return the &lt;code&gt;Failure&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can get access to the exception through pattern matching:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;sumTry&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;thrown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;nc&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Failure: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thrown&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;nc&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Or through &lt;code&gt;failed&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sumTry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isFailure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;thrown&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sumTry&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;failed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&lt;code&gt;Try&lt;/code&gt; will let you recover from exceptions at any point in the chain, so you can defer recovery to the end:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;two&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;recover&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Or &lt;code&gt;recover&lt;/code&gt; in the middle:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recover&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;two&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;There&amp;rsquo;s also a &lt;code&gt;recoverWith&lt;/code&gt; method that will let you swap out a &lt;code&gt;Failure&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sum&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;one&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recoverWith&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;NumberFormatException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;IllegalArgumentException&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Try 1 next time&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;2&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;int1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;int2&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You can mix &lt;code&gt;Either&lt;/code&gt; and &lt;code&gt;Try&lt;/code&gt; together to coerce methods that throw exceptions internally:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;either&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Either&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Integer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parseInt&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Right&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Left&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;FAIL&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;nc&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;either is &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;either&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;fold&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;l&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;l&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;r&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;&lt;code&gt;Try&lt;/code&gt; isn&amp;rsquo;t always appropriate.  If we go back to the first exception example, this is the &lt;code&gt;Try&lt;/code&gt; analogue:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;9&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;10&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;11&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;12&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;13&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;14&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;15&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;BufferedReader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;FileReader&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;file&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;results&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Seq&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Iterator&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;continually&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;readLine&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;takeWhile&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;      &lt;span class=&quot;nc&quot;&gt;Console&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;line&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;close&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;results&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foreach&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;recover&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;IOException&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errorHandler&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;e&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Note the kludge to get around the lack of a &lt;code&gt;finally&lt;/code&gt; block to close the stream.  Victor Klang and Som Snytt suggested using a value class and &lt;code&gt;transform&lt;/code&gt; to pimp &lt;code&gt;Try&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;TryOps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AnyVal&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eventually&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Ignore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;](&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;effect&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Ignore&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;T&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignoring&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;effect&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;transform&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ignoring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ignoring&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eventually&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Oppa Gangnam Style&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Which is cleaner, at the cost of some magic.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Try&lt;/code&gt; was originally invented at Twitter to solve a specific problem: when using Future, the exception may be thrown on a different thread than the caller, and so can&amp;rsquo;t be returned through the stack.  By returning an exception instead of throwing it, the system is able to &lt;a href=&quot;http://grokbase.com/t/gg/scala-user/129w1rkfar/more-about-try-catching-handling#20120930akr7hvezngsw5xhrwztjpx7smq&quot;&gt;reify the bottom type&lt;/a&gt; and let it cross thread boundaries to the calling context.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Try&lt;/code&gt; is new enough that people are still getting comfortable with it.  I think that it&amp;rsquo;s a useful addition when try-catch blocks aren&amp;rsquo;t flexible enough, but it does have a snag: returning &lt;code&gt;Try&lt;/code&gt; in a public API means exceptions must be dealt with by the caller.  Using &lt;code&gt;Try&lt;/code&gt; also implies to the caller that the method has captured all non fatal exceptions itself.  If you&amp;rsquo;re doing this in your trait:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Then &lt;code&gt;Try&lt;/code&gt; should be at the top to ensure exception capture:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Try&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;nc&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Because exceptions must be dealt with the caller, you are placing more trust in the caller to handle or delegate a failure appropriately.  With try-catch blocks, doing nothing means that the exception can pass up the stack to a top level exception handler.  With &lt;code&gt;Try&lt;/code&gt;, exceptions must be either returned or handled by each method in the chain, just like checked exceptions.&lt;/p&gt;

&lt;p&gt;To pass the exception along, use &lt;code&gt;map&lt;/code&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;fooToString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Try&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;modify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;outFoo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;n&quot;&gt;outFoo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;toString&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Or to rethrow the exception up the stack if the return type is Unit:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doStuff&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Unit&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modifiedFoo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;modify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// throws the exception if failure&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;And you want to avoid this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;5&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;6&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;7&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;8&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;modify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;f&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;c1&quot;&gt;// database failure?  don&amp;#39;t care, swallow exception.&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;s&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;o&quot;&gt;&#8230;&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;If you have a system that needs specific error logging or error recovery, it&amp;rsquo;s probably safer to stick to unchecked exceptions.&lt;/p&gt;

&lt;h2&gt;TL;DR&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Throw &lt;code&gt;Exception&lt;/code&gt; to signal unexpected failure in purely functional code.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Option&lt;/code&gt; to return optional values.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Option(possiblyNull)&lt;/code&gt; to avoid instances of &lt;code&gt;Some(null)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Either&lt;/code&gt; to report expected failure.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Try&lt;/code&gt; rather than &lt;code&gt;Either&lt;/code&gt; to return exceptions.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Try&lt;/code&gt; rather than a catch block for handling unexpected failure.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;Try&lt;/code&gt; when working with &lt;code&gt;Future&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Exposing &lt;code&gt;Try&lt;/code&gt; in a public API has a similiar effect as a checked exception.  Consider using exceptions instead.&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      <title>Problems Scala Fixes</title>
      <link>http://tersesystems.com/2012/12/16/problems-scala-fixes</link>
      <pubDate>Sun, 16 Dec 2012 14:47:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/12/16/problems-scala-fixes</guid>
      <description>&lt;p&gt;When I tell people I write code in Scala, a typical question is well, why?  When it comes to writing code, most of my work is straightforward: SQL database on the backend, some architectural glue, CRUD, some exception handling, transactions handlers and an HTML or JSON front end. The tools have changed, but the problems are usually the same: you could get a website up in 5 minutes with &lt;a href=&quot;http://rubyonrails.org/&quot;&gt;Rails&lt;/a&gt; or &lt;a href=&quot;http://dropwizard.codahale.com/&quot;&gt;Dropwizard&lt;/a&gt;.  So why pick Scala?&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s a tough question to answer off the bat. If I point to the language features, it doesn&amp;rsquo;t get the experience across. It&amp;rsquo;s like explaining why I like English by reading from a grammar book.  I don&amp;rsquo;t like Scala because of its functional aspects or its higher kinded type system.  I like Scala because it solves practical, real world problems for me.&lt;/p&gt;

&lt;p&gt;You can think of Scala as Java with all the rough edges filed off, with new features that make it easier to write correct code and harder to create bugs.  Scala is not a purist&amp;rsquo;s language &amp;mdash; it goes out of its way to make it easy for Java programmers to dip their toes in the pool.  You can literally take your Java code and &lt;a href=&quot;http://stackoverflow.com/a/5489232/5266&quot;&gt;hit a key&lt;/a&gt; to create working Scala code.&lt;/p&gt;

&lt;p&gt;So what problems does Scala solve?&lt;/p&gt;

&lt;p&gt;Let&amp;rsquo;s start with the single biggest problem in programming, the design flaw that&amp;rsquo;s caused more errors than anything else combined. &lt;a href=&quot;http://qconlondon.com/london-2009/presentation/Null+References:+The+Billion+Dollar+Mistake&quot;&gt;Null references&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Solving for Null&lt;/h2&gt;

&lt;p&gt;Scala avoids null pointer references by providing a special type called &lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/OptionType&quot;&gt;Option&lt;/a&gt;. Methods that return Option[A] (where A is the type that you want, i.e. Option[String]) will give you an object that is either a wrapper object called &amp;lsquo;Some&amp;rsquo; around your type, or None. There are a number of &lt;a href=&quot;http://blog.tmorris.net/scalaoption-cheat-sheet/&quot;&gt;different ways&lt;/a&gt; you can use Option, but I&amp;rsquo;ll just mention the ones I use most. You can chain Options together in Scala using &lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/ForComprehensions&quot;&gt;for comprehensions&lt;/a&gt;:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;     &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;     &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&amp;#39;bar&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;yield&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;myService&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bar&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;or through a map:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;map&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;or through pattern matching.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Some&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;None&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;debug&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&amp;#39;no&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;foo&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;:-(&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Not only is this easy, but it&amp;rsquo;s also safer. You can flirt with NPE saying myOption.get, but if you do that, you deserve what you get. Not having to deal with NPE is a pleasure.&lt;/p&gt;

&lt;h2&gt;Right Type in the Right Place&lt;/h2&gt;

&lt;p&gt;What&amp;rsquo;s the second biggest problem in programming? It&amp;rsquo;s a huge issue in security and in proving program correctness: &lt;a href=&quot;http://en.wikipedia.org/wiki/Garbage_in,_garbage_out&quot;&gt;invalid, unchecked input&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Take the humble String. The work of manipulating strings is one of the biggest hairballs in programming &amp;mdash; they&amp;rsquo;re pulled in from the environment or embedded in the code itself, and then programs try to figure out how best to deal with them. In one case, a string is displayed to the user and it&amp;rsquo;s done. In another case, an SQL query is embedded as a query parameter on a web page and passed straight through to the database. To the compiler, they&amp;rsquo;re just strings and there is no difference between them.  But there are some types of strings that are suitable to pass to databases, and some which are not. Ideally, we&amp;rsquo;d like to tell the compiler that SQL and query parameters have different types. Scala makes this easy.&lt;/p&gt;

&lt;p&gt;With the &lt;a href=&quot;https://github.com/milessabin/shapeless&quot;&gt;Shapeless library&lt;/a&gt;, you can add distinguishing type information to objects and ensure that you can&amp;rsquo;t pass random input in:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;shapeless.TypeOperators._&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;type&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;SqlString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Newtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;, &lt;span class=&quot;kt&quot;&gt;Any&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;SqlString&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;newtype&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;SELECT * FROM USER&amp;quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;I&amp;rsquo;ve called out strings because it&amp;rsquo;s a good example, but you can also do this for &lt;a href=&quot;http://chemikadze.blogspot.com/2012/11/full-typed-approach-to-data-objects-in.html&quot;&gt;repository IDs&lt;/a&gt;.  No more this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;User&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;When you can have this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;firstName&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;lookup&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;User&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;User&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You can also use this to validate input on the front end. One of the big problems with regular expressions is that when you parse a random string for certain kinds of input, you get back&amp;hellip; more strings. You may be validating a string as a username (no spaces, no odd characters), but what you&amp;rsquo;ve got at the end is a string that says it&amp;rsquo;s a username.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rawInput&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;request&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;params&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;-Symbol&quot;&gt;&amp;#39;foo&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;isUsername&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rawInput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;username&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rawInput&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;You can replace that with something nicer.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Username&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parseUsername&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rawInput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This embeds the constraint in the type itself.  You can design your API to accept Username instead of String, and so enforce a kind of whitelisting.&lt;/p&gt;

&lt;p&gt;Can you do this in Java? Yes, but it&amp;rsquo;s inconvenient. Scala&amp;rsquo;s type system makes it easy for you, and in 2.10 there will be &lt;a href=&quot;http://docs.scala-lang.org/overviews/core/value-classes.html&quot;&gt;Value Classes&lt;/a&gt;, which will provide this functionality in the core language itself.&lt;/p&gt;

&lt;h2&gt;Doing the gruntwork for you&lt;/h2&gt;

&lt;p&gt;The previous example can be improved though. Really, we just want a Username at the end &amp;mdash; we don&amp;rsquo;t want to have to call parseUsername on it. Fortunately, Scala rewards the lazy with &lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/ImplicitConversions&quot;&gt;implicit conversions&lt;/a&gt;.
If you define a method like this and use the implicit keyword:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string2username&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Username&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parseUsername&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;And do this:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;email&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Username&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rawInput&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Then the compiler is smart enough to see that a String isn&amp;rsquo;t an Option[Username], and looks through any implicit methods available to do the conversion.&lt;/p&gt;

&lt;p&gt;There is an element of &amp;lsquo;magic&amp;rsquo; to implicit conversions, especially when you&amp;rsquo;re reading someone else&amp;rsquo;s code and trying to figure out where the conversion is happening. You can find the appropriate implicit through the REPL, or through &lt;a href=&quot;http://devnet.jetbrains.net/message/5265499&quot;&gt;IDEA&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Providing Context&lt;/h2&gt;

&lt;p&gt;There are many cases in programming where everything depends on a &lt;a href=&quot;http://www.corej2eepatterns.com/Patterns2ndEd/ContextObject.htm&quot;&gt;Context object&lt;/a&gt; in some way: either you&amp;rsquo;re using a database connection, or you rely on a security principal, or you&amp;rsquo;re resolving objects from a request or JAAS / LDAP / Spring context&amp;hellip; the list goes on. Whatever it is, it&amp;rsquo;s passed in by the system, it&amp;rsquo;s absolutely essential, and you can count on most of your API to depend on it in some way. A typical Java way to deal with this is to make it part of the parameter list, or try to ignore it and make it a &lt;a href=&quot;http://www.adam-bien.com/roller/abien/entry/how_to_pass_context_with&quot;&gt;ThreadLocal object&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;n&quot;&gt;public&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;void&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doStuff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nc&quot;&gt;Context&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Scala has a better way to deal with this: you can specify &lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/ImplicitParameters&quot;&gt;implicit parameters&lt;/a&gt; on a method.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doStuff&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;which means that anything marked as implicit that is in scope will be applied:&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;val&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;n&quot;&gt;doStuff&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// uses val context automatically.&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;This is all handled by the compiler: just set up the implicits and Scala will do the rest.&lt;/p&gt;

&lt;h2&gt;A place for everything&lt;/h2&gt;

&lt;p&gt;So now you have a number of implicit methods, value classes and type definitions and wotnot.  In Scala, there&amp;rsquo;s a place to keep all this stuff that is so intuitive, you may not think of it as a place at all. It&amp;rsquo;s the &lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/PackageObjects&quot;&gt;package object&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Package objects are supremely useful. You define a file called package.scala, then in the file you put&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;package&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mypackagename&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;implicit&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;string2username&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Option&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Username&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;parseUsername&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;input&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;and after that point, anything with &amp;lsquo;import mypackagename._&amp;rsquo; will import the package object as well. One less thing to think about.&lt;/p&gt;

&lt;h2&gt;Free Data Transfer Objects&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/CaseClasses&quot;&gt;Case classes&lt;/a&gt;.  So called because they&amp;rsquo;re used in case statements (see below).&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Data&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;propertyOne&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;propertyTwo&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;Immutable, convenient, and packed with functionality.  They make creating data types or DTOs trivial.  &lt;a href=&quot;http://www.codecommit.com/blog/scala/case-classes-are-cool&quot;&gt;They&amp;rsquo;re cool&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Free Range (Organic) Checking&lt;/h2&gt;

&lt;p&gt;Scala contains a powerful &lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/PatternMatching&quot;&gt;pattern matching&lt;/a&gt; feature.  You can think of it as a &lt;a href=&quot;http://thecodegeneral.wordpress.com/2012/03/25/switch-statements-on-steroids-scala-pattern-matching/&quot;&gt;switch statement on steroids&lt;/a&gt;.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Something&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doThis&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;   &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SomethingElse&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;doThat&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;There are so many things that feed into pattern matching &amp;mdash; &lt;a href=&quot;http://www.scala-lang.org/node/112&quot;&gt;extractor objects&lt;/a&gt;, &lt;a href=&quot;https://coderwall.com/p/m1bnlq&quot;&gt;aliases&lt;/a&gt;, matching on types, regular expressions and wildcards &amp;mdash; it&amp;rsquo;s the &amp;lsquo;regexp&amp;rsquo; of Scala.  It takes in an object as input, filters it, and manipulates it in exactly the way you want.&lt;/p&gt;

&lt;p&gt;But the thing I really like about pattern matching is what it doesn&amp;rsquo;t let you do. It doesn&amp;rsquo;t let you miss something.&lt;/p&gt;

&lt;p&gt;There&amp;rsquo;s a feature called &lt;a href=&quot;http://www.naildrivin5.com/scalatour/wiki_pages/SealedClasses&quot;&gt;sealed classes&lt;/a&gt; which lets you define all the valid types in a file. If you define a trait with the sealed keyword inside a file, then any classes you define inside that file that extend that trait are the ONLY classes that will extend that trait.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;sealed&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;trait&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Message&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Message&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;extends&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Message&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;p&gt;The compiler knows this, and so when you write use pattern matching against that trait, it knows that it must be one of the case classes defined. If not all of the case classes are defined in the match, it will print out a warning method saying that you don&amp;rsquo;t have an exhaustive match.&lt;/p&gt;

&lt;figure class=&#39;code&#39;&gt;&lt;figcaption&gt;&lt;span&gt;&lt;/span&gt;&lt;/figcaption&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;table&gt;&lt;tr&gt;&lt;td class=&quot;gutter&quot;&gt;&lt;pre class=&quot;line-numbers&quot;&gt;&lt;span class=&#39;line-number&#39;&gt;1&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;2&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;3&lt;/span&gt;
&lt;span class=&#39;line-number&#39;&gt;4&lt;/span&gt;
&lt;/pre&gt;&lt;/td&gt;&lt;td class=&#39;code&#39;&gt;&lt;pre&gt;&lt;code class=&#39;scala&#39;&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;msg&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;match&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Success&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Success: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Failure&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;println&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&amp;quot;Failure: &amp;quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;str&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;span class=&#39;line&#39;&gt;&lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/div&gt;&lt;/figure&gt;


&lt;h2&gt;And More&lt;/h2&gt;

&lt;p&gt;But that&amp;rsquo;s enough for now.  I hope this gives you an idea of why I like Scala.  If you have any features dear to your heart, add them to the comments and let me know what makes you happy.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Remember Me Cookies for Play 2.0</title>
      <link>http://tersesystems.com/2012/07/07/remember-me-cookies-for-play-2-dot-0</link>
      <pubDate>Sat, 07 Jul 2012 15:19:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/07/07/remember-me-cookies-for-play-2-dot-0</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been working with &lt;a href=&quot;http://www.playframework.org/&quot;&gt;Play 2.0&lt;/a&gt; for a while now, and in many ways it&amp;rsquo;s the ideal web
framework for me: it&amp;rsquo;s a light framework that gets a request, puts together a result (either at once or in chunks using
an iteree pattern), and provides some HTML templates and form processors for ease of use.  It lets you change code and
templates while the server is running, and gives you an asset pipeline for compressing LESS and Coffeescript into minified
CSS and Javascript out of the box.&lt;/p&gt;

&lt;p&gt;That being said, it&amp;rsquo;s a new web framework, and the biggest issue right now is all the boring infrastructure that goes
on top of it to make a framework deal with authentication, authorization, and even boring things like resetting a password.&lt;/p&gt;

&lt;p&gt;On the Java side, Yvonnick Esnault has a good &lt;a href=&quot;https://github.com/yesnault/Play20StartApp&quot;&gt;starter application&lt;/a&gt;
(disclaimer; I contributed some code), or you can use &lt;a href=&quot;http://joscha.github.com/play-authenticate/&quot;&gt;Play Authenticate&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;On the Scala side, &lt;a href=&quot;https://github.com/t2v/play20-auth&quot;&gt;play20-auth&lt;/a&gt; is a good starting point for an authentication
system.  However, it didn&amp;rsquo;t do token based authentication, aka &amp;ldquo;Remember Me&amp;rdquo; cookies.  Adding this feature turns out to
be tricky if you&amp;rsquo;re new to Scala, because extending the request pipeline in Play 2.0 Scala requires that you know a functional style
of programming called &amp;ldquo;&lt;a href=&quot;https://github.com/playframework/Play20/wiki/ScalaActionsComposition&quot;&gt;action composition&lt;/a&gt;&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;So here&amp;rsquo;s a boilerplate project &lt;a href=&quot;https://github.com/wsargent/play20-rememberme&quot;&gt;play20-rememberme&lt;/a&gt; that does authentication
with remember me functionality (although it doesn&amp;rsquo;t have the password reset or confirm features added to Play20StartApp).&lt;/p&gt;

&lt;p&gt;UPDATE: Now works with Play 2.1.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The User Illusion</title>
      <link>http://tersesystems.com/2012/05/26/the-user-illusion</link>
      <pubDate>Sat, 26 May 2012 15:51:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/05/26/the-user-illusion</guid>
      <description>&lt;p&gt;Slides from the May 17th &lt;a href=&quot;https://5mof.net/&quot;&gt;Five Minutes of Fame&lt;/a&gt;.  This one is on consciousness and a book called &lt;a href=&quot;http://www.amazon.com/The-User-Illusion-Cutting-Consciousness/dp/0140230122&quot;&gt;The User Illusion&lt;/a&gt;.  I read the book and thought it interesting, but it was only after reading &lt;a href=&quot;http://www.rifters.com/real/Blindsight.htm&quot;&gt;Blindsight&lt;/a&gt; and following Peter Watts&amp;rsquo;s &lt;a href=&quot;http://www.rifters.com/crawl/&quot;&gt;blog&lt;/a&gt; that it clicked as something that happened outside of science experiments.&lt;/p&gt;

&lt;p&gt;That, and I&amp;rsquo;d really been hankering for a good science talk.  There&amp;rsquo;s nothing quite like science; even when it comes to something as wishy-washy as consciousness, it can still give you surprising answers.&lt;/p&gt;

&lt;div style=&quot;width:425px&quot; id=&quot;__ss_13089132&quot;&gt;&lt;object id=&quot;__sse13089132&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=userillusion-120526180356-phpapp02&amp;amp;stripped_title=user-illusion&amp;amp;userName=wsargent&quot; /&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;/&gt;&lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot;/&gt;&lt;param name=&quot;wmode&quot; value=&quot;transparent&quot;/&gt;&lt;embed name=&quot;__sse13089132&quot; src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=userillusion-120526180356-phpapp02&amp;amp;stripped_title=user-illusion&amp;amp;userName=wsargent&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; wmode=&quot;transparent&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;


&lt;p&gt;And video!&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/TYXKN0DSOdg&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;


&lt;p&gt;The short version of the slides:&lt;/p&gt;

&lt;p&gt;When you see, you see what&amp;rsquo;s already been processed and filtered.  Illusions are when the system doesn&amp;rsquo;t work; you don&amp;rsquo;t see when it does work.  In other words, we see &amp;ldquo;car accident&amp;rdquo; as presented to our consciousness &amp;mdash; we don&amp;rsquo;t consciously put it together from our visual input.  I&amp;rsquo;ll spare you the customary link to the &amp;ldquo;You wouldn&amp;rsquo;t know if a Gorilla showed up&amp;rdquo; study, but it&amp;rsquo;s fairly clear the brain only passes on the Cliff Notes version to the executive layer.&lt;/p&gt;

&lt;p&gt;Consciousness lags well behind.  When scientists measure the movement of a finger, the electrical potential rises a full second before the finger moves.  But we report making the decision to move half a second before the finger moves (&lt;a href=&quot;https://en.wikipedia.org/wiki/Benjamin_Libet&quot;&gt;Libet&lt;/a&gt;).  We become aware of making the decision after it&amp;rsquo;s already happened.&lt;/p&gt;

&lt;p&gt;Some scientists conjecture that consciousness may simply be unnecessary (&lt;a href=&quot;http://rifters.com/real/articles/Neuropsychologia_Rosenthal_2008.pdf&quot;&gt;Rosenthal&lt;/a&gt;).  Others think that consciousness may be a result of conflicting subconscious systems (&lt;a href=&quot;http://bss.sfsu.edu/emorsella/images/MorsellaPsychRev.pdf&quot;&gt;Morsella&lt;/a&gt;, &lt;a href=&quot;http://www.amazon.com/Am-Strange-Loop-Douglas-Hofstadter/dp/0465030793&quot;&gt;Hofstader&lt;/a&gt;, &lt;a href=&quot;http://www.amazon.com/Being-No-One-Self-Model-Subjectivity/dp/0262633086&quot;&gt;Metzinger&lt;/a&gt;), and the &lt;a href=&quot;http://www.rifters.com/crawl/?p=791&quot;&gt;Watts commentary&lt;/a&gt; points out that consciousness seems to be strongly associated with inner conflict and/or pain, although I&amp;rsquo;m not spoiling his punchline.&lt;/p&gt;

&lt;p&gt;Despite what &lt;a href=&quot;http://h3ph.com/&quot;&gt;Heph&lt;/a&gt; says, I don&amp;rsquo;t think the talk is depressing.  When you think about consciousness, you assume that it&amp;rsquo;s a good thing, but realistically we&amp;rsquo;re far happier and productive in flow, without that &lt;a href=&quot;http://www.lastwordonnothing.com/2012/02/09/better-living-through-electrochemistry/&quot;&gt;nagging voice inside our heads&lt;/a&gt;.  Rather than life being suffering, suffering itself is the act of consciousness.&lt;/p&gt;

&lt;p&gt;The talk itself went down well, with the coveted  seal of approval. The 5MoF itself was surprisingly wide ranging &amp;mdash; &lt;a href=&quot;http://www.artsology.com/blog/2012/01/eclair-acuda-bandersnatch/&quot;&gt;Eclair Bandersnatch&lt;/a&gt; showed up in a barbie mask and wig to talk about art, &lt;a href=&quot;http://www.oblomovka.com/&quot;&gt;Danny O&amp;#8217;Brien&lt;/a&gt; gave a talk on The Cosmopolitan Anarchist and recapped the news on &lt;a href=&quot;http://freebyron.org/index.php/Main_Page&quot;&gt;Byron Sonne&lt;/a&gt;, &lt;a href=&quot;http://bookmaniac.org&quot;&gt;Liz Henry&lt;/a&gt; read poetry from her &lt;a href=&quot;http://bookmaniac.org/unruly-islands-will-blow-your-mind-so-buy-it/&quot;&gt;new book&lt;/a&gt;, and Josh Juran presented &lt;a href=&quot;http://www.metamage.com/code/forge/&quot;&gt;FORGE&lt;/a&gt;, a GUI based on manipulating what appeared to be symbolic files on the filesystem &amp;mdash; a programming paradigm that apparently came from Plan 9 and hurts my brain every time I think about it.&lt;/p&gt;

&lt;p&gt;We&amp;rsquo;re doing the same thing next month, and I&amp;rsquo;ll probably be talking about &lt;a href=&quot;https://noisebridge.net/wiki/TDCS&quot;&gt;Transcranial Direct Current Stimulation&lt;/a&gt; (if I&amp;rsquo;m not, y&amp;#8217;know, drooling in a corner).  So!  If you have a thought that&amp;rsquo;s been burning a hole in some mental sidepocket, you should &lt;a href=&quot;https://5mof.net/signup&quot;&gt;sign up&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Systemantics</title>
      <link>http://tersesystems.com/2012/03/17/systemantics</link>
      <pubDate>Sat, 17 Mar 2012 12:29:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/03/17/systemantics</guid>
      <description>&lt;p&gt;New Five Minutes of Fame presentation.  This one&amp;rsquo;s a presentation about a little known book called &lt;a href=&quot;http://en.wikipedia.org/wiki/Systemantics&quot;&gt;Systemantics&lt;/a&gt; (a.k.a. The Systems Bible).&lt;/p&gt;

&lt;div style=&quot;width:425px&quot; id=&quot;__ss_12048768&quot;&gt;&lt;strong style=&quot;display:block;margin:12px 0 4px&quot;&gt;&lt;a href=&quot;http://www.slideshare.net/wsargent/systemantics&quot; title=&quot;Systemantics&quot;&gt;Systemantics&lt;/a&gt;&lt;/strong&gt;&lt;object id=&quot;__sse12048768&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=systemantics-120317142231-phpapp01&amp;stripped_title=systemantics&amp;userName=wsargent&quot; /&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;/&gt;&lt;param name=&quot;allowScriptAccess&quot; value=&quot;always&quot;/&gt;&lt;param name=&quot;wmode&quot; value=&quot;transparent&quot;/&gt;&lt;embed name=&quot;__sse12048768&quot; src=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=systemantics-120317142231-phpapp01&amp;stripped_title=systemantics&amp;userName=wsargent&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; wmode=&quot;transparent&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/div&gt;


&lt;p&gt;This is a hard book to get hold of, but a worthwhile one.  Systemantics doesn&amp;rsquo;t make a lot of sense without the context of &lt;a href=&quot;http://en.wikipedia.org/wiki/Systems_theory&quot;&gt;Systems Theory&lt;/a&gt;, which is responsible for the word &amp;ldquo;cybernetics&amp;rdquo; and a whole bunch else, mostly talking about systems in the context of the complex feedback loop of a nuclear power plant.&lt;/p&gt;

&lt;p&gt;Systemantics is a little bit different: it talks about the feedback loop involved in organizations, and how the system has an independent life (and will to live) outside of any of its participants.  It&amp;rsquo;s a book about how systems actually behave, and how what an observer may consider to be a bug looks like appropriate behavior to the system.  It&amp;rsquo;s about the system as you know it at 2 am, the system complete unto itself in all its ineffable complexity.&lt;/p&gt;

&lt;p&gt;That being said, much of it is applicable to complex computer systems as well &amp;mdash;  in fact I&amp;rsquo;d say that Systems Theory is far more applicable to my day job than most CS Theory is, and if there&amp;rsquo;s ever going to be a Software Engineering curriculum then I&amp;rsquo;d want it to include this book.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Interviews without Puzzles</title>
      <link>http://tersesystems.com/2012/02/22/interviews-without-puzzles</link>
      <pubDate>Wed, 22 Feb 2012 19:12:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/02/22/interviews-without-puzzles</guid>
      <description>&lt;p&gt;Technical interviews have their own particular lore, and their own history.  Over the years, there are some interview practices that have sunk into the group subconscious of engineers, to the point where they&amp;rsquo;re used so commonly we don&amp;rsquo;t even question why.  Puzzles, for example.&lt;/p&gt;

&lt;p&gt;There are a few famous interview puzzles out there.  Microsoft has &amp;ldquo;Why are Manhole Covers Round?&amp;rdquo; Google has &amp;ldquo;You are shrunk to the height of a nickel and your mass is proportionally reduced so as to maintain your original density. You are then thrown into an empty glass blender. The blades will start moving in 60 seconds. What do you do?&amp;rdquo;&lt;/p&gt;

&lt;p&gt;The standard answer to the first puzzle is &amp;ldquo;So they don&amp;rsquo;t fall in.&amp;rdquo;  The answer to the second is that assuming you have the same proportionate strength, you can &lt;a href=&quot;http://online.wsj.com/article/SB10001424052970204552304577112522982505222.html?google_editors_picks=true&quot;&gt;jump out&lt;/a&gt;. (There&amp;rsquo;s an inverse square root effect between muscle and body length, so density is not a factor.)&lt;/p&gt;

&lt;p&gt;But here&amp;rsquo;s the thing.  The first answer is &lt;em&gt;incorrect&lt;/em&gt;.  Manhole covers are round because they &lt;a href=&quot;http://www.joblossguide.com/2009/02/why-are-manhole-covers-round_10.html?showComment=1293805783516#c1734354851346190815&quot;&gt;&lt;em&gt;can&lt;/em&gt; be round&lt;/a&gt;.  They could be square or triangular just as easily.&lt;/p&gt;

&lt;p&gt;So as an interviewer, if you pick random interview puzzles out of a book and you think you know the &amp;ldquo;right answer&amp;rdquo; to the puzzle, you run the chance of not hiring someone because the answer he gave was actually the correct one.&lt;/p&gt;

&lt;p&gt;A more common problem is that a clever interview puzzle is usually well-known.  As soon as you figure it out, you&amp;rsquo;ll tell all your friends, and they tell their friends.  Eventually, you can google for the answer.&lt;/p&gt;

&lt;p&gt;Back in the day, Zen Schools had the same problem.  They were looking for insight and flashes of realization, initially, and wanted a way to test for this.  Some people thought up excellent questions that could test the subtle understanding of self, reality and perception required of Zen students.  More and more, the koans were used as the standard by which students&amp;#8217; understanding could be measured. Eventually, someone had the bright idea to put together a book of koans &amp;mdash; complete with &amp;ldquo;acceptable responses&amp;rdquo; &amp;mdash; and through years of formalization, the age old question &amp;ldquo;What is the sound of one hand clapping&amp;rdquo; turned into a &lt;a href=&quot;http://web.archive.org/web/20070125230458sh_re_/www3.tky.3web.ne.jp/~edjacob/koan.html&quot;&gt;meaningless ritual&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Even if you don&amp;rsquo;t use well known puzzles, interviewing with logic puzzles in the long run optimizes for them. Through discussion, shared experiences and research, people will generally know that they should study for a general class of &lt;a href=&quot;http://amzn.com/098478280X&quot;&gt;logic puzzle&lt;/a&gt;. And the company will start getting more people that will do well at those puzzles&amp;hellip; but that doesn&amp;rsquo;t mean they know programming any better.&lt;/p&gt;

&lt;p&gt;Fermi questions, those &amp;ldquo;&lt;a href=&quot;http://www.vendian.org/envelope/dir0/fermi_questions.html&quot;&gt;How many elevators are in New York City?&lt;/a&gt;&amp;rdquo; questions that are popular in interviews, have a clearer structural weakness. They have no right answer at all, and can be completely circumvented with the right training.  Once you know the rules, you can come up with completely the wrong answer and still be &amp;ldquo;correct&amp;rdquo; according to the law of the game.&lt;/p&gt;

&lt;p&gt;I also have a philosophical problem with Fermi questions.  Yes, they&amp;rsquo;re pointless, but it&amp;rsquo;s not just that they&amp;rsquo;re pointless.  Asking a Fermi question says that you don&amp;rsquo;t really care what the answer is.  Asking a Fermi question tells your candidate that you want them to guess.&lt;/p&gt;

&lt;p&gt;Engineers are trained out of guessing.  Engineers are trained to nail down as much as they can &lt;a href=&quot;http://programmers.stackexchange.com/questions/45259/is-premature-optimization-always-bad&quot;&gt;before&lt;/a&gt; solving any problem, because invalid assumptions and requirements are &lt;a href=&quot;http://courses.cs.vt.edu/~cs3604/lib/Therac_25/Therac_1.html&quot;&gt;dangerous&lt;/a&gt; and &lt;a href=&quot;http://www.doc.ic.ac.uk/~ban/pubs/ariane5.pdf&quot;&gt;expensive&lt;/a&gt;.  But that&amp;rsquo;s not why engineers don&amp;rsquo;t like to guess.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Why&lt;/em&gt; is because most engineers remember vividly what happened the last time someone came up to them and said &amp;ldquo;When do you think we can go live?  &lt;a href=&quot;http://gigamonkeys.wordpress.com/2007/04/26/estimation-considered-harmful/&quot;&gt;Just make a guess&lt;/a&gt;.&amp;rdquo;  When it comes to Fermi questions, a cagey and hesitant engineer isn&amp;rsquo;t a bad candidate, but an experienced one.&lt;/p&gt;

&lt;p&gt;So what do I recommend? &lt;a href=&quot;http://amzn.com/0932633595&quot;&gt;This book&lt;/a&gt; is good to get a broader sense of what interviews are supposed to do, and you can ask spot questions about &lt;a href=&quot;http://www.bestcode.com/html/interview_questions.html&quot;&gt;language and system knowledge&lt;/a&gt;, then rate them on the &lt;a href=&quot;http://www.starling-software.com/employment/programmer-competency-matrix.html&quot;&gt;Programmer Competency Matrix&lt;/a&gt;.  But the best way to figure out how someone attacks code is to bring out some buggy code and ask for help debugging it, or bring out a design and talk about how you&amp;rsquo;d implement it, talk about the engineer&amp;rsquo;s background, print out the engineer&amp;rsquo;s github project and ask about it.  They&amp;rsquo;ll appreciate it, and so will you.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Failing with Passwords</title>
      <link>http://tersesystems.com/2012/02/17/failing-with-passwords</link>
      <pubDate>Fri, 17 Feb 2012 11:08:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/02/17/failing-with-passwords</guid>
      <description>&lt;p&gt;Did a talk about implementing password security right last night at Five Minutes of Fame.&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/presentation/embed?id=1PMGgO_bjMhPaCdE5MrcF-6lwuLY1lNvgsS-dx62flKY&amp;start=false&amp;loop=false&amp;delayms=3000&quot; frameborder=&quot;0&quot; width=&quot;529&quot; height=&quot;426&quot; allowfullscreen=&quot;true&quot; mozallowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;


&lt;p&gt;If you don&amp;rsquo;t want to go through the slides, here&amp;rsquo;s the TL;DR version:&lt;/p&gt;

&lt;h2&gt;TL;DR User Security&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use a &lt;a href=&quot;http://arstechnica.com/security/guides/2011/03/ask-ars-where-should-i-store-my-passwords.ars&quot;&gt;password manager&lt;/a&gt; like &lt;a href=&quot;https://lastpass.com/&quot;&gt;LastPass&lt;/a&gt; or &lt;a href=&quot;https://agilebits.com/onepassword&quot;&gt;1Password&lt;/a&gt; (with Dropbox) and use their password generation.&lt;/li&gt;
&lt;li&gt;If no manager available (routers, OS logins, etc), use pass phrases with non-English words or acronyms (see &lt;a href=&quot;http://xkcd.com/936/&quot;&gt;xkcd&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Assume sites get compromised all the time and you never hear about it.  NEVER reuse a password.&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re at a coffee shop or hackerspace, use a &lt;a href=&quot;http://mashable.com/2010/10/28/firesheep-vpns/&quot;&gt;public VPN service&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;OAuth / Twitter / Facebook based authentication is putting your auth credentials in their hands.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;TL;DR Encryption Security&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;a href=&quot;http://chargen.matasano.com/chargen/2007/9/7/enough-with-the-rainbow-tables-what-you-need-to-know-about-s.html&quot;&gt;bcrypt&lt;/a&gt;.  Bounce up the factor every few years.&lt;/li&gt;
&lt;li&gt;Do not limit password field length. (bcrypt takes up to 55 bytes of input.)&lt;/li&gt;
&lt;li&gt;Run a &lt;a href=&quot;http://howsecureismypassword.net/&quot;&gt;JS password tester&lt;/a&gt; to reject weak passwords.&lt;/li&gt;
&lt;li&gt;Run a &lt;a href=&quot;http://www.openwall.com/john/&quot;&gt;password cracker&lt;/a&gt; regularly to test your security.&lt;/li&gt;
&lt;li&gt;Suggest to your users that they use passphrases with acronyms, punctuation or LOLspeak.&lt;/li&gt;
&lt;li&gt;Generate random passwords for your users.&lt;/li&gt;
&lt;li&gt;Consider removing &lt;a href=&quot;http://www.useit.com/alertbox/passwords.html&quot;&gt;password masking&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;TL;DR Operational Security&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Use HTTPS for both &lt;a href=&quot;https://www.owasp.org/index.php/Transport_Layer_Protection_Cheat_Sheet#Rule_-_Use_TLS_for_All_Login_Pages_and_All_Authenticated_Pages&quot;&gt;rendering and submitting&lt;/a&gt; login page.&lt;/li&gt;
&lt;li&gt;Show &lt;a href=&quot;http://www.ethicalhacker.net/content/view/182/1/&quot;&gt;Cain and Abel&lt;/a&gt; video to everyone you work with.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;http://en.wikipedia.org/wiki/HTTP_Strict_Transport_Security&quot;&gt;HSTS&lt;/a&gt; headers with HTTPS.&lt;/li&gt;
&lt;li&gt;Use &lt;a href=&quot;http://www.corej2eepatterns.com/Design/PresoDesign.htm&quot;&gt;Synchronizer Token&lt;/a&gt; to prevent &lt;a href=&quot;http://guides.rubyonrails.org/security.html#cross-site-request-forgery-csrf&quot;&gt;CSRF attacks&lt;/a&gt; (or use a decent web framework).&lt;/li&gt;
&lt;li&gt;Use a &lt;a href=&quot;http://en.wikipedia.org/wiki/CAPTCHA&quot;&gt;captcha&lt;/a&gt; / &lt;a href=&quot;http://datagraph.rubyforge.org/rack-throttle/&quot;&gt;throttle&lt;/a&gt; on password attempts.&lt;/li&gt;
&lt;li&gt;Use double validation for registering accounts (register sends email, clicking email link heads back to site).&lt;/li&gt;
&lt;li&gt;Use one time use password reset links.&lt;/li&gt;
&lt;li&gt;Send email notifications on password change attempts.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Extra Credit&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Add Honeypot Logins.&lt;/li&gt;
&lt;li&gt;Use login token IDs with hidden check bits and math invariants that indicate tampering.&lt;/li&gt;
&lt;li&gt;Implement a secret in the session management system to keep state on the client and verify it on server interaction for better session authentication.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;OWASP also has &lt;a href=&quot;https://www.owasp.org/index.php/Cheat_Sheets&quot;&gt;cheat sheets&lt;/a&gt; which look useful if you&amp;rsquo;re putting a site together.  It still disturbs me how freaking MANUAL so much of this is, but I suppose web frameworks can&amp;rsquo;t do everything for you.  There are &lt;a href=&quot;http://everydayrails.com/2011/09/21/rails-authentication.html&quot;&gt;some options&lt;/a&gt; if you&amp;rsquo;re on Rails.&lt;/p&gt;

&lt;p&gt;It was a surprisingly tough talk to give.  At first I was like, &amp;ldquo;&lt;a href=&quot;http://www.troyhunt.com/2011/01/whos-who-of-bad-password-practices.html&quot;&gt;lol, look at all the companies with crappy security&lt;/a&gt;&amp;rdquo;, but it&amp;rsquo;s a murky field in general. For example, the &lt;a href=&quot;http://xkcd.com/936/&quot;&gt;XKCD cartoon about passphrases&lt;/a&gt; is missing the problem that most people type passphrases in standard English, and only use about two thousand words in general conversation.  It may look like there&amp;rsquo;s more entropy generated, but if your attackers know that your customers use passphrases, you may have just made their jobs &lt;a href=&quot;http://technet.microsoft.com/en-us/library/cc512613.aspx&quot;&gt;much easier&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, brute force cracking is surprisingly effective.  MD5 and the SHA-* algorithms are inappropriate because GPUs chew through them &lt;a href=&quot;http://blog.duosecurity.com/2010/12/brief-analysis-of-the-gawker-password-dump/&quot;&gt;very quickly&lt;/a&gt;, but the newer FPGA chips can do a reasonable implementation of bcrypt in hardware.  It&amp;rsquo;s an issue that computers are fast, but a bigger problem is that they just keep getting faster.&lt;/p&gt;

&lt;p&gt;The biggest thing has to be to not let your users pick &lt;a href=&quot;http://howsecureismypassword.net/&quot;&gt;crappy passwords&lt;/a&gt;.  Even if you have bcrypt with all the factors, if your users are &lt;a href=&quot;http://www.rawstory.com/rs/2012/02/08/anonymous-hacks-syrian-presidents-email-with-12345-password/&quot;&gt;entering &amp;ldquo;12345&amp;rdquo; as the password&lt;/a&gt;, it&amp;rsquo;s not going to make a difference.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Heuristics in Mate Search</title>
      <link>http://tersesystems.com/2012/01/17/heuristics-in-mate-search</link>
      <pubDate>Tue, 17 Jan 2012 15:00:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2012/01/17/heuristics-in-mate-search</guid>
      <description>&lt;p&gt;Five Minutes of Fame talk about dating heuristics.  This went much better than expected because the pictures and subject matter helped balance out the math.&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/presentation/embed?id=1vywPmRpHKE6QwjaLvyXKBINzOAbZ1fiZZ3Bxpw5LFYQ&amp;start=false&amp;loop=false&amp;delayms=3000&quot; frameborder=&quot;0&quot; width=&quot;529&quot; height=&quot;426&quot; allowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;


&lt;p&gt;Although there were a number of people afterwards who were like &amp;ldquo;too unrealistic&amp;rdquo; and I was like &amp;ldquo;yeah, this works better for interviews and college placement but whatchagonnado.&amp;rdquo;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Five Minutes of Web Frameworks</title>
      <link>http://tersesystems.com/2011/11/18/five-minutes-of-web-frameworks</link>
      <pubDate>Fri, 18 Nov 2011 15:00:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2011/11/18/five-minutes-of-web-frameworks</guid>
      <description>&lt;p&gt;New 5MOF presentation, wherein I talk about why web applications are complicated.  In five minutes.&lt;/p&gt;

&lt;p&gt;I really need to write this up as an essay, as I think presentation objects vs domain objects are a much bigger detail than we realize.&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/presentation/embed?id=1GWA93mRUbzX2x-uC5CluojrFsoMu4Awha5OgFflvhkc&amp;start=false&amp;loop=false&amp;delayms=3000&quot;
frameborder=&quot;0&quot; width=&quot;529&quot; height=&quot;426&quot; allowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;

</description>
    </item>
    
    <item>
      <title>How We Make Decisions</title>
      <link>http://tersesystems.com/2011/10/21/how-we-make-decisions</link>
      <pubDate>Fri, 21 Oct 2011 14:04:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2011/10/21/how-we-make-decisions</guid>
      <description>&lt;p&gt;
  Five Minutes of Fame presentation on how we make decisions.  This one was a lot more dry and technical, but it was a nice change of pace after bronies melted my brain.
&lt;/p&gt;

&lt;iframe src=&quot;https://docs.google.com/presentation/embed?id=1pNN9NHaAMCuCKyxfMVpe58vIgcSwOT_gpt4FP1r-nFU&amp;start=false&amp;loop=false&amp;delayms=3000&quot; frameborder=&quot;0&quot; width=&quot;529&quot; height=&quot;426&quot; allowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;
  Part of what makes this so fascinating to me is that you can actually see the algorithm that tells us &amp;#8220;hey, we should do more of this.&amp;#8221;  That&amp;#8217;s a huge step in knowing our blind spots.
&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Happiness Lecture at Noisebridge</title>
      <link>http://tersesystems.com/2011/07/15/happiness-lecture-at-noisebridge</link>
      <pubDate>Fri, 15 Jul 2011 15:11:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2011/07/15/happiness-lecture-at-noisebridge</guid>
      <description>&lt;p&gt;Ty put up a video of me presenting Happiness @ Noisebridge.&lt;/p&gt;




&lt;p&gt;It has kittens.&lt;/p&gt;




&lt;iframe src=&quot;http://www.youtube.com/embed/MCjiCvG1DuY&quot; frameborder=&quot;0&quot;
width=&quot;529&quot; height=&quot;426&quot; allowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;




&lt;p&gt;Updated: Now with slides!&lt;/p&gt;




&lt;iframe src=&quot;https://docs.google.com/presentation/embed?id=16IiPcJKEoDi-_0d3IMcC7MR_Vx-092NZA3Ep5igoF1E&amp;start=false&amp;loop=false&amp;delayms=3000&quot; frameborder=&quot;0&quot; width=&quot;529&quot; height=&quot;426&quot; allowfullscreen=&quot;true&quot; mozallowfullscreen=&quot;true&quot; webkitallowfullscreen=&quot;true&quot;&gt;&lt;/iframe&gt;

</description>
    </item>
    
    <item>
      <title>The Core of Agile</title>
      <link>http://tersesystems.com/2011/06/12/the-core-of-agile</link>
      <pubDate>Sun, 12 Jun 2011 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2011/06/12/the-core-of-agile</guid>
      <description>&lt;p&gt;
    I&amp;#39;ve been thinking lately about Agile. &amp;nbsp;Again.&lt;/p&gt;


&lt;p&gt;
    The first thing I&amp;#39;ve been thinking about is the people who say &amp;quot;You&amp;#39;re doing Agile Wrong.&amp;quot;&lt;/p&gt;


&lt;p&gt;
    There&amp;#39;s always been a dichotomy for me between the theory of Agile, and the practice. &amp;nbsp;It&amp;#39;s a common problem with any dream; it&amp;#39;s always cleaner, brighter, simpler, better than the reality. &amp;nbsp;Reality is messy. &amp;nbsp;It is imprecise. &amp;nbsp;It is never seen directly, always filtered through recollections to make each participant the protagonist of their own play. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    If you try pair programming, then you&amp;#39;re going to find that &amp;quot;you should never pair program 100% of the time.&amp;quot; &amp;nbsp;Or that &amp;quot;you should only pair program between people with equal skill sets.&amp;quot; &amp;nbsp;Or that &amp;quot;you should practice pair programming ping pong&amp;quot;. &amp;nbsp;There will always be a special case. There will always be something that works for you that doesn&amp;#39;t work for someone else. &amp;nbsp; There will always be something that doesn&amp;#39;t work for you that works for someone else.&lt;/p&gt;


&lt;p&gt;
    Not only do we do Agile &amp;quot;wrong&amp;quot;, but we will always do Agile &amp;quot;wrong&amp;quot;. &amp;nbsp;We won&amp;#39;t ever do anything &amp;quot;right&amp;quot; &amp;#8211; we will do imperfect jobs, come home to imperfect relationships, have imperfect children and live imperfect lives. &amp;nbsp; This is what happens when you measure yourself against an ideal.&lt;/p&gt;


&lt;p&gt;
    But why believe in Agile then, if the only way you can do it is wrong? &amp;nbsp;Something that came to mind about that statement. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    If you&amp;#39;re trying to do Agile, and it&amp;#39;s not working for you&amp;#8230; then you&amp;#39;re doing it wrong.&lt;/p&gt;


&lt;p&gt;
    Another way of phrasing that statement is that Agile is Doing It Right. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    In fact, almost by definition, Agile is Doing It Right.&lt;/p&gt;


&lt;p &gt;
    &amp;quot;Agile teams produce a continuous stream of value, at a sustainable pace, while adapting to the changing needs of business.&amp;quot; &amp;#8211; &lt;a href=&quot;http://testobsessed.com/2010/12/14/the-agile-acid-test/&quot;&gt;Elizabeth Hendrickson&lt;/a&gt;.&lt;/p&gt;


&lt;p &gt;
    &amp;quot;Agile development uses feedback to make constant adjustments in a highly collaborative environment.&amp;quot; &amp;#8211; &lt;a href=&quot;http://pragprog.com/titles/pad/practices-of-an-agile-developer&quot;&gt;Practices of an Agile Developer&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    &amp;quot;Agile has no definition. [&amp;#8230;] There&amp;#39;s no standards board, there&amp;#39;s no test, there&amp;#39;s no approved workbook, there&amp;#39;s no checklist. &amp;nbsp;[&amp;#8230;] It&amp;#39;s based on three things: 1) principles not practices, 2) attention to people, and 3) always be adapting.&amp;quot; &amp;#8211; &lt;a href=&quot;http://www.whattofix.com/blog/archives/2010/09/agile-ruined-my.php&quot;&gt;Daniel Markham&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    Three definitions of Agile. &amp;nbsp;Nothing about practices, or even methodology. &amp;nbsp;What they agree on is a feedback cycle that can respond to changing input and produce useful output. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    It&amp;#39;s &lt;a href=&quot;http://tersesystems.com/2011/06/10/the-logic-of-failure&quot;&gt;Dorner&amp;#39;s model of problem solving&lt;/a&gt;. &amp;nbsp;Or Deming&amp;#39;s &lt;a href=&quot;http://en.wikipedia.org/wiki/PDCA&quot;&gt;PDCA cycle&lt;/a&gt;. &amp;nbsp;Or the Military&amp;#39;s&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/OODA_loop&quot;&gt;OODA cycle&lt;/a&gt;. &amp;nbsp; Or the &lt;a href=&quot;http://en.wikipedia.org/wiki/Scientific_method&quot;&gt;Scientific Method&lt;/a&gt;. &amp;nbsp;Or &lt;a href=&quot;http://en.wikipedia.org/wiki/Kaizen&quot;&gt;Kaizen&lt;/a&gt;. &amp;nbsp;It&amp;#39;s continous process improvement, in all its forms.&lt;/p&gt;


&lt;p&gt;
    If you&amp;#39;re following a &amp;quot;best practice&amp;quot; and that &amp;quot;best practice&amp;quot; isn&amp;#39;t working for you, then it&amp;#39;s not a case of &amp;quot;You&amp;#39;re Doing Agile Wrong.&amp;quot; &amp;nbsp;You&amp;#39;re doing something that isn&amp;#39;t providing a benefit for you. &amp;nbsp; By following that &amp;quot;best practice&amp;quot;, you&amp;#39;re not doing Agile at all. Agile is the ability to plan something new, throw out something old, and challenge preconceived beliefs.&lt;/p&gt;


&lt;p&gt;
    That&amp;#39;s the core of Agile for me: it&amp;#39;s not about Wrong or Right. &amp;nbsp;It&amp;#39;s the idea of saying &amp;quot;We can do better.&amp;quot; &amp;nbsp;And then doing it.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>The Logic of Failure</title>
      <link>http://tersesystems.com/2011/06/10/the-logic-of-failure</link>
      <pubDate>Fri, 10 Jun 2011 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2011/06/10/the-logic-of-failure</guid>
      <description>&lt;p&gt;
    Another talk, this time on &lt;a href=&quot;http://www.amazon.com/Logic-Failure-Recognizing-Avoiding-Situations/dp/0201479486&quot;&gt;The Logic of Failure: Recognizing and Avoiding Error in Complex Situations&lt;/a&gt;, a book by &lt;a href=&quot;http://www.uni-bamberg.de/allgpsych/team/dietrich-doerner/&quot;&gt;Dietrich Dorner&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    The book&amp;rsquo;s been a favorite of mine for years, not just for the set up, but for the detailed, unsparing look it provides on how human beings fail to get things right. &amp;nbsp;Too often in psychology, there&amp;rsquo;s an emphasis on either seeing how people feel about a situation, or how well or how poorly they perform at a given task. &amp;nbsp;Dorner goes further, and tries to understand not just how, but why they fail.&lt;/p&gt;


&lt;h4&gt;
    The Slides&lt;/h4&gt;


&lt;p&gt;
&lt;iframe src=&quot;https://docs.google.com/present/embed?id=dcxrsgwk_137cncdckf4&amp;size=m&quot; frameborder=&quot;0&quot; width=&quot;555&quot; height=&quot;451&quot;&gt;&lt;/iframe&gt;
&lt;/p&gt;


&lt;h4&gt;
    The Setup&lt;/h4&gt;


&lt;p&gt;
    The setup was simple. &amp;nbsp;Dorner set up a computer simulation of an African village called Tanaland. &amp;nbsp;This book was written in 1990, and so Sim City was not widely known, but it&amp;rsquo;s the same concept. &amp;nbsp;The players were given dictatorial powers, given the goal to &amp;ldquo;improve the wellbeing of the people&amp;rdquo; and had six opportunities over 10 years to review (and possibly change) their policies.&lt;/p&gt;


&lt;h4&gt;
    The Experiment&lt;/h4&gt;


&lt;p&gt;
    Given the tools the players had at hand, they went to improving what they could. &amp;nbsp;They improved the food supply (using artifical fertilizer) and increased medical care. &amp;nbsp;There were more children and fewer deaths, and lif expectancy was higher. &amp;nbsp;For the first three sessions, everything went well. &amp;nbsp;But unknown to the players, they&amp;rsquo;d set up an unsustainable situation.&lt;/p&gt;


&lt;p&gt;
    Famine typically broke out in the 88th month. &amp;nbsp;The agarian population dropped dramatically, below what they had been initially. &amp;nbsp;Sheep, goats and cows died off in their herds, and the land was left barren by the end. &amp;nbsp;Given a free hand, most players engineered a wasteland.&lt;/p&gt;


&lt;p&gt;
    One player, by the end of the simulation, had a stable population and had significantly better quality of life for the villagers. &amp;nbsp;Failure was the rule, but somehow he had found an exception.&lt;/p&gt;


&lt;h4&gt;
    The Breakdown&lt;/h4&gt;


&lt;p&gt;
    The litany of possible errors was a long one, and so immediately recognisable that it&amp;#39;s hard to suppress a wince of empathy on reading.&lt;/p&gt;


&lt;p&gt;
    The players who did badly tended not to ask &amp;quot;why&amp;quot; things happened. &amp;nbsp;They tended to jump from one subject to another, switching aimlessly, without focus. &amp;nbsp;They proposed hypotheses without testing them. &amp;nbsp;If they did test their hypotheses, they did so on an adhoc basis, testing success cases without testing possible failure cases. &amp;nbsp;In some cases they had tunnel vision: focussing on irrelevancies at the expence of the larger picture. &amp;nbsp;In other cases, they attempted to &amp;quot;delegate&amp;quot; intractable problems to the villagers themselves or refused to deal with the issue at all. &amp;nbsp;Finally, and most tellingly, most players dealt with the problems that they saw &amp;quot;on the spot&amp;quot; without thinking of the larger, longer term problems that they were setting up with that immediate short term solution.&lt;/p&gt;


&lt;p&gt;
    These results were not a surprise. &amp;nbsp;They were just what Dorner&amp;#39;s team was looking for. &amp;nbsp;Where many scientists would have looked at the successes and determined the optimal &amp;quot;working strategy&amp;quot; &amp;#8211; Dorner was just as interested in the range of failures in the experiment. &amp;nbsp; Dorner&amp;#39;s team had specifically designed the simulation so that most people would fail at it, precisely aiming at the weak points of human decision making. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    Not all players failed in the same way. &amp;nbsp;Even amongst the players who failed the same way, many players had different reasons for their particular mode of failure. &amp;nbsp;And yet, there were strong commonalities among the failing players, both in their reactions to incipient failure, and in their attempts at recovery.&lt;/p&gt;


&lt;h4&gt;
    The Reasons&lt;/h4&gt;


&lt;p&gt;
    The reason why most people failed was that they did not understand the nature of Tanaland. &amp;nbsp;Despite being a simulation, Tanaland was no game, and Dorner&amp;#39;s team programmed in as accurate a simulation of an African village as the hardware would allow. &amp;nbsp;The watertable under the village had a limited amount of water available. &amp;nbsp;The population grew at an exponential rate given the available food and healthcare. &amp;nbsp;Even the topsoil was modelled accurately, so that overgrazing caused by massive herds would erode the topsoil over time. &amp;nbsp;All of this data was available to the players &amp;#8211; had they thought to look. &amp;nbsp;But most players didn&amp;#39;t. &amp;nbsp;The experiment ended in three predictable failure modes: either the cattle starved and died, or the groundwater was exhausted, or the population exceeded the available food. &amp;nbsp;Far from being a bundle of independent subsystems, all of Tanaland was deeply intertwingled.&lt;/p&gt;


&lt;h4&gt;
    The Weaknesses&lt;/h4&gt;


&lt;p&gt;
    The deeper reason why Tanaland was so successful at bamboozling players is partly due to the incredible success of the human brain&amp;#39;s pattern recognition system. &amp;nbsp;Human beings are capable of driving in heavy traffic, understanding language, and recognizing patterns in almost random data, feats far beyond most computers. &amp;nbsp;But there are some problems which defeat human intuition. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    &lt;strong&gt;Linear extrapolation.&amp;nbsp;&lt;/strong&gt;Human beings have a tendency to assume change itself is static. &amp;nbsp;Even when shown exponential growth, we&amp;#39;re not good at internalizing that knowledge. &amp;nbsp;This may be why calculus is so hard for many people, because we don&amp;#39;t think about the rate of growth itself growing.&lt;/p&gt;


&lt;p&gt;
    &lt;strong&gt;Delayed Feedback.&amp;nbsp;&lt;/strong&gt;Human beings tend to assume that an action will yield a response immediately, or not at all. &amp;nbsp;This is the way that we interact with the world on a daily basis, and we can become very confused when there&amp;#39;s a significant delay in the system&amp;#39;s response. &amp;nbsp;Even when we recognize intellectually that a change is &amp;quot;in the pipeline&amp;quot;, we may struggle against the instinct to do more and oversteer rather than correctly &amp;quot;sitting on our hands.&amp;quot;&lt;/p&gt;


&lt;p&gt;
    &lt;strong&gt;Contradicting goals.&amp;nbsp;&lt;/strong&gt;Part of the failure of players was inherent in the vague goals that they had. &amp;nbsp;What, exactly does &amp;quot;improve the wellbeing of the people&amp;quot; really mean? &amp;nbsp;Does it mean providing the best quality of life to all the villagers? &amp;nbsp;Growing the village as a whole to be more prosperous? &amp;nbsp;In many cases, the top level goal ended up being broken down into goals that conflicted with each other. &amp;nbsp;In other cases, players tried to find concrete problems to fix. &amp;nbsp;One player, deciding that the village needed irrigation, set out building an irrigation system and quickly became fixated on that one problem, becoming &amp;quot;addicted&amp;quot; to his experience of flow. &amp;nbsp;In such cases, &amp;nbsp;players were unable to clearly form goals at all.&lt;/p&gt;


&lt;p&gt;
    &lt;strong&gt;Priorities&lt;/strong&gt;.&amp;nbsp;Even when the players had clearly defined goals, they had another problem to contend with: they would be stymied by cases where actions which furthered one goal would thwart another. &amp;nbsp;The complex interdependencies in the system did not allow for a full optimization of every variable, and players would either flail uselessly or be paralysed by their inability to cover every base.&lt;/p&gt;


&lt;p&gt;
    &lt;strong&gt;Information overload.&amp;nbsp;&lt;/strong&gt;In many cases, the players used too little information to know how to make the best decisions. &amp;nbsp;However, some players had the opposite problem; given access to all data of a complex system, they tried to see the entire system at once. &amp;nbsp;These players found themselves paralysed by complexity, and unable to interpret the results of the data. &amp;nbsp;Interestingly, the problem the players had was not that they did not see the correct chart. &amp;nbsp;They were literally unable to recognize the charts and the changes in data as relevant &amp;#8211; having looked at all the data available, their abilities to see a pattern was exhausted well before they stumbled on the correct chart.&lt;/p&gt;


&lt;p&gt;
    &lt;strong&gt;Reductive Hypotheses.&amp;nbsp;&lt;/strong&gt;By far the worst problem that players had, above all others, was that the first hypotheses they formed about the system were not changed in response to the data. &amp;nbsp;If anything, the players were apt to be the most sure in their beliefs when the hypotheses were completely wrong. &amp;nbsp;Part of this came from uncertainty and cognitive dissonance. &amp;nbsp;Uncertainty produced fear and doubt. &amp;nbsp;Asserting the hypothesis helped quell this fear and doubt. &amp;nbsp;Over time, the players learned that the more they believed in the hypothesis, the better they felt. &amp;nbsp;This reduced their ability to develop new hypotheses, as they were already &amp;quot;wedded&amp;quot; to their existing ideas.&lt;/p&gt;


&lt;h4&gt;
    The Successes&lt;/h4&gt;


&lt;p&gt;
    There were also commonalities amongst the players who did well. &amp;nbsp;The players who did well were the ones who could tolerate uncertainty. &amp;nbsp;They defined clear goals and priorities. &amp;nbsp;They made many small decisions in different areas, and followed up on the expected vs actual results of most, if not all of those decisions. &amp;nbsp;They kept an eye on the overall processes of the system, and did not succumb to flow experiences.&lt;/p&gt;


&lt;p&gt;
    Adding to this, Dorner&amp;#39;s team ran an experiment with two groups of fifteen players each. &amp;nbsp;One group was drawn from the student population. &amp;nbsp;The other group was made of senior managers from large industrial and commercial firms. &amp;nbsp;The managers did significantly better than the students on every possible metric; given several different challenges, they responded appropriately to each one. &amp;nbsp;Dorner&amp;#39;s team was unable to determine if this was innate talent or the benefit of years of experience.&lt;/p&gt;


&lt;h4&gt;
    A Decision Making Model&lt;/h4&gt;


&lt;p&gt;
    So what is the right thing to do when faced with a complex situation? Dorner presents a possible schema for problem solving, intended more as a helpful aid than as a representation of how people&amp;nbsp;actually solve problems. &amp;nbsp;&amp;nbsp;&lt;/p&gt;


&lt;ol&gt;
    &lt;li&gt;
        Formulation of Goals - deciding what it is that needed fixing, and putting priorities on those goals.&lt;/li&gt;
    &lt;li&gt;
        Formulation of Models - determining the internal workings of the system.&lt;/li&gt;
    &lt;li&gt;
        Prediction and Extrapolation - determining the eventual output of the system.&lt;/li&gt;
    &lt;li&gt;
        Planning of Actions; decision making, and execution of actions - feeding input into the system.&lt;/li&gt;
    &lt;li&gt;
        Review of effects of actions and revision of strategy - determining the expected model vs the actual model.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;
    Interestingly, this is very close to the &lt;a href=&quot;http://en.wikipedia.org/wiki/PDCA&quot;&gt;Plan/Do/Check/Act cycle&lt;/a&gt; proposed by&amp;nbsp;Deming&amp;nbsp;&amp;#8211; it assumes incomplete knowledge of a complex system and tries to improve understanding of the underlying model through repeated iterations of the cycle.&lt;/p&gt;


&lt;p&gt;
    Dorner also notes that being simply told of a decision making strategy did no good at all to players; when given instruction on dealing with complex systems, the players thought that they had been helped and were better able to discuss their failures with better terminology&amp;#8230; but their actual performance was the same as the control group. &amp;nbsp;What really helped players, overall, was repeated exposure to complex systems. &amp;nbsp;Showing was not enough; they had to experience their own reactions and build up their tolerance to decision making in the face of uncertainty and emotional stress.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Life in Fifty Years</title>
      <link>http://tersesystems.com/2011/04/23/life-in-fifty-years</link>
      <pubDate>Sat, 23 Apr 2011 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2011/04/23/life-in-fifty-years</guid>
      <description>&lt;p&gt;
	Another presentation at &lt;a href=&quot;http://5mof.net&quot;&gt;Five Minutes of Fame&lt;/a&gt;. Christina took video of the talk, so
	I might be able to put that up as well.&lt;/p&gt;
&lt;p&gt;
	&lt;iframe src=&quot;https://docs.google.com/present/embed?id=dcxrsgwk_136gnmhrjcq&amp;size=m&quot; frameborder=&quot;0&quot; width=&quot;555&quot; height=&quot;451&quot;&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;
	This one took me a while to go through. I picked up a number of books on the subject when Borders shut down,
	and the talk gave me the impetus to crank through them. The most relevant books were
	&lt;a href=&quot;http://www.amazon.com/Plan-4-0-Mobilizing-Civilization-Substantially/dp/0393337197/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1303521356&amp;amp;sr=1-1&quot;&gt;Plan B 4.0&lt;/a&gt;, &lt;a href=&quot;http://www.amazon.com/Ecotechnic-Future-Envisioning-Post-Peak-World/dp/0865716390/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1303521307&amp;amp;sr=1-1&quot;&gt;The Ecotechnic Future&lt;/a&gt;, and &lt;a href=&quot;http://www.amazon.com/Hot-Living-Through-Fifty-Years/dp/0618826122&quot;&gt;Hot: Living Through The Next Fifty Years&lt;/a&gt;. I also recommend &lt;a href=&quot;http://www.amazon.com/Windup-Girl-Paolo-Bacigalupi/dp/1597801585/ref=sr_1_1?s=books&amp;amp;ie=UTF8&amp;amp;qid=1303522025&amp;amp;sr=1-1&quot;&gt;The Windup Girl&lt;/a&gt; or &lt;a href=&quot;http://www.amazon.com/gp/product/0802144012?ie=UTF8&amp;amp;tag=wwwkunstlerco-20&amp;amp;linkCode=as2&amp;amp;camp=1789&amp;amp;creative=390957&amp;amp;creativeASIN=0802144012&quot;&gt;World Made By Hand&lt;/a&gt; for a much better sense of what the future may feel like.&lt;/p&gt;
&lt;p&gt;
	Part of the reason I went through the books was to see how likely the
	 &lt;a href=&quot;http://en.wikipedia.org/wiki/Technological_singularity&quot;&gt;Singularity&lt;/a&gt; is. As far as I can make out, it&amp;#39;s very dependent on how much free energy is available in fifty years. With a strong global economy, all the parts and dependencies sorted and the sheer power requirements it would take to jam a human-equivalent neural network down through silicon pathways, it&amp;#39;s technically possible to have AI. But then you&amp;#39;ve still got the supply chain management to work through before you can develop more advanced AI, and the overall &amp;quot;cost friction&amp;quot; means that, in practice, AI is only going to be as intelligent as is economically reasonable. Fundamentally, silicon AI is a luxury for the rich. As such, it doesn&amp;#39;t show up much in the slides, but I didn&amp;#39;t have time to do it justice. (This doesn&amp;#39;t go into the biological AI depicted in &lt;a href=&quot;http://www.amazon.com/Starfish-Peter-Watts/dp/0765315963/ref=pd_sim_b_1&quot;&gt;Starfish&lt;/a&gt;, but that&amp;#39;s another talk for another time.)&lt;/p&gt;
&lt;p&gt;
	The reaction from Noisebridge wasn&amp;#39;t quite what I&amp;#39;d hoped with this: most people found it really depressing.
	 I was a bit surprised, because I had made a concerted effort to scale down some of the more apocalyptic predictions
	 and pointed out that the US makes out way better than most other countries (pretty simple reason: the countries that
	  get hit the worst &lt;a href=&quot;http://www.maplecroft.com/about/news/ccvi.html&quot;&gt;are the poorest&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;
	Still, it was worth it to do the research, and I got a couple of compliments and a fun conversation afterwards.
	The future is a large and complicated subject, so I&amp;#39;m going to be going back to the presentation and
	 filling out bits as I find out more.&lt;/p&gt;
&lt;p&gt;
	EDIT: The videos of &lt;a href=&quot;http://fora.tv/2011/03/23/Hot_The_Next_50_Years_on_Earth#fullprogram&quot;&gt;Hot: The Next 50 Years&lt;/a&gt;
	and &lt;a href=&quot;http://fora.tv/2009/08/18/A_REALLY_Inconvenient_Truth_Dan_Miller&quot;&gt;A Really Inconvenient Truth&lt;/a&gt; are worth watching as well.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Responses to &#8220;Where Pair Programming Failed For Me&#8221;</title>
      <link>http://tersesystems.com/2010/12/30/responses-to-where-pair-programming-failed-for-me</link>
      <pubDate>Thu, 30 Dec 2010 00:00:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/12/30/responses-to-where-pair-programming-failed-for-me</guid>
      <description>&lt;p&gt;
    I&amp;#39;d like to thank everyone for reading &lt;a href=&quot;/2010/12/29/where-pair-programming-fails-for-me&quot;&gt;the blog post&lt;/a&gt;. &amp;nbsp;It got far more attention than I was anticipating, and while I&amp;#39;m still processing everything, I&amp;#39;m touched by how much people &amp;quot;got&amp;quot; what I was saying and responded positively to it. &amp;nbsp;There are a number of people out there that have had the same experience (or close to it) that I had, and while it&amp;#39;s not exactly fun to admit vulnerability, I&amp;#39;m happy I did it just to hear from you guys.&lt;/p&gt;


&lt;p&gt;
    So, on with the show. &amp;nbsp;There were a number of responses either in blog comments, or on Twitter (holy god Twitter exploded, thanks &lt;a href=&quot;https://twitter.com/buzz/status/20528340414767104&quot;&gt;@buzz&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/tenderlove/status/20258237722927104&quot;&gt;@tenderlove&lt;/a&gt;), or on &lt;a href=&quot;http://news.ycombinator.com/item?id=2050552&quot;&gt;Hacker News&lt;/a&gt; and &lt;a href=&quot;http://www.reddit.com/r/programming/comments/etdq1/&quot;&gt;Reddit&lt;/a&gt;. &amp;nbsp;I thought about responding to comments individually, but it makes more sense to write it up on the blog itself. &amp;nbsp;In no particular order:&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;You weren&amp;rsquo;t really doing pair programming&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    This is an easy statement to make, and a lazy one. &amp;nbsp;There were a number of engineers there, all of them very competent. &amp;nbsp;Pivotal Labs had gone through the space on at least two occasions. They had several Pivotal Labs alums on staff, and the bulk of the programming library was Agile and XP books. &amp;nbsp;They all believed this was pair programming. &amp;nbsp;If that wasn&amp;rsquo;t pair programming, I don&amp;rsquo;t know what is.&lt;/p&gt;


&lt;p&gt;
    I anticipate the response to be &amp;quot;well, it wasn&amp;#39;t done the way they say to do it in the books.&amp;quot; &amp;nbsp;Yes. &amp;nbsp;That&amp;#39;s because nothing is done the way it&amp;#39;s done in the books. &amp;nbsp;Ever.&lt;/p&gt;


&lt;p&gt;
    EDIT: And as far as I can tell, they were working &lt;a href=&quot;http://xprogramming.com/Practices/PracPairs.html&quot;&gt;directly from the book&lt;/a&gt; in that &amp;quot;all significant development is done in pairs&amp;quot; and &amp;quot;If you prefer to work alone, that&amp;#39;s fine. &amp;nbsp;You just can&amp;#39;t work with us.&amp;quot; &amp;nbsp;People who are saying pairing is a part time or optional activity &amp;#8211; are they also doing it wrong, or just tailoring it to their team? &amp;nbsp;Different practices are agreed on for different teams, and this was the practice they chose.&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;You walked into a situation where you didn&amp;rsquo;t know any of the tools. &amp;nbsp;What were you thinking?&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    I was thinking that pair programming would be an excellent way to be mentored on the appropriate use of those tools. &amp;nbsp;I was upfront about my lack of experience with those tools and front end programming in general, and was looking forward to learning about it. &amp;nbsp;Bear in mind I wasn&amp;rsquo;t going in cold: I know Ruby very well and knew at least the principles of jQuery, while knowing enough CSS and Javascript to get by. &amp;nbsp;But you&amp;rsquo;re correct: it was a large part of the problem initially. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    Something I touched on briefly in &amp;ldquo;No high notes&amp;rdquo;: the best way for me to get the feel of a framework is to sit down and work with it. &amp;nbsp;I&amp;rsquo;ll read through the manual, build a couple of example applications and push the limits of what it can do. &amp;nbsp;I&amp;rsquo;ll read through the source code, sign up to the mailing lists, find a couple of embarrassing bugs, and I&amp;rsquo;ll know the shape of it in my head. &amp;nbsp;And that knowledge is solid: I can tell you some fine details of a framework even if I haven&amp;rsquo;t touched it in five years.&lt;/p&gt;


&lt;p&gt;
    I couldn&amp;rsquo;t do that when pair programming. &amp;nbsp;Lectures and presentations tell me nothing about what the first hand experience is: it&amp;rsquo;s like thinking you know how to ride a bicycle because you saw it done on Youtube. &amp;nbsp;Time after time, my partner would happily dash out a complex jQuery statement pulling out an element by its div and class attributes, and I&amp;rsquo;d then struggle to do something similar while I was still figuring out the syntax. &amp;nbsp;Every day, I&amp;rsquo;d get more and more of an overall larger picture of the system, but it was through the corner of my eye as we were whizzing past to our destination.&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;You should have spoken up more.&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    That&amp;#39;s a fair question. &amp;nbsp;Why didn&amp;rsquo;t I speak up more? &amp;nbsp;I asked co-workers about my general experience and raised some concerns, but I didn&amp;rsquo;t push nearly as hard as I could have.&lt;/p&gt;


&lt;p&gt;
    The best answer I could give is that I expected it to be hard at first, and then to get progressively easier. &amp;nbsp;At the point where it wasn&amp;rsquo;t getting easier I was concerned, but I wasn&amp;rsquo;t going to tell them they were Doing It Wrong. &amp;nbsp;Remember that I was coming into pair programming with a very different background, and was there to learn. &amp;nbsp;I did speak up when it came to the design and refactoring issues I saw, but when it came to XP I had no basis for comparison.&lt;/p&gt;


&lt;p&gt;
    I did tell some of my partners to please stop grabbing the keyboard and suggested that I could tackle problems that didn&amp;rsquo;t require a pair, but XP is fairly clear that pair programming is the rule, not the exception. &amp;nbsp;XP is also clear that this way of working makes programmers happier and more productive. &amp;nbsp;Ultimately, I wanted to believe it. &amp;nbsp;I told myself my own experience was wrong and that the hundreds of books, blogs and comments were right. &amp;nbsp;I kept quiet. &amp;nbsp;&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;You knew pair programming was what they did and you had an interview where you pair programmed: how did you not expect this?&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    Also a fair question. &amp;nbsp;The truth is that I didn&amp;rsquo;t know what to expect, and nothing that I read in the literature lead me to expect that I would dislike it as much as I did. &amp;nbsp;The initial interview was, by necessity, done in a couple of hours with a single person in another room. &amp;nbsp;The following day of pair programming had to be cut short due to a misunderstanding with the recruiter: we&amp;rsquo;d only scheduled an hour. &amp;nbsp;The problem that was supposed to have taken a day was mostly fixed inside of that hour, and we all enjoyed the experience.&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;Have you considered autism / you must suffer from social anxiety.&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    No, I suffer from introversion. (Although, some might say I suffer from extroverts.) &amp;nbsp;Put simply, interaction with people tires me and drains me of energy. &amp;nbsp;Being in a quiet room with one person is fine. &amp;nbsp;Keeping an active conversation with background noise or a television is a noticeable drain. &amp;nbsp;Keeping a conversation up with several people at a party where loud background conversations are happening is a larger drain. &amp;nbsp;And about thirty minutes in IKEA is enough to turn me into a zombie.&lt;/p&gt;


&lt;p&gt;
    I can certainly behave in autistic fashion when I&amp;rsquo;m low energy, but it&amp;rsquo;s not my default state. &amp;nbsp;And social anxiety is something that everyone is prone to, especially when things don&amp;rsquo;t seem to &amp;ldquo;work&amp;rdquo; but it&amp;rsquo;s unclear exactly what to fix.&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;Pride in ownership is a bad thing&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    &amp;#8220;Ownership&amp;#8221; wasn&amp;rsquo;t the best term. &amp;nbsp;Pride in good craftsmanship would have been better. &amp;nbsp;I have absolutely no problem with people refactoring code &amp;#8211; just because I wrote something and it worked for a particular problem at a particular place and time doesn&amp;rsquo;t mean it can&amp;rsquo;t be made better. &amp;nbsp;Seeing how people looked at my code and did one better is actually one of the perks of the job &amp;#8211; the day I stop learning is the day I hang my hat up as a programmer.&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;It was a dysfunctional / deathmarch environment.&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    Actually, no. &amp;nbsp;While it was a dysfunctional environment for me personally, most of the people there certainly seemed to be very happy. It was about as far away from a death march as you can imagine. &amp;nbsp; Bear in mind that there were 10 programmers on the team, and we switched daily. &amp;nbsp;It&amp;rsquo;s not like I had one bad partner: it didn&amp;rsquo;t gel with any of them.&amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    They were doing a UI redesign of the entire front end, and had a hard deadline based on the engineers they had at the time. &amp;nbsp;They had evidently spent much time determining the tools and wireframes involved in the redesign. &amp;nbsp;For many of the engineers there, this was a long overdue opportunity to sit down and really crank. &amp;nbsp;Some of them were amazingly intelligent and ambitious people, as good as any I&amp;rsquo;ve worked with. &amp;nbsp;Pairing with me must have been a frustrating experience, especially for the younger developers who were not used to being mentors. &amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    For my part, I was frustrated by my own lack of skill working on the front end, and was keenly aware that I was slowing people down every time I asked a question. &amp;nbsp;Rightly or wrongly, we had a job to do. &amp;nbsp;No matter how patient and giving they were, ultimately we were being tracked on our points delivered.&lt;/p&gt;


&lt;p&gt;
And&amp;#8230; saying that there was something wrong with the environment is a lazy response. &amp;nbsp;It&amp;rsquo;s the moral equivalent of having a user file a bug, assuming user error, and then closing the bug as WORKSFORME without actually looking at the code. &amp;nbsp;&amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    Bear in mind I am not saying that their approach to development was flawed in principle or &lt;strong&gt;even in practice&lt;/strong&gt; &amp;#8211; I was but one engineer out of many and they had to consider the entire team. &amp;nbsp;Bear in mind that this company followed XP down to a very fine detail and prided itself on its software process. &amp;nbsp; I joined this company specifically because I wanted to work in a company that did Agile. &amp;nbsp;I would have left immediately if it had been obviously dysfunctional or a deathmarch.  It worked for them &amp;#8211; it didn&amp;#8217;t work for me.&lt;/p&gt;


&lt;h4&gt;
    &amp;ldquo;Why were they pairing if they had a fixed deadline and needed to crank out work?&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    Good question. &amp;nbsp;Given the context and the relatively straightforward work that they were doing, I believe that the project would have been completed faster if they had not been pairing for the duration. &amp;nbsp;It may have been slightly lower quality, but it could have worked. &amp;nbsp;It may have been that they judged the benefit of always pairing to be more valuable that any short term gain.&lt;/p&gt;


&lt;p&gt;
    But honestly, my guess is that the question never occurred to them. &amp;nbsp;Pair programming is a core practice of XP. &amp;nbsp;If you&amp;rsquo;re an XP shop, that&amp;rsquo;s what you do.&lt;/p&gt;




&lt;h4&gt; &amp;ldquo;Pair programming can produce amazing work&amp;rdquo;&lt;/h4&gt;


&lt;p&gt;
    This is something I don&amp;rsquo;t dispute. &amp;nbsp;Almost everyone I know, myself included, has done pair programming at some point and had positive results. &amp;nbsp;Even Dijkstra pair programmed and found some use in it. &amp;nbsp;&amp;nbsp;&lt;/p&gt;


&lt;p&gt;
    However, that&amp;rsquo;s very different from saying that long term pair programming is flat out better, which is what XP says. &amp;nbsp;Most studies find little appreciable difference between the work that a pair does, and the same work done individually. &amp;nbsp;Anecdotal evidence is not reliable in this field because humans are subject to all manner of cognitive bias; Hacknot (an under-appreciated website that is now an ebook) does a wonderful dissection in&amp;nbsp;&lt;a href=&quot;http://www.scribd.com/doc/459372/hacknot-book-a4&quot;&gt;Anecdotal Evidence And Fairy Taies&lt;/a&gt;. &amp;nbsp;I&amp;rsquo;m not saying it&amp;rsquo;s a worse practice in general. &amp;nbsp;But a meta analysis shows that there is &lt;a href=&quot;http://dx.doi.org/10.1016%2Fj.infsof.2009.02.001&quot;&gt;no statistical evidence&lt;/a&gt; that this is a better practice overall.&lt;/p&gt;


&lt;p&gt;
    Leaving that aside, there&amp;rsquo;s the small problem that programmers are not fungible. &amp;nbsp;The best programmers are up to &lt;a href=&quot;http://www.codinghorror.com/blog/2008/03/revisiting-the-facts-and-fallacies-of-software-engineering.html&quot;&gt;28 times better&lt;/a&gt; than the worst programmers. &amp;nbsp; Even if pair programming were proven to help the average programmer, it won&amp;#39;t work for some edge cases.&lt;/p&gt;


&lt;p&gt;
    Tying a good programmer to Guy Steele or Richard Stallman will make the good programmer slightly better, but will drastically impede Steele or Stallman. &amp;nbsp;Even tying Steele and Stallman together (or even better, Stallman and Gosling &amp;#8211; they&amp;#39;re both Emacs fans, right?) wouldn&amp;#39;t produce the output of a Voltron-like superprogrammer (EDIT: I am wrong. &amp;nbsp;They did, and &lt;a href=&quot;http://cycle-gap.blogspot.com/2007/09/extreme-pair-programming-guy-steele-and.html&quot;&gt;it did&lt;/a&gt;.). &amp;nbsp;And while I know some people who would love to be paired with Zed Shaw, Jamie Zawinski or Hani Suleiman, I&amp;rsquo;m fairly certain there are others who wouldn&amp;rsquo;t survive the experience.&lt;/p&gt;




&lt;h4&gt;EDIT: &amp;ldquo;Pair Programming done &amp;#8220;right&amp;#8221; works.&amp;rdquo;&lt;/h4&gt;


&lt;p&gt; &lt;p&gt;This is true, as far as it goes.  Pair programming is excellent at covering gaps and edge cases, and it makes doing test driven development much easier as your pair will write tests to verify your code, and vice versa.  For stupid “immediately obvious to the observer” bugs, it’s great.&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;But there’s a problem.  You can’t stop to reflect.  Without that, you are unlikely to see the larger picture of how the system will work in a larger context, or any more subtle bugs under the hood.   Even with an understanding of how the system may work in production, things like transaction management or concurrency bugs may slip past you.&lt;/p&gt;


&lt;p&gt;But that&amp;rsquo;s just my opinion.  Again, I&amp;rsquo;m not saying it doesn&amp;rsquo;t work, just that it doesn&amp;rsquo;t work for me.&lt;/p&gt;

&lt;h4&gt;
    The Point&lt;/h4&gt;


&lt;p&gt;
    This is my point: One size does not fit all. &amp;nbsp;Individuals and Interactions over processes and tools. &amp;nbsp;And if you&amp;rsquo;re considering implementing a process, think about your team and consider what works for them. &amp;nbsp;As Elisabeth says,&amp;nbsp;&lt;a href=&quot;http://testobsessed.com/2010/09/08/agile-backlash/&quot;&gt;introverts need attention too&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Where Pair Programming Fails For Me</title>
      <link>http://tersesystems.com/2010/12/29/where-pair-programming-fails-for-me</link>
      <pubDate>Wed, 29 Dec 2010 00:00:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/12/29/where-pair-programming-fails-for-me</guid>
      <description>&lt;p&gt;
     It’s been almost a year, but I think I have enough perspective now to write about my experience pair programming.  &lt;/p&gt;


&lt;p&gt;
    The short story is that pair programming doesn’t work for me as the main way of developing software.  I can pair program for a day, or maybe a week, especially if we’re focused on a particular problem.  But after that?  I’m done.  Toast.  I don’t want to see anyone, talk to anyone, and I need at least a couple of days in a cave until I’m fit for human company again. &lt;/p&gt;


&lt;p&gt;
    It’s a sad story, but the funny thing is that I’m so much happier now with how it ended.  I’m happily employed on a contract where I work from home or from a coffee shop, and I’ve made new friends and explored more of San Francisco than I ever thought possible. I have a bicycle and a laptop, and as long as I meet my deadlines and check in code regularly, my time is my own.&lt;/p&gt;


&lt;p&gt;
    I’ll list the big problems I have with pair programming up front and give you the detail and anecdotes later. &lt;/p&gt;


&lt;ol&gt;
    &lt;li&gt;
        Split focus.&lt;/li&gt;
    &lt;li&gt;
        No experimentation.&lt;/li&gt;
    &lt;li&gt;
        No high notes.&lt;/li&gt;
    &lt;li&gt;
        No pride in ownership.  &lt;/li&gt;
    &lt;li&gt;
        No escape.&lt;/li&gt;
&lt;/ol&gt;


&lt;h4&gt;
    Background&lt;/h4&gt;


&lt;p&gt;
    My background is as a backend programmer.  I’ve done inventory systems, credit card processing and fulfillment, transcoding and digital asset management.  In non-agile teams, I was used to being handed the largest, hairiest problem in a project, pulling out the domain and putting something solid together inside the deadline.&lt;/p&gt;


&lt;p&gt;
    I came into the company at the tail end of a long period of discussion where they had decided to rewrite the entire front end UI.  They were making heavy use of jQuery (a Javascript AJAX library), SASS (a CSS variant) and a library called Erector, which produced HTML markup from Ruby classes.  I knew none of these things; I knew some Javascript and CSS only from implementing them on my blog.  Because they were focusing on the UI and they were on a tight deadline, they were going to do an eight week sprint, and rewrite as much of the UI as they possibly code in that timeframe.&lt;/p&gt;


&lt;p&gt;
    So, my first day.  &lt;/p&gt;


&lt;p&gt;
    I was watching a man looking at a page &amp;#8211; what the finished product should look like.  He was telling me they’d discussed what the features should be already, and we just had to bang this out inside a day.  &lt;/p&gt;


&lt;p&gt;
    He had opened up a text editor, and we were looking at Ruby code.  The ruby class was actually a page composed of Erector methods &amp;#8211; ruby code that evaluated to HTML &amp;#8211; but it had been refactored into extremely small methods which called each other, so there was no way to ‘see’ the HTML and how that corresponded to the class &amp;#8211; you simply had to know it.  In addition, they had tests attached to each section of UI code.  If you refactored the UI, you had to rewrite all the tests.&lt;/p&gt;


&lt;p&gt;
    Sitting with another man, trying to work together to produce working code.  I was shocked at how unnatural and unintuitive it felt.  Far from being an easy practice, it felt both clumsy and shockingly intimate; both too personal and impersonal.  &lt;/p&gt;


&lt;p&gt;
    If I asked a question, then work stopped.  &lt;/p&gt;


&lt;p&gt;
    If I asked about the background of the code or the design, then work stopped.  &lt;/p&gt;


&lt;p&gt;
    If I tried to follow along, then I found that I was trying to guess at what various methods and frameworks did.  I was being bounced between the domain classes, the Erector classes, the Javascript and the various tests, and I didn’t have a grasp on any of them.  &lt;/p&gt;


&lt;p&gt;
    I understood the HTML code, but even there, I didn’t even know what to say &amp;#8211; did I point out the typos?  The two methods that were almost exactly the same except for the innermost loop?  Was I nitpicking by pointing these things out, or signalling my involvement?&lt;/p&gt;


&lt;p&gt;
    And then, he was done.  It was time for me to write some code.  I opened up some files, looked around at the methods.  Tried to figure out what was going on, and write some exploratory code to see what was happening&amp;#8230;  And then my pair started typing the method I was trying to write, handing it back for me to test.  I found that this would happen if I paused too long, or seemed to be typing the wrong thing &amp;#8211; my pair had another keyboard, and he would type over me to try to “finish the sentence” rather than talk to me. &lt;/p&gt;


&lt;p&gt;
    At the end of my first day, I had a massive headache from trying to absorb everything.  I was told I’d done very well, and that it was a lot to take in on the first day.  I didn’t feel like I’d been very productive, but I hoped that we could settle down into some kind of flow.&lt;/p&gt;


&lt;h4&gt;
    Split Focus&lt;/h4&gt;


&lt;p&gt;
    Split focus happens when I try to do two things at once.  Human beings are not good at multitasking in general, and I’m worse than most.  Pair programming is a balancing act between managing code and managing the pair that you’re working with.  Go too far in one direction or another, and you both fall off and lose effectiveness until you restore balance again.&lt;/p&gt;


&lt;p&gt;
    I found that in order to pair, I had to act as if I was in a continuous meeting.  I had to not just listen to my pair, but appear to be listening; I had to nod in the right places, repeat back what my pair said in active listening fashion.  I had to pick the right moment to interject.   I tried to model my partner’s mental state in my head so I could see his viewpoint better. &lt;/p&gt;


&lt;p&gt;
    While I was doing this, I was trying to see the code that he was writing, and the design that he was trying to make the code fit.  If there was a failing test, I was trying to figure out the test and the test framework at the same time.&lt;/p&gt;


&lt;p&gt;
    And if I was writing code, I found something very interesting: I don’t think in English when I write code.  I think in code first, and I can translate written code to English.  When I was trying to talk to people when I was writing code, I found that I’d have to write pseudocode and then talk to them about it &amp;#8211; and when my pair wanted me to talk about code, he wanted me to stop typing.  But if I stopped typing, I couldn’t describe what I was doing.  Every time I tried to write code and talk to my partner at the same time, I could feel the lurch between what I could feel &amp;#8211; the complex shape of it in my head &amp;#8211; and what I was having to say.&lt;/p&gt;


&lt;p&gt;
    So pair programming split my focus not just in one way.  It split it in three or four different ways, and kept it split.  No wonder I had a headache.&lt;/p&gt;


&lt;h4&gt;
    No experimentation&lt;/h4&gt;


&lt;p&gt;
    The large part of pair programming was doing things in “The Simplest Possible Way That Could Work.”  In practice, this meant doing it the way that it had been done previously, with the least possible amount of change.&lt;/p&gt;


&lt;p&gt;
    The way that the Erector toolkit was used, combined with pair programming and test driven development, ensured that two Ruby programmers were required to change any and all elements of the UI.  Tests were written to check for every single element in the UI, and with good reason; because elements of the UI had been abstracted out into subclasses and views, there was no clear way to see what code would do until it had been fully executed.  Sometimes the simplest possible thing to do had been to hack one of the classes for a special-case logic.  Then more code had been put on top, until a refactoring was just too expensive.  As long as all the tests were passing, the code was in a known, &amp;#8220;good&amp;#8221; state &amp;#8211; and we had to keep it that way.&lt;/p&gt;


&lt;p&gt;
    The simplest thing that could possibly work as far as I was concerned was to put together an ERB page.  A straight HTML page with some embedded Ruby was a known, easy solution that would have enabled straight web designers to work on the UI without involving the full programming team, or at least have allowed us to quickly compare the mockup with a page.  But that ran into another problem; there is no facility in pair programming to change tracks, or try anything different.  Spikes only happen at the beginning of an iteration, and this iteration was budgeted at 8 weeks &amp;#8211; we were locked into our current way of doing things.&lt;/p&gt;


&lt;p&gt;
    Not that it mattered; there was simply no leverage to explore the framework or try different approaches.  Any code changes that weren’t immediately applicable to changing the current page were “going off track”.  I couldn’t see the parameters of the current system, or feel for the fragile points if it didn’t match up with what my pair thought was important.  Every single moment I was typing, I was being watched.&lt;/p&gt;


&lt;h4&gt;
    No high notes&lt;/h4&gt;


&lt;p&gt;
    &lt;meta content=&quot;text/html; charset=utf-8&quot; equiv=&quot;content-type&quot; /&gt;When I got to the point where I understood some of the framework, I saw that there were some bugs inherent in the existing design which would make the system act unpredictably in production.  In other situations, the design could improved by eliminating some classes and moving some other classes to have a single responsibility.&lt;/p&gt;


&lt;p&gt;
    To me, this was “refactor mercilessly” and “once and only once.”  But to my partner, this was a violation of “do the simplest thing that could possibly work.”  It also went against the daily switching of partners.  Whatever you start when you pair has to be finished, and checked in, by the end of the day.  If you’re only looking at getting the story done by the end of the day, you’re not interested in hypothetical bugs or refactoring &amp;#8211; you don’t have time for them and they’re not budgeted for.  &lt;/p&gt;


&lt;p&gt;
    The only way I could move discussion along was if I could write a test for it.  If I couldn’t write an effective test, or I described it in unfamiliar terms (usually from books or blogs), he wouldn’t hear “solves a problem that is difficult to test but is real.”  He would hear “introduces needless complexity and complicates design” and point to the simplest solution that makes sense to him.  If I tried writing a test and it took too long, I lost there as well. &lt;/p&gt;


&lt;p&gt;
    Eventually, I realized that many of my partners had never worked outside a test driven development process: they didn’t have the same idea of design or architecture as patterns distinct from code.  Trying to argue for encapsulation or adherence to SOLID principles is pointless if your partner has no background, let alone hands on experience, with what you’re saying.  This goes double when you’re talking about hard-won domain expertise: the more I knew about a subject, the less I could say.&lt;/p&gt;


&lt;p&gt;
    I started picking my battles.  &lt;/p&gt;


&lt;p&gt;
    How you pick your battles is, you plan to lose in the best way possible.  You try to leave an opening so that the bug that you know, from past experience, is going to hit, is not going to result in any lost data and can be easily fixed later.  It’s not great, but at least you can recover from it.&lt;/p&gt;


&lt;p&gt;
    There are no high notes, no thought out design.  There’s only the design that could have tests written for it, in the time you had to write the tests.  The classes look reasonable at first glance, and the methods are seemingly bug free.  But the cracks are there, if you know where to look.&lt;/p&gt;


&lt;h4&gt;
    No pride in ownership&lt;/h4&gt;


&lt;p&gt;
    There is no ownership in pair programming.  You’re working on a different piece every day, with a different partner.  Everyone owns all the code equally.  No-one really has responsibility for a single piece of it.  Pair programming views this as a strength.&lt;/p&gt;


&lt;p&gt;
    I had no pride in ownership.  The code that ended up on the ground every day wasn’t something I felt I had input into.  It didn’t feel right to me.  Doing a good job matters to me.  My idea of a good job: years after I’d moved on from one project, someone I’d never met wrote me a thank you note for taking the time to make my code clear and easy to work with.&lt;/p&gt;


&lt;p&gt;
    The part of my brain that works though code will chew through things.  Impede the flow, and that part of my brain starts to itch.   Block it, and it starts pounding, chewing away at anything that comes close.  Without pride in ownership, there was no meaning to any of the work that I was doing.  I couldn’t even identify it as mine.&lt;/p&gt;


&lt;p&gt;
    It was about this time that my physical health started to pack up.  Winter set in, and it started raining constantly.  I got a cold that got into my lungs.  I couldn’t climb the stairs without resting.  I couldn’t write code.  I couldn’t think.  The rain beat against my window.  I couldn’t sleep.&lt;/p&gt;


&lt;h4&gt;
    No escape&lt;/h4&gt;


&lt;p&gt;
    The worst part of pair programming was getting up in the morning and realizing I had to do it all over again.   No matter how drained I was, no matter how much I wanted to get away from people: I couldn’t.  As an introvert, I yearned to be left alone with a large problem and the freedom to slice it into pieces.  But there was no escape. &lt;/p&gt;


&lt;p&gt;
    Even at the best of times, there were people.  First, a fifteen minute standup meeting.  Then sitting down at a work station with engineers on either side of me, two to a table.  Talking.  An engineer sitting next to me in my personal space.  Every moment I was sitting there watching him, I was trying to think of something to say.  Whenever I was typing I was worried that I was too slow, or that I was taking too much time to think, wasn’t saying enough, wasn’t being clear.  Was I being anti-social?  Talking too much?  Too much smalltalk?  There was no way to know.&lt;/p&gt;


&lt;p&gt;
    Even when pairing worked, it was the slow, clumsy communication of two people trying to move a large sofa down a staircase.  There was no flow.  There were no spots where there was no conscious movement between thinking something and having it appear on the screen.  I missed it horribly.  Even the small discussions: was having “as_currency” method on an ActiveRecord Model the correct thing to do?  Or was it something that should belong to the UI, as a helper method?  Just how much did I really care?&lt;/p&gt;


&lt;p&gt;
    And then a group lunch, where there was food, small talk and team bonding experiences.  I started stealing moments of solitude whenever I could.  &lt;/p&gt;


&lt;p&gt;
    I asked my co-workers if they saw what I saw, if I was missing something, anything &amp;#8211; I didn’t see how this could work, how people could keep doing this.  They said I was doing fine, that it just took time to settle in and adjust.  That it was hard for everyone at first.&lt;/p&gt;


&lt;p&gt;
    Eventually, I retreated into myself.  Between the blinding headaches, the insomnia, and the pounding, unmet need to write code, I stopped responding to input.  I could stare at a screen and not see anything.  Someone could talk to me unexpectedly and I wouldn’t hear them.  I was fulfilling the rote requirements of my job, but I wasn’t there.  I’d used up everything I had just showing up for the day.  I started checking my iPhone when my other partner was typing.&lt;/p&gt;


&lt;p&gt;
    Finally &amp;#8211; just shy of three months later, and for the first time ever &amp;#8211; I was fired for not being a team fit when pair programming.&lt;/p&gt;


&lt;h4&gt;
    Not Alone&lt;/h4&gt;


&lt;p&gt;
    I wrote this not just to understand it, but also to be able to talk about it.  There’s been a presumption that pair programming works for most people and is much easier and faster than programming solo would be.  This may or may not be the case, but as a long term practice, pair programming doesn’t work for me.  There are many other people that pair programming doesn’t work for either.  We matter too.&lt;/p&gt;


&lt;p&gt;
    Mark Wilden had a &lt;a href=&quot;http://mwilden.blogspot.com/2009/11/why-i-dont-like-pair-programming-and.html&quot;&gt;similar experience&lt;/a&gt; at Pivotal Labs. His discussion of design rings very true.&lt;br /&gt;
    Nick Carroll says that pair programming is &lt;a href=&quot;http://ca.rroll.net/2009/01/04/pair-programming-is-not-for-me/&quot;&gt;not for him&lt;/a&gt;. He thinks peer review is more useful.&lt;br /&gt;
    William Pietri has a list of &lt;a href=&quot;http://agilefocus.com/2009/01/06/21-ways-to-hate-pair-programming/&quot;&gt;anti-social practices&lt;/a&gt;, many of which I saw and/or practiced.&lt;br /&gt;
    Software Reality has more to say about the XP approach to &lt;a href=&quot;http://www.softwarereality.com/lifecycle/xp/key_rules.jsp&quot;&gt;pair programming and design&lt;/a&gt;.  He also has a seperate &lt;a href=&quot;http://www.theregister.co.uk/2007/01/31/perils_pair_programming/&quot;&gt;p&lt;/a&gt;&lt;a href=&quot;http://www.theregister.co.uk/2007/01/31/perils_pair_programming/&quot;&gt;ost&lt;/a&gt; addressing pair programming specifically.&lt;br /&gt;
    A CodeRanch discussion also &lt;a href=&quot;http://www.coderanch.com/t/130868/Agile/Pair-programming-sucks&quot;&gt;discusses issues&lt;/a&gt; with pair programming, including Damon Black’s &lt;a href=&quot;http://www.coderanch.com/t/130868/Agile/Pair-programming-sucks#636650&quot;&gt;experience&lt;/a&gt;.&lt;br /&gt;
    More generally, Daniel Markham talks about some gaps in agile &lt;a href=&quot;http://www.whattofix.com/blog/archives/2010/09/agile-ruined-my.php&quot;&gt;as it is practiced&lt;/a&gt; and has made an interesting list of the &lt;a href=&quot;http://www.whattofix.com/blog/archives/2010/09/agilholics-anon.php&quot;&gt;responses&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    EDIT: Also, Kathy Sierra writes about her experiences with pair programming in &lt;a href=&quot;http://weblogs.java.net/blog/kathysierra/archive/2004/03/pair_programmin.html&quot;&gt;Pair Programming is NOT a choice&lt;/a&gt;, complete with pre-filled in responses.&lt;/p&gt;


&lt;p&gt;
    EDIT: Another programmer describes &lt;a href=&quot;http://www.techrepublic.com/forum/discussions/10-97701-1536234?tag=discussion-asset-thread&quot;&gt;his experience&lt;/a&gt; and gets a follow up response &lt;a href=&quot;http://efficientsoftwaremethodology.wordpress.com/esdm-home/pair-programming/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    EDIT: Another article: &lt;a href=&quot;http://www.perlmonks.org/?node_id=823108&quot;&gt;Nobody Expects The Agile Imposition&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    EDIT: Alex Ruiz discusses his &lt;a href=&quot;http://www.jroller.com/alexRuiz/entry/mixed_feelings_about_pair_programming&quot;&gt;mixed feelings&lt;/a&gt; about pair programming.&lt;/p&gt;


&lt;p&gt;
    EDIT: A story from Xebia about &lt;a href=&quot;http://blog.xebia.com/2011/04/true-agile-stories-chris-the-tester/&quot;&gt;Chris, the tester&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    EDIT: Jay Fields talks about why he doesn&amp;#8217;t pair program &lt;a href=&quot;http://blog.jayfields.com/2011/08/life-after-pair-programming.html&quot;&gt;any more&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
  EDIT: Adam Logic discusses his dislike of pair programming and compares it to &lt;a href=&quot;https://gist.github.com/1369045&quot;&gt;Design By Committee&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
  EDIT: Buzz Andersen: &amp;#8221;&lt;a href=&quot;http://log.scifihifi.com/post/20670335726/techcrunch-pair-programming-considered-harmful&quot;&gt;I’ve never been more sure of my absolute distaste for anything in my professional life.&lt;/a&gt;&amp;#8221;
  &lt;/p&gt;


&lt;p&gt;
    Also, it’s important to note that I still believe that Agile development can lead to better business solutions with less wasted effort.  
    Pair programming is part of a single agile process called XP, and there are many other Agile processes such as
    &lt;a href=&quot;http://www.agilekiwi.com/other/agile/crystal-clear-methodology/&quot;&gt;Crystal Clear&lt;/a&gt; which do not mandate pair
     programming as a daily practice.&lt;/p&gt;


&lt;p&gt;EDIT: I&amp;#8217;ve read through the responses and replied &lt;a href=&quot;/2010/12/30/responses-to-where-pair-programming-failed-for-me&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Best Practices Crypto Algorithms</title>
      <link>http://tersesystems.com/2010/10/08/best-practices-crypto-algorithms</link>
      <pubDate>Fri, 08 Oct 2010 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/10/08/best-practices-crypto-algorithms</guid>
      <description>&lt;p&gt;
    I&amp;#8217;ve always wanted just a nice simple list of what crypto algorithms go where. Finally, from &lt;a href=&quot;http://www.subspacefield.org/security/web_20_crypto/&quot;&gt;Web Security 2.0&lt;/a&gt;:&lt;/p&gt;


&lt;ul&gt;
    &lt;li&gt;
        &lt;a href=&quot;http://en.wikipedia.org/wiki/Advanced_Encryption_Standard&quot;&gt;AES256&lt;/a&gt; in CBC mode for encryption&lt;/li&gt;
    &lt;li&gt;
        &lt;a href=&quot;http://en.wikipedia.org/wiki/SHA-2&quot;&gt;HMAC-SHA512&lt;/a&gt; for integrity protection&lt;/li&gt;
    &lt;li&gt;
        &lt;a href=&quot;http://en.wikipedia.org/wiki/SHA-2&quot;&gt;SHA-256&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/SHA-2&quot;&gt;SHA-512&lt;/a&gt; with salt for hashing&lt;/li&gt;
    &lt;li&gt;
        &lt;a href=&quot;http://en.wikipedia.org/wiki/PBKDF2&quot;&gt;PBKDF2&lt;/a&gt; or &lt;a href=&quot;http://en.wikipedia.org/wiki/Bcrypt&quot;&gt;bcrypt&lt;/a&gt; for passwords, see &lt;a href=&quot;http://security.stackexchange.com/a/6415&quot;&gt;here&lt;/a&gt; for a comparison between the two.&lt;/li&gt;
    &lt;li&gt;
        /dev/urandom or RtlGenRandom/CryptGenRandom&amp;nbsp;for random numbers&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    
    <item>
      <title>Simplest Possible Acceptance Test</title>
      <link>http://tersesystems.com/2010/10/05/simplest-possible-acceptance-test</link>
      <pubDate>Tue, 05 Oct 2010 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/10/05/simplest-possible-acceptance-test</guid>
      <description>&lt;p&gt;
    If you are fed up with walking through the same flow over and over again and want to have some code drive the browser around (what is sometimes called is known as acceptance/system/end-to-end testing) and don&amp;#39;t know quite how: this is for you.&lt;/p&gt;


&lt;p&gt;
    I remember when I first wanted to automate my tests. It was painful. Not only did I have to read through lots and lots of documentation, but so much of it was out of date, or badly written, or just incomplete. So let me say up front: I&amp;#39;ve read through a bunch of different options. The best option right now (October 2010) is &lt;a href=&quot;http://seleniumhq.org/docs/09_webdriver.html&quot;&gt;Selenium Webdriver&lt;/a&gt;.&lt;/p&gt;


&lt;p&gt;
    There are a variety of options for setting up Webdriver. If you want to do it using raw Java, then the &lt;a href=&quot;http://seleniumhq.org/docs/09_webdriver.html#the-5-minute-getting-started-guide&quot;&gt;5 minute guide&lt;/a&gt; is your best option.&lt;/p&gt;


&lt;p&gt;
    The way I do it normally is to use &lt;a href=&quot;http://github.com/jnicklas/capybara&quot;&gt;Capybara&lt;/a&gt; and &lt;a href=&quot;http://github.com/cavalle/steak&quot;&gt;Steak&lt;/a&gt;, and tie them together with &lt;a href=&quot;http://rspec.info/&quot;&gt;rspec&lt;/a&gt; &amp;#8211; I find writing tests easier this way, both because Capybara tries very hard to make the API intuitive, and because Ruby tends to be very concise. What this looks like in practice is:&lt;/p&gt;


&lt;pre&gt;# spec/acceptance/checkout_spec.rb
require File.dirname(__FILE__) + &amp;#39;/acceptance_helper&amp;#39;

# You may find the following useful:
#
# http://rspec.info/documentation/
# http://jeffkreeftmeijer.com/2010/steak-because-cucumber-is-for-vegetarians/
# http://richardconroy.blogspot.com/2010/08/capybara-reference.html
#
feature &amp;quot;Feature name&amp;quot;, %q{
  In order to check out
  As a user
  I want to submit an order
} do

  scenario &amp;quot;Checkout&amp;quot; do
    email = Time.now.to_i.to_s + &amp;#39;@example.com&amp;#39;
    
    visit &amp;quot;/orders&amp;quot;
  
    within(&amp;quot;//form[@id=&amp;#39;commitOrderForm&amp;#39;]&amp;quot;) do
      fill_in &amp;quot;login-email&amp;quot;, :with =&amp;gt; email
      fill_in &amp;quot;login-pass&amp;quot;, :with =&amp;gt; &amp;#39;password1&amp;#39;
      fill_in &amp;quot;login-pass-confirm&amp;quot;, :with =&amp;gt; &amp;#39;password1&amp;#39;
      
      find(&amp;quot;//input[@type=&amp;#39;submit&amp;#39;]&amp;quot;).click
    end
    
    page.should have_content(&amp;quot;Your order is complete&amp;quot;)
  end

end
&lt;/pre&gt;


&lt;p&gt;
    There is some stuff in the acceptance_helper.rb you have to worry about:&lt;/p&gt;


&lt;pre&gt;# spec/acceptance/acceptance_helper.rb
require File.dirname(__FILE__) + &amp;quot;/../spec_helper&amp;quot;

require &amp;quot;steak&amp;quot;
require &amp;#39;capybara&amp;#39;
require &amp;#39;capybara/dsl&amp;#39;

Capybara.default_driver = :selenium                # Uses webdriver by default.
Capybara.app_host = &amp;#39;http://localhost:8080&amp;#39;        # used for relative URLs.
Capybara.run_server = false                        # turn off the internal rack server.
Capybara.default_wait_time = 5

Spec::Runner.configure do |config|
  config.include Capybara 
end

# Put your acceptance spec helpers inside /spec/acceptance/support
Dir[&amp;quot;#{File.dirname(__FILE__)}/support/**/*.rb&amp;quot;].each {|f| require f}
&lt;/pre&gt;


&lt;p&gt;
    And then there&amp;#39;s the spec helper itself:&lt;/p&gt;


&lt;pre&gt;# spec/spec_helper.rb
require &amp;#39;spec&amp;#39;

# Requires supporting files with custom matchers and macros, etc,
# in ./support/ and its subdirectories.
Dir[File.expand_path(File.join(File.dirname(__FILE__),&amp;#39;support&amp;#39;,&amp;#39;**&amp;#39;,&amp;#39;*.rb&amp;#39;))].each {|f| require f}

Spec::Runner.configure do |config|

end
&lt;/pre&gt;


&lt;p&gt;
    That&amp;#39;s pretty much it as far as Ruby code goes. Note that you will need to set up all the gems first. Here&amp;#39;s what should be in the Gemfile:&lt;/p&gt;


&lt;pre&gt;# Gemfile
gem &amp;#39;rspec&amp;#39;
gem &amp;#39;steak&amp;#39;
gem &amp;#39;capybara&amp;#39;
&lt;/pre&gt;


&lt;p&gt;
    And, well&amp;#8230; you&amp;#39;ll need to install Ruby. This can be a pain, but it&amp;#39;s at least a fairly well known one and there are many guides that will show you the way. Assuming that you&amp;#39;re using MacOS (If you are using Linux or another Unix based system, you do not need to install MacPorts and disable the OOTB Ruby):&lt;/p&gt;


&lt;div&gt;
    Disable the OOTB Ruby by moving:&lt;/div&gt;


&lt;pre&gt;  mv /usr/bin/ruby /usr/bin/ruby.bak
  mv /usr/bin/gem /usr/bin/gem.bak
&lt;/pre&gt;


&lt;div&gt;
    Install MacPorts and add it to your PATH environment variable. (Note, this may require Xcode Tools and X11 as prerequisites, please see http://guide.macports.org/#installing)&lt;/div&gt;


&lt;pre&gt;  sudo port selfupdate
&lt;/pre&gt;


&lt;div&gt;
    Install the MacPorts Ruby:&amp;nbsp;&lt;/div&gt;


&lt;pre&gt; sudo port install ruby&lt;/pre&gt;


&lt;div&gt;
    Make sure that rubygems is up to date:&amp;nbsp;&lt;/div&gt;


&lt;pre&gt;  sudo port install rb-rubygems # or download rubygems from rubyforge &#8211; they seem to break their update method every odd number of releases
  sudo gem update &#8211;system
&lt;/pre&gt;


&lt;div&gt;
    Install a library that Capybara uses:&lt;/div&gt;


&lt;pre&gt;  sudo port install libffi
&lt;/pre&gt;


&lt;div&gt;
    And then finally, we can install bundler, and then the bundle:&lt;/div&gt;


&lt;pre&gt;  sudo gem install bundler
  cd mytests # assume you have Gemfile here
  bundle install
&lt;/pre&gt;


&lt;div&gt;
    Then to run the spec:&lt;/div&gt;


&lt;pre&gt;  spec spec/acceptance/checkout_spec.rb
&lt;/pre&gt;


&lt;div&gt;
    And finally: I know how frustrating it can be to get everything set up even for the &amp;quot;simplest&amp;quot; solution, so I&amp;#39;ve tried my best not to leave out any steps here. If you&amp;#39;ve gone through these steps and they don&amp;#39;t work for you, don&amp;#39;t stew: send me an email at will.sargent@gmail.com. Send me a stack trace and I&amp;#39;ll see if I can help.&lt;/div&gt;


&lt;div&gt;
    &lt;span _fck_bookmark=&quot;1&quot; id=&quot;cke_bm_53E&quot; style=&quot;display: none; &quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;

</description>
    </item>
    
    <item>
      <title>Information Radiator with Toodledo</title>
      <link>http://tersesystems.com/2010/10/04/information-radiator-with-toodledo</link>
      <pubDate>Mon, 04 Oct 2010 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/10/04/information-radiator-with-toodledo</guid>
      <description>&lt;p&gt;In something that has been fairly two years in the making, I wrote a &lt;a href=&quot;http://github.com/wsargent/toodledo&quot;&gt;Toodledo gem&lt;/a&gt; for Ruby, bought a USB Betabrite Machine, and finally got the two talking to one another.&lt;/p&gt;




&lt;p&gt;Here is what goes into Toodledo:&lt;a href=&quot;http://twitpic.com/2uh58x&quot;&gt; http://twitpic.com/2uh58x&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Here is what comes out of the Betabrite: &lt;a href=&quot;http://twitpic.com/2uh5ft&quot;&gt;http://twitpic.com/2uh5ft&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;It’s based on a Thoughtworks project called Radiator (which, in turn, uses some of &lt;a href=&quot;http://tenderlovemaking.com/category/computadora/betabrite/&quot;&gt;Aaron Patterson&amp;#8217;s code&lt;/a&gt;, the inspiration for this): I forked the code and then pounded on it until it did what I wanted.  The fork is here: &lt;a href=&quot; http://github.com/wsargent/radiator &quot;&gt;http://github.com/wsargent/radiator&lt;/a&gt; and I’ve tried to include as clear step by step instructions as I could.  I’ve tried to write it so I can add other plugins as well (twitter, itunes, bugs, build failures) that I can add without changing the core rendering server.&lt;/p&gt;




&lt;p&gt;&lt;p&gt;As a management tool, it is surprisingly effective and unobtrusive.  If I’m working on something and it scrolls by, it’s a good feeling.  If I’m doing something else and it scrolls by, then it’s a context shift rather than an alarm &amp;mdash; I can choose to do something else, but I am at least reminded of it.  And if I’m in a space where I can easily do it, then it’s a win.&lt;p&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Why you should be using PostgreSQL with Rails</title>
      <link>http://tersesystems.com/2010/09/30/why-you-should-be-using-postgresql-with-rails</link>
      <pubDate>Thu, 30 Sep 2010 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/09/30/why-you-should-be-using-postgresql-with-rails</guid>
      <description>&lt;p&gt;
Rails has a problem.  The standard way of dealing with scale in Rails is to scale horizontally: add more servers.  This is commonly called &amp;#8220;shared nothing&amp;#8221;, although it&amp;#8217;s really more &amp;#8220;shared database&amp;#8221; &amp;#8211; the usual pattern is that no state is kept in individual application servers.
&lt;/p&gt;




&lt;p&gt;
That&amp;#8217;s not the case in a stateful application that uses the database directly.  As soon as you have several servers running in parallel against the database, you are essentially running concurrently.  There are many subtle problems in dealing with concurrency, but it turns out that there are some very nasty bugs that only show up with multiple servers: depending on the libraries you&amp;#8217;re using, your collections can get out of sync.
&lt;/p&gt;




&lt;p&gt;&lt;p&gt;
Xavier Shay has done an excellent job of documenting this, so I&amp;rsquo;ll wait while you go read the following links:
&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://rhnh.net/2010/07/05/acts-as-state-machine-is-not-concurrent&quot;&gt;Acts As State Machine is not concurrent&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://rhnh.net/2010/06/30/acts-as-list-will-break-in-production&quot;&gt;Acts As list will break in production&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://github.com/collectiveidea/awesome_nested_set/issues#issue/33&quot;&gt;Massively corrupted nested set using awesome_nested_set&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
You have some choices when you have concurrency, and you need to maintain state immediately.  You can use a central lock server.  Or you can use the locking that comes into the database in the form of transactions or optimistic locking.  And, in fact, the &amp;ldquo;quick fixes&amp;rdquo; for using acts as list or acts as state machine involve wrapping it in a SERIALIZABLE transaction.
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
So.  Why don&amp;rsquo;t Rails developers use transactions?  More broadly, why the aversion to databases in general?  Why do Rails developers tend to treat the database as a &lt;a href=&quot;http://www.loudthinking.com/arc/2005_09.html&quot;&gt;raw, dumb datastore&lt;/a&gt; and shun &lt;a href=&quot;http://lesscode.org/2005/09/29/should-database-manage-the-meaning/&quot;&gt;even simple database constraints&lt;/a&gt;?&lt;p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
Frankly, I think the reason is &lt;a href=&quot;http://howfuckedismydatabase.com/&quot;&gt;MySQL&lt;/a&gt;.
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
From what I can tell, MySQL got where it was mostly by having better documentation than PostgreSQL when it really mattered, working on Windows with IIS, and better marketing.  It came in by default by Perl and PHP websites, and never left.  For a long time, MySQL didn&amp;rsquo;t support transactions, let alone sub selects &amp;mdash; and since it was the first database that most developers had been introduced to, they didn&amp;rsquo;t know it worked any other way.
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
Now MySQL has transactions.  Sort of.  Most of the time, they work.  But sometimes, they deadlock.
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
To a developer, it can seem like deadlock can happen for pretty much any reason at all.
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
&lt;ul&gt;
&lt;li&gt;A single insert into an InnoDB table can cause a deadlock, because they use row level locks internally.&lt;/li&gt;
&lt;li&gt;Foreign key references use row level locks internally.&lt;/li&gt;
&lt;li&gt;You can also get silent deadlocks &amp;mdash; you&amp;rsquo;ll just get lock wait timeouts when you have row level locking between an InnoDB table and a table level lock MyISAM table, and it won&amp;rsquo;t trigger the InnoDB deadlock detection.&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;The &lt;a href=&quot;http://dev.mysql.com/doc/refman/5.1/en/innodb-deadlocks.html&quot;&gt;documentation&lt;/a&gt; mentions that you should be prepared to reissue a transaction if it fails.&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
&lt;blockquote&gt;&amp;ldquo;Always be prepared to re-issue a transaction if it fails due to deadlock. Deadlocks are not dangerous. Just try again.&amp;rdquo;&lt;/blockquote&gt;
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;This is not something you can do when you&amp;rsquo;ve submitted a credit card authorization to the payment gateway.&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;But MySQL doesn&amp;rsquo;t stop there.  It also &lt;a href=&quot;http://stackoverflow.com/questions/110927/do-you-recommend-postgresql-over-mysql/112805#112805&quot;&gt;locks the entire table&lt;/a&gt; when you add or remove a column or an index.  It does this because, under the hood, it creates a new table with the extra column, and then copies all the data from one table to the other.  I have seen this take hours.  This gets even worse when you consider that the quick fix solution, creating auxiliary tables and joining between them, will only work up to the point where it gets you into serious trouble.  Add this to the naive query optimizer that MySQL uses under the hood, and &lt;a href=&quot;http://arstechnica.com/civis/viewtopic.php?f=20&amp;t=92525&quot;&gt;you&amp;rsquo;re screwed&lt;/a&gt;.  (Let&amp;rsquo;s not even talk about the &lt;a href=&quot;http://exortech.com/blog/2009/11/30/weekly-release-53-environment-bug-bites/&quot;&gt;bugs&lt;/a&gt;.)
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
My theory is that Rails developers treat the database as a raw, dumb datastore with &lt;a href=&quot;http://www.thirdbit.net/articles/2007/11/02/database-constraints-stereotypes-rails-culture-talmud-gender-minaswan-religion-but-absolutely-no-bondage-play/&quot;&gt;no data integrity&lt;/a&gt; because that is all MySQL is good for. Every time they tried to follow &amp;ldquo;best DBA practice&amp;rdquo; and do useful with MySQL, &lt;a href=&quot;http://blog.amber.org/2005/09/27/least-common-denominator/&quot;&gt;they got bit&lt;/a&gt;, and the more they started hating touching (or even thinking about) databases. Over time, MySQL has trained developers into avoiding the bits that don&amp;rsquo;t work effectively.  It&amp;rsquo;s now to the point where it&amp;rsquo;s controversial to use any database features at all.
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;&lt;u&gt;TL;DR&lt;/u&gt;&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;Use &lt;a href=&quot;http://www.postgresql.org/&quot;&gt;PostgreSQL&lt;/a&gt;.  It&amp;rsquo;s a much better choice if you&amp;rsquo;re in any kind of startup.  Not only does it have better transaction support, it allows you to &lt;a href=&quot;http://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis&quot;&gt;rollback DDL operations&lt;/a&gt;, so you can do complicated schema upgrades atomically.  If you&amp;rsquo;re doing a bunch of database migrations and refactorings, this is really useful.  PostgreSQL does have some gotchas (notably, raw COUNT(*) can be slow), but you can always use counter_cache.&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;If you need to get hold of data really fast, use NoSQL, or plug memcached into &lt;a href=&quot;http://github.com/nkallen/cache-money&quot;&gt;CacheMoney&lt;/a&gt;.  Then start working your way into replication, either using the built in PostgreSQL 9.0 or &lt;a href=&quot;http://www.continuent.com/news/press/950-continuenttungstenofferscaleoutsolutionforpostgresql9&quot;&gt;Tungsten&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;Wrap all your controller logic in transaction blocks, or move your ActiveRecord logic into a service / manager class and set up transaction management around that.  Either way, transactional behavior should be the default.   Use &lt;a href=&quot;http://github.com/matthuhiggins/foreigner&quot;&gt;Foreigner&lt;/a&gt; to integrate foreign key references into ActiveRecord migrations, and use &lt;a href=&quot;http://ewout.name/2009/12/rails-models-with-teeth-and-database-constraints/&quot;&gt;simple constraints&lt;/a&gt; to enforce integrity.  You should still use application level validation as you will get better error messages and have finer control, but things like &amp;ldquo;validates_uniqueness_of&amp;rdquo; are more trouble than they are worth.
&lt;/p&gt;&lt;/p&gt;

&lt;p&gt;&lt;p&gt;Finally, have Xavier Shay give a demonstration at your company.  I&amp;rsquo;ve never met the man, but his website is &lt;a href=&quot;http://dbisyourfriend.com/&quot;&gt;right on the money&lt;/a&gt;.&lt;/p&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What I Believe About Writing Software</title>
      <link>http://tersesystems.com/2010/09/28/what-i-believe-about-writing-software</link>
      <pubDate>Tue, 28 Sep 2010 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/09/28/what-i-believe-about-writing-software</guid>
      <description>&lt;p&gt;
So. I left ATG consulting so I could get a better understanding of what different environments are like. I&amp;#8217;ve worked at a variety of startups, and written some Ruby, some Scala, even some Flex and Actionscript, and done a fair amount of fixing, writing and rewriting different systems and architectures.
&lt;/p&gt;




&lt;p&gt;
The good news is that all in all, I don&amp;#8217;t suck. I&amp;#8217;m very much of the &lt;a href=&quot;http://domaindrivendesign.org/resources/what_is_ddd&quot;&gt;&amp;#8220;Domain Driven Design&amp;#8221;&lt;/a&gt; school of development: I think that the domain and the concerns of the business team are a (if not THE) priority and I believe that it&amp;#8217;s possible to write code in such a way that makes it hard to write bugs.  I&amp;#8217;ve tried different styles, and while the style of code I prefer has been charitably described as &amp;#8220;verbose and up front,&amp;#8221; I think it is clear and leaves little room for ambiguity.  If there are bugs, it&amp;#8217;s not a mystery where they are &amp;#8211; I don&amp;#8217;t like metaprogramming and I don&amp;#8217;t like using any more tricks than I have to, so I can live with the occasional verbosity.  In fact, some of the code is actually better than I remember.  It&amp;#8217;s a nice feeling to read code and be impressed by the writer&amp;#8230; and then realize the writer was you.
&lt;/p&gt;




&lt;p&gt;
It turns out that the biggest problem I have is not a technical problem.  It&amp;#8217;s that I believe different things than other people.  Some people believe different things than me, and are surprised and concerned when they find that I have a different background than them and don&amp;#8217;t believe the same things they do.
&lt;/p&gt;




&lt;p&gt;
I&amp;#8217;ve been told that some of the things on the list are &amp;#8220;not agile&amp;#8221; (not XP, technically) and that &amp;#8220;you aren&amp;#8217;t going to need this.&amp;#8221;  I don&amp;#8217;t believe XP prescribes or proscribes any programming technique: I don&amp;#8217;t believe that &lt;a href=&quot;http://en.wikipedia.org/wiki/You_ain&#39;t_gonna_need_it&quot;&gt;YouAintGonnaNeedIt&lt;/a&gt; is an automatic veto, just as &lt;a href=&quot;http://c2.com/xp/DoTheSimplestThingThatCouldPossiblyWork.html&quot;&gt;TheSimplestThingThatCouldPossiblyWork&lt;/a&gt; isn&amp;#8217;t a green light to do what you want: I&amp;#8217;ve heard &amp;#8220;simplest thing&amp;#8221; used as a justification for everything from never using transactions to checking in over a gigabyte of binaries into a project (including both Linux and MacOS binaries of Apache and MySQL) to &amp;#8220;simplify&amp;#8221; the developer&amp;#8217;s build environment.
&lt;/p&gt;




&lt;p&gt;
So.  Here&amp;#8217;s what I believe.
&lt;/p&gt;


&lt;p&gt;
I believe that loosely coupled, encapsulated systems are the way to go, for many reasons.  I believe that they are easier to mock, easier to debug, and easier to use.&lt;br&gt;
I believe that good strong interfaces make for good neighbors.  &lt;br&gt;
I believe in &lt;a href=&quot;http://en.wikipedia.org/wiki/Separation_of_concerns&quot;&gt;separation of concerns&lt;/a&gt;.  Specifically, I believe in separation of content from presentation. &lt;br&gt; 
I believe in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Solid_(object-oriented_design)&quot;&gt;SOLID&lt;/a&gt; principles.
&lt;/p&gt;




&lt;p&gt;
I believe that programming languages have their strengths and weaknesses.  Arguing which is better is like asking if a hammer is better than a trowel.&lt;br&gt;
I believe that operating systems have their strengths and weaknesses.  Given the right toolset, I&amp;#8217;m as happy programming in Windows as I am in Linux or MacOS.&lt;br&gt;
I believe that editors have their strengths and weaknesses.  On a given day, I&amp;#8217;ll use vim, jEdit, Textmate, Eclipse and IDEA to edit files.  I&amp;#8217;m fine with all of them.&lt;br&gt;
I believe that frameworks have their strengths and weaknesses.  J2EE works in its context.  Rails works in its context.  They both suck outside their context.&lt;br&gt;
I believe that design by contract, program functions and static analysis tools such as ESC/2 are going to be the next wave of programming.&lt;br&gt;
I believe that weak typing is good, because it speeds rapid prototyping and code flexibility.&lt;br&gt;
I believe that strong typing is good, because it limits the number of possible bugs that the programmer can generate and provides a rich abstract syntax tree that can be used by tools.&lt;br&gt;
&lt;/p&gt;




&lt;p&gt;
I believe that simple database constraints are a good thing.  Specifically, I believe that adding NOT NULL directly to your tables is a good thing.  &lt;br&gt;
I believe that referential integrity can, in some cases, be a good thing.  I think that used properly, they reduce the amount of bugs and bad data possible.&lt;br&gt;
I believe that database transactions are a good thing.  You may have &lt;a href=&quot;http://rhnh.net/2010/06/30/acts-as-list-will-break-in-production&quot;&gt;concurrency bugs&lt;/a&gt; when you scale your app if you don&amp;#8217;t use them. &lt;br&gt;
I believe that 99% of the time, a decent SQL database with transaction and constraint support (i.e. not MySQL) will serve your needs, and that NoSQL is required only in some exceptional scenarios.&lt;br&gt;
&lt;/p&gt;




&lt;p&gt;
I believe that designing systems using finite state machines and explicit state transition can be a good way to tightly define a system and eliminate bugs. &lt;br&gt;
I believe that validating an object is good, validating a state change is better, and validating a system is best.&lt;br&gt;
I believe in PMD, Checkstyle, and Findbugs.  I believe in Flog, Heckle, and Saikuro.&lt;br/&gt;  
I believe in &lt;a href=&quot;http://www.pragprog.com/titles/mnee/release-it&quot;&gt;Release It&lt;/a&gt;, in its entirety.  I believe in fail fast.  I believe in bulkheads.  I believe in circuit breakers.&lt;br&gt;
&lt;/p&gt;




&lt;p&gt;
I believe that most of the really nasty bugs come from miscommunication between different parts of a system.&lt;br&gt;
I believe that defensive programming is a good thing, because it flushes out hidden assumptions between the different parts of a system.&lt;br&gt;
I believe that code is not finished until you have thought about how the system responds to invalid input and exceptions.&lt;br&gt;
I believe that, on some level, unit tests, assertions, defensive programming, design by contract and validation logic are all the same thing.&lt;br&gt;
I believe that that a good solid configurable logging framework is a requirement for production code.&lt;br&gt; 
I believe that having diagnostic logging statements in production code is a good thing.&lt;br&gt;
I believe that code is not finished until you have thought about how someone else is going to have to debug it.&lt;br&gt;
I believe that comments can be valuable and worthwhile when they augment and not repeat the source code.&lt;br&gt;
I believe that tests are not documentation.  Documentation is for a human audience first, and tests have to work first and be readable second.&lt;br&gt;
&lt;/p&gt;




&lt;p&gt;
I believe that some tests are inherently useless, notably when they test the underlying library code and not the system under test.&lt;br&gt;
I believe that any testing done by a programmer, automated or otherwise, is inherently biased in ways that don&amp;#8217;t reflect a user.&lt;br&gt;
I believe that automated tests can be useful, but they can only show you the programmer&amp;#8217;s intent.  Even end to end system tests will only look for specific areas of a page.&lt;br&gt;
I believe that 100% code coverage provides little advantage over 80% code coverage.&lt;br&gt;
I believe that a good integration test suite is better than a great unit test suite.&lt;br&gt;
I believe that there is no substitute for a good QA team.&lt;br&gt;
&lt;/p&gt;




&lt;p&gt;
Finally, I believe that two people pair programming are no more efficient or effective than two people programming alone.  The most cited study points to a 15% development time cost, but mentions that the co-workers believed that code was consistently at a higher level of design quality and had fewer defects.  This has not been my experience: just looking back at the rate and quality of work produced, I can&amp;#8217;t see &lt;a href=&quot;http://evidencebasedse.com/?q=node/356&quot;&gt;a substantive improvement over a regular team&lt;/a&gt;.  To be clear, I don&amp;#8217;t think it&amp;#8217;s markedly LESS efficient or effective, just that I haven&amp;#8217;t seen it take teams to a different level.  Which is saddening, but I&amp;#8217;m not going to go into it.
&lt;/p&gt;




&lt;p&gt;
Thank you.
&lt;/p&gt;

</description>
    </item>
    
    <item>
      <title>Making Avatar Make Sense</title>
      <link>http://tersesystems.com/2010/01/03/making-avatar-make-sense</link>
      <pubDate>Sun, 03 Jan 2010 00:00:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2010/01/03/making-avatar-make-sense</guid>
      <description>&lt;p&gt;Okay, so.  I&amp;rsquo;m going to assume that everyone has now seen Avatar, and hence I&amp;rsquo;ll assume you&amp;rsquo;re all up for massive spoilers, etc.&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
The movie we all just watched was not the movie we thought we watched.  And this is not just some George &amp;ldquo;hahaha, I destroyed the hopes and dreams of a generation&amp;rdquo; Lucas screwing with the fanbase&amp;hellip; this is lurking beneath the surface of Avatar from the beginning.  The existence of the Na&amp;#8217;vi.
&lt;p&gt;
The Na&amp;#8217;vi have no common morphology with the rest of the planet.  Sig even comments on it in a &lt;a href=&quot;http://www.pandorapedia.com/doku.php&quot;&gt;Youtube article&lt;/a&gt;.  Why do they exist?  How is it that they speak a recognizable language, and have genes close enough to human that it&amp;rsquo;s possible to MIX IN HUMAN DNA with the Na&amp;#8217;vi?  How is it that the Na&amp;#8217;vi have built in neural interfacing equipment that can instantly domesticate the larger animals and even predators?  Wouldn&amp;rsquo;t evolution make such a thing impossible?
&lt;p&gt;
The answer is that the Na&amp;#8217;vi aren&amp;rsquo;t a natural race.  Eywa made them.  They&amp;rsquo;re close enough to human that the humans can communicate with them and think they look cute and cuddly (Ewya may have been slightly confused here), and alien enough that they can survive in the local environment.  If that wasn&amp;rsquo;t enough, Eywa provided with some elevated sudo privileges, so they could take advantage of the local fauna without Eywa being directly involved.
&lt;p&gt;
The how is easy.  Eywa&amp;rsquo;s a worldmind capable of transferring human neural networks into Na&amp;#8217;vi clones on the second try, and it&amp;rsquo;s entirely feasible to create a race and set it up with false memories.  And something that&amp;rsquo;s smart enough to create room temperature superconductor in bulk (what? You think Eywa runs on plants alone, when there&amp;rsquo;s massively complex electromagnetic flux happening around the tree and the Na&amp;#8217;vi just happening to be sitting on giant deposits of unobtainium?) will have no problem reading our electromagnetic communications.  Eywa&amp;rsquo;s on Alpha Centauri; it&amp;rsquo;s been listening in since the first radio broadcasts.
&lt;p&gt;
The why is a bit harder to explain.  Why would a worldmind play dumb?
&lt;p&gt;
Well, probably because it has a very good understanding of what happens to things that look like a threat to humanity.  If we had any conception of what Eywa is, we&amp;rsquo;d be terrified, and we&amp;rsquo;d probably sterilize the entire planet before we even set foot on it.  As it is, Eywa looks harmless.  It looks beautiful.  It&amp;rsquo;s not exactly friendly, but it&amp;rsquo;s the kind of environment that keeps humans focused on the trees instead of on the forest.  Eywa can afford to watch and wait until it has to act.
&lt;p&gt;
It also makes a hell of a way to see human capabilities up close and personal.  Eywa is well capable of doing a vacuum cleaner impression on every single EM communication on the planet. And when Eywa saw a human built Na&amp;#8217;vi run out the container and disregard orders, it could lay bets that this was someone stupid and romantic enough to provide Eywa with more insight into the military command structure.  The cute floaty things aren&amp;rsquo;t accidental.  They are Eywa&amp;rsquo;s way of saying &amp;ldquo;hold up, this guy could be useful.&amp;rdquo;
&lt;p&gt;
And Eywa gains massively out of it.  Not only does it have a neural imprint of a woman with a massive amount of scientific knowledge, it also got to see a run through of the military.  It had to expose itself to a certain extent to get the humans to back off, but you can be certain that the humans will have Eywa bacteria in their digestive tracts when they reach Earth.  I wouldn&amp;rsquo;t be surprised if Eywa had a very specific form of toxoplasmosis all ready to go if needed.  (Indeed, one plot treatment specifically mentioned &lt;a href=&quot;http://chud.com/articles/articles/21969/1/PROJECT-880-THE-AVATAR-THAT-ALMOST-WAS/Page1.html&quot;&gt;this possibility&lt;/a&gt;.) It doesn&amp;rsquo;t have space travel down, but as long as it stays quiet, it can build up and infiltrate the military before they get to the point they know what they&amp;rsquo;re dealing with.
&lt;p&gt;
And for those romantic souls thinking this was about Jake Sully&amp;hellip; dude.  THEY LOST.  Jake and the Na&amp;#8217;vi didn&amp;rsquo;t stand a chance against the military, they used up most of what they had, and THEN, as soon as it looked like Eywa might actually lose a valuable resource, it acted.  It was perfectly happy to use the Na&amp;#8217;vi as cannon fodder if it meant it didn&amp;rsquo;t have to show a card.
&lt;p&gt;
And I, for one, welcome our worldmind overlord.  Life under Eywa would not be a bad thing for the vast majority of people, and Eywa would make better use of our technology and infrastructure than we could.  Eywa keeps the reins loose for the most part, and doesn&amp;rsquo;t enforce behaviour as much as &amp;ldquo;convincingly persuade.&amp;rdquo;  That may be the Na&amp;#8217;vi, the charming public face presented by the unknowable, near-omniscient power that is Eywa, but even if the Na&amp;#8217;vi are rolled up and tossed out like last week&amp;rsquo;s pizza once we are no longer a threat (which is unlikely &amp;mdash; the Na&amp;#8217;vi are too damn useful for offworld activity), then humanity, and Earth as a whole, can rest in peace knowing that something much smarter, tougher and biologically engineered to perfection took us out.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What Makes People Happy</title>
      <link>http://tersesystems.com/2009/12/28/what-makes-people-happy</link>
      <pubDate>Mon, 28 Dec 2009 00:00:00 -0800</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2009/12/28/what-makes-people-happy</guid>
      <description>&lt;p&gt;If you want to know what makes you happy, you have to be willing to think hard about what happiness is, and pay attention to what makes you happy.&lt;/p&gt;

&lt;p&gt;&lt;p&gt;
&amp;ldquo;Happiness comes in small doses, folks. It&amp;rsquo;s a cigarette butt, or a chocolate chip cookie, or a five second orgasm. You come, you smoke the butt, you eat the cookie, you go to sleep, wake up and go back to fucking work the next morning, THAT&amp;rsquo;S IT! End of fucking list!&amp;rdquo; &amp;ndash; Denis Leary
&lt;p&gt;
So after much time and experience, here&amp;rsquo;s the list of things that make me happy.
&lt;p&gt;
1) Direct sunlight.&lt;br&gt;
2) 8 hours of sleep.&lt;br&gt;
3) Movement outside.&lt;br&gt;
4) Social interaction.&lt;br&gt;
5) Regular meals.&lt;br&gt;
6) Satisfying work.&lt;br&gt;
&lt;p&gt;
The upshot from this list is that I&amp;rsquo;m not all that complicated.  Also, what actually makes me happy may not be what I spend most of your time thinking about.  I don&amp;rsquo;t think about sunlight all that much.  But I can tell the difference between when I have it and when I don&amp;rsquo;t.  Biking has a huge effect on my mood.  Not eating has a huge effect on my mood.  And I&amp;rsquo;m going to take a leap in logic and say that this list is globally applicable to all humans.
&lt;p&gt;
The complicated part of this is social interaction and satisfying work.  But even the satisfying work is simpler than you &lt;a href=&quot;http://blog.penelopetrunk.com/2007/09/07/do-you-have-a-good-job-take-the-test/&quot;&gt;might expect&lt;/a&gt;.
&lt;p&gt;
But hang on a sec.  This list doesn&amp;rsquo;t just apply to humans.  Look at dogs, for example.
&lt;p&gt;
Dogs need sunlight.  Just ask one.&lt;br&gt;
Dogs need sleep.  They get cranky if they don&amp;rsquo;t.&lt;br&gt;
Dogs need walkies.&lt;br&gt;
Dogs need to meet other dogs and sniff each others butts.  And humans.&lt;br&gt;
Dogs need regular meals.  And they&amp;rsquo;ll eat anything you give them.&lt;br&gt;
Dogs need to do something.  Pointers need to herd, bloodhounds need to sniff.&lt;br&gt;
&lt;p&gt;
You break it down and you&amp;rsquo;ll conclude that human beings are social animals, and have the same needs as social animals.  I used to think that the people who get up at 8 am, eat breakfast and then jog for an hour were obnoxiously happy people who were just naturally gifted.  They&amp;rsquo;re not.  They&amp;rsquo;re happy because doing those things will make you a happy human.  Likewise, staying up until 3 am, not getting outside, getting crappy sleep and reading existentialist philosophy will make you pretty damn unhappy.  It doesn&amp;rsquo;t matter what your brain thinks about the activities you&amp;rsquo;re doing &amp;mdash; do these things and you&amp;rsquo;ll look and act like an unhappy person the next day.
&lt;p&gt;
Again, this goes back to how to get the most milk out out of cows or the &lt;a href=&quot;/2007/08/16/getting-work-out-of-programmers-part-1&quot;&gt;most work out of programmers&lt;/a&gt;.
&lt;p&gt;
The Dog Hypothesis: Human beings need walkies.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Getting work out of Programmers, Part 2</title>
      <link>http://tersesystems.com/2007/08/20/getting-work-out-of-programmers-part-2</link>
      <pubDate>Mon, 20 Aug 2007 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2007/08/20/getting-work-out-of-programmers-part-2</guid>
      <description>&lt;p&gt;So here&amp;rsquo;s how I think you get the most work out of programmers.  This is a follow on from &lt;a href=&quot;/2007/08/16/getting-work-out-of-programmers-part-1&quot;&gt;part 1&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Morale&lt;/h2&gt;

&lt;p&gt; Programmers have good morale when they are treated well, and they are given a problem that they know they can solve.  Thank programmers whenever they do something.  Let them know you not only know how much they work, but that you care. Keep track of morale through weekly one on ones with each and every programmer.  Keep track of commitments you make to your programmers (including the verbal ones) and follow through on them.  Make it clear that you are looking out for their interests. (Creating a Software Engineering Culture, Chapter 3.)&lt;/p&gt;

&lt;p&gt;Money and stock options only have a limited effect on morale, and may have a negative effect (Agile Development, p63).  Most often, a gift of money or stock options is a substitute. (Rapid Development, p262).  Morale events can be fun, but don&amp;rsquo;t actually raise morale &amp;mdash; they just allow for a different kind of interaction with people. (&lt;a href=&quot;http://www.scottberkun.com/blog/2006/how-to-avoid-lame-morale-events/&quot;&gt;How to avoid Lame Morale Events&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;And there are all kinds of things that can hurt morale.  I think the major one is the &lt;a href=&quot;http://en.wikipedia.org/wiki/Broken_windows&quot;&gt;Broken Window Theory&lt;/a&gt; (Pragmatic Programmer, p4).  Under the Broken Window Theory, any neglect or rot in a system that is not directly addressed and countered is a drag on morale.  People wonder why it is that they have to write good code and do things right, when they&amp;rsquo;re not allowed to fix the crappy code.  Management assertions that &amp;ldquo;we don&amp;rsquo;t have time right now&amp;rdquo; or &amp;ldquo;we&amp;rsquo;ll do it later&amp;rdquo; start to sound empty and hollow as project after project goes by, and the crappy code festers and rots as hack after hack is piled on top of it.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.amazon.com/Psychology-Computer-Programming-Silver-Anniversary/dp/0932633420/ref=pd_bbs_sr_1/002-6097181-5465654?ie=UTF8&amp;s=books&amp;qid=1187629423&amp;sr=1-1&quot;&gt;The Psychology of Computer Programming&lt;/a&gt;, Chapter 10 deals specifically with Morale and Motivation.  &lt;a href=&quot;http://www.amazon.com/Psychology-Computer-Programming-Silver-Anniversary/dp/0932633420/ref=pd_bbs_sr_1/002-6097181-5465654?ie=UTF8&amp;s=books&amp;qid=1187629423&amp;sr=1-1&quot;&gt;Rapid Development&lt;/a&gt;, Chapter 11 goes into typical developer motivations.  They are both very much worth reading.&lt;/p&gt;

&lt;h2&gt;Sleep&lt;/h2&gt;

&lt;p&gt;You can&amp;rsquo;t make people sleep, and you can&amp;rsquo;t do much about sleeping arrangements.  But you can tell them that you want them to get 8 hours of sleep a night, and you can bring up lack of sleep as an issue.  Anyone who looks sleep deprived needs help; either they have been trying to sneak in work late at night, or they&amp;rsquo;re suffering in other ways.  Give them all the help you can.  The number of work hours will be an issue there.  And if someone loads up on caffeine and junk food late at night&amp;hellip; well, I&amp;rsquo;d point out that there may be a connection (&lt;a href=&quot;http://www.stanford.edu/~dement/howto.html&quot;&gt;How to Sleep Better&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Exhausted employees are easy to spot.  They&amp;rsquo;re the people who frighten small children and spouses. They are not fit for work. They barely even know they are at work.  They should be sent home until they know what they&amp;rsquo;re doing.  Just that simple act of humanity will raise morale.&lt;/p&gt;

&lt;h2&gt;Focus&lt;/h2&gt;

&lt;p&gt;The best way to ensure focus is to ensure transparency and feedback.  If programmers have a public, physical way to see what needs to be done at a granular level, whether in a todo list on a whiteboard  or a series of 3x5 cards on the wall, they can see at a glance what they will be working on not just today, but next week as well.  (Agile Development, p97) This works very well for helping out programmers who have a large list, or determining the priorities &amp;mdash; you can only have one task on the top of the list, so what you are supposed to do is never in doubt.  This is a technique that is used in several agile methodologies, and is known as an information radiator. (Crystal Clear, p32)&lt;/p&gt;

&lt;p&gt;Don&amp;rsquo;t confuse your programmers, or worse, try to multitask them.  If you give them two jobs to do at the same time with the same priority, you&amp;rsquo;re putting them in a situation where they cannot win; no matter what they do, they&amp;rsquo;ll be working on the wrong thing.  And if they try to do them in parallel, they&amp;rsquo;ll do both jobs more slowly than they would if they did them sequentially. (&lt;a href=&quot;http://www.joelonsoftware.com/articles/fog0000000022.html&quot;&gt;Joel on Software&lt;/a&gt;)  (&lt;a href=&quot;http://www.codinghorror.com/blog/archives/000691.html&quot;&gt;The Multitasking Myth&lt;/a&gt;) (Quality Software Management)&lt;/p&gt;

&lt;p&gt;Keep the number of goals small in a project.  Pick one objective and make it clear that it&amp;rsquo;s the most important one. (Rapid Development, p257)&lt;/p&gt;

&lt;p&gt;But the best thing you can do for programmers is to let them work.  Don&amp;rsquo;t interrupt them.  Don&amp;rsquo;t spring meetings or interviews on them with no warning.  Don&amp;rsquo;t change what they&amp;rsquo;re working on.  Don&amp;rsquo;t spring last minute high priority projects on them.  Don&amp;rsquo;t file marketing requests to change the font size as priority one critical bugs.  Don&amp;rsquo;t come up and ask when a bug is going to be fixed.  Don&amp;rsquo;t ask them for status updates every five minutes.  I&amp;rsquo;ve seen constant change requests happen at company after company and I can tell you from experience what happens&amp;hellip; the programmers roll their eyes, and they stop taking priority changes seriously.  Because they know that in an hour&amp;rsquo;s time, it won&amp;rsquo;t be a priority any more. (Rapid Development, p259)&lt;/p&gt;

&lt;p&gt;If you let your programmers work uninterrupted, something wonderful will happen.  There&amp;rsquo;s a psychological state called &lt;a href=&quot;http://en.wikipedia.org/wiki/Flow_%28psychology%29&quot;&gt;flow&lt;/a&gt; that has been documented by &lt;a href=&quot;http://en.wikipedia.org/wiki/Mihaly_Csikszentmihalyi&quot;&gt;Mihaly Csikszentmihalyi&lt;/a&gt;.  In this state, programmers are able to be &amp;ldquo;in the zone&amp;rdquo; and become focused to a great extent.  Programmers in flow can produce far more code than they would be able to ordinarily.  There is a catch though; it takes the average person at least 15 minutes of uninterrupted work to enter flow.  If they are interrupted, or even expect to be interrupted, then they&amp;rsquo;re less lightly to enter flow.  (Rapid Development, p506)  Some teams implement a policy called &amp;ldquo;focus time&amp;rdquo; (Crystal Clear, p33) or the &amp;ldquo;cone of silence&amp;rdquo; (&lt;a href=&quot;http://alistair.cockburn.us/index.php/Cone_of_silence_strategy_and_related_project_management_strategies&quot;&gt;Alistair Cockburn&lt;/a&gt;) where meetings and interruptions are banned for a portion of the day.  Other teams use a red bandanna (Peopleware) or a sign to indicate that they are not to be interrupted, or &lt;a href=&quot;http://www.doolwind.com/blog/?p=65&quot;&gt;other methods&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;Background&lt;/h2&gt;

&lt;p&gt;The best way to have programmers with the best background in the problem domain is to cultivate them.  I&amp;rsquo;ve been surprised in the past how little programmers know what the business does.  I&amp;rsquo;ve often thought it would be a useful exercise to have new programmers spend some time with each member of the business team to understand their concerns and priorities.  Failing that, it can be a good idea to have documentation (business process management or six sigma documentation) that can bring new programmers up to speed on the organization as a whole.  Of course, this only works so far in that it doesn&amp;rsquo;t track the history of the organization.  Legacy code is nettlesome to new programmers, because typically they reflect legacy business processes and legacy business decisions.  But ultimately, it comes with time.&lt;/p&gt;

&lt;p&gt;Business specific domains, by nature, share little common ground with each other.  There are only a couple of books I can recommend here.  &lt;a href=&quot;http://www.amazon.com/Domain-Driven-Design-Tackling-Complexity-Software/dp/0321125215/ref=pd_bbs_sr_1/002-6097181-5465654?ie=UTF8&amp;s=books&amp;qid=1187629072&amp;sr=1-1&quot;&gt;Domain Driven Design&lt;/a&gt; is the single best book I have read about how to effectively model and discuss domains.  It is a similar book to Design Patterns, as it not only talks about implementation and common patterns, but it talks about domains as a common language.  And &lt;a href=&quot;http://www.amazon.com/Working-Effectively-Legacy-Robert-Martin/dp/0131177052/ref=pd_bbs_sr_1/002-6097181-5465654?ie=UTF8&amp;s=books&amp;qid=1187628994&amp;sr=8-1&quot;&gt;Working Effectively with Legacy Code&lt;/a&gt; does an excellent job of pointing out useful ways to desnarl and refactor code that is no longer up to snuff.&lt;/p&gt;

&lt;h2&gt;Experience&lt;/h2&gt;

&lt;p&gt;Experience comes with work.  It doesn&amp;rsquo;t always come with time.  To quote Weinburg, experience is the best teacher, but it doesn&amp;rsquo;t necessarily teach anything.  Experience can be passed on by proxy, through education and mentoring: some of the best experiences I&amp;rsquo;ve learned from have been the ones other people have had.  If you want books that give experience, then &lt;a href=&quot;http://www.cc2e.com/&quot;&gt;Code Complete 2&lt;/a&gt; and &lt;a href=&quot;http://www.amazon.com/exec/obidos/ASIN/0201485672&quot;&gt;Refactoring&lt;/a&gt; are the best bets.  If you want to read about experience, then &lt;a href=&quot;http://www.mcbreen.ab.ca/SoftwareCraftsmanship/&quot;&gt;Software Craftsmanship&lt;/a&gt; and &lt;a href=&quot;http://www.developerdotstar.com/books/software_creativity_glass.html&quot;&gt;Software Creativity&lt;/a&gt; are the best books.  But if you want to make gathering experience, then make it available to your programmers.  Set aside an education budget.  Encourage your employees to attend conferences and seminars.  Join a software engineering book club and have programmers pick out reference books for an in-house library.  Have regular brown bag sessions and encourage your team to pass techniques around the company.  Do this, and you will not only raise the general experience level of your team, but you will raise morale as well.  (Rapid Development p257) (Software Craftsmanship, Chapter 19) (Building a Software Engineering Culture, Chapter 4).&lt;/p&gt;

&lt;h2&gt;Talent&lt;/h2&gt;

&lt;p&gt;You can hire talented programmers, but I think that&amp;rsquo;s as much as can be done.  I think that talent is not a static quality.  I believe talent is a series of mental habits, and that new habits can be learned, just as old habits can be put aside.  I believe that some useful habits are solid grasp of systems theory, along with an ability to ask the &amp;ldquo;right&amp;rdquo; question.  But that&amp;rsquo;s another essay.  And there is another problem: talented people get bored doing things that don&amp;rsquo;t stretch their capabilities.  If you have work that doesn&amp;rsquo;t require PhDs, you may be better off not hiring them.&lt;/p&gt;

&lt;h2&gt;Hours Worked&lt;/h2&gt;

&lt;p&gt;According to decades of economists and management experts: 40 hours.  Contrary to popular belief, the standard work week was not invented by the government or the unions.  It was pioneered by Henry Ford in 1926.  More than 40 hours a week, and the factories didn&amp;rsquo;t produce as much money; the temporary increase in productivity was more than offset by industrial accidents and mistakes, and after two weeks there was less productivity. (&lt;a href=&quot;http://legacy.igda.org/why-crunch-modes-doesnt-work-six-lessons&quot;&gt;Why Crunch Mode Doesn&amp;rsquo;t Work&lt;/a&gt;)  (&lt;a href=&quot;http://evanrobinson.typepad.com/ramblings/2004/11/can-people-real.html&quot;&gt;Can People Really Program 80 Hours a Week?&lt;/a&gt;) (&lt;a href=&quot;http://www.stickyminds.com/sitewide.asp?Function=WEEKLYCOLUMN&amp;ObjectId=6545&amp;ObjectType=ARTCOL&quot;&gt;When Should You Start Project Overtime?&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;This is counter-intuitive, so I&amp;rsquo;ll say it again: studies prove overtime provides a temporary benefit for a maximum of two weeks, and is worse than useless thereafter.  James Shore provides a recent &lt;a href=&quot;http://jamesshore.com/Blog/An-Energized-Work-Experience.html&quot;&gt;example&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I believe this, not just from the studies, but from my own experience with extended overtime.  Programmers will not only do less work, they&amp;rsquo;ll make mistakes in the work that they do.  Then they&amp;rsquo;ll get irritable and suffer from low morale.  Then they&amp;rsquo;ll burn out completely.  I believe (but do not have the studies to prove) that after even after normal work hours are restored, there is a convalescent effect; people will produce less work following the overtime, producing the same amount of work overall.  So after the project goes live, they&amp;rsquo;ll need a long convalescent period before they&amp;rsquo;re up to snuff, or even worse, they&amp;rsquo;ll look up from their monitors, take a good hard look at the results of their labor and their (usually meager) rewards, and quit, producing a huge opportunity cost for the company in terms of hiring, maintenance, and reputation.  (&lt;a href=&quot;http://evanrobinson.typepad.com/ramblings/2004/11/its-not-just-ab.html&quot;&gt;It&amp;rsquo;s Not Just Abusive, It&amp;rsquo;s Stupid&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;For every complex problem, there is a solution which is simple, obvious, and wrong.  Extended overtime is that solution.&lt;/p&gt;

&lt;h2&gt;Pressure&lt;/h2&gt;

&lt;p&gt;Fine; hours worked have no effect.  What about directly applied pressure?  What happens if we keep the hours, and if we tell the programmers to work harder and produce more work during those 8 hours?&lt;/p&gt;

&lt;p&gt;Surprisingly, nothing.  Programmers produce work using their brains; the amount of thoughts a programmer can have is fairly constant.  Tom DeMarco and Tim Lister researched this and formulated Lister&amp;rsquo;s Law: People under time pressure don&amp;rsquo;t think faster. (Slack, p50) They might be more stressed, but that doesn&amp;rsquo;t help people think faster; stress impedes complex thought, and pushes the brain to a &amp;ldquo;flight or flight&amp;rdquo; response.  If you&amp;rsquo;re stressing your programmers, they&amp;rsquo;ll be at their desks more.  But they&amp;rsquo;re not going to write any more code.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;This advice is all simple and straightforward.  I don&amp;rsquo;t see anything in here that comes as a shock, and even my mother said &amp;ldquo;Well, that&amp;rsquo;s obvious, isn&amp;rsquo;t it?  It&amp;rsquo;s like being a farmer and taking care of your cows.  If you want your cows producing the most milk, you make sure they&amp;rsquo;re treated like cows should be treated.&amp;rdquo;&lt;/p&gt;

&lt;p&gt;So treat your programmers well.  Keep track of morale through weekly one on ones.  Make it clear you care about the health and welfare of your programmers. Make sure programmers know what they should be working on at all times.  Don&amp;rsquo;t change out work that the programmers are doing or abuse the bug tracking system.  Keep interruptions to a minimum to allow for flow.  Establish a training and education budget, and establish mentoring and brown bag sessions to transfer experience.  Keep to 40 hour work weeks, and forgo direct pressure.&lt;/p&gt;

&lt;p&gt;Do all of these things, and you&amp;rsquo;ll get more work out of your programmers.  And you&amp;rsquo;ll probably have programmers beating down your door to work for you.&lt;/p&gt;

&lt;p&gt;EDIT: Also see this LinkedIn &lt;a href=&quot;http://www.linkedin.com/answers/technology/software-development/TCH_SFT/126527-1526192&quot;&gt;question&lt;/a&gt; that provides some useful advice.  Larger monitors have been mentioned in several studies, but I don&amp;rsquo;t have the references to hand.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Getting work out of Programmers, Part 1</title>
      <link>http://tersesystems.com/2007/08/16/getting-work-out-of-programmers-part-1</link>
      <pubDate>Thu, 16 Aug 2007 00:00:00 -0700</pubDate>
      <author>wsargent@tersesystems.com (Will Sargent)</author>
      <guid>http://tersesystems.com/2007/08/16/getting-work-out-of-programmers-part-1</guid>
      <description>&lt;p&gt;I was recently asked the question: what is the best way to get the most work out of my programmers?&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve thought about this for a while.  In some ways, it&amp;rsquo;s the story of my career &amp;mdash; every manager I&amp;rsquo;ve ever had has wrestled with this question.  I&amp;rsquo;ve worked with enough teams and individuals that I think I have a good understanding of what programmers can and can&amp;rsquo;t do, and how work gets done.  And how work doesn&amp;rsquo;t get done, for that matter.  I believe I have an answer, although certainly not the answer.&lt;/p&gt;

&lt;p&gt;The first thing to do is to look at the assumptions behind the way the question is phrased.  The assumption here is that there are veins of untapped work, hidden inside of programmers somewhere.  And the manager&amp;rsquo;s job is to extract it.  I think that this is the wrong place to start from.  I believe that most people would rather do a good job than a bad one, and will do the best work they can do given what they have to work with. (Software Creativity 2.0, p22.)  The best way to phrase this question would be: &amp;ldquo;What can I do to help an individual programmer be most productive?&amp;rdquo;&lt;/p&gt;

&lt;p&gt;So, let&amp;rsquo;s construct a hypothetical employee.  What is known to create productivity?  Let&amp;rsquo;s start from the simplest level and work up.&lt;/p&gt;

&lt;h2&gt;Morale&lt;/h2&gt;

&lt;p&gt;An employee who feels safe and secure in his position and his ability to raise issues will do more work.  You can argue whether this is the cause or the effect, but it&amp;rsquo;s well recognized that morale is extraordinarily important.  Someone who believes in the team, the company and the work he is doing is likely to do more of it.  I believe motivation and morale are equivalent, but morale feels like a better word to me.&lt;/p&gt;

&lt;h2&gt;Sleep&lt;/h2&gt;

&lt;p&gt;An employee who has slept 8 hours a day will be more productive than one who has slept 5 hours.  I have yet to hear anyone argue with this in principle.  Studies have been done that compare the effects of sleep deprivation to alcohol intoxication. The outcome: a programmer awake for 21 hours is effectively &lt;a href=&quot;http://archives.cnn.com/2000/HEALTH/09/20/sleep.deprivation/&quot;&gt;too drunk to drive&lt;/a&gt;. Think about that.  There is a second stage of incapacitation, which is exhaustion AKA &lt;a href=&quot;http://nymag.com/news/features/24757/&quot;&gt;burnout&lt;/a&gt;. Exhausted employees are, by definition, not productive.&lt;/p&gt;

&lt;h2&gt;Focus&lt;/h2&gt;

&lt;p&gt;An employee who knows what he is supposed to be working on will be more productive than one who is not sure which programming task takes priority. An employee who knows that he can complete the work he is doing without having his priorities changed will be more productive than one who does not know what&amp;rsquo;s coming next.  Programmers dislike surprises as much as anyone else.  But this also covers the programmer&amp;rsquo;s inherent self-discipline.  Given a gap in work, will the programmer ask what he should be working on, or will he create his own scripting language?&lt;/p&gt;

&lt;h2&gt;Background&lt;/h2&gt;

&lt;p&gt;An employee who knows the domain, the history and the subtle interplay of forces at work in the codebase will be more productive than a programmer who has no previous background in the work assigned.  This factor is often overlooked, but domain expertise is an incredibly valuable asset for a programmer, and anecdotally speaking I&amp;rsquo;d say it makes an order of magnitude difference in time and quality.&lt;/p&gt;&lt;/p&gt;

&lt;h2&gt;Experience&lt;/h2&gt;

&lt;p&gt;An experienced programmer &amp;mdash; a veteran &amp;mdash; is more productive than an inexperienced one.  An experienced programmer will understand that this project needs two weeks just to be deployed, that there&amp;rsquo;s a particular tool that&amp;rsquo;s perfectly suited to refactoring the database, and when it&amp;rsquo;s worth building extra flexibility into an area of the system because the business team will almost certainly want customized logic in the next release.&lt;/p&gt;

&lt;h2&gt;Talent&lt;/h2&gt;

&lt;p&gt;Some people are just good programmers.  It&amp;rsquo;s not simply intelligence, or interest; I&amp;rsquo;ve known very smart people who don&amp;rsquo;t make good programmers, and some of the most interested programmers often did the worst work.  A talented programmer may do work that may be simply beyond other programmers, no matter how much experience or background they have.&lt;/p&gt;

&lt;h2&gt;Hours Worked&lt;/h2&gt;

&lt;p&gt;A programmer who works 40 hours a week will do more work than one who works 20 hours a week.  And a programmer who works no hours a week, will do no work.  But I think everyone will agree that a programmer who works 168 hours in a week will not produce 168 hours of work.  In fact, I feel fairly safe in saying that a programmer who works 168 hours will produce less usable work than the programmer who works 40 hours, because the programmer&amp;rsquo;s ability to work will be degraded by lack of sleep long before they stop working. &amp;lt;/&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;I don&amp;rsquo;t think anyone will argue that the above factors matter.   If any one of these goes to zero, your programmers will be effectively useless.&lt;/p&gt;

&lt;p&gt;Obviously, these factors are interconnected.  Someone with no experience will typically lack background.  Someone with no sleep will he low morale very shortly, and will even lose talent. So let&amp;rsquo;s see what we can do to increase these variables.&lt;/p&gt;
</description>
    </item>
    

  </channel>
</rss>