<?xml version="1.0" encoding='utf-8'?>
<?xml-stylesheet type="text/xsl" href="https://raibledesigns.com/roller-ui/styles/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" 
      xmlns:app="http://www.w3.org/2007/app"
      xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/">

    <title type="html">Search for [appfuse] in weblog rd</title>
    <subtitle type="html">Search results for [appfuse] within weblog Raible Designs</subtitle>
    <id>https://raibledesigns.com/rd/feed/entries/atom?q=appfuse</id>

    <link rel="self" type="application/atom+xml" 
        href="https://raibledesigns.com/rd/feed/entries/atom?q=appfuse" />

    <link rel="alternate" type="text/html" 
        href="https://raibledesigns.com/rd/search?q=appfuse" />

    <link rel="search" type="application/opensearchdescription+xml" 
        href="https://raibledesigns.com/roller-services/opensearch/rd" />
    <opensearch:Query role="request" searchTerms="appfuse" startPage="1" />

    <link rel="first" type="application/atom+xml" href="https://raibledesigns.com/rd/feed/entries/atom?q=appfuse" />
    <link rel="next" type="application/atom+xml" href="https://raibledesigns.com/rd/feed/entries/atom?q=appfuse&amp;page=1" />
    <updated>2026-04-30T03:43:46-06:00</updated>
    <generator uri="http://roller.apache.org" version="5.0.3 (1388864191739:dave)">Apache Roller</generator>

        <entry>
        <id>https://raibledesigns.com/rd/entry/life_update_new_job_same</id>
        <title type="html">Life Update: New Job, Same House, and Same Awesome Family!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/life_update_new_job_same"/>
        <published>2024-11-16T09:31:40-07:00</published>
        <updated>2025-01-19T13:21:29-07:00</updated> 
        <category term="/General" label="General" />
        <category term="abbie" scheme="http://roller.apache.org/ns/tags/" />
        <category term="career" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jack" scheme="http://roller.apache.org/ns/tags/" />
        <category term="family" scheme="http://roller.apache.org/ns/tags/" />
        <category term="summer2024" scheme="http://roller.apache.org/ns/tags/" />
        <category term="crowdstrike" scheme="http://roller.apache.org/ns/tags/" />
        <category term="trish" scheme="http://roller.apache.org/ns/tags/" />
        <category term="horse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="life" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
    It&apos;s been over eight years since I wrote a &lt;a href=&quot;https://raibledesigns.com/rd/entry/life_update_a_summer_to&quot;&gt;life update blog post&lt;/a&gt;. At that time (2016), we&apos;d just moved into the &quot;Raible Ranch&quot;, the bus was finished, and the kids were in high school. I&apos;d just started one of my few-and-far-between full-time jobs at Stormpath.
&lt;/p&gt;
&lt;p&gt;
    Fast-forward to today. Our kids are in college at the University of Colorado during the Coach Prime Era, we&apos;re empty nesters with an affection for live music, and our pet zoo is cuter than ever.
&lt;/p&gt;
&lt;p&gt;
    You probably know me. But in case you don&apos;t, my name is Matt Raible, and I&apos;m married to a fabulous woman named Trish McGinity. She&apos;s been a hero in my life ever since I met her in 2010. She dazzled me so much, I asked her to marry me at Versailles in 2011. We married in my hometown (Condon, Montana) in 2013, on the most beautiful lake you&apos;ve ever seen.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/7442/9627648458_38de03b06a_c.jpg&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mcginityphoto/9627648458/in/album-72157635299136347&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/7442/9627648458_38de03b06a.jpg&quot; width=&quot;500&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    When I met Trish, I was an independent consultant, and she was in cybersecurity sales. On a fateful night in 2010, on a friend Jarvis&apos;s birthday, I asked her what she had done for a living. She said, &quot;Have you ever heard of OWASP?&quot;
&lt;/p&gt;
&lt;p&gt;
    My heart lifted and I felt a moment of joy. This woman was speaking my language! 14 years later and &lt;em&gt;Oh My!&lt;/em&gt;, Trish has had an incredible influence on my life and career.
&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;
    It&apos;s been over eight years since I wrote a &lt;a href=&quot;https://raibledesigns.com/rd/entry/life_update_a_summer_to&quot;&gt;life update blog post&lt;/a&gt;. At that time (2016), we&apos;d just moved into the &quot;Raible Ranch&quot;, the bus was finished, and the kids were in high school. I&apos;d just started one of my few-and-far-between full-time jobs at Stormpath.
&lt;/p&gt;
&lt;p&gt;
    Fast-forward to today. Our kids are in college at the University of Colorado during the Coach Prime Era, we&apos;re empty nesters with an affection for live music, and our pet zoo is cuter than ever.
&lt;/p&gt;
&lt;p&gt;
    You probably know me. But in case you don&apos;t, my name is Matt Raible, and I&apos;m married to a fabulous woman named Trish McGinity. She&apos;s been a hero in my life ever since I met her in 2010. She dazzled me so much, I asked her to marry me at Versailles in 2011. We married in my hometown (Condon, Montana) in 2013, on the most beautiful lake you&apos;ve ever seen.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/7442/9627648458_38de03b06a_c.jpg&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mcginityphoto/9627648458/in/album-72157635299136347&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/7442/9627648458_38de03b06a.jpg&quot; width=&quot;500&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    When I met Trish, I was an independent consultant, and she was in cybersecurity sales. On a fateful night in 2010, on a friend Jarvis&apos;s birthday, I asked her what she had done for a living. She said, &quot;Have you ever heard of OWASP?&quot;
&lt;/p&gt;
&lt;p&gt;
    My heart lifted and I felt a moment of joy. This woman was speaking my language! 14 years later and &lt;em&gt;Oh My!&lt;/em&gt;, Trish has had an incredible influence on my life and career.
&lt;/p&gt;
&lt;p&gt;
    You might think of me as the AppFuse guy, the JHipster promoter, or some dude who talked about Okta a lot. I&apos;m cool with that, but it&apos;s irrefutable to say that Trish hasn&apos;t influenced my career. She encouraged me to &lt;em&gt;lean&lt;/em&gt; into cybersecurity and constantly said I was &quot;doing it wrong&quot; with my carefree attitude toward security.
&lt;/p&gt;
&lt;p&gt;
    These days, I&apos;m a Senior Cloud Engineer at &lt;a href=&quot;https://www.crowdstrike.com/&quot;&gt;CrowdStrike&lt;/a&gt;, the foremost cybersecurity company in the world.  My previous gig was with Okta, where I spent seven years educating developers about OAuth and OpenID Connect.
&lt;/p&gt;
&lt;p&gt;
    I&apos;ll admit, I had a lot of anxiety about joining CrowdStrike. In late June, after enjoying &lt;a href=&quot;https://raibledesigns.com/rd/entry/funemployment_2024&quot;&gt;funemployment&lt;/a&gt;, I had three excellent offers from FusionAuth, Yugabyte, and CrowdStrike. It&apos;s the first time in my life that I&apos;ve had more than one offer at the same time.
&lt;/p&gt;
&lt;p&gt;
    The first two opportunities were excellent. But, both had &lt;em&gt;maybe equity&lt;/em&gt;. As an old fogey in the twilight of my career, I thought &lt;em&gt;guaranteed equity&lt;/em&gt; was a better opportunity. I chose the company trajectory over my passion for open source and Java. I accepted the CrowdStrike offer on July 3rd as we were departing for a 4th of July trip to Montana.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/53844138485_916ae753a4_c.jpg&quot; title=&quot;The Fam&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/53844138485/in/album-72177720318595725&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/53844138485_916ae753a4_m.jpg&quot; width=&quot;240&quot; alt=&quot;The Fam&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/53843962478_a9734b21e6_c.jpg&quot; title=&quot;Joy &amp;#x2764;&amp;#xFE0F;&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/53843962478/in/album-72177720318595725&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/53843962478_a9734b21e6_m.jpg&quot; width=&quot;240&quot; alt=&quot;Joy &amp;#x2764;&amp;#xFE0F;&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/53843965048_435217e98d_c.jpg&quot; title=&quot;Happy 4th of July from the last best place on Earth! &amp;#x1F389; #Montana&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/53843965048/in/album-72177720318595725&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/53843965048_435217e98d.jpg&quot; width=&quot;500&quot; alt=&quot;Happy 4th of July from the last best place on Earth! &amp;#x1F389; #Montana&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    At that time, I felt totally confident about my decision. I was taking the path less traveled and abandoning all my Java celebrityism for a skyrocketing company that was kicking ass and taking names. You&apos;re supposed to do things outside your comfort zone, &lt;em&gt;right?&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
    Take the road less traveled.
&lt;/p&gt;
&lt;p&gt;
    I was a little worried about the equity though. After all, CrowdStrike&apos;s stock price was at an all-time high.
&lt;/p&gt;
&lt;p&gt;
    I turned 50 on July 16th. We hosted a backyard party at the ranch the weekend before (July 13th), complete with a local Grateful Dead band. &lt;a href=&quot;http://shakedownstreetband.com.phtemp.com/&quot;&gt;Shakedown Street&lt;/a&gt; was excellent and everyone had a good time.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141270635_7284615540_c.jpg&quot; title=&quot;Matt, Trish, Chris, and Eva - so many awesome people in one photo! &amp;#x2764;&amp;#xFE0F;&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141270635/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141270635_7284615540_m.jpg&quot; width=&quot;240&quot; alt=&quot;Matt, Trish, Chris, and Eva - so many awesome people in one photo! &amp;#x2764;&amp;#xFE0F;&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141089283_4af90859b1_c.jpg&quot; title=&quot;&amp;#x201C;We don&#8217;t grow older, we grow riper.&amp;#x201D; &#8211; Pablo Picasso&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141089283/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141089283_4af90859b1_m.jpg&quot; width=&quot;240&quot; alt=&quot;&amp;#x201C;We don&#8217;t grow older, we grow riper.&amp;#x201D; &#8211; Pablo Picasso&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54140782936_b1a25fe7b0_c.jpg&quot; title=&quot;Shakedown Street&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54140782936/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54140782936_b1a25fe7b0_m.jpg&quot; width=&quot;240&quot; alt=&quot;Shakedown Street&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a rel=&quot;lightbox[lifeupdate2024]&quot; href=&quot;https://live.staticflickr.com/65535/54139926042_a1fd54ed67_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54139926042/in/album-72177720321954143&quot; title=&quot;Eva, Chris, Dawn&#233;, and Trish &amp;#x1F970;&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54139926042_a1fd54ed67_m.jpg&quot; width=&quot;240&quot; alt=&quot;Eva, Chris, Dawn&#233;, and Trish &amp;#x1F970;&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141239200_36e461b594_c.jpg&quot; title=&quot;The Chi Phi Brothers! &amp;#x2764;&amp;#xFE0F; &amp;#x1F37B;&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141239200/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141239200_36e461b594.jpg&quot; width=&quot;500&quot; alt=&quot;The Chi Phi Brothers! &amp;#x2764;&amp;#xFE0F; &amp;#x1F37B;&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3&gt;The Incident&lt;/h3&gt;
&lt;p&gt;
    On my birthday, while blowing out candles, I wished for CrowdStrike&apos;s stock price to drop.
&lt;/p&gt;
&lt;p&gt;
    On Friday (July 19th), I woke up to more unread texts than I received on my milestone birthday. A lot of friends were aware that I&apos;d accepted a new job at CrowdStrike and were texting me about an incident.
&lt;/p&gt;
&lt;p&gt;
    Apparently, CrowdStrike had just caused a worldwide computer outage. If you were flying that day, you were probably affected. I received more text messages that morning than on my birthday.
&lt;/p&gt;
&lt;p&gt;
    My response was positive: this situation will be very good for my equity grant&apos;s strike price!
&lt;/p&gt;
&lt;p&gt;
    I quickly realized that CrowdStrike was way bigger than I originally thought. There were computer issues at the golf club I ventured into that morning. Their systems were down and they apologized. I smirked, apologized back, and mentioned I recently accepted a job offer from CrowdStrike.
&lt;/p&gt;
&lt;p&gt;
    I started working for CrowdStrike on July 29th. 10 days after &lt;em&gt;the incident&lt;/em&gt;. I quickly realized that making developers &lt;em&gt;aware&lt;/em&gt; of CrowdStrike wouldn&apos;t be a problem. Everyone knew about us because of July 19th. In a sense, it was a blessing in my DevRel journey at CrowdStrike.
&lt;/p&gt;
&lt;p&gt;
    I worked at Okta for seven years and there were a couple of incidents. CrowdStrike&apos;s response was &lt;em&gt;waayyyy&lt;/em&gt; different than Okta&apos;s.
&lt;/p&gt;
&lt;p&gt;
    First of all, CrowdStrike&apos;s incident wasn&apos;t a breach. It was a bug that they shipped. It was &lt;em&gt;totally&lt;/em&gt; their fault. Okta had a full-on breach that they didn&apos;t disclose for a month. Regardless of the incident details, as a tech worker for said company, it&apos;s a severe morale hit when it happens to you.
&lt;/p&gt;
&lt;p&gt;
    That&apos;s been one of my biggest struggles. I was extremely proud to join CrowdStrike as a Senior Engineer. Heck, I passed the coding test using Java, and they were a Go shop! When this all happened in June, I was so proud of my non-traditional path to excellence in the tech industry.
&lt;/p&gt;
&lt;p&gt;
    I wasn&apos;t hired as a senior engineer who cranks out code, maintains functionality, and implements new features. Instead, I was hired as a &quot;Senior Engineer - Cloud&quot; that&apos;s focused on DevRel. I&apos;m still a developer advocate, but my title indicates I can still sling some code.
&lt;/p&gt;
&lt;p&gt;
    I&apos;ve been coming up to speed on Go and Python as fast as I can. I&apos;ve also been doing a lot of CrowdStrike Foundry tutorials, finding/fixing issues, and improving our learning materials as fast as I can. I even published my first CrowdStrike blog post!
&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://developer.crowdstrike.com/blog/get-started-with-falcon-foundry/&quot;&gt;Get Started with Falcon Foundry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;
    Now that I&apos;ve filled you in on the life of Matt Raible, I feel like I&apos;ve ignored the best parts of my life: Trish, Abbie, and Jack.
&lt;/p&gt;

&lt;p&gt;
    Trish continues to excel as the Head of Cybersecurity Communications at &lt;a href=&quot;https://www.empower.com/&quot;&gt;Empower&lt;/a&gt;. Yes, &lt;em&gt;the&lt;/em&gt; Empower that has the naming rights to the Empower Field at Mile High where the Denver Broncos play. We haven&apos;t experienced box seats yet, but we&apos;re still hopeful. Trish is the star of her team, and it&apos;s her favorite job, &lt;strong&gt;ever&lt;/strong&gt;. She&apos;s delighted at the fact that I&apos;m asking her if SIEM and SOAR are acronyms or just fancy industry terms.
&lt;/p&gt;
&lt;p&gt;
    You&apos;re probably wondering if we&apos;re evil parents at this point. You&apos;ve learned about Trish and me, but what about the kids, the pets, and our parents? I mean, this is a life update after all!
&lt;/p&gt;
&lt;p&gt;
    The kids are doing great. As a casual blogger, I still managed to post about both of their birthdays this year. &lt;a href=&quot;https://raibledesigns.com/rd/entry/happy_birthday_jack13&quot;&gt;Jack&lt;/a&gt; and &lt;a href=&quot;https://raibledesigns.com/rd/entry/happy_birthday_abbie18&quot;&gt;Abbie&lt;/a&gt; are thriving! 
&lt;/p&gt;
&lt;p&gt;They&apos;re still in school at CU Boulder and enjoying the Coach Prime Era. Abbie&apos;s a senior and &lt;a href=&quot;https://www.linkedin.com/posts/abigail-raible_spectrum-success-internship-activity-7231712846441541633-kPrb&quot;&gt;already has a job&lt;/a&gt;. That&apos;s quite an accomplishment, and we&apos;re very impressed!
&lt;/p&gt;
&lt;p&gt;
    Jack&apos;s thinking about dating. He didn&apos;t try out for the CU basketball team, but he&apos;s still interested in making it happen.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54142861804_2d6b45fede_c.jpg&quot; title=&quot;Fall Birthday Celebration&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54142861804/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54142861804_2d6b45fede.jpg&quot; width=&quot;500&quot; alt=&quot;Fall Birthday Celebration&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    The pets are currently spoiled. Trish&apos;s best friend, Caroline, has moved in. She takes the two dogs (Daisy and Kai) on daily walks. I tend to like the same activity, and they&apos;re very good at pretending it&apos;s their first walk of the day with both of us!
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;https://live.staticflickr.com/65535/54139906827_58f2562759_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54139906827/in/album-72177720321954143&quot; title=&quot;Gracie and Kai &amp;#x1F63B;&quot; rel=&quot;lightbox[lifeupdate2024]&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54139906827_58f2562759_q.jpg&quot; width=&quot;150&quot; alt=&quot;Gracie and Kai &amp;#x1F63B;&quot; style=&quot;border: 1px solid black;&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://live.staticflickr.com/65535/54141222015_39750a6a5a_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141222015/in/album-72177720321954143&quot; title=&quot;My summer walking crew&quot; rel=&quot;lightbox[lifeupdate2024]&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141222015_39750a6a5a_q.jpg&quot; width=&quot;150&quot; alt=&quot;My summer walking crew&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;/&gt;&lt;/a&gt;
&lt;a href=&quot;https://live.staticflickr.com/65535/54120350913_ee9f5d87d4_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54120350913/&quot; title=&quot;Strike a pose&quot; rel=&quot;lightbox[lifeupdate2024]&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54120350913_ee9f5d87d4_q.jpg&quot; width=&quot;150&quot; alt=&quot;Strike a pose&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Our parents are thriving too! I recently attended Trish&apos;s Dad&apos;s 85th birthday celebration. He&apos;s doing splendid and likes to swim and play tennis daily.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141084639_137cf2cddc_c.jpg&quot; title=&quot;Beautiful family at sunset&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141084639/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141084639_137cf2cddc.jpg&quot; width=&quot;500&quot; alt=&quot;Beautiful family at sunset&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141034108_519541e79f_c.jpg&quot; title=&quot;Sunset on the Spit&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141034108/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141034108_519541e79f.jpg&quot; width=&quot;500&quot; alt=&quot;Sunset on the Spit&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    My parents are still loving life in Montana. A friend of theirs has a photo trap set up for wildlife on the homestead. He captures some amazing photos! Check out &lt;a href=&quot;https://www.marcelhuijserphotography.com/&quot;&gt;his website&lt;/a&gt; for more fabulous shots.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141220470_d67217aa5a_c.jpg&quot; title=&quot;Meanwhile, at the homestead in Montana...&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141220470/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141220470_d67217aa5a.jpg&quot; width=&quot;500&quot; alt=&quot;Meanwhile, at the homestead in Montana...&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141035163_525b6a1039_c.jpg&quot; title=&quot;Back at the homestead, a deer emerges&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141035163/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141035163_525b6a1039.jpg&quot; width=&quot;500&quot; alt=&quot;Back at the homestead, a deer emerges&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Trish has more to her story. She&apos;s experienced some of the most extreme ups and downs of her life. In July, shortly after we celebrated my birthday, we spent a week in Estes Park. The reason was simple: she wanted to compete in a horse show and I wanted to support her, explore the nearby trails, and visit the local breweries.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141228485_b95064cec2_c.jpg&quot; title=&quot;Happy Trish in Estes Park&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141228485/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141228485_b95064cec2_m.jpg&quot; width=&quot;240&quot; alt=&quot;Happy Trish in Estes Park&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54139914827_1bbed3f29e_c.jpg&quot; title=&quot;The Morning Crew&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54139914827/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54139914827_1bbed3f29e_m.jpg&quot; width=&quot;240&quot; alt=&quot;The Morning Crew&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54139912477_6a3a08e7a9_c.jpg&quot; title=&quot;What a beautiful world! &amp;#x2764;&amp;#xFE0F;&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54139912477/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54139912477_6a3a08e7a9.jpg&quot; width=&quot;500&quot; alt=&quot;What a beautiful world! &amp;#x2764;&amp;#xFE0F;&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54139911547_098aeae28c_c.jpg&quot; title=&quot;Last day of Funemployment.&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54139911547/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54139911547_098aeae28c_q.jpg&quot; width=&quot;150&quot; alt=&quot;Last day of Funemployment.&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54140764661_5bccdd1469_c.jpg&quot; title=&quot;Happy Anniversary! &amp;#x1F495;&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54140764661/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54140764661_5bccdd1469_q.jpg&quot; width=&quot;150&quot; alt=&quot;Happy Anniversary! &amp;#x1F495;&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54139910182_d5826a21ec_c.jpg&quot; title=&quot;Trish in her happy place!&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54139910182/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54139910182_d5826a21ec_q.jpg&quot; width=&quot;150&quot; alt=&quot;Trish in her happy place!&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We decided to make her lifelong dreams come true and leased the most kick-ass horse she could find. His name is Athos, and he was the horse she competed with in Estes Park. He&apos;s 18.2 hands tall, which means he&apos;s 6&apos; at the saddle. Trish is only 5&apos;1&quot;. They won Reserve Champion on their first collaboration!
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://live.staticflickr.com/65535/54141223880_9a7f76d179_c.jpg&quot; title=&quot;Look at all those ribbons!&quot; rel=&quot;lightbox[lifeupdate2024]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/54141223880/in/album-72177720321954143&quot;&gt;&lt;img src=&quot;https://live.staticflickr.com/65535/54141223880_9a7f76d179.jpg&quot; width=&quot;500&quot; alt=&quot;Look at all those ribbons!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Trish and Athos were a match made in heaven. Until they weren&apos;t.
&lt;/p&gt;
&lt;p&gt;
    A month ago, Trish fell off Athos after a jump in a training lesson. It was a tack failure while demoing a new saddle, and the stirrup strap slid right off. She almost saved it, but proceeded to fall and injure herself badly in the process. When I met her at the ER (Emergency Room), her pain level was 9.5/10 for her wrist and 3/10 for her ankle. She broke both her wrist and her ankle in the same accident. It wasn&apos;t Athos&apos; fault, but rather a faulty stirrup bar.
&lt;/p&gt;
&lt;p&gt;
    Since this happened, we&apos;ve learned I&apos;m a terribly grumpy caregiver, she&apos;s had her wrist surgically repaired, and her ankle had surgery a week later.
&lt;/p&gt;
&lt;p&gt;
    Breaking two bones at the same time really limits your mobility. I wouldn&apos;t wish it upon anyone. Trish is optimistic that she&apos;ll compete with horses in the future, but she&apos;s also realizing it gets harder as you get older.
&lt;/p&gt;
&lt;h3&gt;What&apos;s Next?&lt;/h3&gt;
&lt;p&gt;
    Trish, Jack, and I have all had midlife crises this year. Trish cranked things up a notch to be a world-class eventer with horses, then got hurt. Jack was going to be an aeronautics engineer, then took a helicopter flight over Glacier National Park and changed his mind. I abandoned all my Java experience and chose CrowdStrike, a Go and Python shop.
&lt;/p&gt;
&lt;p&gt;
    Abbie&apos;s a senior in college and already has a job. I think she&apos;s winning the family badass contest!
&lt;/p&gt;
&lt;p&gt;
    We have no idea what&apos;s next. But we&apos;re proud of Abbie for securing her first job.
&lt;/p&gt;
&lt;p&gt;
    As for the rest of us? We&apos;ll figure it out. Raibles and McGinitys are known for thriving in the face of adversity. &amp;#x1F4AA;&amp;#x1F603;
&lt;/p&gt;
&lt;p style=&quot;font-size: .9em&quot;&gt;For a photo and video experience of our summer adventures, see my &lt;a href=&quot;https://www.flickr.com/photos/mraible/albums/72177720321954143/&quot;&gt;Summer Adventures 2024&lt;/a&gt; album on Flickr.&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/jhipsterconf_2018_summer_solstice_in</id>
        <title type="html">JHipster Conf 2018: Summer Solstice in Paris</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/jhipsterconf_2018_summer_solstice_in"/>
        <published>2018-06-28T10:13:27-06:00</published>
        <updated>2018-06-28T16:15:28-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="angular" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jhipster" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jhipsterconf2018" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="paris" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ippon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="react" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jhipsterconf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring-boot" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;
Last week, I journeyed to Paris with my son, Jack. It was his first time in Europe and I brought him along for good reason. I&#8217;d been invited to the first ever JHipster Conf, and I was eager to attend. We were both pretty excited when we left Denver last Monday.
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 600px&quot;&gt;
&lt;blockquote class=&quot;instagram-media&quot; data-instgrm-captioned data-instgrm-permalink=&quot;https://www.instagram.com/p/BkLwcPPHvGt/&quot; data-instgrm-version=&quot;8&quot; style=&quot; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);&quot;&gt;&lt;div style=&quot;padding:8px;&quot;&gt; &lt;div style=&quot; background:#F8F8F8; line-height:0; margin-top:40px; padding:37.5% 0; text-align:center; width:100%;&quot;&gt; &lt;div style=&quot; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;&quot;&gt;&lt;/div&gt;&lt;/div&gt; &lt;p style=&quot; margin:8px 0 0 0; padding:0 4px;&quot;&gt; &lt;a href=&quot;https://www.instagram.com/p/BkLwcPPHvGt/&quot; style=&quot; color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;&quot; target=&quot;_blank&quot;&gt;Our adventure to Paris begins! #jhipsterconf&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;&quot;&gt;A post shared by &lt;a href=&quot;https://www.instagram.com/vwsforlife/&quot; style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;&quot; target=&quot;_blank&quot;&gt; Matt Raible&lt;/a&gt; (@vwsforlife) on &lt;time style=&quot; font-family:Arial,sans-serif; font-size:14px; line-height:17px;&quot; datetime=&quot;2018-06-18T23:01:22+00:00&quot;&gt;Jun 18, 2018 at 4:01pm PDT&lt;/time&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt; &lt;script async defer src=&quot;//www.instagram.com/embed.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;h3 id=&quot;background&quot;&gt;My Background with JHipster&lt;/h3&gt;
&lt;p&gt;
I&#8217;ve been a part of the &lt;a href=&quot;https://www.jhipster.tech&quot;&gt;JHipster&lt;/a&gt; community for a few years now. I joined by accident, really. I was trying to market myself as an independent consultant by spouting my knowledge of Spring Boot and Angular with an InfoQ mini-book. Since JHipster leveraged both to jumpstart app development, it seemed like a perfect fit. I&#8217;ve been a long-time fan of app jumpstarts, having developed my own called AppFuse in days long gone.
&lt;/p&gt;
&lt;p&gt;
Through the process of writing the mini-book, finding issues, and submitting pull requests, I eventually found myself to be a member of the JHipster development team. Through my relationship with JHipster, and it&#8217;s 3.0 release, I found myself intrigued my microservices and how to develop them with Spring Boot, Spring Cloud, all through the generation expertise of JHipster.
&lt;/p&gt;
&lt;p&gt;
I&#8217;ve learned a ton by being part of the project and trying to figure out how all of its options work.
&lt;/p&gt;
&lt;p&gt;
    When I found myself with a &lt;a href=&quot;//raibledesigns.com/rd/entry/life_update_a_summer_to&quot;&gt;full-time job at Stormpath&lt;/a&gt;, I did my best to create a Stormpath module for JHipster. When Okta acquired Stormpath, I added a similar module to my list of things I wanted to write.
&lt;/p&gt;
&lt;p&gt;
When it came time to implement an Okta module, I discovered JHipster&#8217;s OAuth support only worked internally, not with an external OAuth provider, also known as an Identity Provider, or IdP. I mentioned to the JHipster team I thought we could do better and add support for external providers instead. They agreed, and I went to work.
&lt;/p&gt;
&lt;p&gt;
    In hindsight, it was a great decision and not terribly difficult to implement thanks to Spring Security, Keycloak, and Docker. We had a ton of help from the community along the way, and as of last October, &lt;a href=&quot;https://developer.okta.com/blog/2017/10/20/oidc-with-jhipster&quot;&gt;JHipster added support for single sign-on with OIDC&lt;/a&gt; (tested with Keycloak and Okta).
&lt;/p&gt;
&lt;h3 id=&quot;jhipster5&quot;&gt;JHipster 5.0: Spring Boot 2.0, Angular 6, and React&lt;/h3&gt;
&lt;p&gt;It&#8217;s been a fabulous adventure on the JHipster train and it&#8217;s still going strong. We just &lt;a href=&quot;https://www.jhipster.tech/2018/06/20/jhipster-release-5.0.0.html&quot;&gt;released version 5.0&lt;/a&gt; with React and Spring Boot 2.0 support, there&#8217;s client generators for &lt;a href=&quot;https://github.com/oktadeveloper/generator-jhipster-ionic&quot;&gt;Ionic&lt;/a&gt; and &lt;a href=&quot;https://github.com/oktadeveloper/generator-jhipster-ionic&quot;&gt;React Native&lt;/a&gt;, and &lt;a href=&quot;https://jhipster-conf.github.io/&quot;&gt;we just hosted a kick-ass conference about JHipster in Paris&lt;/a&gt;.
&lt;/p&gt;
&lt;h3 id=&quot;jhipsterconf-2018&quot;&gt;JHipster Conf 2018&lt;/h3&gt;
&lt;p&gt;
The conference featured members of the core team, the well-dressed and fit &lt;a href=&quot;https://twitter.com/codefinger&quot;&gt;Joe Kutner&lt;/a&gt; from Heroku, as well as Java celebrities like &lt;a href=&quot;https://twitter.com/saturnism&quot;&gt;Ray Tsang&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/starbuxman&quot;&gt;Josh Long&lt;/a&gt;. You can &lt;a href=&quot;https://blog.ippon.tech/jhipster-conf-2018/&quot;&gt;read about the festivities and presentations from JHipster&apos;s founder&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/juliendubois&quot;&gt;Julien Dubois&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    The conference was a little over 24 hours long, starting with a speaker&#8217;s dinner on Wednesday evening. Before attending, Jack and I spent the day strolling around Versailles. Versailles is a special place in my life since &lt;a href=&quot;https://raibledesigns.com/rd/entry/our_engaging_trip_to_paris&quot;&gt;I proposed to my double rainbow there&lt;/a&gt; after Devoxx Belgium in 2011.
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 600px&quot;&gt;
&lt;blockquote class=&quot;instagram-media&quot; data-instgrm-captioned data-instgrm-permalink=&quot;https://www.instagram.com/p/BkQLlMnnsJo/&quot; data-instgrm-version=&quot;8&quot; style=&quot; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);&quot;&gt;&lt;div style=&quot;padding:8px;&quot;&gt; &lt;div style=&quot; background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;&quot;&gt; &lt;div style=&quot; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;&quot;&gt;&lt;/div&gt;&lt;/div&gt; &lt;p style=&quot; margin:8px 0 0 0; padding:0 4px;&quot;&gt; &lt;a href=&quot;https://www.instagram.com/p/BkQLlMnnsJo/&quot; style=&quot; color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;&quot; target=&quot;_blank&quot;&gt;?? Versailles #working #jhipsterconf&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;&quot;&gt;A post shared by &lt;a href=&quot;https://www.instagram.com/vwsforlife/&quot; style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;&quot; target=&quot;_blank&quot;&gt; Matt Raible&lt;/a&gt; (@vwsforlife) on &lt;time style=&quot; font-family:Arial,sans-serif; font-size:14px; line-height:17px;&quot; datetime=&quot;2018-06-20T16:15:29+00:00&quot;&gt;Jun 20, 2018 at 9:15am PDT&lt;/time&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;p&gt;The conference kicked off with &lt;a href=&quot;https://www.slideshare.net/julien.dubois/jhipster-conf-2018-keynote&quot;&gt;a keynote by the JHipster&apos;s co-leads: Julien and Deepu&lt;/a&gt;. 
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 500px&quot;&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;Full house at &lt;a href=&quot;https://twitter.com/hashtag/JHipsterConf?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#JHipsterConf&lt;/a&gt; &lt;a href=&quot;https://twitter.com/java_hipster?ref_src=twsrc%5Etfw&quot;&gt;@java_hipster&lt;/a&gt; &lt;a href=&quot;https://twitter.com/hashtag/paris?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#paris&lt;/a&gt; &lt;a href=&quot;https://t.co/nnZ6JmlXrW&quot;&gt;pic.twitter.com/nnZ6JmlXrW&lt;/a&gt;&lt;/p&gt;&amp;mdash; Deepu K Sasidharan (@deepu105) &lt;a href=&quot;https://twitter.com/deepu105/status/1009729525071187969?ref_src=twsrc%5Etfw&quot;&gt;June 21, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 500px&quot;&gt;
&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/wdZWHmGx3zJHnK&quot; width=&quot;500&quot; height=&quot;319&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; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen&gt; &lt;/iframe&gt; &lt;div style=&quot;margin-bottom:5px&quot;&gt; &lt;strong&gt; &lt;a href=&quot;//www.slideshare.net/julien.dubois/jhipster-conf-2018-keynote&quot; title=&quot;JHipster Conf 2018 keynote&quot; target=&quot;_blank&quot;&gt;JHipster Conf 2018 keynote&lt;/a&gt; &lt;/strong&gt; from &lt;strong&gt;&lt;a href=&quot;https://www.slideshare.net/julien.dubois&quot; target=&quot;_blank&quot;&gt;Julien Dubois&lt;/a&gt;&lt;/strong&gt; &lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;
During my talk, I had Jack join me on stage for an intro, and tried to give him a taste of public speaking in front of hundreds.
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 600px&quot;&gt;
&lt;blockquote class=&quot;instagram-media&quot; data-instgrm-captioned data-instgrm-permalink=&quot;https://www.instagram.com/p/BkTWAN2HhU-/&quot; data-instgrm-version=&quot;8&quot; style=&quot; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);&quot;&gt;&lt;div style=&quot;padding:8px;&quot;&gt; &lt;div style=&quot; background:#F8F8F8; line-height:0; margin-top:40px; padding:50% 0; text-align:center; width:100%;&quot;&gt; &lt;div style=&quot; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;&quot;&gt;&lt;/div&gt;&lt;/div&gt; &lt;p style=&quot; margin:8px 0 0 0; padding:0 4px;&quot;&gt; &lt;a href=&quot;https://www.instagram.com/p/BkTWAN2HhU-/&quot; style=&quot; color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;&quot; target=&quot;_blank&quot;&gt;After a fabulous day at #JHipsterConf and a fun rooftop party at @ippon_technologies , Jack and I enjoyed a romantic dinner and a bit of F&#234;te de la Musique. ??&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;&quot;&gt;A post shared by &lt;a href=&quot;https://www.instagram.com/vwsforlife/&quot; style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;&quot; target=&quot;_blank&quot;&gt; Matt Raible&lt;/a&gt; (@vwsforlife) on &lt;time style=&quot; font-family:Arial,sans-serif; font-size:14px; line-height:17px;&quot; datetime=&quot;2018-06-21T21:44:16+00:00&quot;&gt;Jun 21, 2018 at 2:44pm PDT&lt;/time&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;p&gt;
My talk went well, with some successful and some failed demos. Hopefully people got the point that it&#8217;s cool to store your users outside of JHipster so you can share them between apps. I also tried to show that &lt;a href=&quot;https://developer.okta.com/books/api-security/&quot;&gt;OAuth and OIDC are excellent for securing APIs&lt;/a&gt;. You can &lt;a href=&quot;https://speakerdeck.com/mraible/add-sso-to-your-jhipster-apps-with-oidc-jhipsterconf-2018&quot;&gt;download my presentation from Add JHipster to Your JHipster Apps with OIDC&lt;/a&gt; or view it below.
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 600px&quot;&gt;
&lt;script async class=&quot;speakerdeck-embed&quot; data-id=&quot;255494c7d9024d99a5ca260cd65085b2&quot; data-ratio=&quot;1.77777777777778&quot; src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;I created a tutorial of the app I showed in my talk and published it to the Okta developer blog: &lt;a href=&quot;https://developer.okta.com/blog/2018/06/25/react-spring-boot-photo-gallery-pwa&quot;&gt;Build a Photo Gallery PWA with React, Spring Boot, and JHipster&lt;/a&gt;. If you like React and OAuth, you&apos;re gonna love this guide!
&lt;/p&gt;
&lt;p&gt;
Jack and I had a day in Paris after the conference, so we made the most of it. We hit the Eiffel Tower, hiked the stairs, and marveled at the view. After, we waited in a long line for The Catacombs and walked among the dead.
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 500px&quot;&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I had a wonderful time this week in Paris and at &lt;a href=&quot;https://twitter.com/jhipsterconf?ref_src=twsrc%5Etfw&quot;&gt;@jhipsterconf&lt;/a&gt;. Many thanks to the &lt;a href=&quot;https://twitter.com/java_hipster?ref_src=twsrc%5Etfw&quot;&gt;@java_hipster&lt;/a&gt; developers, community, &lt;a href=&quot;https://twitter.com/juliendubois?ref_src=twsrc%5Etfw&quot;&gt;@juliendubois&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/deepu105?ref_src=twsrc%5Etfw&quot;&gt;@deepu105&lt;/a&gt;, and &lt;a href=&quot;https://twitter.com/ippontech?ref_src=twsrc%5Etfw&quot;&gt;@ippontech&lt;/a&gt; for making it all possible! &lt;a href=&quot;https://twitter.com/hashtag/JHipsterConf?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#JHipsterConf&lt;/a&gt; &lt;a href=&quot;https://t.co/61ZfRZxg8G&quot;&gt;pic.twitter.com/61ZfRZxg8G&lt;/a&gt;&lt;/p&gt;&amp;mdash; Matt Raible (@mraible) &lt;a href=&quot;https://twitter.com/mraible/status/1010477663943909377?ref_src=twsrc%5Etfw&quot;&gt;June 23, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;/div&gt;
&lt;h3 id=&quot;kudos&quot;&gt;Kudos to the JHipster Community!&lt;/h3&gt;
&lt;p&gt;
What a trip! It&#8217;s so much fun to be a part of JHipster&#8217;s thriving open source community. It&#8217;s not just the project itself; it&#8217;s all the projects we build upon, from Java to TypeScript to Spring Boot to Spring Data to Spring Security to Angular to React to webpack to Bootstrap. It&#8217;s a conglomeration of all of my favorite tools and open source developers encompassed in several awesome projects!
&lt;/p&gt;
&lt;p&gt;
Life as an open source developer is pretty fun. I encourage you to get involved in open source too! I started way back in the early 2000s with Struts and Ant, and it&#8217;s done wonders for my career.
&lt;/p&gt;
&lt;p&gt;
    &lt;em&gt;Viva La Open Source!&lt;/em&gt;
&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/2017_a_year_in_review</id>
        <title type="html">2017 - A Year in Review</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/2017_a_year_in_review"/>
        <published>2018-01-31T16:16:39-07:00</published>
        <updated>2019-01-26T22:42:28-07:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="okta" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="porschebus" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="syncro" scheme="http://roller.apache.org/ns/tags/" />
        <category term="2017" scheme="http://roller.apache.org/ns/tags/" />
        <category term="pets" scheme="http://roller.apache.org/ns/tags/" />
        <category term="family" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hefethebus" scheme="http://roller.apache.org/ns/tags/" />
        <category term="stoutthesyncro" scheme="http://roller.apache.org/ns/tags/" />
        <category term="blogging" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yearinreview" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;2017 was a year with many changes. We changed presidents, Stormpath joined forces with Okta, our daughter started high school, and we lost two of our precious pets. On the upside, I traveled to many beautiful places, talked to developers around the world, and became a Devoxx Champion. Not only that, but our two classic VWs ran like champs the whole year. We put upwards of 10K adventure miles on our Syncro, and another couple thousand on Hefe the Bus.&lt;/p&gt;

&lt;p&gt;I&apos;m going to look back on 2017 using the following categories.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#stout_and_hefe&quot;&gt;Stout and Hefe&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#2018&quot;&gt;2018&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;2017 was the first year I started with a full-time job in January since the turn of the century. I&apos;d been an independent consultant for most of my career. Stormpath enticed me enough with their people and vision that I &lt;a
        href=&quot;//raibledesigns.com/rd/entry/life_update_a_summer_to&quot;&gt;became a full-time employee with them in
    September 2016&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;January started slow, but I started to hit my stride in February when I &lt;a
        href=&quot;//raibledesigns.com/rd/entry/a_jolly_good_time_at&quot;&gt;traveled to Sweden for Jfokus and skiing&lt;/a&gt;.
    Coincidentally, it was shortly after the conference that I found myself negotiating with &lt;a
            href=&quot;https://www.linkedin.com/in/epberg&quot;&gt;Eric Berg&lt;/a&gt; about joining forces with &lt;a
            href=&quot;https://www.okta.com&quot;&gt;Okta&lt;/a&gt;. I remember it well: I was sitting in the hotel lobby, with James Ward and Ray Tsang, when it all happened. Shortly after, we were sitting in the back of the bus on our way to a skiing
    adventure.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;2017 was a year with many changes. We changed presidents, Stormpath joined forces with Okta, our daughter started high school, and we lost two of our precious pets. On the upside, I traveled to many beautiful places, talked to developers around the world, and became a Devoxx Champion. Not only that, but our two classic VWs ran like champs the whole year. We put upwards of 10K adventure miles on our Syncro, and another couple thousand on Hefe the Bus.&lt;/p&gt;

&lt;p&gt;I&apos;m going to look back on 2017 using the following categories.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#stout-and-hefe&quot;&gt;Stout and Hefe&lt;/a&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2017_a_year_in_review#2018&quot;&gt;2018&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;2017 was the first year I started with a full-time job in January since the turn of the century. I&apos;d been an independent consultant for most of my career. Stormpath enticed me enough with their people and vision that I &lt;a
    href=&quot;//raibledesigns.com/rd/entry/life_update_a_summer_to&quot;&gt;became a full-time employee with them in
  September 2016&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;January started slow, but I started to hit my stride in February when I &lt;a
    href=&quot;//raibledesigns.com/rd/entry/a_jolly_good_time_at&quot;&gt;traveled to Sweden for Jfokus and skiing&lt;/a&gt;.
  Coincidentally, it was shortly after the conference that I found myself negotiating with &lt;a
      href=&quot;https://www.linkedin.com/in/epberg&quot;&gt;Eric Berg&lt;/a&gt; about joining forces with &lt;a
      href=&quot;https://www.okta.com&quot;&gt;Okta&lt;/a&gt;. I remember it well: I was sitting in the hotel lobby, with James Ward and Ray Tsang, when it all happened. Shortly after, we were sitting in the back of the bus on our way to a skiing
  adventure.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://c1.staticflickr.com/3/2212/32098286464_d3d55d7192_c.jpg&quot; title=&quot;Sunrise at Storhogna&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/32098286464/in/datetaken-public/&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/3/2212/32098286464_d3d55d7192_m.jpg&quot; width=&quot;240&quot; alt=&quot;Sunrise at Storhogna&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
  &lt;a href=&quot;https://c1.staticflickr.com/4/3869/32788113292_c7d359d8f2_c.jpg&quot; title=&quot;It was a beautiful day for skiing at Kl&#246;vsj&#246;!&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/32788113292/in/datetaken-public/&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/4/3869/32788113292_c7d359d8f2_m.jpg&quot; width=&quot;240&quot; alt=&quot;It was a beautiful day for skiing at Kl&#246;vsj&#246;!&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;A week later, I was back in the states and the deal with Okta was happening. Throughout January, I thought the possibility was 20%. When I returned home from Jfokus, it was full-on happening. In fact, I was one of the last ones to sign the deal, causing panic and a few phone calls in the process. Most of the folks at Stormpath became Okta employees on February 27. &lt;/p&gt;
&lt;p&gt;The awkward part was we knew about the deal when we traveled to Devnexus. We had a Stormpath booth there, and we were
  unable to tell everyone there would be no more signups after Friday, February 24.&lt;/p&gt;
&lt;p&gt;The following week, we had a massive onboarding with everyone. There was excitement in the room and many high spirits, so it was a fun day. Shortly after, we entered into a 90-day quiet period for Okta&apos;s IPO. It was strange to
  start a new job with a new company and not be able to talk about it.&lt;/p&gt;
&lt;p&gt;Okta didn&apos;t have much for SDKs when we started writing blog posts in March. However, it supports standards like SAML and
  OAuth, so I was able to put together some posts using Spring Security.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/03/16/spring-boot-saml&quot;&gt;Get Started with Spring Boot, SAML, and
    Okta&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/03/21/spring-boot-oauth&quot;&gt;Get Started with Spring Boot, OAuth 2.0,
    and Okta&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I wrote about my anticipation for &lt;a href=&quot;//raibledesigns.com/rd/entry/let_the_okta_and_devoxx&quot;&gt;Devoxx US and
  France&lt;/a&gt; in mid-March.
&lt;p&gt;
  Towards the end of March and early April, I had some luck integrating with Angular, both with Okta&apos;s &lt;a
    href=&quot;https://developer.okta.com/blog/2017/03/27/angular-okta-sign-in-widget&quot;&gt;Sign-In Widget&lt;/a&gt; and &lt;a
    href=&quot;https://developer.okta.com/blog/2017/04/17/angular-authentication-with-oidc&quot;&gt;OpenID Connect&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;In early April, I hosted an &lt;a
    href=&quot;https://speakerdeck.com/mraible/the-ultimate-getting-started-with-angular-workshop-devoxx-france-2017&quot;&gt;Angular
  Workshop&lt;/a&gt; and spoke about &lt;a href=&quot;//raibledesigns.com/rd/entry/angular_and_cloud_native_pwas&quot;&gt;Cloud Native
  Progressive Web Apps&lt;/a&gt; with &lt;a href=&quot;https://twitter.com/starbuxman&quot;&gt;Josh Long&lt;/a&gt; at Devoxx France.&lt;/p&gt;
&lt;div style=&quot;max-width: 500px; margin: 0 auto&quot;&gt;
  &lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;We&amp;#39;re about to kick off the part deux of our Cloud Native Apps series with &lt;a href=&quot;https://twitter.com/mraible&quot;&gt;@mraible&lt;/a&gt; &lt;a href=&quot;https://twitter.com/DevoxxFR&quot;&gt;@DevoxxFR&lt;/a&gt; &lt;a href=&quot;https://t.co/0GCSAiUgs4&quot;&gt;pic.twitter.com/0GCSAiUgs4&lt;/a&gt;&lt;/p&gt;&amp;mdash; Josh Long (???, ???) (@starbuxman) &lt;a href=&quot;https://twitter.com/starbuxman/status/850002466783584257&quot;&gt;April 6, 2017&lt;/a&gt;&lt;/blockquote&gt;
  &lt;script async src=&quot;https://platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
On my flight home from that
trip &amp;mdash; on April 7 &amp;mdash; Okta had its IPO. Things started trucking along after the IPO. I wrote a plethora of blogs posts in April and published them over the spring and summer months.
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/04/26/bootiful-development-with-spring-boot-and-angular&quot;&gt;Bootiful
    Development with Spring Boot and Angular&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/05/09/progressive-web-applications-with-angular-and-spring-boot&quot;&gt;Build
    Your First Progressive Web Application with Angular and Spring Boot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/05/17/develop-a-mobile-app-with-ionic-and-spring-boot&quot;&gt;Tutorial:
    Develop a Mobile App With Ionic and Spring Boot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/06/13/add-authentication-angular-pwa&quot;&gt;Add Authentication to Your
    Angular PWA&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/06/15/build-microservices-architecture-spring-boot&quot;&gt;Build a
    Microservices Architecture for Microbrews with Spring Boot&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/06/20/develop-microservices-with-jhipster&quot;&gt;Develop and Deploy
    Microservices with JHipster&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/06/21/what-the-heck-is-oauth&quot;&gt;What the Heck is OAuth?&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/07/20/the-ultimate-guide-to-progressive-web-applications&quot;&gt;The
    Ultimate Guide to Progressive Web Applications&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;speaking&quot;&gt;Speaking&lt;/h3&gt;
&lt;p&gt;This year, speaking became a part of my job, so I spoke frequently. According to &lt;a href=&quot;https://www.tripit.com&quot;&gt;TripIt&lt;/a&gt;, I took 29 trips, to 41 cities, and 14 countries. I traveled 115,456 miles and spent &lt;a
    href=&quot;http://cem.re/year-in-review/55145c02b97d22c568e9f7668cf0eb65f2652779.html&quot;&gt;most of my time on
  United&lt;/a&gt;. By my count, I spoke at 22 events.&lt;/p&gt;
&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;
      &lt;ol&gt;
        &lt;li&gt;&lt;a href=&quot;http://www.jfokus.se/jfokus/&quot;&gt;Jfokus&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://devnexus.com/&quot;&gt;Devnexus&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://www.meetup.com/kc-spring/&quot;&gt;Kansas City Spring User Group&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://devoxx.us/&quot;&gt;Devoxx US&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://devoxx.fr/&quot;&gt;Devoxx France&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;http://jspring.nl/&quot;&gt;J-Spring&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://www.devoxx.co.uk/&quot;&gt;Devoxx UK&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://geecon.org/&quot;&gt;GeeCON&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://2018.springio.net/&quot;&gt;Spring I/O&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;http://devoxx.pl/&quot;&gt;Devoxx Poland&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://uberconf.com/conference/denver/2018/07/home&quot;&gt;UberConf&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/td&gt;
    &lt;td&gt;
      &lt;ol start=&quot;12&quot;&gt;
        &lt;li&gt;&lt;a href=&quot;https://virtualjug.com/&quot;&gt;Virtual JUG&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://www.okta.com/oktane17/&quot;&gt;Oktane17&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;http://connect.tech/&quot;&gt;Connect.Tech&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://www.denverstartupweek.org/&quot;&gt;Denver Startup Week&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://www.oracle.com/javaone/index.html&quot;&gt;JavaOne&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://2017.java2days.com/&quot;&gt;Java2Days&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://virtualjug.com/vjug24/&quot;&gt;vJUG24&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://devoxx.be/&quot;&gt;Devoxx Belgium&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://devoxx.ma/&quot;&gt;Devoxx Morocco&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://springoneplatform.io/&quot;&gt;SpringOne&lt;/a&gt;&lt;/li&gt;
        &lt;li&gt;&lt;a href=&quot;https://therichwebexperience.com/conference/clearwater/2017/12/home&quot;&gt;The Rich Web Experience&lt;/a&gt;&lt;/li&gt;
      &lt;/ol&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;

&lt;p&gt;I wrote about my experiences at &lt;a href=&quot;//raibledesigns.com/rd/entry/speaking_adventures_at_j_spring&quot;&gt;J-Spring,
  Devoxx UK, GeeCON, and Spring I/O&lt;/a&gt; in May, and &lt;a
    href=&quot;//raibledesigns.com/rd/entry/devoxx_poland_a_huge_conference&quot;&gt;Devoxx Poland&lt;/a&gt; in June. Spring I/O was especially fun because Trish met me in Barcelona.&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://c1.staticflickr.com/5/4204/34056220883_3b09f9692f_c.jpg&quot; title=&quot;Amazing Architecture in Barcelona&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/34056220883/in/album-72157682270620100/&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/5/4204/34056220883_3b09f9692f_n.jpg&quot; width=&quot;240&quot; alt=&quot;Amazing Architecture in Barcelona&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
  &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4195/34826706046_ef7ecf690e_c.jpg&quot; title=&quot;Barcelona&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/34826706046/in/album-72157682270620100/&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/5/4195/34826706046_ef7ecf690e_n.jpg&quot; width=&quot;240&quot; alt=&quot;Barcelona&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;I was featured on the main Okta blog in late September in &lt;a href=&quot;https://www.okta.com/blog/2017/09/developer-dna-a-day-in-the-life-of-matt-raible/&quot;&gt;Developer DNA: A Day in the Life of Matt Raible&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4547/37491517464_14d37e8eda_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/37491517464/&quot; title=&quot;Matt the Hipster&quot; rel=&quot;lightbox[2017yearinreview]&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4547/37491517464_14d37e8eda.jpg&quot; width=&quot;500&quot; alt=&quot;Matt the Hipster&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;As the year was waning, I wrote about &lt;a href=&quot;//raibledesigns.com/rd/entry/life_as_an_open_source1&quot;&gt;life as an open
  source developer&lt;/a&gt; and &lt;a href=&quot;//raibledesigns.com/rd/entry/a_stressful_but_rewarding_trip&quot;&gt;my adventures to Devoxx
  Belgium and Devoxx Morocco&lt;/a&gt;.

&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4543/26811844159_1b82a326bf_c.jpg&quot; title=&quot;Angular vs React Smackdown with Deepu&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/26811844159/in/album-72157690880978696/&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4543/26811844159_1b82a326bf.jpg&quot; width=&quot;500&quot; alt=&quot;Angular vs React Smackdown with Deepu&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4562/37700212995_9b7bf52f74_c.jpg&quot; title=&quot;Devoxx Champion!&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/37700212995/in/album-72157690880978696/&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4562/37700212995_9b7bf52f74_n.jpg&quot; width=&quot;240&quot; alt=&quot;Devoxx Champion!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4528/26811841249_2cf6c7ab1b_c.jpg&quot; title=&quot;Devoxx Champions!&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/26811841249/in/album-72157690880978696/&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4528/26811841249_2cf6c7ab1b_n.jpg&quot; width=&quot;240&quot; alt=&quot;Devoxx Champions!&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;In my blog post about &lt;a href=&quot;//raibledesigns.com/rd/entry/springone_the_rich_web_experience&quot;&gt;SpringOne
  and The Rich Web Experience&lt;/a&gt;, I included a picture of my 2017 conference lanyard collection.&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4634/38516035974_9910bd1df0_c.jpg&quot; title=&quot;2017 Conferences&quot;
     rel=&quot;lightbox[2017yearinreview]&quot;
     data-href=&quot;https://www.flickr.com/photos/mraible/38516035974/in/datetaken-public/&quot;&gt;&lt;img
      src=&quot;https://farm5.staticflickr.com/4634/38516035974_9910bd1df0.jpg&quot; alt=&quot;2017 Conferences&quot;
      style=&quot;border: 1px solid black;&quot; width=&quot;500&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;To end the year, I published some popular posts on the Okta Developer blog:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/12/04/basic-crud-angular-and-spring-boot&quot;&gt;Build a Basic CRUD App with Angular 5.0 and Spring Boot 2.0&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/12/06/bootiful-development-with-spring-boot-and-react&quot;&gt;Bootiful Development with Spring Boot and React&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.okta.com/blog/2017/12/18/spring-security-5-oidc&quot;&gt;Get Started with Spring Security 5.0 and OIDC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;devoxx4kids&quot;&gt;Devoxx4Kids&lt;/h3&gt;
&lt;p&gt;We held two &lt;a href=&quot;http://www.meetup.com/Devoxx4Kids-Denver&quot;&gt;Devoxx4Kids Denver&lt;/a&gt; workshops in 2017: &lt;a
    href=&quot;https://www.meetup.com/Devoxx4Kids-Denver/events/239523578/&quot;&gt;MIT App Inventor - Anyone Can Build Apps&lt;/a&gt;
  and &lt;a href=&quot;https://www.meetup.com/Devoxx4Kids-Denver/events/245437411/&quot;&gt;Fruit Ninja with Scratch&lt;/a&gt;. These
  classes were taught by &lt;a href=&quot;https://twitter.com/rpeyfuss&quot;&gt;Regina Peyfuss&lt;/a&gt; and &lt;a
      href=&quot;https://twitter.com/melissajmckay&quot;&gt;Melissa McKay&lt;/a&gt;, respectively. I&apos;m happy to announce they&apos;ve both
  since joined the board for Devoxx4Kids Denver and have been doing a great deal to help organize things.
&lt;/p&gt;
&lt;div style=&quot;max-width: 500px; margin: 0 auto&quot;&gt;
  &lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;I ?? the smell of learning in the morning. &lt;a href=&quot;https://twitter.com/hashtag/Devoxx4Kids?src=hash&amp;amp;ref_src=twsrc%5Etfw&quot;&gt;#Devoxx4Kids&lt;/a&gt; Denver in full swing w/ &lt;a href=&quot;https://twitter.com/rpeyfuss?ref_src=twsrc%5Etfw&quot;&gt;@rpeyfuss&lt;/a&gt; at &lt;a href=&quot;https://twitter.com/ThriveWorkplace?ref_src=twsrc%5Etfw&quot;&gt;@ThriveWorkplace&lt;/a&gt;. Awesome space and instructor! &lt;a href=&quot;https://t.co/a6Ac1qAJh0&quot;&gt;pic.twitter.com/a6Ac1qAJh0&lt;/a&gt;&lt;/p&gt;&amp;mdash; Matt Raible (@mraible) &lt;a href=&quot;https://twitter.com/mraible/status/871025101994565633?ref_src=twsrc%5Etfw&quot;&gt;June 3, 2017&lt;/a&gt;&lt;/blockquote&gt;
&lt;/div&gt;

&lt;p&gt;Our &lt;a href=&quot;https://www.meetup.com/Devoxx4Kids-Denver/events/247280135/&quot;&gt;next meetup will be on March 10&lt;/a&gt; and
  will be taught by Melissa&apos;s daughter, Kaitlyn! I think it&apos;s pretty cool we have an opportunity to have kids teaching kids.
  I&apos;ve also been working with Jay Zimmerman and &lt;a href=&quot;https://uberconf.com/conference/denver/2018/07/home&quot;&gt;UberConf&lt;/a&gt;
  to have an UberKids this summer.
&lt;/p&gt;

&lt;h3 id=&quot;projects&quot;&gt;Projects&lt;/h3&gt;
&lt;p&gt;AppFuse &lt;a href=&quot;//raibledesigns.com/rd/entry/moving_appfuse_into_the_attic&quot;&gt;is no more&lt;/a&gt;, so I primarily work on &lt;a href=&quot;http://www.jhipster.tech&quot;&gt;JHipster&lt;/a&gt; and the &lt;a href=&quot;https://www.infoq.com/minibooks/jhipster-2-mini-book&quot;&gt;JHipster-Mini Book&lt;/a&gt; these days. I refactored JHipster&apos;s OAuth authentication in September to use an external identity provider (e.g., Keycloak or Okta) instead of an embedded one. I wrote about how to &lt;a href=&quot;https://developer.okta.com/blog/2017/10/20/oidc-with-jhipster&quot;&gt;use OpenID Connect with JHipster&lt;/a&gt; on the Okta Developer blog in October.
&lt;/p&gt;
&lt;p&gt;With the help of InfoQ, &lt;a href=&quot;//raibledesigns.com/rd/entry/the_jhipster_mini_book_v4&quot;&gt;we released v4.0 of the JHipster Mini-Book&lt;/a&gt; on September 22nd. It&apos;s hard to believe, but it&apos;s &lt;em&gt;still&lt;/em&gt; up-to-date!&lt;/p&gt;

&lt;h2 id=&quot;personal&quot;&gt;Personal&lt;/h2&gt;

&lt;p&gt;I wrote down my goal at the beginning of 2017: to drive Hefe up the California coast. In July, &lt;a href=&quot;http://raibledesigns.com/rd/entry/driving_rafting_hiking_and_enjoying&quot;&gt;I wrote about why that goal got moved to my bucket list&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
  I wanted to spend our summer vacation driving our VWs up the California coast, on a mammoth 3500-mile road trip over two weeks. However, when &lt;a href=&quot;https://www.nytimes.com/2017/05/24/us/big-sur-landslide-coastal-highway.html&quot;&gt;a landslide happened near Big Sur&lt;/a&gt;, I knew it was probably best to move this road trip from my yearly goals to my bucket list. Instead, we opted to drive to Montana and spend a couple of weeks vacationing in my childhood playground.
&lt;/blockquote&gt;
&lt;p&gt;We had a blast road-tripping, hiking, and rafting in Montana. A highlight for me was hiking to Rumble Lake, somewhere I hadn&apos;t been to since I was a kid.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4318/35414905693_1ea174b49a_c.jpg&quot; title=&quot;Worth the hike&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/35414905693/in/album-72157686877599325/&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4318/35414905693_1ea174b49a_z.jpg&quot; width=&quot;500&quot; alt=&quot;Worth the hike&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;The drive home through Jackson Hole and the Flaming Gorge was pretty nice as well!&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4305/35387297204_b5086cb17a_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/35387297204/in/album-72157686877599325/&quot; title=&quot;Pretty nice views to wake up to this morning! #carpediem #working #vanlife&quot; rel=&quot;lightbox[2017yearinreview]&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4305/35387297204_b5086cb17a_n.jpg&quot; width=&quot;240&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Pretty nice views to wake up to this morning! #carpediem #working #vanlife&quot;&gt;&lt;/a&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4316/36086428211_c7a2fcf727_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/36086428211/in/album-72157686877599325/&quot; title=&quot;We name it Flaming Gorge&amp;quot; &#8212; John Wesley Powell&quot; rel=&quot;lightbox[2017yearinreview]&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4316/36086428211_c7a2fcf727_n.jpg&quot; width=&quot;240&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot; alt=&quot;We name it Flaming Gorge &#8212; John Wesley Powell&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;My only other personal post in the first half of 2017 was &lt;a href=&quot;//raibledesigns.com/rd/entry/farewell_to_the_2016_17&quot;&gt;Farewell to the 2016-17 Ski Season&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://c1.staticflickr.com/5/4198/34026949363_7ffeccd5e3_c.jpg&quot; title=&quot;On top of the world!&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/34026949363/in/album-72157684160000955/&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/5/4198/34026949363_7ffeccd5e3.jpg&quot; width=&quot;500&quot; alt=&quot;On top of the world!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I had a blast skiing in Winter Park, Copper, Crested Butte, Sweden, Steamboat, Tahoe, and Montana.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a data-flickr-embed=&quot;true&quot; data-header=&quot;true&quot; data-footer=&quot;true&quot; href=&quot;https://www.flickr.com/photos/mraible/albums/72157684160000955&quot; title=&quot;Ski Season 2016-17&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4223/34836701955_fd02d1beb5.jpg&quot; width=&quot;500&quot; alt=&quot;Ski Season 2016-17&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/p&gt;
&lt;p&gt;The highlight of the season was skiing at Big Sky Resort in Montana. We&apos;re super pumped that &lt;a href=&quot;https://www.ikonpass.com/&quot;&gt;next year&apos;s ski pass&lt;/a&gt; includes Big Sky!&lt;/p&gt;
&lt;p&gt;In early August, we &lt;a href=&quot;http://raibledesigns.com/rd/entry/rafting_the_salmon_river_in&quot;&gt;rafted the Salmon River in Idaho&lt;/a&gt; with our rafting family and had an epic trip.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

  &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://farm5.staticflickr.com/4402/36200202894_3a5c7ecdc1_c.jpg&quot; title=&quot;Salmon River Posse&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mcginityphoto/36200202894/in/dateposted/&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4402/36200202894_3a5c7ecdc1.jpg&quot; width=&quot;500&quot; alt=&quot;Salmon River Posse&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
  Jack &lt;a href=&quot;//raibledesigns.com/rd/entry/happy_birthday_jack6&quot;&gt;turned 13&lt;/a&gt; in late August and we had a splendid weekend with my folks in town.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4365/36481847010_3e66370b62_c.jpg&quot; title=&quot;Family photo on Jack&apos;s 13th Birthday&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/36481847010/in/dateposted-public/&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4365/36481847010_3e66370b62.jpg&quot; width=&quot;500&quot; alt=&quot;Family photo on Jack&apos;s 13th Birthday&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Abbie and Tucker won their division at the SummerFest Horse Show in September!&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://farm5.staticflickr.com/4364/36239170203_efb7b6261f_c.jpg&quot; title=&quot;Abbie and Tucker&quot; rel=&quot;lightbox[2017yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/36239170203&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4364/36239170203_efb7b6261f.jpg&quot; width=&quot;500&quot; alt=&quot;Abbie and Tucker&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Abbie didn&apos;t want a birthday party this year, so &lt;a href=&quot;//raibledesigns.com/rd/entry/happy_birthday_abbie11&quot;&gt;we surprised her with one instead&lt;/a&gt;. It&apos;s hard to believe she&apos;s a freshman in high school. She&apos;s even driving us around with her learner&apos;s permit these days! Her
  birthday was a bittersweet celebration since we had to &lt;a href=&quot;//raibledesigns.com/rd/entry/goodbye_sir_jake&quot;&gt;say goodbye to Jake&lt;/a&gt; earlier that day.
&lt;/p&gt;
&lt;p&gt;We welcomed a new Australian Shepperd-Border Collie mix puppy into our home in December. Her name is Daisy.&lt;/p&gt;
&lt;div style=&quot;max-width:500px; margin: 0 auto&quot;&gt;
  &lt;blockquote class=&quot;instagram-media&quot; data-instgrm-permalink=&quot;https://www.instagram.com/p/BcN9o-zly7T/&quot; data-instgrm-version=&quot;8&quot; style=&quot; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);&quot;&gt;&lt;div style=&quot;padding:8px;&quot;&gt; &lt;div style=&quot; background:#F8F8F8; line-height:0; margin-top:40px; padding:49.76851851851852% 0; text-align:center; width:100%;&quot;&gt; &lt;div style=&quot; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;&quot;&gt;&lt;/div&gt;&lt;/div&gt;&lt;p style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;&quot;&gt;&lt;a href=&quot;https://www.instagram.com/p/BcN9o-zly7T/&quot; style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none;&quot; target=&quot;_blank&quot;&gt;A post shared by Matt Raible (@vwsforlife)&lt;/a&gt; on &lt;time style=&quot; font-family:Arial,sans-serif; font-size:14px; line-height:17px;&quot; datetime=&quot;2017-12-02T23:24:02+00:00&quot;&gt;Dec 2, 2017 at 3:24pm PST&lt;/time&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt; &lt;script async defer src=&quot;//platform.instagram.com/en_US/embeds.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;h3 id=&quot;stout-and-hefe&quot;&gt;Stout and Hefe&lt;/h3&gt;
&lt;p&gt;Stout 5.0 and Hefe 3.0 were released in early May. Stout had his hood painted and Hefe got a kick-ass stereo system installed.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4178/34451049790_5a20227d4d_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/34451049790/in/album-72157681042076004/&quot; title=&quot;Stout 5.0 and Hefe 3.0!&quot; rel=&quot;lightbox[2017yearinreview]&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4178/34451049790_5a20227d4d.jpg&quot; width=&quot;500&quot; alt=&quot;Stout 5.0 and Hefe 3.0!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;For Hefe&apos;s stereo, I tried going phone-only for a controller. This turned out to be a bad idea, mostly due to &lt;a href=&quot;http://www.audison.eu/products/bit-play-hd/&quot;&gt;bit Play HD&lt;/a&gt; and its terrible mobile app. Also, Hefe is lowered and a bit bumpy in the front, so trying to use a touch screen while driving doesn&apos;t work very well. He&apos;s in the shop now getting a &lt;a href=&quot;http://www.kenwood.com/usa/car/excelon/kdc-x702/&quot;&gt;new deck&lt;/a&gt; installed. &lt;/p&gt;
&lt;p&gt;We drove Stout over 5000 miles this summer and he&apos;s been super dependable. Now that he&apos;s reliable, we often marvel that he really is &lt;a href=&quot;https://www.outsideonline.com/1915261/greatest-car-ever-built&quot;&gt;the greatest car ever built&lt;/a&gt;. &lt;/p&gt;

&lt;h2 id=&quot;2018&quot;&gt;2018&lt;/h2&gt;

&lt;p&gt;Professionally, I&apos;ll be speaking at a lot of Java User Groups in 2018. The Developer Relations team at Okta is focusing on large US cities this year, so you won&apos;t see me overseas as much. This is nice because it means I get to spend more time with my family. I have received offers to speak in other countries where they&apos;ll pay for all my expenses. If expenses are covered, Okta will allow me to travel overseas. However, I&apos;ve been telling people I&apos;m only willing to speak if they&apos;ll pay for a family member&apos;s flight too. It seems to be a win-win so far: most conferences have declined, and I don&apos;t have to travel as much. If I find a conference that is willing pay, I&apos;ll get to travel with someone from my awesome family!&lt;/p&gt;
&lt;p&gt;
  I&apos;ll be coding loads of example apps and writing heaps of tutorials for the &lt;a href=&quot;https://developer.okta.com/blog&quot;&gt;Okta Developer blog&lt;/a&gt; and I&apos;m super excited about our &lt;a href=&quot;https://iterateconf.com&quot;&gt;Iterate Conference&lt;/a&gt; next month. I&apos;ll also continue to help organize DJUG and Devoxx4Kids Denver.
&lt;/p&gt;
&lt;p&gt;
  Romantically, Trish and I hope to &lt;a href=&quot;https://lifehacker.com/never-stop-dating-your-significant-other-with-the-2-2-2-1700410479&quot;&gt;never stop dating with the 2-2-2 rule&lt;/a&gt;. I look forward to a year with running VWs, long dog walks, and disconnecting to connect. As for goals, I&apos;ll go for the ol&apos; standby: to be happy and content with what I have. &amp;#128522;&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;https://farm5.staticflickr.com/4654/28231771799_ab652f6db3_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/28231771799/&quot; title=&quot;Hefe at Parker Days Parade&quot; rel=&quot;lightbox[2017yearinreview]&quot;&gt;&lt;img src=&quot;https://farm5.staticflickr.com/4654/28231771799_ab652f6db3.jpg&quot; width=&quot;500&quot; alt=&quot;Hefe at Parker Days Parade&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/2016_a_year_in_review</id>
        <title type="html">2016 - A Year in Review</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/2016_a_year_in_review"/>
        <published>2017-02-01T17:46:59-07:00</published>
        <updated>2018-01-31T16:10:43-07:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="raibleranch" scheme="http://roller.apache.org/ns/tags/" />
        <category term="2016" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="syncro" scheme="http://roller.apache.org/ns/tags/" />
        <category term="blogging" scheme="http://roller.apache.org/ns/tags/" />
        <category term="porschebus" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yearinreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="stormpath" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;When I wrote my &lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review&quot;&gt;2015 year in review blog post&lt;/a&gt;,
    I was certain my &apos;66 VW Bus would finally be finished. AND IT IS! Do I need to even write this year&apos;s post? Yes,
    because
    I want to tell you how awesome it is to own this incredible-looking, awesomely-fast, mean machine. &lt;img src=&quot;//raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot;&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;https://c1.staticflickr.com/1/325/31876057643_4a4cb6b330_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/31876057643/in/datetaken-public/&quot; title=&quot;Hefe 2.0&quot; rel=&quot;lightbox[yearinreview2016]&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/1/325/31876057643_4a4cb6b330.jpg&quot; width=&quot;500&quot; alt=&quot;Hefe 2.0&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;But first, let&apos;s review the year using the following categories.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#stout&quot;&gt;The Ski Bus (&lt;em&gt;aka&lt;/em&gt; Stout)&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#hefe&quot;&gt;The Porsche Bus (&lt;em&gt;aka&lt;/em&gt;
                Hefe)&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#2017&quot;&gt;2017&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;
    I had two different clients in 2016: &lt;a href=&quot;https://www.ca.com/&quot;&gt;CA Technologies&lt;/a&gt; and &lt;a
    href=&quot;https://stormpath.com&quot;&gt;Stormpath&lt;/a&gt;. I worked full-time for CA in January and February, helping them adopt
    AngularJS.
    To help them learn about Angular 2, I rewrote my AngularJS &lt;a
    href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angularjs&quot;&gt;getting started&lt;/a&gt; and &lt;a
    href=&quot;//raibledesigns.com/rd/entry/testing_angularjs_applications&quot;&gt;testing&lt;/a&gt; tutorials for Angular 2. The first
    versions were published at
    &lt;a href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angular_2&quot;&gt;Getting Started with Angular 2&lt;/a&gt; and &lt;a
    href=&quot;//raibledesigns.com/rd/entry/testing_angular_2_applications&quot;&gt;Testing Angular 2 Applications&lt;/a&gt;.
    I refactored both tutorials to use Angular CLI in August and published &lt;a
    href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angular_cli&quot;&gt;Getting Started + Testing with Angular CLI and
    Angular 2 (RC5)&lt;/a&gt;. Since then, I&apos;ve been maintaining an up-to-date version &lt;a
    href=&quot;https://github.com/mraible/ng-demo/blob/master/README.adoc&quot;&gt;on GitHub&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    In April, I started working half-time for CA and half-time for Stormpath. For Stormpath, I worked on their Java SDK
    and helped them launch their &lt;a href=&quot;https://www.infoq.com/news/2016/08/stormpath-java-1.0&quot;&gt;Java SDK 1.0&lt;/a&gt;. I
    really enjoyed working with the team at Stormpath. This led to me think about my priorities in life. I realized
    that I wanted to work remotely, get paid to speak at conferences, and get paid to work on open source. Stormpath
    provided me with all of these opportunities and I &lt;a href=&quot;https://stormpath.com/blog/hello-stormpath-matt-raible&quot;&gt;started
    working full-time&lt;/a&gt; for them on September 26, 2016.
&lt;/p&gt;
&lt;p&gt;
    In May, I joined the board of the &lt;a href=&quot;http://www.denverjug.org/&quot;&gt;Denver Java User Group&lt;/a&gt;. I&apos;ve been helping
    organize meetups, find speakers, and secure location sponsors. If you&apos;re interested in speaking at DJUG in 2017, please let me know!
&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;When I wrote my &lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review&quot;&gt;2015 year in review blog post&lt;/a&gt;,
    I was certain my &apos;66 VW Bus would finally be finished. AND IT IS! Do I need to even write this year&apos;s post? Yes,
    because
    I want to tell you how awesome it is to own this incredible-looking, awesomely-fast, mean machine. &lt;img src=&quot;//raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot;&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a data-flickr-embed=&quot;true&quot; data-header=&quot;false&quot; data-footer=&quot;false&quot;  href=&quot;https://www.flickr.com/photos/mraible/albums/72157666949317472&quot; title=&quot;Hello Hefe&quot;&gt;&lt;img src=&quot;https://farm2.staticflickr.com/1538/26402259315_8fff390a71_z.jpg&quot; width=&quot;640&quot; height=&quot;500&quot; alt=&quot;Hello Hefe&quot;&gt;&lt;/a&gt;&lt;script async src=&quot;//embedr.flickr.com/assets/client-code.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/p&gt;

&lt;p&gt;But first, let&apos;s review the year using the following categories.&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#stout&quot;&gt;The Ski Bus (&lt;em&gt;aka&lt;/em&gt; Stout)&lt;/a&gt;
            &lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#hefe&quot;&gt;The Porsche Bus (&lt;em&gt;aka&lt;/em&gt;
                Hefe)&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2016_a_year_in_review#2017&quot;&gt;2017&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;
    I had two different clients in 2016: &lt;a href=&quot;https://www.ca.com/&quot;&gt;CA Technologies&lt;/a&gt; and &lt;a
    href=&quot;https://stormpath.com&quot;&gt;Stormpath&lt;/a&gt;. I worked full-time for CA in January and February, helping them adopt
    AngularJS.
    To help them learn about Angular 2, I rewrote my AngularJS &lt;a
    href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angularjs&quot;&gt;getting started&lt;/a&gt; and &lt;a
    href=&quot;//raibledesigns.com/rd/entry/testing_angularjs_applications&quot;&gt;testing&lt;/a&gt; tutorials for Angular 2. The first
    versions were published at
    &lt;a href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angular_2&quot;&gt;Getting Started with Angular 2&lt;/a&gt; and &lt;a
    href=&quot;//raibledesigns.com/rd/entry/testing_angular_2_applications&quot;&gt;Testing Angular 2 Applications&lt;/a&gt;.
    I refactored both tutorials to use Angular CLI in August and published &lt;a
    href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angular_cli&quot;&gt;Getting Started + Testing with Angular CLI and
    Angular 2 (RC5)&lt;/a&gt;. Since then, I&apos;ve been maintaining an up-to-date version &lt;a
    href=&quot;https://github.com/mraible/ng-demo/blob/master/README.adoc&quot;&gt;on GitHub&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    In April, I started working half-time for CA and half-time for Stormpath. For Stormpath, I worked on their Java SDK
    and helped them launch their &lt;a href=&quot;https://www.infoq.com/news/2016/08/stormpath-java-1.0&quot;&gt;Java SDK 1.0&lt;/a&gt;. I
    really enjoyed working with the team at Stormpath. This led to me think about my priorities in life. I realized
    that I wanted to work remotely, get paid to speak at conferences, and get paid to work on open source. Stormpath
    provided me with all of these opportunities and I &lt;a href=&quot;https://stormpath.com/blog/hello-stormpath-matt-raible&quot;&gt;started
    working full-time&lt;/a&gt; for them on September 26, 2016.
&lt;/p&gt;
&lt;p&gt;
    In May, I joined the board of the &lt;a href=&quot;http://www.denverjug.org/&quot;&gt;Denver Java User Group&lt;/a&gt;. I&apos;ve been helping
    organize meetups, find speakers, and secure location sponsors. If you&apos;re interested in speaking at DJUG in 2017, please let me know!
&lt;/p&gt;
&lt;p&gt;
    I wrote about &lt;a href=&quot;//raibledesigns.com/rd/entry/life_as_an_open_source&quot;&gt;life as an open source developer&lt;/a&gt; in
    early November. At that time, I mentioned being more stressed than I was used to. My stress levels continued to be high through the
    end of the year because I get to create my own job. I get to choose the conferences I submit too, the talks I
    create, the example apps, the blog posts, everything. There&apos;s so much I want to do that I&apos;ve had to learn to &lt;em&gt;scale
        back&lt;/em&gt; and not try to do so much at once.
&lt;/p&gt;
&lt;p&gt;
    I didn&apos;t blog much on raibledesigns.com in Q4 of 2016, but I wrote a bunch of technical posts on the &lt;a
    href=&quot;https://stormpath.com/blog&quot;&gt;Stormpath
    blog&lt;/a&gt;.
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://stormpath.com/blog/angularjs-spring-boot-tutorial&quot;&gt;Tutorial: Get Started with AngularJS, Spring
        Boot, and Stormpath&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://stormpath.com/blog/stormpath-jhipster-application&quot;&gt;Add Stormpath to Your JHipster
        Application&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://stormpath.com/blog/angular-2-user-authentication&quot;&gt;Build an Angular 2 Application with User
        Authentication in 10 Minutes&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://stormpath.com/blog/java-sdk-architecture&quot;&gt;The Architecture of Stormpath&#8217;s Java SDK&lt;/a&gt;
    &lt;li&gt;&lt;a href=&quot;https://stormpath.com/blog/angularjs-spring-boot-tips&quot;&gt;Tips and Tricks for AngularJS and Spring
        Boot with Stormpath&lt;/a&gt;
    &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;According to TripIt, I flew &lt;a href=&quot;http://cem.re/year-in-review/55145c02b97d22c568e9f7668cf0eb65f2652779.html&quot;&gt;59K
    miles in 2016&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;speaking&quot;&gt;Speaking&lt;/h3&gt;
&lt;p&gt;I spoke at nine different events in 2016. You can find links to my presentations on &lt;a href=&quot;//raibledesigns.com/rd/page/publications&quot;&gt;my
    presentations page&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;February: Denver Open Source Users Group&lt;/li&gt;
    &lt;li&gt;April: Colorado Springs Open Source Software Meetup Group and Devoxx France&lt;/li&gt;
    &lt;li&gt;June: Devoxx UK and GeekOut&lt;/li&gt;
    &lt;li&gt;August: HTML5 Denver Users Group&lt;/li&gt;
    &lt;li&gt;September: vJUG24&lt;/li&gt;
    &lt;li&gt;November: Rocky Mountain Software Symposium&lt;/li&gt;
    &lt;li&gt;December: The Rich Web Experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;My most memorable conference in 2016 was Devoxx France because I took Abbie and we experienced &lt;a
    href=&quot;//raibledesigns.com/rd/entry/devoxx_france_2016_springtime_in&quot;&gt;springtime in Paris&lt;/a&gt; together.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm2.staticflickr.com/1650/26377054130_d1d6561024_c.jpg&quot; title=&quot;Obligatory Arc de Triomphe selfie&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/26377054130/in/album-72157667022214770/&quot;&gt;&lt;img
        src=&quot;https://farm2.staticflickr.com/1650/26377054130_d1d6561024_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Obligatory Arc de Triomphe selfie&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm2.staticflickr.com/1548/26377063160_2cc22299cf_c.jpg&quot; title=&quot;Abbie and Eiffel Tower&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/26377063160/in/album-72157667022214770/&quot;&gt;&lt;img
        src=&quot;https://farm2.staticflickr.com/1548/26377063160_2cc22299cf_m.jpg&quot; width=&quot;240&quot; alt=&quot;Abbie and Eiffel Tower&quot;
        style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm2.staticflickr.com/1490/26044647774_97f6749313_c.jpg&quot; title=&quot;Spring in Paris is beautiful!&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/26044647774/in/album-72157667022214770/&quot;&gt;&lt;img
        src=&quot;https://farm2.staticflickr.com/1490/26044647774_97f6749313.jpg&quot; width=&quot;500&quot;
        alt=&quot;Spring in Paris is beautiful!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Becoming a &lt;a href=&quot;https://community.oracle.com/community/java/java-champions&quot;&gt;Java Champion&lt;/a&gt; at Devoxx France was certainly a surprise too!
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm2.staticflickr.com/1495/26044726404_91272a2bae_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/26044726404/in/album-72157667022214770/&quot;
       title=&quot;Les Cast Codeurs&quot; rel=&quot;lightbox[yearinreview2016]&quot;&gt;
        &lt;img src=&quot;https://farm2.staticflickr.com/1495/26044726404_91272a2bae_m.jpg&quot; width=&quot;240&quot; alt=&quot;Les Cast Codeurs&quot;
             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm2.staticflickr.com/1465/26044729304_080e658df0_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/26044729304/in/album-72157667022214770/&quot;
       title=&quot;I&apos;m a Java Champion! :)&quot; rel=&quot;lightbox[yearinreview2016]&quot;&gt;
        &lt;img src=&quot;https://farm2.staticflickr.com/1465/26044729304_080e658df0_m.jpg&quot; width=&quot;240&quot;
             alt=&quot;I&apos;m a Java Champion! :)&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
    I really enjoyed taking my mom with me to &lt;a href=&quot;//raibledesigns.com/rd/entry/a_delightful_trip_to_devoxx&quot;&gt;Devoxx
    UK and GeekOut&lt;/a&gt;. It was my first time speaking at both conferences and I was impressed by both personnel
    and venues.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c2.staticflickr.com/8/7725/27617750865_1e2f064928_c.jpg&quot; title=&quot;St. Paul&apos;s Cathedral&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/27617750865/in/album-72157666992992284/&quot;&gt;&lt;img
        src=&quot;https://c2.staticflickr.com/8/7725/27617750865_1e2f064928_m.jpg&quot; width=&quot;240&quot; alt=&quot;St. Paul&apos;s Cathedral&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://c5.staticflickr.com/8/7387/27340321980_2438e8585b_c.jpg&quot; title=&quot;Tallin, Estonia&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/27340321980/in/album-72157666992992284/&quot;&gt;&lt;img
        src=&quot;https://c5.staticflickr.com/8/7387/27340321980_2438e8585b_m.jpg&quot; width=&quot;240&quot; alt=&quot;Tallin, Estonia&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3 id=&quot;devoxx4kids&quot;&gt;Devoxx4Kids&lt;/h3&gt;
&lt;p&gt;We only had two &lt;a href=&quot;http://www.meetup.com/Devoxx4Kids-Denver&quot;&gt;Devoxx4Kids Denver&lt;/a&gt; workshops in 2016: &lt;a
    href=&quot;https://www.meetup.com/Devoxx4Kids-Denver/events/228591168/&quot;&gt;Introduction to Object-Oriented JavaScript using
    Bitsbox&lt;/a&gt; and &lt;a href=&quot;https://www.meetup.com/Devoxx4Kids-Denver/events/232720431/&quot;&gt;Exploring JavaScript&lt;/a&gt;. The
    second one was taught by the world-famous &lt;a href=&quot;https://twitter.com/venkat_s&quot;&gt;Venkat Subramaniam&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;max-width: 500px; margin: 0 auto&quot;&gt;
    &lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;The great &lt;a
        href=&quot;https://twitter.com/venkat_s&quot;&gt;@venkat_s&lt;/a&gt; teaching &lt;a
        href=&quot;https://twitter.com/hashtag/Denver?src=hash&quot;&gt;#Denver&lt;/a&gt; kids about JavaScript. So awesome! &lt;a
        href=&quot;https://twitter.com/hashtag/Devoxx4Kids?src=hash&quot;&gt;#Devoxx4Kids&lt;/a&gt; &lt;a href=&quot;https://t.co/CqOW5ma6Cq&quot;&gt;pic.twitter.com/CqOW5ma6Cq&lt;/a&gt;
    &lt;/p&gt;&amp;mdash; Matt Raible (@mraible) &lt;a href=&quot;https://twitter.com/mraible/status/774645470681403392&quot;&gt;September 10,
        2016&lt;/a&gt;&lt;/blockquote&gt;
    &lt;script async src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;
    I&apos;d like to plan a few Devoxx4Kids Denver events in 2017, so &lt;a href=&quot;//raibledesigns.com/rd/page/contact&quot;&gt;please let me know&lt;/a&gt;
    if you have a topic you&apos;d like to present.
&lt;/p&gt;
&lt;h3 id=&quot;projects&quot;&gt;Projects&lt;/h3&gt;
&lt;p&gt;
    I stopped working on AppFuse in February and announced I was &lt;a
    href=&quot;//raibledesigns.com/rd/entry/moving_appfuse_into_the_attic&quot;&gt;mothballing the project&lt;/a&gt; in April. &lt;b&gt;Reminder:&lt;/b&gt;
    the &lt;a href=&quot;http://demo.appfuse.org&quot;&gt;demos&lt;/a&gt;, &lt;a href=&quot;http://appfuse.org&quot;&gt;documentation&lt;/a&gt; and &lt;a
    href=&quot;http://issues.appfuse.org&quot;&gt;bug tracker&lt;/a&gt; will cease to exist on April 30, 2017.&lt;/p&gt;
&lt;p&gt;
    &lt;a href=&quot;https://www.infoq.com/minibooks/jhipster-4-mini-book&quot;&gt;
        &lt;img src=&quot;https://res.infoq.com/minibooks/jhipster-4-mini-book/en/cover/JHipster-Mini-book-COVER-thumb.jpg&quot;
             alt=&quot;The JHipster Mini-Book&quot; width=&quot;100&quot; class=&quot;picture&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    I spent many late nights in July through October updating the &lt;a
    href=&quot;https://www.infoq.com/minibooks/jhipster-2-mini-book&quot;&gt;JHipster Mini-Book&lt;/a&gt; for JHipster 3.x. On the book&apos;s
    blog, I wrote about &lt;a
    href=&quot;http://www.jhipster-book.com/#!/news/entry/book-updated-for-jhipster-3-and-jhipster-gets-dirty&quot;&gt;what&apos;s
    changed&lt;/a&gt; and &lt;a
    href=&quot;http://www.jhipster-book.com/#!/news/entry/jhipster-mini-book-v2-now-available-for-download&quot;&gt;how to buy a
    print version&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;personal&quot;&gt;Personal&lt;/h2&gt;

&lt;p&gt;I wrote down my goals at the beginning of 2016:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Finish the bus&lt;/li&gt;
    &lt;li&gt;Win a trophy&lt;/li&gt;
    &lt;li&gt;Ski a lot&lt;/li&gt;
    &lt;li&gt;Raft a lot&lt;/li&gt;
    &lt;li&gt;Stay in shape&lt;/li&gt;
    &lt;li&gt;July in Montana&lt;/li&gt;
    &lt;li&gt;Happy Trish&lt;/li&gt;
    &lt;li&gt;Ionic/Angular2 app&lt;/li&gt;
    &lt;li&gt;Learn how to make a good dirty martini&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I&apos;m proud to &lt;a href=&quot;//raibledesigns.com/rd/entry/the_bus_is_home&quot;&gt;the bus is finished&lt;/a&gt; and it won Best in Class
    at VWs on the Green.&lt;/p&gt;
&lt;div style=&quot;width: 350px; margin: 0 auto&quot;&gt;
&lt;blockquote class=&quot;instagram-media&quot; data-instgrm-captioned data-instgrm-version=&quot;7&quot; style=&quot; background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);&quot;&gt;&lt;div style=&quot;padding:8px;&quot;&gt; &lt;div style=&quot; background:#F8F8F8; line-height:0; margin-top:40px; padding:47.22222222222222% 0; text-align:center; width:100%;&quot;&gt; &lt;div style=&quot; background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;&quot;&gt;&lt;/div&gt;&lt;/div&gt; &lt;p style=&quot; margin:8px 0 0 0; padding:0 4px;&quot;&gt; &lt;a href=&quot;https://www.instagram.com/p/BFcYBZyFPFk/&quot; style=&quot; color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;&quot; target=&quot;_blank&quot;&gt;Today was a great day! Won best in class Bus, Camper, Pickup Custom 1949-67 Split Window. #vwbus&lt;/a&gt;&lt;/p&gt; &lt;p style=&quot; color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;&quot;&gt;A photo posted by Matt Raible (@vwsforlife) on &lt;time style=&quot; font-family:Arial,sans-serif; font-size:14px; line-height:17px;&quot; datetime=&quot;2016-05-15T21:41:51+00:00&quot;&gt;May 15, 2016 at 2:41pm PDT&lt;/time&gt;&lt;/p&gt;&lt;/div&gt;&lt;/blockquote&gt;
&lt;script async defer src=&quot;//platform.instagram.com/en_US/embeds.js&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;We skied a lot, but never took our own raft on river. I stayed in shape and have records to prove it thanks to &lt;a
    href=&quot;http://www.21-points.com&quot;&gt;21-Points Health&lt;/a&gt; and &lt;a
    href=&quot;http://www.dailymile.com/people/mraible/training/2016/summary&quot;&gt;dailymile&lt;/a&gt;. This summer, I spent seven
    weekends in a row away from home; with three weeks in Montana. Not quite a month, but close. Trish was happy because
    we journeyed to Hawaii to celebrate her parents&apos; 50th anniversary.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c7.staticflickr.com/9/8060/29900654526_7c112a74e7_c.jpg&quot; title=&quot;Happy 50th Mau and Joe!&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900654526/in/album-72157673202240580/&quot;&gt;&lt;img
        src=&quot;https://c7.staticflickr.com/9/8060/29900654526_7c112a74e7.jpg&quot; width=&quot;500&quot; alt=&quot;Happy 50th Mau and Joe!&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;Her happiness continued when she found her dream home in July. We moved into
    &lt;a href=&quot;//raibledesigns.com/rd/entry/life_update_a_summer_to&quot;&gt;The Raible Ranch&lt;/a&gt; in September.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c1.staticflickr.com/9/8085/29900652696_22d3a60f0b_c.jpg&quot; title=&quot;Home Sweet Home!&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900652696/in/album-72157673202240580/&quot;&gt;&lt;img
        src=&quot;https://c1.staticflickr.com/9/8085/29900652696_22d3a60f0b.jpg&quot; width=&quot;500&quot; alt=&quot;Home Sweet Home!&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
    Weeks later, she and Abbie bought their dream horse named Tucker. I wrote about him in &lt;a
    href=&quot;//raibledesigns.com/rd/entry/happy_birthday_abbie10&quot;&gt;Abbie&apos;s 14th birthday post&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c7.staticflickr.com/6/5717/30766171446_2e96dd2477_c.jpg&quot; title=&quot;Abbie and Tucker&quot;
       rel=&quot;lightbox[yearinreview2016]&quot; data-href=&quot;https://www.flickr.com/photos/mcginityphoto/30766171446/in/feed&quot;&gt;&lt;img
        src=&quot;https://c7.staticflickr.com/6/5717/30766171446_2e96dd2477_m.jpg&quot; width=&quot;240&quot; alt=&quot;Abbie and Tucker&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://c3.staticflickr.com/6/5348/30501849050_0001c1ee48_c.jpg&quot; title=&quot;Abbie and Tucker&quot;
       rel=&quot;lightbox[yearinreview2016]&quot; data-href=&quot;https://www.flickr.com/photos/mcginityphoto/30501849050/in/feed&quot;&gt;&lt;img
        src=&quot;https://c3.staticflickr.com/6/5348/30501849050_0001c1ee48_m.jpg&quot; width=&quot;240&quot; alt=&quot;Abbie and Tucker&quot;
        style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I learned how to make an excellent dirty martini, but did not find the time to create an Ionic/Angular2 app.
&lt;h3 id=&quot;stout&quot;&gt;The Ski Bus (&lt;em&gt;aka&lt;/em&gt; Stout)&lt;/h3&gt;
&lt;p&gt;Stout the Syncro spent a couple months &lt;a href=&quot;https://www.flickr.com/photos/mraible/sets/72157674783246243&quot;&gt;getting
    upgrades&lt;/a&gt; in late 2015: transmission rebuilt, fridge installed, Propex heater installed, and new headlights.
    We leveraged these improvements on an &lt;a href=&quot;//raibledesigns.com/rd/entry/raible_road_trip_70_to&quot;&gt;epic family
        road trip to Jekyll Island (Georgia)&lt;/a&gt; for my Dad&apos;s 70th birthday.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm2.staticflickr.com/1477/24510650770_94df1d646b_c.jpg&quot; title=&quot;Cards in the van&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/24510650770/in/album-72157661957952463/&quot;&gt;&lt;img
        src=&quot;https://farm2.staticflickr.com/1477/24510650770_94df1d646b_m.jpg&quot; width=&quot;240&quot; alt=&quot;Cards in the van&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;https://farm2.staticflickr.com/1720/24688342302_0a0cd91280_c.jpg&quot;
       title=&quot;Our campsite in Hot Springs, AR. 21F that night.&quot; rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/24688342302/in/album-72157661957952463/&quot;&gt;&lt;img
        src=&quot;https://farm2.staticflickr.com/1720/24688342302_0a0cd91280_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Our campsite in Hot Springs, AR. 21F that night.&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We made it back to Denver just in time for the AFC Championship game and thoroughly enjoyed ourselves tailgating
    beforehand.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm2.staticflickr.com/1657/24438602429_06d112155c_c.jpg&quot;
       title=&quot;We made it to Denver at 11pm Saturday. Broncos tailgate on Sunday!&quot; rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/24438602429/in/album-72157661957952463/&quot;&gt;&lt;img
        src=&quot;https://farm2.staticflickr.com/1657/24438602429_06d112155c.jpg&quot; width=&quot;500&quot;
        alt=&quot;We made it to Denver at 11pm Saturday. Broncos tailgate on Sunday!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Watching the Broncos win Super Bowl 50 was definitely a highlight of 2016.&lt;/p&gt;
&lt;p&gt;We took Stout on a bunch of ski trips and winter camped several times. The Propex heater and Reflectix insulation
    worked great and kept it around 50&amp;deg;F even when it was 0&amp;deg;F out.&lt;/p&gt;
&lt;p&gt;I bought a new mountain bike (Yeti SB 95) in May and Trish and I drove the van to &lt;a
    href=&quot;http://syncrosolstice.com&quot;&gt;Syncro Solstice&lt;/a&gt; in Moab. We were hoping for a weekend of mountain biking and 4-wheeling, but Trish had a bad crash and
    stabbed herself in the chest with a handlebar. That ended our 4x4 aspirations for the weekend, but the van ran
    great!&lt;/p&gt;
&lt;p&gt;The other major road trip for Stout was when I drove from Colorado to Montana over four days. I drove to Grand
    Junction on Monday evenning, worked during the day on Tuesday, went mountain biking in the afternoon, then drove to
    Jackson Hole that night. Wednesday, I worked in Jackson Hole, went mountain biking, then drove to Montana that
    night. I woke up early on Thursday and made it to Missoula to start working promptly at 8am. That evening, I drove
    to Seeley Lake and setup camp at the first annual &lt;a href=&quot;http://www.thebobmusic.com/&quot;&gt;Bob Marshall Music
        Festival&lt;/a&gt;. Trish flew in on Friday and we danced and celebrated my birthday all weekend.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c1.staticflickr.com/8/7490/29900643306_92e64b8945_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900643306/in/datetaken/&quot;
       title=&quot;I like how this birthday week is progressing!&quot; rel=&quot;lightbox[yearinreview2016]&quot;&gt;&lt;img
        src=&quot;https://c1.staticflickr.com/8/7490/29900643306_92e64b8945_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;I like how this birthday week is progressing!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a rel=&quot;lightbox[yearinreview2016]&quot; href=&quot;https://c1.staticflickr.com/9/8468/29900643616_f47aa962c2_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900643616/in/datetaken/&quot;
       title=&quot;It&amp;#x27;s easy to fall in love with Jackson, Wyoming on a day like today!&quot;&gt;&lt;img
        src=&quot;https://c1.staticflickr.com/9/8468/29900643616_f47aa962c2_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;It&amp;#x27;s easy to fall in love with Jackson, Wyoming on a day like today!&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
    &lt;a rel=&quot;lightbox[yearinreview2016]&quot; href=&quot;https://c1.staticflickr.com/8/7526/29900643736_cf5b6ef57c_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900643736/in/datetaken/&quot; title=&quot;Idaho Sunset in Teton Valley&quot;&gt;&lt;img
        src=&quot;https://c1.staticflickr.com/8/7526/29900643736_cf5b6ef57c_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;Idaho Sunset in Teton Valley&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a rel=&quot;lightbox[yearinreview2016]&quot; href=&quot;https://c1.staticflickr.com/9/8819/29900643836_3b78c8a092_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900643836/in/datetaken/&quot; title=&quot;Montana!&quot;&gt;&lt;img
        src=&quot;https://c1.staticflickr.com/9/8819/29900643836_3b78c8a092.jpg&quot; width=&quot;500&quot; alt=&quot;Montana!&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3 id=&quot;hefe&quot;&gt;The Porsche Bus (&lt;em&gt;aka&lt;/em&gt; Hefe)&lt;/h3&gt;
&lt;p&gt;Hefe&apos;s debut at VWs on the Green was a wild success and we had a lot of fun that day. In June, we showed him at
    Colorado Concours d&apos;Elegance and won a blue ribbon. We trailered him to Montana and drove him in the Swan Valley
    parade &lt;em&gt;and&lt;/em&gt; the Seeley Lake parade.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c4.staticflickr.com/9/8265/29869377531_391704082d_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29869377531/in/album-72157673202240580/&quot;
       title=&quot;Hefe in the Swan Valley Parade&quot; rel=&quot;lightbox[yearinreview2016]&quot;&gt;&lt;img
        src=&quot;https://c4.staticflickr.com/9/8265/29869377531_391704082d_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Hefe in the Swan Valley Parade&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://c7.staticflickr.com/9/8770/29900642926_1ec60a28d1_c.jpg&quot;
       title=&quot;Our 2nd parade of the day! Hefe is lookin&apos; good. Happy 4th y&apos;all!&quot; rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900642926/in/album-72157673202240580/&quot;&gt;&lt;img
        src=&quot;https://c7.staticflickr.com/9/8770/29900642926_1ec60a28d1_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Our 2nd parade of the day! Hefe is lookin&apos; good. Happy 4th y&apos;all!&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We hauled him back in Denver to be in the Colorado Bug-In at Bandimere Speedway, where he got second in the
    custom/radical class.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a rel=&quot;lightbox[yearinreview2016]&quot; href=&quot;https://c7.staticflickr.com/9/8509/29900643086_753e1e8e1c_c.jpg&quot;
       title=&quot;Hefe at his finest&quot; rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900643086/in/album-72157673202240580/&quot;&gt;&lt;img
        src=&quot;https://c7.staticflickr.com/9/8509/29900643086_753e1e8e1c_m.jpg&quot; width=&quot;240&quot; alt=&quot;Hefe at his finest&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

    &lt;a rel=&quot;lightbox[yearinreview2016]&quot; href=&quot;https://c5.staticflickr.com/8/7472/29900643196_0a3d735d17_c.jpg&quot;
       title=&quot;Got Runner Up in our class. Lost to a very nice Karmann Ghia. However, they trailered theirs home and I&apos;m driving mine!&quot;
       rel=&quot;lightbox[yearinreview2016]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/29900643196/in/album-72157673202240580/&quot;&gt;&lt;img
        src=&quot;https://c5.staticflickr.com/8/7472/29900643196_0a3d735d17_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Got Runner Up in our class. Lost to a very nice Karmann Ghia. However, they trailered theirs home and I&apos;m driving mine!&quot;
        style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;On the way home from that event, one of the rear shocks blew up from rubbing against the axle. That was the beginning
    of the end for my air suspension. I drove Hefe to &lt;a href=&quot;http://kustomcoachwerks.com&quot;&gt;Kustom Coach Werks&lt;/a&gt; in
    early August to have fix the doors (they had gaps) and tune the suspension. When they finished, I called it &quot;release
    1.5&quot;.
&lt;/p&gt;
&lt;p&gt;
    I drove Hefe for a month without rear shocks and didn&apos;t have too many issues; it was just bouncy in the back. &lt;a
    href=&quot;https://www.facebook.com/pg/Colorado-Buses-at-the-Brewery-184288431618852&quot;&gt;Buses at the Brewery&lt;/a&gt; in
    Colorado Springs was a fun event and the first time that Hefe went viral on Facebook. This has happened a few times
    since then. He gets thousands of likes from being featured on a VW fan page.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a rel=&quot;lightbox[yearinreview2016]&quot; href=&quot;https://c1.staticflickr.com/9/8555/28695920833_7e4e36bd73_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/28695920833/in/datetaken-public/&quot;
       title=&quot;Buses at the Brewery&quot;&gt;&lt;img src=&quot;https://c1.staticflickr.com/9/8555/28695920833_7e4e36bd73.jpg&quot; width=&quot;500&quot;
                                         style=&quot;border: 1px solid black&quot; alt=&quot;Buses at the Brewery&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Before the drive to Colorado Springs, I noticed the rear suspension was missing bolts, causing the rear end to
    shimmy. I was able to find a new bolt and fix it, but the problem with bolts falling out continued in September. I
    tried &lt;a href=&quot;https://www.flickr.com/photos/mraible/29383276332/in/datetaken/&quot;&gt;smaller wheels (15&quot; Fuchs)&lt;/a&gt;, but
    the suspension was still really stiff in front. Because of the suspension issues, I shipped it back to KCW in
    October. They ripped out the air suspension and replaced it with coil over shocks, making for a much better ride. It
    now can cruise at 90 mph easily and looks great all the time! After these repairs, it&apos;s now Hefe 2.0.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c1.staticflickr.com/1/710/31888383051_1e996f40ac_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/31888383051/in/datetaken/&quot;
       title=&quot;2nd stop: liquor store for the KCW guys!&quot; rel=&quot;lightbox[yearinreview2016]&quot;&gt;&lt;img
        src=&quot;https://c1.staticflickr.com/1/710/31888383051_1e996f40ac.jpg&quot; width=&quot;500&quot; style=&quot;border: 1px solid black&quot;
        alt=&quot;2nd stop: liquor store for the KCW guys!&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;If you&apos;re interested in reading about the suspension decision process, or to see pictures, see &lt;a
    href=&quot;http://www.kustomcoachwerks.com/forums//viewtopic.php?f=17&amp;t=8072&amp;start=930#p253244&quot;&gt;this thread on KCW&apos;s
    forums&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;2017&quot;&gt;2017&lt;/h2&gt;
&lt;p&gt;
    Professionally, I&apos;ll be speaking at a lot of conferences and meetups this year. As a Developer Evangelist for
    Stormpath, I&apos;m expected to speak at least once a month. I did a webinar on &lt;a
    href=&quot;https://www.youtube.com/watch?v=Jq3szz2KOOs&quot;&gt;Getting Started with Angular&lt;/a&gt; in mid-January and I&apos;m traveling
    next week to &lt;a href=&quot;http://jfokus.com&quot;&gt;Jfokus&lt;/a&gt; in Stockholm. See my &lt;a
    href=&quot;//raibledesigns.com/rd/page/publications&quot;&gt;future engagements&lt;/a&gt; for more scheduled events.
&lt;/p&gt;
&lt;p&gt;
    I suspect most of the coding I&apos;ll be doing will be related to Stormpath&apos;s SDKs, both &lt;a
    href=&quot;https://github.com/stormpath/stormpath-sdk-angular&quot;&gt;Angular&lt;/a&gt; and &lt;a
    href=&quot;https://github.com/stormpath/stormpath-sdk-java&quot;&gt;Java&lt;/a&gt;. Of course, I&apos;ll help out on &lt;a
    href=&quot;http://jhipster.github.io&quot;&gt;JHipster&lt;/a&gt; as much as I can too. With &lt;a href=&quot;https://twitter.com/java_hipster/status/826819045068505089&quot;&gt;JHipster
    4 on the horizon&lt;/a&gt;, there will be a lot of work to update the JHipster Mini-Book.
&lt;/p&gt;
&lt;p&gt;Hefe 3.0 will be released this spring after I get a sweet sound system installed. As far as personal goals for 2017,
    I have only one: to drive Hefe up the California coast. With a new house, two running VWs, and a job that&apos;s a
    helluva
    lot of fun, life is pretty awesome right now. &lt;img src=&quot;//raibledesigns.com/images/smileys/grin.gif&quot; class=&quot;smiley&quot; alt=&quot;:-D&quot; title=&quot;:-D&quot;&gt;
&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/a_delightful_trip_to_devoxx</id>
        <title type="html">A Delightful Trip to Devoxx UK and GeekOut 2016</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/a_delightful_trip_to_devoxx"/>
        <published>2016-06-12T11:13:17-06:00</published>
        <updated>2016-06-20T22:26:30-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="travel" scheme="http://roller.apache.org/ns/tags/" />
        <category term="london" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxxuk" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tallinn" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jhipster" scheme="http://roller.apache.org/ns/tags/" />
        <category term="mom" scheme="http://roller.apache.org/ns/tags/" />
        <category term="angular2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="geekoutee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="speaking" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
    &lt;a data-href=&quot;https://www.flickr.com/photos/mraible/27617751605/in/album-72157666992992284/&quot; class=&quot;picture&quot; href=&quot;https://c2.staticflickr.com/8/7396/27617746825_9ff773434e_c.jpg&quot; title=&quot;We found a pub!&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot;&gt;&lt;img src=&quot;https://c2.staticflickr.com/8/7396/27617746825_9ff773434e_t.jpg&quot; width=&quot;100&quot; alt=&quot;We found a pub!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    I had the pleasure of traveling to London, England and Tallin, Estonia this past week. In London, I spoke at
    &lt;a href=&quot;http://www.devoxx.co.uk/&quot;&gt;Devoxx UK&lt;/a&gt;. In Tallin, I spoke at &lt;a href=&quot;http://2016.geekout.ee/&quot;&gt;GeekOut&lt;/a&gt;.
    I took my mom (or mum, if you
    prefer)
    and we explored the sights, enjoyed local cuisines and savored a few beverages. Our trip started with a direct
    flight from Denver to London. We arrived on Tuesday, June 7, around noon.
&lt;/p&gt;
&lt;p&gt;We were only in London for two nights, but it was enough time for us to savor excellent Indian food, fancy a walk
    through
    London, and order a bow tie. I forgot the bow tie for my &lt;a href=&quot;http://jhipster.github.io&quot;&gt;JHipster&lt;/a&gt; outfit. Luckily, I found &lt;a href=&quot;http://www.dobell.co.uk/heritage-blue-knitted-bow-tie/&quot;&gt;
        a good replacement&lt;/a&gt; and was able to order it for next-day delivery. I had to order it by 5pm and the site
    declined both my credit cards with time running out. I ended up using PayPal and got my order placed in the nick of
    time: 16:59:51.
&lt;/p&gt;

&lt;p&gt;The big news announced at Devoxx UK is that Devoxx is &lt;a href=&quot;https://devoxx.us&quot;&gt;coming to the United States in
    2017&lt;/a&gt;! I&apos;m on the program committee for this conference, so I look forward to helping make it spectacular.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c6.staticflickr.com/8/7402/27617748525_d75d56ec06_c.jpg&quot; title=&quot;Devoxx coming to US in 2017!&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27617748525/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c6.staticflickr.com/8/7402/27617748525_d75d56ec06.jpg&quot; width=&quot;500&quot; alt=&quot;Devoxx coming to US in 2017!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 500px;&quot;&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;The first ever &lt;a href=&quot;https://twitter.com/hashtag/DevoxxUS?src=hash&quot;&gt;#DevoxxUS&lt;/a&gt; is happening March 21-23, 2017 in San Jose, CA!
    &lt;a href=&quot;https://t.co/jtQe95LNOL&quot;&gt;https://t.co/jtQe95LNOL&lt;/a&gt;&lt;/p&gt;&#8212; Devoxx US (@devoxxus) &lt;a href=&quot;https://twitter.com/devoxxus/status/740466417703616512&quot;&gt;June 8, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;</summary>
        <content type="html">&lt;p&gt;
    &lt;a data-href=&quot;https://www.flickr.com/photos/mraible/27617751605/in/album-72157666992992284/&quot; class=&quot;picture&quot; href=&quot;https://c2.staticflickr.com/8/7396/27617746825_9ff773434e_c.jpg&quot; title=&quot;We found a pub!&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot;&gt;&lt;img src=&quot;https://c2.staticflickr.com/8/7396/27617746825_9ff773434e_t.jpg&quot; width=&quot;100&quot; alt=&quot;We found a pub!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    I had the pleasure of traveling to London, England and Tallin, Estonia this past week. In London, I spoke at
    &lt;a href=&quot;http://www.devoxx.co.uk/&quot;&gt;Devoxx UK&lt;/a&gt;. In Tallin, I spoke at &lt;a href=&quot;http://2016.geekout.ee/&quot;&gt;GeekOut&lt;/a&gt;.
    I took my mom (or mum, if you
    prefer)
    and we explored the sights, enjoyed local cuisines and savored a few beverages. Our trip started with a direct
    flight from Denver to London. We arrived on Tuesday, June 7, around noon.
&lt;/p&gt;
&lt;p&gt;We were only in London for two nights, but it was enough time for us to savor excellent Indian food, fancy a walk
    through
    London, and order a bow tie. I forgot the bow tie for my &lt;a href=&quot;http://jhipster.github.io&quot;&gt;JHipster&lt;/a&gt; outfit. Luckily, I found &lt;a href=&quot;http://www.dobell.co.uk/heritage-blue-knitted-bow-tie/&quot;&gt;
        a good replacement&lt;/a&gt; and was able to order it for next-day delivery. I had to order it by 5pm and the site
    declined both my credit cards with time running out. I ended up using PayPal and got my order placed in the nick of
    time:
    16:59:51.
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
        &lt;a href=&quot;https://c2.staticflickr.com/8/7725/27617750865_1e2f064928_c.jpg&quot; title=&quot;St. Paul&apos;s Cathedral&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27617750865/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c2.staticflickr.com/8/7725/27617750865_1e2f064928.jpg&quot; width=&quot;500&quot; alt=&quot;St. Paul&apos;s Cathedral&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c6.staticflickr.com/8/7455/27617751605_8f634559e4_c.jpg&quot; title=&quot;River Thames&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27617751605/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c6.staticflickr.com/8/7455/27617751605_8f634559e4_m.jpg&quot; width=&quot;240&quot; alt=&quot;River Thames&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;


    &lt;a href=&quot;https://c2.staticflickr.com/8/7311/27008343553_edcb7f6ea9_c.jpg&quot; title=&quot;Sphynx&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27008343553/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c2.staticflickr.com/8/7311/27008343553_edcb7f6ea9_m.jpg&quot; width=&quot;240&quot; alt=&quot;Sphynx&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;The big news announced at Devoxx UK is that Devoxx is &lt;a href=&quot;https://devoxx.us&quot;&gt;coming to the United States in
    2017&lt;/a&gt;! I&apos;m on the program committee for this conference, so I look forward to helping make it spectacular.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c6.staticflickr.com/8/7402/27617748525_d75d56ec06_c.jpg&quot; title=&quot;Devoxx coming to US in 2017!&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27617748525/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c6.staticflickr.com/8/7402/27617748525_d75d56ec06.jpg&quot; width=&quot;500&quot; alt=&quot;Devoxx coming to US in 2017!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; max-width: 500px;&quot;&gt;
&lt;blockquote class=&quot;twitter-tweet&quot; data-lang=&quot;en&quot;&gt;&lt;p lang=&quot;en&quot; dir=&quot;ltr&quot;&gt;The first ever &lt;a href=&quot;https://twitter.com/hashtag/DevoxxUS?src=hash&quot;&gt;#DevoxxUS&lt;/a&gt; is happening March 21-23, 2017 in San Jose, CA!
    &lt;a href=&quot;https://t.co/jtQe95LNOL&quot;&gt;https://t.co/jtQe95LNOL&lt;/a&gt;&lt;/p&gt;&#8212; Devoxx US (@devoxxus) &lt;a href=&quot;https://twitter.com/devoxxus/status/740466417703616512&quot;&gt;June 8, 2016&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async=&quot;&quot; src=&quot;//platform.twitter.com/widgets.js&quot; charset=&quot;utf-8&quot;&gt;&lt;/script&gt;
&lt;/div&gt;
&lt;p&gt;I thought both my talks went well, but I did have some issues during my Angular 2 talk. I used
    &lt;a href=&quot;https://github.com/angular/angular-cli&quot;&gt;Angular CLI&lt;/a&gt; to do the demo and IDEA kept indexing,
    which caused my live templates to fail. I later learned from an attendee (thanks!) that excluding the
    &lt;code&gt;dist&lt;/code&gt; and &lt;code&gt;tmp&lt;/code&gt;
    directories helps prevents this. You can find the &lt;a href=&quot;https://github.com/mraible/ng2-demo&quot;&gt;source code for my
        demo on GitHub&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;You can &lt;a href=&quot;www.slideshare.net/mraible/the-art-of-angular-in-2016-devoxx-uk-2016&quot;&gt;view my &quot;Art of Angular in 2016&quot; presentation on SlideShare&lt;/a&gt;, &lt;a href=&quot;https://www.youtube.com/watch?v=T4zsanOnKtk&quot;&gt;watch it on YouTube&lt;/a&gt;, or just click through it below.
&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
    &lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/4Axcf5U5cJiJev&quot; width=&quot;595&quot; height=&quot;373&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; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;
    I also did a &lt;a href=&quot;http://www.slideshare.net/mraible/get-hip-with-jhipster-spring-boot-angularjs-bootstrap-devoxx-uk-2016&quot;&gt;presentation
    on JHipster&lt;/a&gt;, leveraging &lt;a href=&quot;https://jhipster.github.io/jdl-studio/&quot;&gt;JDL Studio&lt;/a&gt; heavily. You can
    &lt;a href=&quot;https://gist.github.com/mraible/8640fa406f32cb0f18e1aa7d73ab8022&quot;&gt;click here to see the JDL&lt;/a&gt; I used
    for my blog demo. A &lt;a href=&quot;https://www.youtube.com/watch?v=UKMn5UNaUM4&quot;&gt;video of this session is on YouTube&lt;/a&gt;.
&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
    &lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/ztvafuoJSA4y9t&quot; width=&quot;595&quot; height=&quot;373&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; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;We closed out our visit to London with a fun speaker&apos;s dinner and an early morning flight to Helsinki, then Tallinn.
&lt;/p&gt;
&lt;p&gt;
    In Tallinn, we wandered through its Old Town, had some great meals and marveled at how late the sun set. We stopped
    in at the GeekOut conference&apos;s party on Thursday night. The &lt;a href=&quot;https://zeroturnaround.com/&quot;&gt;ZeroTurnaround&lt;/a&gt;
    guys did a heckuva job planning this conference.
    I loved how both the party and the conference were in large, industrial-but-modern buildings with great sound
    systems.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c5.staticflickr.com/8/7387/27340321980_2438e8585b_c.jpg&quot; title=&quot;Tallin, Estonia&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27340321980/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c5.staticflickr.com/8/7387/27340321980_2438e8585b.jpg&quot; width=&quot;500&quot; alt=&quot;Tallin, Estonia&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c7.staticflickr.com/8/7285/27340323510_94f77f5374_c.jpg&quot; title=&quot;GeekOut Party&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27340323510/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c7.staticflickr.com/8/7285/27340323510_94f77f5374_m.jpg&quot; width=&quot;240&quot; alt=&quot;GeekOut Party&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://c3.staticflickr.com/8/7366/27518144042_3335da602d_c.jpg&quot; title=&quot;Tallin Sunset&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/27518144042/in/album-72157666992992284/&quot;&gt;&lt;img src=&quot;https://c3.staticflickr.com/8/7366/27518144042_3335da602d_m.jpg&quot; width=&quot;240&quot; alt=&quot;Tallin Sunset&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    My JHipster talk went well on Friday (&lt;a href=&quot;http://www.slideshare.net/mraible/get-hip-with-jhipster-geekout-2016&quot;&gt;slides here&lt;/a&gt;)
    and my mom and I celebrated at &lt;a href=&quot;http://rataskaevu16.ee/&quot;&gt;Rataskaevu 16&lt;/a&gt; that
    evening. Then we shared laughs and
    learned how to play &lt;a href=&quot;http://jackbox.tv/&quot;&gt;jackbox.tv&lt;/a&gt; at ZeroTurnaround&apos;s post-conference party.
&lt;/p&gt;
&lt;p&gt;
    Our last night was spent in Helsinki, a 20-minute flight from Tallinn. Since my grandparents are Finnish, my mom
    delighted in hearing words from her youth along the streets. We both took advantage and relaxed in our hotel&apos;s roof
    top saunas too. We indulged in a food/wine-paired dinner over three hours that evening.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a data-href=&quot;https://www.flickr.com/photos/mraible/27518153982/in/album-72157666992992284/&quot; href=&quot;//c7.staticflickr.com/8/7342/27518153982_3ae4a9f774_c.jpg&quot; title=&quot;Homeward bound with a stop for a sauna and dinner in Helsinki&quot; rel=&quot;lightbox[devoxxuk-geekout-2016]&quot;&gt;&lt;img src=&quot;//c7.staticflickr.com/8/7342/27518153982_3ae4a9f774_n.jpg&quot; width=&quot;320&quot; alt=&quot;Homeward bound with a stop for a sauna and dinner in Helsinki&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Thanks to the organizers and good friends from Devoxx UK and GeekOut. We had a great time and are still smiling about
    &lt;a href=&quot;https://www.flickr.com/photos/mraible/albums/72157666992992284&quot;&gt;all our new memories&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;&lt;strong&gt;Update on June 20, 2016:&lt;/strong&gt; Devoxx UK has posted &lt;a href=&quot;https://www.youtube.com/channel/UCxIamwHotqAAdmecaKT9WpA&quot;&gt;a channel on YouTube&lt;/a&gt; with all of its sessions. You can view my &lt;a href=&quot;https://www.youtube.com/watch?v=T4zsanOnKtk&quot;&gt;Art of Angular&lt;/a&gt; talk or &lt;a href=&quot;https://www.youtube.com/watch?v=UKMn5UNaUM4&quot;&gt;Get Hip with JHipster&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/moving_appfuse_into_the_attic</id>
        <title type="html">Moving AppFuse into the Attic</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/moving_appfuse_into_the_attic"/>
        <published>2016-04-28T15:40:16-06:00</published>
        <updated>2016-04-29T13:12:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="attic" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jhipster" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;&lt;img src=&quot;http://static.appfuse.org/images/appfuse-icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0; margin-top: -25px&quot;&gt;
In mid-February, I decided to stop working on &lt;a href=&quot;https://github.com/appfuse/appfuse&quot;&gt;AppFuse&lt;/a&gt;. My reason was simple: I was no longer getting any value from my contributions to the project. I sent &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/New-version-of-AppFuse-td4657900.html&quot;&gt;a message&lt;/a&gt; to the developers mailing list the next day:&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot; style=&quot;margin-left: 20px&quot;&gt;
&lt;p style=&quot;margin-top: 0&quot;&gt;Hello everyone, &lt;/p&gt;
&lt;p&gt;
Last night, I started working on AppFuse 4.0, with the following features from the roadmap: &lt;/p&gt;
&lt;ul&gt;
       &lt;li&gt;Remove XML wherever possible&lt;/li&gt;
       &lt;li&gt;Java 8&lt;/li&gt;
       &lt;li&gt;Spring Boot&lt;/li&gt;
       &lt;li&gt;Spring Data&lt;/li&gt;
       &lt;li&gt;JSR 303 (might require removing or developing client-side support)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
As I started removing XML and integrating Spring Boot and Spring Data, it quickly became apparent that it&#8217;d be a lot of work to make all of these changes. My guess is it&#8217;d take over 100 hours of my time to do everything. This is time I&#8217;d be taking away from my family and personal time. 
&lt;/p&gt;
&lt;p&gt;
At the end of last year, I wanted to make AppFuse 4.0 happen because I thought it&#8217;d help me stay up-to-date with Java technologies and learn some things along the way. As I dug into the codebase last night, I realized it&#8217;d be more of a headache than a learning experience. It seems there would be little reward for all the work. 
&lt;/p&gt;
&lt;p&gt;
Because there&#8217;s little-to-no activity on the mailing list these days, it seems like it&#8217;s the right time to shutdown the project and dedicate my free time to other open source endeavors. As you might know, I&#8217;m a big fan of JHipster (&lt;a href=&quot;http://jhipster.github.io/&quot;&gt;http://jhipster.github.io/&lt;/a&gt;). It combines AngularJS and Spring Boot and has all the features that AppFuse has - but with a more modern technology stack. 
&lt;/p&gt;
&lt;p&gt;
If we had everything hosted on GitHub, I think it&#8217;d make sense to add a line to the README that says &#8220;This project is no longer maintained&#8221;. However, since there&#8217;s a lot hosted on appfuse.org (with Confluence), it might not be that easy. Maybe it&#8217;s possible to export everything from Confluence to static HTML pages and host them somewhere with the same URLs so there&#8217;s not a bunch of 404s from shutting down the project. 
&lt;/p&gt;
&lt;p&gt;
Thank you for your contributions over the years. AppFuse was pretty cool back in the day, but now there&#8217;s better solutions. 
&lt;/p&gt;
&lt;p&gt;
Cheers, 
&lt;/p&gt;
&lt;p style=&quot;margin-bottom: 0&quot;&gt;
Matt&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;
The good news is I&apos;ve worked out a deal with &lt;a href=&quot;http://contegix.com&quot;&gt;Contegix&lt;/a&gt; to keep appfuse.org up and running for the next year. The &lt;a href=&quot;http://demo.appfuse.org&quot;&gt;demos&lt;/a&gt;, &lt;a href=&quot;http://appfuse.org&quot;&gt;documentation&lt;/a&gt; and &lt;a href=&quot;http://issues.appfuse.org&quot;&gt;bug tracker&lt;/a&gt; will be available until April 30, 2017. Bamboo and FishEye will be discontinued in the next week since they&apos;re too memory intensive for a smaller server. I&apos;d love to figure out a way to export all the documentation from Confluence to Asciidoctor so everything can be on GitHub for years to come. However, there&apos;s something to be said for just letting a project fade away rather than holding onto nostalgic artifacts.&lt;/p&gt;
&lt;p&gt;On a related note, &lt;a href=&quot;https://community.oracle.com/community/java/javanet-forge-sunset&quot;&gt;Java.net will be closing in a year from today&lt;/a&gt;. AppFuse started &lt;a href=&quot;https://sourceforge.net/projects/struts/files/appfuse/&quot;&gt;on SourceForge&lt;/a&gt;, but moved to &lt;a href=&quot;http://appfuse.java.net&quot;&gt;appfuse.java.net&lt;/a&gt; shortly after. Today, the only thing left on java.net are AppFuse&apos;s mailing lists. I suppose it makes sense that both projects will cease to exist around the same time. &lt;/p&gt;
&lt;p&gt;AppFuse&apos;s &lt;a href=&quot;https://github.com/appfuse&quot;&gt;source code will remain on GitHub&lt;/a&gt;. I have no plans to delete it.&lt;/p&gt;
&lt;p&gt;Thanks to everyone that used and contributed to AppFuse over the years. It was a pretty wild and crazy ride from 2003-2007! &lt;img src=&quot;https://raibledesigns.com/images/smileys/smile.gif&quot; class=&quot;smiley&quot; alt=&quot;:)&quot; title=&quot;:)&quot; /&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/2015_a_year_in_review</id>
        <title type="html">2015 - A Year in Review</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/2015_a_year_in_review"/>
        <published>2016-01-12T16:21:15-07:00</published>
        <updated>2016-03-11T22:46:30-07:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="blogging" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="syncro" scheme="http://roller.apache.org/ns/tags/" />
        <category term="2015" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yearinreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="porschebus" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
    2015 was the year &lt;a href=&quot;//raibledesigns.com/rd/category/The+Bus&quot;&gt;The Bus&lt;/a&gt; was supposed to be finished. If you
    read my &lt;a
    href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review&quot;&gt;year in review from last year&lt;/a&gt;, you&apos;ll see I was
    certain of it. To be fair, I did have estimates from people that had me expecting it to be done in July. The good
    news is the interior was finished in July. Since then, it&apos;s been back at Reincarnation getting the finishing touches
    applied. I believe if it was worked on for a week straight, it could be finished. It&apos;s &lt;em&gt;that&lt;/em&gt; close. So
    close I can taste it. THIS will be the year!
&lt;/p&gt;
&lt;p&gt;For this &lt;a href=&quot;//raibledesigns.com/rd/tags/yearinreview&quot;&gt;Year in Review&lt;/a&gt; post, I&apos;ll same the format I&apos;ve used
    the last few years.
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#theskibus&quot;&gt;The Ski Bus&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#2016&quot;&gt;2016&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;I had four different clients in 2015. The first was in the healthcare industry, the second in the API hosting space,
    one in the fashion industry and one in computer software. For the first client, I wrote about &lt;a
        href=&quot;//raibledesigns.com/rd/entry/integrating_node_js_ruby_and&quot;&gt;integrating Node.js,
        Ruby and Spring with Okta&apos;s SAML support&lt;/a&gt;. I also &lt;a
        href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angularjs&quot;&gt;helped them adopt&lt;/a&gt; and
    &lt;a href=&quot;//raibledesigns.com/rd/entry/testing_angularjs_applications&quot;&gt;learn AngularJS&lt;/a&gt;. Learning about
    &lt;a href=&quot;//raibledesigns.com/rd/entry/best_practices_for_using_foundation1&quot;&gt;Foundation and Angular&lt;/a&gt; was a nice
    treat too.
&lt;/p&gt;
&lt;p&gt;In March, I revisited &lt;a href=&quot;//raibledesigns.com/rd/entry/how_to_setup_your_own1&quot;&gt;how to setup your own software
    company&lt;/a&gt;. In that post, I wrote about how I felt when valuing time over money.&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
    Earlier this year, I had the opportunity to work 20 hours per week instead of 40. It was one of the greatest
    work-life experiences I&apos;ve had to date. I was still able to pay all my bills, and I had time during
    each-and-every-day to do something fun. When working 40 hours per week, exercising and cooking dinner were somewhat
    of a chore. When I flipped to working less, work became the chore and exercise and cooking became the fun parts of
    my day. I read somewhere recently that if Americans valued &lt;em&gt;health over wealth&lt;/em&gt;, we&apos;d be a lot better off. I
    felt like I did this when working less and that I was &lt;em&gt;rich in time&lt;/em&gt;.
&lt;/blockquote&gt;</summary>
        <content type="html">&lt;p&gt;
    2015 was the year &lt;a href=&quot;//raibledesigns.com/rd/category/The+Bus&quot;&gt;The Bus&lt;/a&gt; was supposed to be finished. If you
    read my &lt;a
    href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review&quot;&gt;year in review from last year&lt;/a&gt;, you&apos;ll see I was
    certain of it. To be fair, I did have estimates from people that had me expecting it to be done in July. The good
    news is the interior was finished in July. Since then, it&apos;s been back at Reincarnation getting the finishing touches
    applied. I believe if it was worked on for a week straight, it could be finished. It&apos;s &lt;em&gt;that&lt;/em&gt; close. So
    close I can taste it. THIS will be the year!
&lt;/p&gt;
&lt;p&gt;For this &lt;a href=&quot;//raibledesigns.com/rd/tags/yearinreview&quot;&gt;Year in Review&lt;/a&gt; post, I&apos;ll same the format I&apos;ve used
    the last few years.
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#theskibus&quot;&gt;The Ski Bus&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2015_a_year_in_review#2016&quot;&gt;2016&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;I had four different clients in 2015. The first was in the healthcare industry, the second in the API hosting space,
    one in the fashion industry and one in computer software. For the first client, I wrote about &lt;a
        href=&quot;//raibledesigns.com/rd/entry/integrating_node_js_ruby_and&quot;&gt;integrating Node.js,
        Ruby and Spring with Okta&apos;s SAML support&lt;/a&gt;. I also &lt;a
        href=&quot;//raibledesigns.com/rd/entry/getting_started_with_angularjs&quot;&gt;helped them adopt&lt;/a&gt; and
    &lt;a href=&quot;//raibledesigns.com/rd/entry/testing_angularjs_applications&quot;&gt;learn AngularJS&lt;/a&gt;. Learning about
    &lt;a href=&quot;//raibledesigns.com/rd/entry/best_practices_for_using_foundation1&quot;&gt;Foundation and Angular&lt;/a&gt; was a nice
    treat too.
&lt;/p&gt;
&lt;p&gt;In March, I revisited &lt;a href=&quot;//raibledesigns.com/rd/entry/how_to_setup_your_own1&quot;&gt;how to setup your own software
    company&lt;/a&gt;. In that post, I wrote about how I felt when valuing time over money.&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
    Earlier this year, I had the opportunity to work 20 hours per week instead of 40. It was one of the greatest
    work-life experiences I&apos;ve had to date. I was still able to pay all my bills, and I had time during
    each-and-every-day to do something fun. When working 40 hours per week, exercising and cooking dinner were somewhat
    of a chore. When I flipped to working less, work became the chore and exercise and cooking became the fun parts of
    my day. I read somewhere recently that if Americans valued &lt;em&gt;health over wealth&lt;/em&gt;, we&apos;d be a lot better off. I
    felt like I did this when working less and that I was &lt;em&gt;rich in time&lt;/em&gt;.
&lt;/blockquote&gt;
&lt;p&gt;
    The second client asked me to do a research project where I tried a bunch of API platforms (e.g.
    Apigee and 3Scale) and wrote up an analysis about five different stories they provided. It was a fun project where
    I learned a lot.
&lt;/p&gt;
&lt;p&gt;
    In April, I went to work at a fashion industry startup in downtown Denver. I wrote JavaScript, CSS and HTML for them
    for most of the year. The location afforded me the ability to discontinue my office at
    &lt;a href=&quot;http://www.thriveworkplace.com/en&quot;&gt;Thrive&lt;/a&gt;, a co-working space in Denver. While I missed having kombucha
    and
    local craft beer on tap, I loved the standup desk and the office environment with conversations, banter and laughter
    between desks.
&lt;/p&gt;
&lt;p&gt;In November, I picked up a new client that I&apos;m currently working with. They&apos;ve recently adopted Angular and I&apos;ve
    enjoyed the experience of working with a team of UI developers. We&apos;re putting a fresh UI on a legacy product and
    the team has been able to move really quickly. They&apos;re also in the Bay Area so it&apos;s been fun traveling to Silicon
    Valley once a month. My contract with them ends this spring.
&lt;/p&gt;
&lt;h3 id=&quot;speaking&quot;&gt;Speaking&lt;/h3&gt;
&lt;p&gt;
    I spoke about &lt;a href=&quot;//raibledesigns.com/rd/entry/the_art_of_angularjs_in&quot;&gt;Angular at Denver&apos;s Open Source User
    Group&lt;/a&gt; in February
    and about &lt;a href=&quot;//raibledesigns.com/rd/entry/getting_hip_with_jhipster_at&quot;&gt;JHipster at Denver&apos;s Java User
    Group&lt;/a&gt; in April. In the second half of the year, I re-joined the conference circuit, starting with
    &lt;a href=&quot;//raibledesigns.com/rd/entry/uberconf_2015_my_presentations_on&quot;&gt;UberConf&lt;/a&gt; in July. September brought me
    to &lt;a href=&quot;//raibledesigns.com/rd/entry/springone_2gx_2015_my_presentations&quot;&gt;SpringOne 2GX&lt;/a&gt; in Washington, DC
    and the &lt;a href=&quot;//raibledesigns.com/rd/entry/angular_summit_2015&quot;&gt;Angular Summit&lt;/a&gt; in Boston.
&lt;/p&gt;
&lt;p&gt;
    Trish and I giggled with glee as we &lt;a href=&quot;//raibledesigns.com/rd/entry/devoxx_2015_a_java_hipster&quot;&gt;returned to
    the Devoxx Belgium&lt;/a&gt; in November.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a rel=&quot;lightbox[2015yearinreview]&quot; href=&quot;https://farm6.staticflickr.com/5696/22675879269_b89c0d7368_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/22675879269/&quot; title=&quot;First stop: Bier Central!&quot;&gt;&lt;img
        src=&quot;https://farm6.staticflickr.com/5696/22675879269_b89c0d7368_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;First stop: Bier Central!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a rel=&quot;lightbox[2015yearinreview]&quot; href=&quot;https://farm6.staticflickr.com/5811/22649819637_1381655f70_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/22649819637/&quot; title=&quot;Shopping&quot;&gt;&lt;img
        src=&quot;https://farm6.staticflickr.com/5811/22649819637_1381655f70_m.jpg&quot; width=&quot;240&quot; alt=&quot;Shopping&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    &lt;a href=&quot;https://www.youtube.com/watch?v=baVOGuFIe9M&quot;&gt;My JHipster talk was a hit&lt;/a&gt; and we loved our brief tour of
    Brugge.
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm6.staticflickr.com/5752/22690142739_24b443fc6a_c.jpg&quot; title=&quot;Stadhuis Brugge Belgium&quot;
       rel=&quot;lightbox[2015yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mcginityphoto/22690142739&quot;&gt;&lt;img
        src=&quot;https://farm6.staticflickr.com/5752/22690142739_24b443fc6a.jpg&quot; width=&quot;500&quot; alt=&quot;Stadhuis Brugge Belgium&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
    As always, the people and the memories were the
    best part.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm1.staticflickr.com/595/22445469834_21210403fb_c.jpg&quot;
       title=&quot;Java Hipsters!&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/22445469834&quot;&gt;&lt;img
        src=&quot;https://farm1.staticflickr.com/595/22445469834_21210403fb_m.jpg&quot; width=&quot;240&quot; alt=&quot;Java Hipsters!&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;https://farm1.staticflickr.com/579/23042227126_7e05081502_c.jpg&quot;
       title=&quot;More Cowbell!&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/23042227126&quot;&gt;&lt;img
        src=&quot;https://farm1.staticflickr.com/579/23042227126_7e05081502_m.jpg&quot; width=&quot;240&quot; alt=&quot;More Cowbell!&quot;
        style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
    To end the year, I journeyed to Fort Lauderdale for the Rich Web Experience. After speaking, I worked remotely and
    networked for a few days. The networking lasted until the wee hours of the morning and good fun was had by all.
&lt;/p&gt;


&lt;h3 id=&quot;devoxx4kids&quot;&gt;Devoxx4Kids&lt;/h3&gt;
&lt;p&gt;I didn&apos;t plan any &lt;a href=&quot;http://www.meetup.com/Devoxx4Kids-Denver&quot;&gt;Devoxx4Kids&lt;/a&gt; events until later in the
    year. The Denver Chapter watched Arun and Aditya Gupta &lt;a
        href=&quot;//raibledesigns.com/rd/entry/minecraft_modding_at_denver_s&quot;&gt;
        speak about modding Minecraft&lt;/a&gt; in August. I also presented on
    &lt;a href=&quot;//raibledesigns.com/rd/entry/setting_up_a_minecraft_server&quot;&gt;setting up a Minecraft server in the cloud&lt;/a&gt;.
    In October, the talented &lt;a href=&quot;http://dbakevlar.com/&quot;&gt;Kellyn Pot&apos;Vin-Gorman&lt;/a&gt; taught a class about &lt;a
        href=&quot;http://www.meetup.com/Devoxx4Kids-Denver/events/224932151/&quot;&gt;coding
        simple games with the Raspberry Pi&lt;/a&gt;. It&apos;s always fun to see the kids&apos; faces light up when they solve a
    programming problem.
&lt;/p&gt;
&lt;p&gt;
    This year, with the help of &lt;a href=&quot;http://tuliva.com/&quot;&gt;Tuliva&lt;/a&gt;, we hope to host one Devoxx4Kids class per
    quarter. If there&apos;s a particular topic
    or speaker you&apos;d like to see, &lt;a href=&quot;//raibledesigns.com/rd/page/contact&quot;&gt;please let me know&lt;/a&gt;.
&lt;/p&gt;

&lt;h3 id=&quot;projects&quot;&gt;Projects&lt;/h3&gt;
&lt;p&gt;
    &lt;a href=&quot;http://www.infoq.com/minibooks/jhipster-mini-book&quot;&gt;
        &lt;img src=&quot;http://www.infoq.com/resource/minibooks/jhipster-mini-book/en/cover/Cover.jpg&quot;
             alt=&quot;The JHipster Mini-Book&quot; width=&quot;100&quot; class=&quot;picture&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
I released a &lt;a href=&quot;//raibledesigns.com/rd/entry/appfuse_3_5_released&quot;&gt;new version of AppFuse in February&lt;/a&gt; and
    started working on the &lt;a href=&quot;http://jhipster.github.io/&quot;&gt;JHipster&lt;/a&gt; Mini-Book in March. To help
    provide updates about
    the book, I created a blogging app with JHipster and started &lt;a href=&quot;http://www.jhipster-book.com&quot;&gt;www.jhipster-book.com&lt;/a&gt;.
    I wrote the book and created
    &lt;a href=&quot;http://www.21-points.com&quot;&gt;21-Points Health&lt;/a&gt; as its
    example application. I &lt;a href=&quot;http://www.jhipster-book.com/#!/news/entry/jhipster-at-devoxx-belgium&quot;&gt;open-sourced
        21-Points on GitHub&lt;/a&gt; during my Devoxx presentation. Because of my writing and speaking
    about JHipster, I was invited to join the &lt;a href=&quot;https://jhipster.github.io/team.html&quot;&gt;JHipster Team&lt;/a&gt;. I
    happily accepted; it&apos;s been a great group to work with.
&lt;/p&gt;
&lt;p&gt;
    The &lt;a href=&quot;http://www.jhipster-book.com/#!/news/entry/jhipster-mini-book-released&quot;&gt;JHipster Mini-Book 1.0 was
    released on October 30, 2015&lt;/a&gt;. I wrote about &lt;a
    href=&quot;//raibledesigns.com/rd/entry/the_jhipster_mini_book_how&quot;&gt;how I wrote it&lt;/a&gt; a few days later.
&lt;/p&gt;

&lt;h2 id=&quot;personal&quot;&gt;Personal&lt;/h2&gt;
&lt;p&gt;I wrote down my goals at the beginning of 2015: &lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;21-Points Fitness App&lt;/li&gt;
    &lt;li&gt;JHipster Mini Book (InfoQ)&lt;/li&gt;
    &lt;li&gt;Finish Bus&lt;/li&gt;
    &lt;li&gt;New House&lt;/li&gt;
    &lt;li&gt;Good Blood Pressure&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m proud to say I accomplished three out of five. The Bus didn&apos;t get finished and we failed to sell our house.
    I did create &lt;a href=&quot;http://www.21-points.com/&quot;&gt;21-Points Health&lt;/a&gt;, wrote &lt;a
        href=&quot;http://www.infoq.com/minibooks/jhipster-mini-book&quot;&gt;
        The JHipster Mini-Book&lt;/a&gt; and maintained good health all year.
&lt;/p&gt;

&lt;p&gt;We weren&apos;t planning on selling our house this year; we wanted to find a new house and rent out our current one.
    However, we
    found a house we loved (small house, lots of land) in the heart of DTC and putting our house on the market was the
    best way to try and get it. Our offer failed
    and we endured the house-is-on-the-market dance through July and August. It was pretty sweet living in such a clean
    house, but we got tired of living in a de-personalized abode. We took it off the market in September and plan
    on renting it once we find our next home.
&lt;/p&gt;
&lt;p&gt;The worst part of the year started with a phone call from a friend in the early afternoon on October 7. My good
    friend, Cletus, called to notify me that he&apos;d found our friend, Jason Miller, dead that morning. Jason was a pledge
    class
    brother of Cletus and mine in the Chi Phi Fraternity at DU. You might remember Jason from my
    &lt;a href=&quot;//raibledesigns.com/rd/entry/oktoberfest_best_vacation_ever&quot;&gt;trip to Oktoberfest in 2008&lt;/a&gt;. He was one of my best friends.
&lt;/p&gt;
&lt;p&gt;
    Jason was a heckuva guy and an awesome friend. He always inspired laughter and smiles with his witty humor. He will
    be missed, but not forgotten. Jason had a zest for life and a good time that we&apos;ve resolved to remember annually
    with a
    brother&apos;s trip to an exotic gambling destination. This year, we&apos;ll be traveling to Las Vegas for St. Patty&apos;s Day
    and March Madness.
&lt;/p&gt;
&lt;h3 id=&quot;theskibus&quot;&gt;The Ski Bus&lt;/h3&gt;
&lt;p&gt;
    The Syncro Ski Bus had a pretty good year. We took it on &lt;a
    href=&quot;//raibledesigns.com/rd/entry/farewell_to_the_2014_2015&quot;&gt;many skiing adventures&lt;/a&gt;, with trips to
    Steamboat, Crested Butte, and Telluride.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c1.staticflickr.com/9/8729/16180350303_c112218136_c.jpg&quot;
       title=&quot;Packed and ready for Crested Butte. by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/16180350303&quot;&gt;&lt;img
        src=&quot;https://c1.staticflickr.com/9/8729/16180350303_c112218136_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;Packed and ready for Crested Butte.&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm9.staticflickr.com/8613/16799153151_12e8b3d9ea_c.jpg&quot;
       title=&quot;Jack, James, Abbie and myself skiing in heaven! by Matt Raible, on Flickr&quot;
       rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://farm9.staticflickr.com/8613/16799153151_12e8b3d9ea_c.jpg&quot;&gt;&lt;img
        src=&quot;https://farm9.staticflickr.com/8613/16799153151_12e8b3d9ea_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;Jack, James, Abbie and myself skiing in heaven!&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm9.staticflickr.com/8738/16612686298_1ea3dfc384_c.jpg&quot;
       title=&quot;Yay! Car bombs at Ice bar by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://farm9.staticflickr.com/8738/16612686298_1ea3dfc384_c.jpg&quot;&gt;&lt;img
        src=&quot;https://farm9.staticflickr.com/8738/16612686298_1ea3dfc384_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;Yay! Car bombs at Ice bar&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c4.staticflickr.com/8/7603/16799164872_82944691da_c.jpg&quot;
       title=&quot;We love you Telluride! by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/16799164872&quot;&gt;&lt;img
        src=&quot;https://c4.staticflickr.com/8/7603/16799164872_82944691da.jpg&quot; width=&quot;500&quot; alt=&quot;We love you Telluride!&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;p&gt;
    We enjoyed a couple overnights and tailgated a few times at our favorite ski area: Mary Jane.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm9.staticflickr.com/8628/16800248455_de547b4489_c.jpg&quot;
       title=&quot;Ski In, Ski Out at Challenger Lift by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://farm9.staticflickr.com/8628/16800248455_de547b4489_c.jpg&quot;&gt;&lt;img
        src=&quot;https://farm9.staticflickr.com/8628/16800248455_de547b4489_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Ski In, Ski Out at Challenger Lift&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm9.staticflickr.com/8628/16180349473_b99397f8f9_c.jpg&quot;
       title=&quot;Tailgating at Mary Jane by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://farm9.staticflickr.com/8628/16180349473_b99397f8f9_c.jpg&quot;&gt;&lt;img
        src=&quot;https://farm9.staticflickr.com/8628/16180349473_b99397f8f9_m.jpg&quot; width=&quot;240&quot; alt=&quot;Tailgating at Mary Jane&quot;
        style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    I took Jack and we met my parents in Moab in May for &lt;a href=&quot;//raibledesigns.com/rd/entry/syncro_solstice_2015&quot;&gt;Syncro Solstice 2015&lt;/a&gt;. We took it for
    some off-roading, busted a cooling hose a couple times, and almost made it back to Denver.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://c2.staticflickr.com/8/7753/17920503935_5e8c033cb8_c.jpg&quot;
       title=&quot;Syncro Solstice 2015! by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/17920503935&quot;&gt;&lt;img
        src=&quot;https://c2.staticflickr.com/8/7753/17920503935_5e8c033cb8.jpg&quot; width=&quot;500&quot; alt=&quot;Syncro Solstice 2015!&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    That next weekend, we took it to &lt;a href=&quot;https://www.flickr.com/photos/mcginityphoto/albums/72157654071550305&quot;&gt;VWs
    on the Green&lt;/a&gt; and showed it alongside The (under construction) Bus.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://www.mcginityphoto.com/Portfolio/VWClassic/i-FvTx9Mx/0/L/Raibles%20at%20VW%20on%20the%20Green-L.jpg&quot;
       rel=&quot;lightbox[2015yearinreview]&quot;&gt;
        &lt;img
            src=&quot;http://www.mcginityphoto.com/Portfolio/VWClassic/i-FvTx9Mx/0/M/Raibles%20at%20VW%20on%20the%20Green-M.jpg&quot;
            alt=&quot;Raibles on the VW Green&quot; width=&quot;600&quot; style=&quot;border: 1px solid black&quot;&gt;
    &lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    In July, we journeyed to Montana for the 4th of July. We drove our Westy in the Swan Valley parade while the kids
    rode on top and threw water balloons and candy to the crowd.
    We drove back from Montana in a single day (900 miles). I remember Wyoming well. Sirius XM was broadcasting the last
    Grateful Dead concert from Soldier Field
    and Trish was driving. She sang for hours, driving through the rain and fog while I dozed periodically.
&lt;/p&gt;

&lt;p&gt;Sewfine finished The Bus&apos;s interior in July. I wrote about this and many other things in &lt;a
    href=&quot;//raibledesigns.com/rd/entry/life_update_the_bus_project&quot;&gt;
    Life Update: The Bus Project, New Gigs, New House and More&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm1.staticflickr.com/404/19352716089_59ed639749_c.jpg&quot;
       title=&quot;Love the color scheme with chrome accents&quot; rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/19352716089/in/album-72157655642253461/&quot;&gt;&lt;img
        src=&quot;https://farm1.staticflickr.com/404/19352716089_59ed639749_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Love the color scheme with chrome accents&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm4.staticflickr.com/3786/19543443241_8eeb15dd74_c.jpg&quot; title=&quot;The cockpit&quot;
       rel=&quot;lightbox[2015yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/19543443241/in/album-72157655642253461/&quot;&gt;&lt;img
        src=&quot;https://farm4.staticflickr.com/3786/19543443241_8eeb15dd74_m.jpg&quot; width=&quot;240&quot; alt=&quot;The cockpit&quot;
        style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    A week later, I won a runner-up trophy for the Syncro at &lt;a
    href=&quot;http://www.bandimere.com/tickets-schedule/event-details/2015/07/12/default-calendar/colorado-bug-in-pres-by-nuvintage&quot;&gt;
    The Colorado Bug-In at Bandimere Speedway&lt;/a&gt;. On my birthday,
    July 16, we drove it to Dinosaur National Monument for a week-long raft trip, starting at Gates of Lodore. I hit my
    first deer
    that night, driving at 3am and doing minimal damage to our German-engineered RV. The deer broke the headlight, but
    not the bulb.
&lt;/p&gt;
&lt;p&gt;
    We had some more camping/rafting adventures with it in the fall, but eventually had to take it to the shop for a
    transmission rebuild in November. While it was getting repairs, we upgraded a few things. It now has a South African
    grill, modern headlights, a new fridge and a Propex heater. It&apos;s finally become the ultimate camping vehicle, for
    summer or winter.
&lt;/p&gt;
&lt;h2 id=&quot;2016&quot;&gt;2016&lt;/h2&gt;
&lt;p&gt;Professionally, I plan to continue speaking at conferences this year. I&apos;ve submitted a few proposals to &lt;a
    href=&quot;http://www.devoxx.fr/&quot;&gt;Devoxx France&lt;/a&gt;,
    &lt;a href=&quot;http://www.devoxx.co.uk/&quot;&gt;Devoxx UK&lt;/a&gt; and I&apos;ve agreed to speak at &lt;a href=&quot;http://2016.geekout.ee/&quot;&gt;Geek
        Out&lt;/a&gt;. And did you hear that &lt;a href=&quot;http://springone.com/&quot;&gt;SpringOne 2016&lt;/a&gt; is in Las Vegas?!
&lt;/p&gt;
&lt;p&gt;
    I suspect this will be the year of &lt;a href=&quot;https://angular.io/&quot;&gt;Angular 2&lt;/a&gt; and microservices. Watch &lt;a
    href=&quot;https://github.com/jhipster/jhipster-experimental-microservices&quot;&gt;
    this project&lt;/a&gt; to see how JHipster implements microservices. I plan to pump out a release of AppFuse in the near
    future, implementing #NoXML and moving to Java 8.
&lt;/p&gt;
&lt;p&gt;
    Trish and I hope to move into a new house this year, but won&apos;t be disappointed if we don&apos;t find the right one. We
    have
    another year before Abbie starts high school at 7am.
&lt;/p&gt;&lt;p&gt;
    I have no real big projects planned, except for driving The Bus. We do have a few fun vacations planned.
    In fact,
    I&apos;m writing this while riding in the back of our Westy. My parents and I are road-tripping from Denver to Jekyll
    Island, Georgia.
    We&apos;re taking the scenic route to see some places we&apos;ve never been and staying at RV Parks with the top popped. We
    arrive in
    New Orleans this afternoon and will be staying two nights to enjoy the culture and cuisine.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a  rel=&quot;lightbox[2015yearinreview]&quot; href=&quot;https://farm2.staticflickr.com/1682/24235662332_ef9e21ff8e_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/24235662332/&quot;
       title=&quot;The back seat&quot;&gt;&lt;img src=&quot;https://farm2.staticflickr.com/1682/24235662332_ef9e21ff8e_m.jpg&quot; width=&quot;240&quot; style=&quot;border: 1px solid black&quot; alt=&quot;The back seat&quot;&gt;&lt;/a&gt;
    &lt;a  rel=&quot;lightbox[2015yearinreview]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/24317694286/&quot; href=&quot;https://farm2.staticflickr.com/1612/24317694286_e05ec2fd4a_c.jpg&quot;
       title=&quot;Somewhere in Arkansas...&quot;&gt;&lt;img src=&quot;https://farm2.staticflickr.com/1612/24317694286_e05ec2fd4a_m.jpg&quot;
                                             width=&quot;240&quot; alt=&quot;Somewhere in Arkansas...&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt; My Dad turns 70 this weekend and we planned a family vacation to celebrate. His brother and sister are joining us
    and Trish and the kids are flying in this weekend. We figured a road trip across the country was appropriate since
    we&apos;ve done so many together and I happen to own the ultimate vehicle for car camping. Below is a &lt;a href=&quot;https://goo.gl/maps/9hE5aNkF7k22&quot;&gt;map of our
    route&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;https://www.google.com/maps/embed?pb=!1m58!1m12!1m3!1d13460084.342798809!2d-102.15251344423332!3d34.54967111566971!2m3!1f0!2f0!3f0!3m2!1i1024!2i768!4f13.1!4m43!3e0!4m5!1s0x876b80aa231f17cf%3A0x118ef4f8278a36d6!2sDenver%2C+CO!3m2!1d39.739235799999996!2d-104.990251!4m5!1s0x87cf62f745c8983f%3A0x6bfd6cb31e690da0!2sSpringfield%2C+MO!3m2!1d37.2089572!2d-93.29229889999999!4m5!1s0x87cd2a9388325047%3A0xbaa8bef944021e0d!2sHot+Springs%2C+AR!3m2!1d34.5037004!2d-93.0551795!4m5!1s0x8620a454b2118265%3A0xdb065be85e22d3b4!2sNew+Orleans%2C+LA!3m2!1d29.9510658!2d-90.0715323!4m5!1s0x889381562ac66341%3A0xbf585ed52c4701f3!2sPanama+City%2C+FL!3m2!1d30.158812899999997!2d-85.6602058!4m5!1s0x88e4dbf62542c839%3A0x10d22d63ea360435!2sJekyll+Island%2C+Glynn+County%2C+GA!3m2!1d31.0685662!2d-81.4134297!4m5!1s0x876b80aa231f17cf%3A0x118ef4f8278a36d6!2sDenver%2C+CO!3m2!1d39.739235799999996!2d-104.990251!5e0!3m2!1sen!2sus!4v1452694275660&quot; width=&quot;600&quot; height=&quot;450&quot; frameborder=&quot;0&quot; style=&quot;border:0&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;In June, we&apos;ll be celebrating Trish&apos;s parents 50th wedding anniversary in Kauai. With Trish&apos;s brother, sister and
    children joining in, everyone is sure to have a fantastic vacation. I hope to continue the fun by working remotely
    from Montana in July.
&lt;/p&gt;
&lt;p&gt;When I drive the finished bus in the Swan Valley parade on the 4th of July, I&apos;ll be smiling from ear-to-ear. 2016
    &lt;em&gt;is&lt;/em&gt; the year! The long wait will be over soon...
&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/google_s_mirror_of_maven</id>
        <title type="html">Google&apos;s Mirror of Maven Central 25% Faster</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/google_s_mirror_of_maven"/>
        <published>2015-11-10T00:13:51-07:00</published>
        <updated>2015-11-18T19:44:43-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="dependencies" scheme="http://roller.apache.org/ns/tags/" />
        <category term="googlecloudstorage" scheme="http://roller.apache.org/ns/tags/" />
        <category term="mavencentral" scheme="http://roller.apache.org/ns/tags/" />
        <category term="infoq" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;
Last week, &lt;a href=&quot;http://takari.io/2015/10/28/google-maven-central.html&quot;&gt;Takari announced that Google is Maven Central&apos;s New Best Friend&lt;/a&gt;. While writing a
    &lt;a href=&quot;http://www.infoq.com/news/2015/11/maven-central-at-google&quot;&gt;news article about this&lt;/a&gt; for
InfoQ, I decided to run a small test to see the speed of the default Maven Central versus the new Google Cloud Storage instance. This
micro benchmark didn&apos;t seem worthy of including in the article, but I think it&apos;s interesting to see the speed improvements I found.
&lt;/p&gt;
&lt;p&gt;
I ran &lt;code&gt;rm -rf ~/.m2/repository&lt;/code&gt;, then &lt;code&gt;mvn install&lt;/code&gt; with the default repository configured. I ran the commands again with
Google Cloud Storage. I found that the downloading of dependencies, compilation and running unit tests on
    &lt;a href=&quot;https://github.com/appfuse/appfuse/tree/master/web&quot;&gt;AppFuse&apos;s web projects&lt;/a&gt; averaged 4 minutes, 30 seconds.
With Google Cloud Storage, the same process averaged 3 minutes and 37 seconds. By my calculations, this means you speed up artifact resolution
for your Maven projects by 25% by switching to Google. To do that, create a &lt;code&gt;~/.m2/settings.xml&lt;/code&gt; file with
    the following contents.
    &lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;settings&amp;gt;
  &amp;lt;mirrors&amp;gt;
    &amp;lt;mirror&amp;gt;
      &amp;lt;id&amp;gt;google-maven-central&amp;lt;/id&amp;gt;
      &amp;lt;name&amp;gt;Google Maven Central&amp;lt;/name&amp;gt;
      &amp;lt;url&amp;gt;https://maven-central.storage.googleapis.com&amp;lt;/url&amp;gt;
      &amp;lt;mirrorOf&amp;gt;central&amp;lt;/mirrorOf&amp;gt;
    &amp;lt;/mirror&amp;gt;
  &amp;lt;/mirrors&amp;gt;
&amp;lt;/settings&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Benchmark Details&lt;/strong&gt;&lt;br&gt;
My tests were run on a Mac Pro (late 2013)
with a 3.5 GHz 6-Core Intel Xeon E5 processor and 32 GB of RAM. Bandwidth speeds during this test averaged 57 Mbps down,
6 Mbps up. Below are the timing numbers (in minutes) from my test:
&lt;/p&gt;
&lt;pre&gt;
Default: 4:33, 4:36, 4:32, 4:24, 4:09
Google: 5:13, 3:35, 2:15, 3:38, 3:39
&lt;/pre&gt;
&lt;p&gt;Google had some wide variances in its results, with five minutes and two minutes. Because of this, I dropped the
low and high numbers for each service before calculating the average. My math with raw numbers is below.
&lt;/p&gt;
&lt;pre&gt;
Default:
273, 276, 272, 264, 213 = 260, 4:20
276, 272, 264 = 270, 4:30

Google:
313, 215, 135, 218, 219 = 220, 3.66 = 3:40
215, 218, 219 = 3:37
&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://www.infoq.com/news/2015/11/maven-central-at-google#anch129463&quot;&gt;Chen Eric commented on the InfoQ article&lt;/a&gt;
    to note that Chinese programmers are blocked from using Google.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Jason Swank of Sonatype has done some more extensive benchmarking and &lt;a href=&quot;//raibledesigns.com/rd/entry/google_s_mirror_of_maven#comment-1447442881000&quot;&gt;found different results&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
We found that average unprimed Google API (first mvn run) caching performed 30% slower than Maven Central. Primed Google API cache performance (second run) was 3% faster then Maven Central (second run). We also ran a number of cloud-based tests with similar results.
&lt;/blockquote&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/springone_2gx_2015_my_presentations</id>
        <title type="html">SpringOne 2GX 2015: My Presentations on Comparing Hot JavaScript Frameworks and NoXML </title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/springone_2gx_2015_my_presentations"/>
        <published>2015-09-20T12:29:00-06:00</published>
        <updated>2015-09-20T18:40:33-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="xml" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springframework" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javascript" scheme="http://roller.apache.org/ns/tags/" />
        <category term="s2gx" scheme="http://roller.apache.org/ns/tags/" />
        <category term="emberjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="angularjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="noxml" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springone2gx" scheme="http://roller.apache.org/ns/tags/" />
        <category term="reactjs" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last week, I had the pleasure of traveling to Washington, DC to speak at the annual &lt;a href=&quot;http://www.springone2gx.com/&quot;&gt;SpringOne 2GX conference&lt;/a&gt;. I was pretty stressed for the last few weeks because I had to create two new presentations from scratch, and both had to be 90 minutes long. I was also hoping to finish the JHipster Book before the conference started. I was able to finish both presentations in the nick of time, but did not find the time to write the last chapter in the JHipster Book.&lt;/p&gt;
&lt;p&gt;The first presentation was titled &lt;a href=&quot;https://2015.event.springone2gx.com/schedule/sessions/comparing_hot_javascript_frameworks_angularjs_ember_js_and_react_js.html&quot;&gt;Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js&lt;/a&gt;. I started by revisiting the &lt;a href=&quot;//raibledesigns.com/rd/entry/comparing_jvm_web_frameworks_at&quot;&gt;Comparing JVM Web Frameworks talk I did at vJUG&lt;/a&gt; last February. I explained how I think traditional web frameworks are no longer relevant in 2015, but I do believe server-side rendering is still &lt;em&gt;very&lt;/em&gt; relevant. From there, I used &lt;a href=&quot;http://www.ybrikman.com/&quot;&gt;Yevgeniy Brikman&#8217;s&lt;/a&gt; framework scorecard (from his &lt;a href=&quot;http://www.slideshare.net/brikis98/nodejs-vs-play-framework&quot;&gt;Node.js vs. Play Framework presentation&lt;/a&gt;) to rank each framework by a number of different criteria. You can see the final results on &lt;a href=&quot;http://www.slideshare.net/mraible/comparing-hot-javascript-frameworks-angularjs-emberjs-and-reactjs-springone-2gx-2015/160&quot;&gt;slide 160&lt;/a&gt;. Since the scores were so close, I believe you could tweak some scores a bit (or add weights to the different criteria) and make any of the frameworks come out on top.
&lt;/p&gt;
&lt;p&gt;
You can click through the presentation below, download it from &lt;a href=&quot;//raibledesigns.com/rd/page/publications&quot;&gt;my presentations page&lt;/a&gt;, or &lt;a href=&quot;//www.slideshare.net/mraible/comparing-hot-javascript-frameworks-angularjs-emberjs-and-reactjs-springone-2gx-2015&quot;&gt;see it on SlideShare&lt;/a&gt;.
&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/NGLRPcZiLF0pBo&quot; width=&quot;512&quot; height=&quot;325&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; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen&gt; &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;I started writing the second presentation a week before I had to deliver it. On Thursday, September 10th, I stayed up late, trying to figure out how to create a good presentation on NoXML &lt;em&gt;and&lt;/em&gt; finish the last part of the JHipster Book. Then it came to me, I needed to &lt;em&gt;parallelize&lt;/em&gt; and do them both at the same time. I decided to compare AppFuse (which is similar to a legacy Spring application with lots of XML) to JHipster (which hardly contains any XML). 
&lt;/p&gt;
&lt;p&gt;
I wrote a 10-page Google Doc on how I planned to do this, then went rafting and camping with my family for the weekend. I finished most of the presentation on Monday night, but then realized the presentation wouldn&apos;t be long enough to fill 90 minutes. So I hunkered down at midnight, created a new AppFuse application and removed a bunch of its XML. This took me until 3:30am, and I was able to accomplish the following tasks:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spring XML to Java&lt;/li&gt;
&lt;li&gt;Spring Security Configuration to Java&lt;/li&gt;
&lt;li&gt;web.xml to WebApplicationInitializer&lt;/li&gt;
&lt;li&gt;Spring MVC to Java&lt;/li&gt;
&lt;li&gt;Migrated to Spring Boot&lt;/li&gt;
&lt;li&gt;Maven to Groovy&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;p&gt;I was pretty pumped when I completed my final goal: converting to Spring Boot and getting a test to pass. I made commits to an &lt;a href=&quot;https://github.com/mraible/appfuse-noxml/commits/master&quot;&gt;appfuse-noxml project on GitHub&lt;/a&gt; as I accomplished each step. You can see all the changes in &lt;a href=&quot;https://github.com/mraible/appfuse-noxml/commits/master&quot;&gt;the project&apos;s commit log&lt;/a&gt;. While I&apos;d figured everything out, I still needed to complete the presentation. Luckily, I found time to do this the night before, the morning of, and in the final hour before I had to deliver the talk. You can imagine my relief when I was done delivering both talks. 
&lt;/p&gt;
&lt;p&gt;
You can click through the presentation below, download it from &lt;a href=&quot;//raibledesigns.com/rd/page/publications&quot;&gt;my presentations page&lt;/a&gt;, or &lt;a href=&quot;//www.slideshare.net/mraible/noxml-eliminating-xml-in-spring-projects-springone-2gx-2015&quot;&gt;view it on SlideShare&lt;/a&gt;.
&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/4V9V7NSsNC2rd7&quot; width=&quot;512&quot; height=&quot;325&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; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen&gt; &lt;/iframe&gt; 
&lt;/div&gt;
&lt;p&gt;While I didn&apos;t get to spend much time at the conference, I did have a lot of fun while I was there. I got to meet some new folks, reconnect with old friends, and enjoy beers and dinner with a smiling crew on Thursday night. The Broncos victory late that night was the icing on the cake. &lt;img src=&quot;//raibledesigns.com/images/smileys/smile.gif&quot; class=&quot;smiley&quot; alt=&quot;:)&quot; title=&quot;:)&quot;&gt;&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/getting_hip_with_jhipster_at</id>
        <title type="html">Getting Hip with JHipster at Denver&apos;s Java User Group</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/getting_hip_with_jhipster_at"/>
        <published>2015-04-09T08:31:54-06:00</published>
        <updated>2015-04-09T19:20:43-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="angularjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring-boot" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jhipster" scheme="http://roller.apache.org/ns/tags/" />
        <category term="bootstrap" scheme="http://roller.apache.org/ns/tags/" />
        <category term="html5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yeoman" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Last night, I had the pleasure of &lt;a href=&quot;http://www.meetup.com/DenverJavaUsersGroup/events/220309287/&quot;&gt;speaking at Denver&apos;s Java User Group Meetup about JHipster&lt;/a&gt;. I&apos;ve been a big fan of &lt;a href=&quot;http://jhipster.github.io/&quot;&gt;JHipster&lt;/a&gt; ever since I started using it last fall. I developed a quick prototype for a client and wrote about &lt;a href=&quot;//raibledesigns.com/rd/entry/getting_started_with_jhipster_on&quot;&gt;solving some issues I had with it on OS X&lt;/a&gt;. I like the project because it encapsulates the primary open source tools I&apos;ve been using for the last couple of years: &lt;a href=&quot;http://projects.spring.io/spring-boot/&quot;&gt;Spring Boot&lt;/a&gt;, &lt;a href=&quot;https://angularjs.org/&quot;&gt;AngularJS&lt;/a&gt; and &lt;a href=&quot;http://getbootstrap.com/&quot;&gt;Bootstrap&lt;/a&gt;. I also wrote about its &lt;a href=&quot;http://www.infoq.com/news/2015/01/jhipster-2.0&quot;&gt;2.0 release&lt;/a&gt; on InfoQ in January.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;https://farm9.staticflickr.com/8820/16900780428_7093ff1754_c.jpg&quot; rel=&quot;lightbox[jhipsterdjug]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/16900780428&quot; title=&quot;My Hipster Getup by Matt Raible, on Flickr&quot;&gt;&lt;img src=&quot;https://farm9.staticflickr.com/8820/16900780428_7093ff1754_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;My Hipster Getup&quot; class=&quot;picture&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
To add some humor to my talk, I showed up as a well-dressed Java Developer. Like a mature gentleman might do, I started the evening with a glass of scotch (Glenlivet 12). Throughout the talk I became more hip and adjusted my attire, and beverage, accordingly. As you might expect, my demos had failures. The initial project creation stalled during Bower&apos;s &lt;em&gt;download all JavaScript dependencies&lt;/em&gt;. Luckily, I had a backup and was able to proceed. Towards the end, when I tried to deploy to Heroku, I was presented with a lovely message that &quot;Heroku toolbelt updating, please try again later&quot;. I guess auto-updating has its downsides. &lt;/p&gt;
&lt;p&gt;After finishing the demo, I cracked open a cold PBR to ease my frustration.&lt;/p&gt;
&lt;p&gt;I did two live coding sessions during this presentation; standing on the shoulders of giants to do so. I modeled Josh Long&apos;s &lt;a href=&quot;http://www.joshlong.com/jl/blogPost/tech_tip_geting_started_with_spring_boot.html&quot;&gt;Getting Started with Spring Boot&lt;/a&gt; to create a quick introduction to Spring Boot. IntelliJ IDEA 14.1 has a &lt;a href=&quot;http://blog.jetbrains.com/idea/2015/03/develop-spring-boot-applications-more-productively-with-intellij-idea-14-1/&quot;&gt;nice way to create Spring Boot projects&lt;/a&gt;, so that came in handy.  For the JHipster portion, I created a blogging app and used relationships and business logic similar to what Julien Dubois did in his &lt;a href=&quot;https://spring.io/blog/2015/03/31/webinar-replay-jhipster-for-spring-boot&quot;&gt;JHipster for Spring Boot Webinar&lt;/a&gt;. Watching Josh and Julien&apos;s demos will give you a similar experience to what DJUG attendees experienced last night, without the download/deployment failures.
&lt;/p&gt;
&lt;p&gt;You can click through my presentation below, download it from &lt;a href=&quot;//raibledesigns.com/rd/page/publications&quot;&gt;my
    presentations page&lt;/a&gt;, or &lt;a href=&quot;http://www.slideshare.net/mraible/get-hip-with-jhipster&quot;&gt;view it on SlideShare&lt;/a&gt;.
&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/46814366&quot; width=&quot;512&quot; height=&quot;325&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot;&gt;&lt;/iframe&gt;
&lt;/div&gt;
&lt;p&gt;You might notice my &lt;a href=&quot;http://www.slideshare.net/mraible/get-hip-with-jhipster/32&quot;&gt;announcement on slide #32&lt;/a&gt; that I&apos;ve signed up to write a book on JHipster.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;https://farm9.staticflickr.com/8825/17062597206_60a5bd6e19_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mraible/17062597206&quot; rel=&quot;lightbox[jhipsterdjug]&quot; title=&quot;The JHipster Mini-Book by Matt Raible&quot;&gt;&lt;img src=&quot;https://farm9.staticflickr.com/8825/17062597206_60a5bd6e19.jpg&quot; width=&quot;500&quot; alt=&quot;The JHipster Mini-Book&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I haven&apos;t started writing the book yet, but I have been talking with &lt;a href=&quot;http://infoq.com&quot;&gt;InfoQ&lt;/a&gt; and other folks about it for several months. I plan to use &lt;a href=&quot;https://github.com/asciidoctor/asciidoctor-gradle-examples&quot;&gt;Asciidoctor and Gradle&lt;/a&gt; as my authoring tools. If you have experience writing a book with these tools, I&apos;d love to hear about it. If you&apos;ve developed an application with JHipster and have some experience in the trenches, I&apos;d love to hear your stories too. 
&lt;/p&gt;
&lt;p&gt;
As I told DJUG last night, I plan to be done with the book in a few months. However, if you&apos;ve been a reader of this blog, you&apos;ll know I&apos;ve been planning to be done with my &apos;66 VW Bus in &lt;em&gt;just a few more months&lt;/em&gt; for quite some time, so that phrase has an interesting meaning for me. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/how_to_setup_your_own1</id>
        <title type="html">How To Setup Your Own Software Development Company, 6 Years Later</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/how_to_setup_your_own1"/>
        <published>2015-03-02T09:26:01-07:00</published>
        <updated>2015-03-03T00:03:22-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="healthoverwealth" scheme="http://roller.apache.org/ns/tags/" />
        <category term="contract" scheme="http://roller.apache.org/ns/tags/" />
        <category term="scorp" scheme="http://roller.apache.org/ns/tags/" />
        <category term="fulltime" scheme="http://roller.apache.org/ns/tags/" />
        <category term="development" scheme="http://roller.apache.org/ns/tags/" />
        <category term="time" scheme="http://roller.apache.org/ns/tags/" />
        <category term="insurance" scheme="http://roller.apache.org/ns/tags/" />
        <category term="career" scheme="http://roller.apache.org/ns/tags/" />
        <category term="smallbusiness" scheme="http://roller.apache.org/ns/tags/" />
        <category term="software" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Just over six years ago, I wrote a popular post titled &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_to_setup_your_own&quot;&gt;How To Setup Your Own Software Development Company&lt;/a&gt;. I&apos;d just left LinkedIn a few months earlier and was enjoying consulting life again, working with a group of friends at Evite. In the article, I wrote about how I liked consulting because it forces you to keep your skills up-to-date and it pays a lot better. I also talked about the type of legal entity you should form (I have an S Corp), what business insurance you should buy, what I had for health insurance and how I automated payroll and tax payments.&lt;/p&gt;
&lt;p&gt;I recently received an email from a reader, asking me if I had any updated thoughts.&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
&lt;p style=&quot;margin-top: 0&quot;&gt;
It&apos;s been nearly six years since you wrote &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_to_setup_your_own&quot;&gt;the article about starting your own business&lt;/a&gt; ... and thanks, by the way. 
&lt;/p&gt;
&lt;p&gt;
I am starting my venture into independent contract work as a software engineer (Java technology) in California and most likely will setup an S corp entity. 
&lt;/p&gt;
&lt;p&gt;
Seeing that you wrote this six years ago and things have considerably changed in the U.S. (economy, health care, etc.), I was wondering if you had some updated thoughts to share, perhaps some learned lessons even. 
&lt;/p&gt;
&lt;p style=&quot;margin-bottom: 0&quot;&gt;
And also, I have questions about business insurance: what type of insurance should I opt for? Is there really an umbrella insurance out there? Or does each (or many) clients out there dictate the insurance you need? &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, a lot has changed in the last six years. The economy has improved and health care costs have risen. Through this time, I&apos;ve been able to continue to operate as an independent software developer and keep the contracts flowing. Personally, the biggest changes in my life have been outside of work. I &lt;a href=&quot;http://raibledesigns.com/rd/entry/an_epic_weekend_in_estes&quot;&gt;met an exceptional woman&lt;/a&gt;, traveled to &lt;a href=&quot;http://raibledesigns.com/rd/entry/an_awesome_trip_to_amsterdam&quot;&gt;conferences&lt;/a&gt; all &lt;a href=&quot;http://raibledesigns.com/rd/entry/a_fun_week_in_florida&quot;&gt;around&lt;/a&gt; &lt;a href=&quot;http://raibledesigns.com/rd/entry/two_opening_days_with_a&quot;&gt;the&lt;/a&gt; &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_france_a_great_conference&quot;&gt;world&lt;/a&gt; with her, got &lt;a href=&quot;http://raibledesigns.com/rd/entry/matrimony_in_montana&quot;&gt;married&lt;/a&gt;, &lt;a href=&quot;http://raibledesigns.com/rd/entry/around_the_world_honeymoon_1st&quot;&gt;traveled&lt;/a&gt; some more, then bought a &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_syncro_rescue_road_trip&quot;&gt;VW Westfalia&lt;/a&gt; so we could have &lt;a href=&quot;http://raibledesigns.com/rd/entry/farewell_to_the_2013_2014&quot;&gt;lots of fun&lt;/a&gt; &lt;a href=&quot;http://raibledesigns.com/rd/entry/syncro_solstice_2014&quot;&gt;traveling&lt;/a&gt; in our own &lt;a href=&quot;http://raibledesigns.com/rd/entry/rafting_the_yampa_through_dinosaur&quot;&gt;backyard&lt;/a&gt;. All the while, I&apos;ve worked for some great clients. I &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_s_the_ol_team&quot;&gt;built a team of hot shots&lt;/a&gt; at Time Warner Cable (many of them still work there), I skied the &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_greatest_snow_on_earth&quot;&gt;awesome powder of Utah&lt;/a&gt; while working at Overstock and I enjoyed a long-term contract at Oracle. After Oracle, I got into the healthcare industry and I&apos;ve been working in it ever since. &lt;/p&gt;
&lt;p&gt;In fact, I just finished working for a healthcare company last week and I&apos;m on the hunt for my next gig in April. Check out &lt;a href=&quot;https://www.linkedin.com/in/mraible&quot;&gt;my LinkedIn profile&lt;/a&gt; if you&apos;d like to see my r&#233;sum&#233;.&lt;/p&gt;
&lt;p&gt;I&apos;ve learned quite a few lessons over the last several years. As an independent developer, the biggest thing I&apos;ve learned is &lt;em&gt;marketing is key&lt;/em&gt;. I&apos;ve always known this, but I&apos;ve been reminded of its importance a few times. When I worked at Taleo (after Overstock), I was on a 3-month contract that turned into a 9-month contract that got a 1-year extension when Oracle bought them. The work was challenging, but the application was outdated. Getting them to adopt new technologies like Bootstrap and AngularJS was difficult. When Oracle took over, they offered me a 1-year contract at a great rate. I accepted, never thinking it would be difficult to get paid from someone like Oracle. It took them over &lt;em&gt;three months&lt;/em&gt; to pay my first invoice and it took me another three months to get payments flowing regularly. I felt like I was trapped. I felt like I could quit, but that wouldn&apos;t speed up the process of getting my invoices paid. From this experience, I&apos;m hesitant to start with any contract that&apos;s longer than three months.&lt;/p&gt;
&lt;p&gt;During my time at Oracle, I didn&apos;t blog as much as I had previously (because the day-to-day work wasn&apos;t that exciting), but I did still speak at conferences. Last year, I took the year off from speaking at conferences altogether. Speaking is an excellent marketing tool. Because of my lack of speaking, I saw a downturn in contract opportunities in Q4 last year.&lt;/p&gt;
&lt;p&gt;As far as health insurance is concerned, I continued to have a disaster prevention plan, with a $5K per year deductible. I paid around $300/month for this, and rarely used it. By riding my bike to my office in downtown Denver, and skiing a bunch in the winter, I felt like I was pretty healthy. After I &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_21_day_sugar_detox&quot;&gt;stopped eating sugar&lt;/a&gt; last fall, I became much healthier. So much healthier that I&apos;ve stopped taking high blood pressure medication. Today, I don&apos;t pay for health insurance. Trish went back to IT Security Sales in November and she was able to get me on her company&apos;s plan for $100 cheaper than what I was paying. I didn&apos;t have dental insurance for the last five years and I did have to shell out $5K for a tooth implant at one point.&lt;/p&gt;
&lt;p&gt;For business insurance, I have the &lt;a href=&quot;http://www.thehartford.com/business-owner-policy/&quot;&gt;Business Owner&apos;s Policy&lt;/a&gt; from The Hartford. I pay around $600/year and I&apos;ve gotten that back when I&apos;ve had laptops stolen or accidentally killed my iPhone. I&apos;ve got automated backups going all the time, so I haven&apos;t lost any data in several years. This insurance policy and its liability coverage has been &quot;good enough&quot; for all my clients, including the big ones.&lt;/p&gt;
&lt;p&gt;I think the biggest lesson I&apos;ve learned in the last several years is that the best way to be rich is to be rich in &lt;em&gt;time&lt;/em&gt;. I&apos;ve always dreamed of making $500/hour and working 20 hours per week. While $500/hour sounds crazy, you know there&apos;s consultants out there that are making that kinda cash. They&apos;re probably not in software, maybe they&apos;re political consultants, or former professional athletes, but those consulting rates do exist. In software, there&apos;s certainly companies that bill those kinda rates. My rates for the last several years haven&apos;t been &lt;em&gt;that&lt;/em&gt; good, but they&apos;ve been pretty awesome. 
&lt;/p&gt;
&lt;p&gt;
Earlier this year, I had the opportunity to work 20 hours per week instead of 40. It was one of the greatest work-life experiences I&apos;ve had to date. I was still able to pay all my bills, and I had time during each-and-every-day to do something fun. When working 40 hours per week, exercising and cooking dinner were somewhat of a chore. When I flipped to working less, work became the chore and exercise and cooking became the fun parts of my day. I read somewhere recently that if Americans valued &lt;em&gt;health over wealth&lt;/em&gt;, we&apos;d be a lot better off. I felt like I did this when working less and that I was &lt;em&gt;rich in time&lt;/em&gt;. 
&lt;/p&gt;
&lt;p&gt;Related to feeling better over making more, I&apos;ve started to target employment opportunities that offer a good team to work with. For the last year, most of my contracts have been with remote clients, where they haven&apos;t required me to travel onsite. While this sounds great in theory, I do miss the comradery that exists when working with a team. Working with someone over a Skype/HipChat call is nothing like sitting next to each other and cracking jokes while writing code. Don&apos;t get me wrong, I love remote work, but I do think it&apos;s important to be onsite and collaborating face-to-face at least once per month.&lt;/p&gt;
&lt;p&gt;To those individuals looking to start their own Solopreneurship, I hope this advice helps. It&apos;s been a great experience for me.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_3_5_released</id>
        <title type="html">AppFuse 3.5 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_3_5_released"/>
        <published>2015-02-20T09:08:53-07:00</published>
        <updated>2015-02-20T17:24:22-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;
&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;http://static.appfuse.org/images/appfuse-icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the release of AppFuse 3.5. This release contains a number of improvements.&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;XML reduced by 8x in projects generated with AppFuse&lt;/li&gt;&lt;li&gt;CRUD generation&amp;nbsp;support for Wicket, as well as AppFuse Light archetypes (Spring Security, Spring FreeMarker and Stripes)&lt;/li&gt;&lt;li&gt;Upgraded Tapestry to 5.4&lt;/li&gt;&lt;li&gt;Integrated&amp;nbsp;Spring IO Platform for dependency management&lt;/li&gt;&lt;li&gt;Refactored unit tests to use JUnit 4&lt;/li&gt;&lt;li&gt;Renamed maven-warpath-plugin to warpath-maven-plugin&lt;/li&gt;&lt;li&gt;Upgraded to jWebUnit 3 for AppFuse Light integration tests&lt;/li&gt;&lt;li&gt;Updated all AppFuse Light modules to be up-to-date&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;For more details on specific changes
    see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+3.5.0&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;alert alert-info&quot;&gt;&lt;strong&gt;What is AppFuse?&lt;/strong&gt;&lt;br&gt;
    AppFuse is a full-stack framework for building web applications on the JVM. It was
    originally developed to eliminate the ramp-up time when building new web applications. Over
    the years, it has matured into a very testable and secure system for creating Java-based
    webapps.
&lt;/p&gt;
&lt;p&gt;Demos for this release can be viewed at &lt;a href=&quot;http://demo.appfuse.org/&quot;&gt;http://demo.appfuse.org&lt;/a&gt;. Please see
    the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; style=&quot;font-weight: bold&quot;&gt;QuickStart Guide&lt;/a&gt; to
    get started with this release. &lt;/p&gt;

&lt;p&gt;If you have questions about AppFuse, please read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot;&gt;FAQ&lt;/a&gt; or join the
    &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;user mailing list&lt;/a&gt;. If you find any
    issues, please report them on the users mailing list. You can also post them to &lt;a href=&quot;http://stackoverflow.com/questions/tagged/appfuse&quot;&gt;Stack Overflow&lt;/a&gt; with the &quot;appfuse&quot; tag.&lt;/p&gt;

&lt;p&gt;Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing
    lists.&lt;/p&gt;

&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;We greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot;&gt;our
    sponsors&lt;/a&gt;, particularly &lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot;&gt;Atlassian&lt;/a&gt;,
    &lt;a href=&quot;http://contegix.com/&quot;&gt;Contegix&lt;/a&gt;, and &lt;a href=&quot;http://www.jetbrains.com/&quot;&gt;JetBrains&lt;/a&gt;.
    Atlassian and Contegix are especially awesome:
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_now_powered_by_contegix&quot;&gt;Atlassian has donated licenses to all
        its products and Contegix has donated an entire server&lt;/a&gt; to the AppFuse project. &lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/2014_a_year_in_review</id>
        <title type="html">2014 - A Year in Review</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/2014_a_year_in_review"/>
        <published>2015-01-31T09:37:43-07:00</published>
        <updated>2015-02-02T12:13:34-07:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yearinreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="2014" scheme="http://roller.apache.org/ns/tags/" />
        <category term="blogging" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
    2014 was destined to be a spectacular year. When I &lt;a
    href=&quot;//raibledesigns.com/rd/entry/2013_a_year_in_review&quot;&gt;wrote my thoughts down last
    January&lt;/a&gt;, I thought the Broncos would win the Super Bowl and my &lt;a href=&quot;//raibledesigns.com/rd/category/The+Bus&quot;&gt;VW Bus restoration project&lt;/a&gt; would be finished by summer.
    To focus on finishing the bus project, I didn&apos;t submit any talks to conferences.
    Instead of traveling to exotic locations, we opted to visit a bunch in our own backyard instead.
&lt;/p&gt;
I should&apos;ve known it&apos;d be an interesting year when the Broncos flopped in the Super Bowl.
&lt;p&gt;For this &lt;a href=&quot;//raibledesigns.com/rd/tags/yearinreview&quot;&gt;Year in Review&lt;/a&gt; post, I&apos;ll use the format I&apos;ve used
    the last couple of years.
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#2015&quot;&gt;2015&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;I had three different clients throughout the year, all in the health care industry. I continued working on a project
    with &lt;a href=&quot;http://www.johnmuirhealth.com/&quot;&gt;John
        Muir Health&lt;/a&gt; where we developed a hybrid mobile app. I wrote about what I learned in
    &lt;a href=&quot;//raibledesigns.com/rd/entry/documenting_your_spring_api_with&quot;&gt;Documenting your Spring API with Swagger&lt;/a&gt;
    and &lt;a href=&quot;//raibledesigns.com/rd/entry/developing_an_ios_native_app&quot;&gt;Developing an iOS Native App with Ionic&lt;/a&gt;.
    Since I wrote the article about &lt;a href=&quot;https://github.com/martypitt/swagger-springmvc&quot;&gt;Swagger&apos;s Spring MVC&lt;/a&gt;
    support,
    it has become much easier to integrate; now it only requires an &lt;code&gt;@EnableSwagger&lt;/code&gt; annotation.
&lt;/p&gt;
&lt;p&gt;
    In April, I started consulting with a small company in Alabama. I helped them modernize their tech stack and
    implemented a number of web services with
    &lt;a href=&quot;http://camel.apache.org&quot;&gt;Apache Camel&lt;/a&gt;. I wrote about this in a four-part series in September and
    October.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;
    2014 was destined to be a spectacular year. When I &lt;a
    href=&quot;//raibledesigns.com/rd/entry/2013_a_year_in_review&quot;&gt;wrote my thoughts down last
    January&lt;/a&gt;, I thought the Broncos would win the Super Bowl and my &lt;a href=&quot;//raibledesigns.com/rd/category/The+Bus&quot;&gt;VW Bus restoration project&lt;/a&gt; would be finished by summer.
    To focus on finishing the bus project, I didn&apos;t submit any talks to conferences.
    Instead of traveling to exotic locations, we opted to visit a bunch in our own backyard instead.
&lt;/p&gt;
I should&apos;ve known it&apos;d be an interesting year when the Broncos flopped in the Super Bowl.
&lt;p&gt;For this &lt;a href=&quot;//raibledesigns.com/rd/tags/yearinreview&quot;&gt;Year in Review&lt;/a&gt; post, I&apos;ll use the format I&apos;ve used
    the last couple of years.
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#devoxx4kids&quot;&gt;Devoxx4Kids&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/2014_a_year_in_review#2015&quot;&gt;2015&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;I had three different clients throughout the year, all in the health care industry. I continued working on a project
    with &lt;a href=&quot;http://www.johnmuirhealth.com/&quot;&gt;John
        Muir Health&lt;/a&gt; where we developed a hybrid mobile app. I wrote about what I learned in
    &lt;a href=&quot;//raibledesigns.com/rd/entry/documenting_your_spring_api_with&quot;&gt;Documenting your Spring API with Swagger&lt;/a&gt;
    and &lt;a href=&quot;//raibledesigns.com/rd/entry/developing_an_ios_native_app&quot;&gt;Developing an iOS Native App with Ionic&lt;/a&gt;.
    Since I wrote the article about &lt;a href=&quot;https://github.com/martypitt/swagger-springmvc&quot;&gt;Swagger&apos;s Spring MVC&lt;/a&gt;
    support,
    it has become much easier to integrate; now it only requires an &lt;code&gt;@EnableSwagger&lt;/code&gt; annotation.
&lt;/p&gt;
&lt;p&gt;
    In April, I started consulting with a small company in Alabama. I helped them modernize their tech stack and
    implemented a number of web services with
    &lt;a href=&quot;http://camel.apache.org&quot;&gt;Apache Camel&lt;/a&gt;. I wrote about this in a four-part series in September and
    October.&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/developing_services_with_apache_camel&quot;&gt;Developing Services with Apache
        Camel - Part I: The Inspiration&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/developing_services_with_apache_camel1&quot;&gt;Developing Services with Apache
        Camel - Part II: Creating and Testing Routes&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/developing_services_with_apache_camel2&quot;&gt;Developing Services with Apache
        Camel - Part III: Integrating Spring 4 and Spring Boot&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;//raibledesigns.com/rd/entry/developing_services_with_apache_camel3&quot;&gt;Developing Services with Apache
        Camel - Part IV: Load Testing and Monitoring&lt;/a&gt;&lt;/li&gt;

&lt;/ol&gt;
&lt;p&gt;
    I continued leveraging Spring Boot in my client projects and wrote about
    &lt;a href=&quot;//raibledesigns.com/rd/entry/building_a_rest_api_with&quot;&gt;Building a REST API with JAXB, Spring Boot and
        Spring Data&lt;/a&gt; at the end of that engagement.
&lt;/p&gt;
&lt;p&gt;
    In November, I had time off between clients. I visited my parents and their awesome retirement home in
    Montana. I also took some time to refactor AppFuse to be a bit leaner and meaner. I signed up with a new health care
    client in December. It&apos;s been an enjoyable experience so far, especially since I&apos;m only working
    20 hours per week this quarter.
&lt;/p&gt;
&lt;p&gt;I&apos;m currently booked with clients through the end of March, but hoping to find one with a challenging project in
    April.&lt;/p&gt;
&lt;h3 id=&quot;speaking&quot;&gt;Speaking&lt;/h3&gt;
&lt;p&gt;
    To optimize cash flow towards the bus project, I didn&apos;t submit any talks to conferences in 2014. However, I did
    talk about &lt;a href=&quot;//raibledesigns.com/rd/entry/comparing_jvm_web_frameworks_at&quot;&gt;Comparing JVM Web
    Frameworks&lt;/a&gt;
    at the &lt;a href=&quot;http://www.meetup.com/DOSUG1/events/155080452/&quot;&gt;Denver Open Source Users Group&lt;/a&gt; and
    &lt;a href=&quot;http://www.meetup.com/virtualJUG/events/153096902/&quot;&gt;vJUG&lt;/a&gt; in February. I also spoke at local user groups
    (DeRailed and HTML5 Users)
    about &lt;a href=&quot;//raibledesigns.com/rd/entry/the_art_of_angularjs&quot;&gt;The Art of AngularJS&lt;/a&gt; in the first part of
    the year.
    In the fall, I participated in panels on unit testing at &lt;a href=&quot;http://www.denverstartupweek.org&quot;&gt;Denver Startup
    Week&lt;/a&gt; and
    &lt;a href=&quot;https://www.airpair.com/airconf2014/keynote/developer-writing-tips-and-tricks&quot;&gt;building a personal
        brand&lt;/a&gt;
    at &lt;a href=&quot;https://www.airpair.com/airconf2014/&quot;&gt;AirConf&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;I hope to attend and speak at more conferences in 2015. To help facilitate this, I&apos;ve &lt;a
    href=&quot;https://gist.github.com/mraible/3754940a56ecfe560b17&quot;&gt;published a list of talks&lt;/a&gt; I&apos;d like to present.&lt;/p&gt;
&lt;h4 id=&quot;devoxx4kids&quot;&gt;Devoxx4Kids Denver&lt;/h4&gt;
&lt;p&gt;2014 was the inaugural year for &lt;a href=&quot;http://www.meetup.com/Devoxx4Kids-Denver/&quot;&gt;Devoxx4Kids Denver&lt;/a&gt;. In April,
    I &lt;a href=&quot;//raibledesigns.com/rd/entry/devoxx4kids_denver_chapter_begins&quot;&gt;announced our first meetup&lt;/a&gt;. It
    was an
    &lt;a href=&quot;http://www.meetup.com/Devoxx4Kids-Denver/events/172037212/&quot;&gt;Introduction to Server-Side Minecraft
        Programming&lt;/a&gt;,
    taught by Denver&apos;s own &lt;a href=&quot;http://thirstyhead.com&quot;&gt;Scott Davis&lt;/a&gt;. It was a &lt;a
        href=&quot;//raibledesigns.com/rd/entry/first_devoxx4kids_in_denver_a&quot;&gt;
        wild success&lt;/a&gt; and the kids had a great time hacking.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm8.staticflickr.com/7342/13930299459_a81657c6b4_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/13930299459&quot;
       title=&quot;Devoxx4Kids Denver by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7342/13930299459_a81657c6b4_q.jpg&quot; width=&quot;150&quot; alt=&quot;Devoxx4Kids Denver&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;//farm3.staticflickr.com/2908/14137000853_14f916473f_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14137000853&quot;
       title=&quot;Devoxx4Kids Denver by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm3.staticflickr.com/2908/14137000853_14f916473f_q.jpg&quot; width=&quot;150&quot; alt=&quot;Devoxx4Kids Denver&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;//farm8.staticflickr.com/7192/13930311930_cc968f16d7_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/13930311930&quot;
       title=&quot;Devoxx4Kids Denver by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7192/13930311930_cc968f16d7_q.jpg&quot; width=&quot;150&quot; alt=&quot;Devoxx4Kids Denver&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm8.staticflickr.com/7201/13930237257_acff755c13_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/13930237257&quot;
       title=&quot;Scott Davis by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7201/13930237257_acff755c13_m.jpg&quot; width=&quot;240&quot; alt=&quot;Scott Davis&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;//farm8.staticflickr.com/7338/14116881615_c61ce047dd_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14116881615&quot;
       title=&quot;Thanks for the great room Thrive! by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7338/14116881615_c61ce047dd_m.jpg&quot; width=&quot;240&quot;
        alt=&quot;Thanks for the great room Thrive!&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I didn&apos;t plan any events during the summer, but we held a couple workshops in the fall: one on &lt;a
    href=&quot;http://www.meetup.com/Devoxx4Kids-Denver/events/216557092/&quot;&gt;littleBits&lt;/a&gt; and a second on &lt;a
    href=&quot;http://www.meetup.com/Devoxx4Kids-Denver/events/219019619/&quot;&gt;Greenfoot&lt;/a&gt;.
    The kids had &lt;a href=&quot;//raibledesigns.com/rd/entry/devoxx4kids_denver_having_fun_with&quot;&gt;a lot of fun with
        littleBits&lt;/a&gt; thanks to &lt;a href=&quot;https://twitter.com/juansanchez&quot;&gt;Juan Sanchez&lt;/a&gt; of &lt;a
        href=&quot;https://twitter.com/tackmobile&quot;&gt;Tack Mobile&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a href=&quot;https://farm8.staticflickr.com/7502/15713320297_7e878f557d_c.jpg&quot;
       title=&quot;Juan in Action by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/15713320297&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7502/15713320297_7e878f557d.jpg&quot; width=&quot;500&quot; alt=&quot;Juan in Action&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Unfortunately, I wasn&apos;t able to attend the Greenfoot workshop with &lt;a href=&quot;https://twitter.com/thesteve0&quot;&gt;Steve
    Pousty&lt;/a&gt;, but I heard it was awesome. Thanks again to &lt;a href=&quot;https://twitter.com/mojavelinux&quot;&gt;Dan Allen&lt;/a&gt; for
    assisting with this class.&lt;/p&gt;
&lt;p&gt;I haven&apos;t scheduled any Devoxx4Kids Denver meetups for 2015 yet. If you&apos;re interested in speaking, please let me
    know!&lt;/p&gt;
&lt;h3 id=&quot;projects&quot;&gt;Projects&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;AppFuse:&lt;/strong&gt; I didn&apos;t have many posts about AppFuse in 2014, but I did work on it from time to time.
    Upgrading its dependencies was a good way to stay up-to-date with open source frameworks, in addition to
    &lt;a href=&quot;//raibledesigns.com/rd/entry/how_do_you_stay_current&quot;&gt;lots of reading&lt;/a&gt;.
    &lt;a href=&quot;http://www.infoq.com/news/2014/01/appfuse-3.0-java7-spring-4&quot;&gt;InfoQ covered the AppFuse 3.0 release&lt;/a&gt;
    and I &lt;a href=&quot;http://www.infoq.com/author/Matt-Raible&quot;&gt;continue to write for them&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
    In December, I &lt;a href=&quot;//raibledesigns.com/rd/entry/appfuse_reduced&quot;&gt;removed 10,000 lines of XML&lt;/a&gt; from the
    project without affecting any functionality. In the past month, I&apos;ve &lt;a
    href=&quot;https://github.com/appfuse/appfuse/pull/22&quot;&gt;added support for generating CRUD&lt;/a&gt; for all
    its web frameworks (including AppFuse Light&apos;s). This includes Spring + FreeMarker, Stripes and Wicket. GWT support
    is still in progress. I hope to do a release soon; there&apos;s only &lt;a
    href=&quot;http://issues.appfuse.org/issues/?filter=10290&quot;&gt;10 issues left&lt;/a&gt; as of this writing.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Roller:&lt;/strong&gt; I didn&apos;t contribute any code to &lt;a href=&quot;http://roller.apache.org&quot;&gt;Apache Roller&lt;/a&gt; in
    2014, but I
    &lt;a href=&quot;//raibledesigns.com/rd/entry/this_site_now_powered_by&quot;&gt;upgraded this site to the latest release,
        upgraded to Java 8 + Tomcat 7, and integrated Wufoo Forms&lt;/a&gt;.
    I hope to make some scalability improvements to how I&apos;ve deployed Roller in the near future.&lt;/p&gt;

&lt;h2 id=&quot;personal&quot;&gt;Personal&lt;/h2&gt;
&lt;p&gt;I started off the year with a trip of a lifetime: &lt;a
    href=&quot;//raibledesigns.com/rd/entry/heli_skiing_in_british_columbia&quot;&gt;Heli Skiing in British Columbia with CMH
    Gothics&lt;/a&gt;. An excerpt from my blog post:
&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
    Everyday was awesome, but Wednesday was incredible. It snowed 10 cm on Tuesday night, which turned into knee-deep
    powder and face shots. The hoots and hollers from everyone floating down forced my face into a sorta perma-grin. For
    many of us, it was the best skiing day of our entire lives. The video below tries to capture how much fun we had
    throughout the week, but ultimately fails. It&apos;s one of those things you have to experience to really appreciate. I
    ended up skiing around 80,000 vertical feet in four days.
&lt;/blockquote&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm8.staticflickr.com/7296/12079639335_d260827bdd_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/12079639335/&quot; title=&quot;Yee Haw! by mraible, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7296/12079639335_d260827bdd_m.jpg&quot; width=&quot;240&quot;
                                    alt=&quot;Yee Haw!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;http://farm3.staticflickr.com/2853/12079930503_7b5271e6f1_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/12079930503/&quot; title=&quot;Group Photo by mraible, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm3.staticflickr.com/2853/12079930503_7b5271e6f1_m.jpg&quot; width=&quot;240&quot;
                                    alt=&quot;Group Photo&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm4.staticflickr.com/3829/12438946834_b13c351fc2_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/12438946834/&quot; title=&quot;Freshies by mraible, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3829/12438946834_b13c351fc2.jpg&quot; width=&quot;500&quot;
                                    alt=&quot;Freshies&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;iframe src=&quot;//player.vimeo.com/video/86139573&quot; width=&quot;500&quot; height=&quot;281&quot; frameborder=&quot;0&quot; webkitallowfullscreen=&quot;&quot;
            mozallowfullscreen=&quot;&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;
    After returning from British Columbia, Trish and I skied Breckenridge and Copper before taking the kids to Aspen for
    three feet of powder on Super Bowl weekend.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm8.staticflickr.com/7449/13966477190_b401b0450b_c.jpg&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/13966477190&quot; title=&quot;Copper! by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7449/13966477190_b401b0450b.jpg&quot; width=&quot;500&quot; alt=&quot;Copper!&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm8.staticflickr.com/7352/14153277974_751d0a62c4_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/14153277974&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       title=&quot;Happy Kids by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7352/14153277974_751d0a62c4_m.jpg&quot; width=&quot;240&quot; alt=&quot;Happy Kids&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;//farm8.staticflickr.com/7450/14153278784_fe50b717d8_c.jpg&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/14153278784&quot; title=&quot;Happy Trish by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7450/14153278784_fe50b717d8_m.jpg&quot; width=&quot;240&quot; alt=&quot;Happy Trish&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We skied all over Colorado in February and March. We even did some winter camping in the Syncro for Valentine&apos;s Day.
    It snowed a lot that night.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;//farm8.staticflickr.com/7295/13966464277_d75d38efda_c.jpg&quot;
                                 data-href=&quot;https://www.flickr.com/photos/mraible/13966464277&quot;
                                 rel=&quot;lightbox[2014yearinreview]&quot;
                                 title=&quot;Yikes! by Matt Raible, on Flickr&quot;&gt;&lt;img
    src=&quot;//farm8.staticflickr.com/7295/13966464277_d75d38efda.jpg&quot;
    width=&quot;500&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Yikes!&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I wrote about all our skiing adventures in &lt;a href=&quot;//raibledesigns.com/rd/entry/farewell_to_the_2013_2014&quot;&gt;Farewell
    to the 2013-2014 Ski Season&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;On April 10th, I reminisced that &lt;a href=&quot;//raibledesigns.com/rd/entry/10_years_ago_today_i&quot;&gt;10 years ago today,
    I bought a VW Bus&lt;/a&gt;. In that post,
    I explained some body-work quality issues the current restoration shop found. Nevertheless, I still thought it would
    be done in &lt;em&gt;just a few more months&lt;/em&gt;.
&lt;/p&gt;
&lt;p&gt;
    We journeyed to Florida with Abbie and Jack for Spring Break. We relished in a super-fun family vacation where we
    golfed, swam and even spent a day frolicking with their Mom and
    fianc&#233; (now husband), Dave. We&apos;re pretty proud that we&apos;re all still a family even though Julie and I are divorced. I
    wrote about our vacation in
    &lt;a href=&quot;//raibledesigns.com/rd/entry/spring_break_in_florida_golf&quot;&gt;Spring Break in Florida: Golf, Beaches and
        Boats!&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm3.staticflickr.com/2871/13630302365_cdd438a1da_c.jpg&quot;
       data-href=&quot;//www.flickr.com/photos/mcginityphoto/13630302365&quot; title=&quot;Family photo by Trish McGinity, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm3.staticflickr.com/2871/13630302365_cdd438a1da_m.jpg&quot; width=&quot;240&quot;
                                            alt=&quot;Family photo&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;//farm4.staticflickr.com/3770/13630730864_66e90d2dcc_c.jpg&quot;
       data-href=&quot;//www.flickr.com/photos/mcginityphoto/13630730864&quot; title=&quot;Family photo by Trish McGinity, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3770/13630730864_66e90d2dcc_m.jpg&quot; width=&quot;240&quot;
                                            alt=&quot;Family photo&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm8.staticflickr.com/7138/13630479433_2220968cfb_c.jpg&quot;
       data-href=&quot;//www.flickr.com/photos/mcginityphoto/13630479433&quot;
       title=&quot;Abbie and Jack playing at the beach by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm8.staticflickr.com/7138/13630479433_2220968cfb.jpg&quot; width=&quot;500&quot;
        alt=&quot;Abbie and Jack playing at the beach&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm8.staticflickr.com/7174/13695119114_2fbccbaa98_c.jpg&quot;
       data-href=&quot;//www.flickr.com/photos/mraible/13695119114&quot; title=&quot;Family Fun Day by Matt Raible, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7174/13695119114_2fbccbaa98.jpg&quot; width=&quot;500&quot;
                                            alt=&quot;Family Fun Day&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;//farm8.staticflickr.com/7152/13694777145_1fac338f01_c.jpg&quot; data-href=&quot;//www.flickr.com/photos/mraible/13694777145&quot; title=&quot;Happy Tuesday! by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7152/13694777145_1fac338f01.jpg&quot; width=&quot;500&quot; alt=&quot;Happy Tuesday!&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;The hospitality from Trish&apos;s parents was like no other. I especially enjoyed a fishing trip with her Dad Joe in the
    Everglades. I love these people!&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm8.staticflickr.com/7046/13694837593_58d9e6b107_c.jpg&quot;
       data-href=&quot;//www.flickr.com/photos/mraible/13694837593&quot; title=&quot;Good lookin&apos; McGinity&apos;s by Matt Raible, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7046/13694837593_58d9e6b107.jpg&quot; width=&quot;500&quot;
                                            alt=&quot;Good lookin&apos; McGinity&apos;s&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Our winter activities in the Syncro were incredible. Trish sold her Nissan Xterra (the one with the &lt;a
    href=&quot;//raibledesigns.com/rd/entry/music_mountain_biking_and_memories&quot;&gt;sick bass&lt;/a&gt;) in December.
    Yes, that&apos;s right - we only had one vehicle during ski season last year. The fact that it worked so well
    is amazing. In May, we kicked it up a knotch and drove it to Moab for
    &lt;a href=&quot;//raibledesigns.com/rd/entry/syncro_solstice_2014&quot;&gt;Syncro Solstice&lt;/a&gt;. My parents went with us
    and we experienced fabulous weather and met a bunch of super-cool Vanagon owners.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm6.staticflickr.com/5078/14224287244_6265231910_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/14224287244&quot;
       title=&quot;National Park Lovers by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm6.staticflickr.com/5078/14224287244_6265231910_m.jpg&quot; width=&quot;240&quot; alt=&quot;National Park Lovers&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;//farm3.staticflickr.com/2898/14224288314_88efc37ddc_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/14224288314&quot; title=&quot;Arches Lover by Matt Raible, on Flickr&quot;
       rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm3.staticflickr.com/2898/14224288314_88efc37ddc_m.jpg&quot;
                                               width=&quot;240&quot; alt=&quot;Arches Lover&quot;
                                               style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm6.staticflickr.com/5554/14217096892_99a2cd5868_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14217096892&quot;
       title=&quot;Moab Sunset by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm6.staticflickr.com/5554/14217096892_99a2cd5868.jpg&quot; width=&quot;500&quot; alt=&quot;Moab Sunset&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We made record time from Moab back to Denver (5 hours). The next day is when things started to go downhill. I washed
    the engine for the &lt;a href=&quot;http://www.vwgreenshow.com/&quot;&gt;VWs on the Green&lt;/a&gt; show. On that Monday, the engine started
    &quot;lurching&quot; where it seemed like it wasn&apos;t getting gas (it turned out to be caused by a lack of air). We drove the lurcher for several weeks, journeying to &lt;a href=&quot;http://campoutforthecause.org/&quot;&gt;Campout for
        the Cause&lt;/a&gt; and
    a &lt;a href=&quot;//raibledesigns.com/rd/entry/rafting_the_yampa_through_dinosaur&quot;&gt;exhilarating raft trip down the Yampa River&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm3.staticflickr.com/2933/14390991814_5f505549d1_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14390991814&quot;
       title=&quot;80&apos;s Party Group! by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm3.staticflickr.com/2933/14390991814_5f505549d1.jpg&quot; width=&quot;500&quot; style=&quot;border: 1px solid black&quot;
        alt=&quot;80&apos;s Party Group!&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm3.staticflickr.com/2896/14390758792_9d6270b5ee_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14390758792&quot;
       title=&quot;2014 DNM Raft Sunset by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm3.staticflickr.com/2896/14390758792_9d6270b5ee.jpg&quot; width=&quot;500&quot; style=&quot;border: 1px solid black&quot;
        alt=&quot;2014 DNM Raft Sunset&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    We had the lurching examined in mid-June by &lt;a href=&quot;http://www.rockymountainwesty.com/&quot;&gt;Rocky Mountain Westy&lt;/a&gt;; we also had them install some
    bumpers (for a better trailer hitch) and refreshed the tires. &lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm4.staticflickr.com/3863/14455716405_3e62021f4f_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/14455716405&quot;
       title=&quot;She cleans up real nice! by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm4.staticflickr.com/3863/14455716405_3e62021f4f.jpg&quot; width=&quot;500&quot; alt=&quot;She cleans up real nice!&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;The ol&apos; van looked pretty good when our Dads arrived in Denver for &lt;a
    href=&quot;//raibledesigns.com/rd/entry/father_s_day_weekend_on1&quot;&gt;some whitewater on the Arkansas&lt;/a&gt;.

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm4.staticflickr.com/3846/14269111618_d3edcef091_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14269111618&quot;
       title=&quot;Abbie doesn&apos;t approve of Jack&apos;s ponytail by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm4.staticflickr.com/3846/14269111618_d3edcef091_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;Abbie doesn&apos;t approve of Jack&apos;s ponytail&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;//farm3.staticflickr.com/2904/14269108790_a028704fd5_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14269108790&quot;
       title=&quot;Here we go on the Arkansas River! by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm3.staticflickr.com/2904/14269108790_a028704fd5_q.jpg&quot; width=&quot;150&quot;
        alt=&quot;Here we go on the Arkansas River!&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;//farm4.staticflickr.com/3917/14269273977_5a9c0e24b7_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14269273977&quot;
       title=&quot;Kids having a blast :) by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm4.staticflickr.com/3917/14269273977_5a9c0e24b7_q.jpg&quot; width=&quot;150&quot; alt=&quot;Kids having a blast :)&quot;
        style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm4.staticflickr.com/3880/14475890743_dd49939dd1_c.jpg&quot; data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14475890743&quot; title=&quot;Dads Rule! by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3880/14475890743_dd49939dd1.jpg&quot; width=&quot;500&quot; alt=&quot;Dads Rule!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;In July, we skipped the annual road trip to The Cabin in favor of a &lt;a
    href=&quot;//raibledesigns.com/rd/entry/the_scenic_way_to_santa&quot;&gt;romantic road trip to see old friends in Santa Fe&lt;/a&gt;.
    The Syncro&apos;s engine seized on that trip and I experienced my favorite breakdown ever. The engine froze at a gas
    station near our Ski Shack and I was able to walk home. Luckily, Trish&apos;s Dad had recently (over Father&apos;s Day
    weekend) gifted his Nissan Maxima to us. After a train ride to fetch our other car, our road trip continued and we celebrated our
    first anniversary at &lt;a href=&quot;http://www.broadmoor.com/&quot;&gt;The Broadmoor&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm3.staticflickr.com/2919/14731242511_21c3bfb306_c.jpg&quot;
       title=&quot;Let me count the ways I love my husband! by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14731242511&quot;&gt;&lt;img
        src=&quot;https://farm3.staticflickr.com/2919/14731242511_21c3bfb306_m.jpg&quot;
        alt=&quot;Let me count the ways I love my husband!&quot; height=&quot;213&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm4.staticflickr.com/3836/14734139772_a1a4587d6e_c.jpg&quot;
       title=&quot;The Broadmoor Reflection by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14734139772&quot;&gt;&lt;img
        src=&quot;https://farm4.staticflickr.com/3836/14734139772_a1a4587d6e_n.jpg&quot; alt=&quot;The Broadmoor Reflection&quot;
        width=&quot;320&quot; style=&quot;border: 1px solid black; margin-left: 20px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm3.staticflickr.com/2909/14734449205_cf43a022fb_c.jpg&quot;
       title=&quot;Broadmoor Pools Sunset by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/14734449205&quot;&gt;&lt;img
        src=&quot;https://farm3.staticflickr.com/2909/14734449205_cf43a022fb.jpg&quot; width=&quot;500&quot; alt=&quot;Broadmoor Pools Sunset&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;After we returned from Santa Fe, I turned 40 years old. We rocked out a Journey concert to celebrate and Trish
    surprised me with a birthday visit from my kick-ass sister. The following evening, a bunch of friends took me
    on a Craft Brewery Tour in a school/prison bus. Both nights were epic.&lt;/p&gt;
&lt;p&gt;At the end of July, Trish had one of her favorite photos &lt;a
    href=&quot;//raibledesigns.com/rd/entry/mcginity_photo_on_the_cover&quot;&gt;featured on the cover of Whisky Magazine&lt;/a&gt;.&lt;/p&gt;
&lt;div style=&quot;text-align: center&quot;&gt;
    &lt;div class=&quot;fb-post fb_iframe_widget&quot;
         data-href=&quot;https://www.facebook.com/McGinityPhoto/photos/a.850652041614866.1073741826.227903283889748/900521199961283/?type=1&quot;
         data-width=&quot;381&quot; fb-xfbml-state=&quot;rendered&quot;
         fb-iframe-plugin-query=&quot;app_id=226411374036019&amp;amp;href=https%3A%2F%2Fwww.facebook.com%2FMcGinityPhoto%2Fphotos%2Fa.850652041614866.1073741826.227903283889748%2F900521199961283%2F%3Ftype%3D1&amp;amp;locale=en_US&amp;amp;sdk=joey&amp;amp;width=381&quot;&gt;&lt;span
        style=&quot;vertical-align: bottom; width: 381px; height: 688px;&quot;&gt;
&lt;iframe name=&quot;f34c3266e8&quot; width=&quot;381px&quot; height=&quot;1000px&quot; frameborder=&quot;0&quot; allowtransparency=&quot;true&quot; scrolling=&quot;no&quot;
        title=&quot;fb:post Facebook Social Plugin&quot;
        src=&quot;https://www.facebook.com/plugins/post.php?app_id=226411374036019&amp;amp;channel=https%3A%2F%2Fs-static.ak.facebook.com%2Fconnect%2Fxd_arbiter%2FoDB-fAAStWy.js%3Fversion%3D41%23cb%3Df24185ec44%26domain%3Draibledesigns.com%26origin%3Dhttps%253A%252F%252Fraibledesigns.com%252Ff23d0f86c%26relation%3Dparent.parent&amp;amp;href=https%3A%2F%2Fwww.facebook.com%2FMcGinityPhoto%2Fphotos%2Fa.850652041614866.1073741826.227903283889748%2F900521199961283%2F%3Ftype%3D1&amp;amp;locale=en_US&amp;amp;sdk=joey&amp;amp;width=381&quot;
        style=&quot;border: none; visibility: visible; width: 381px; height: 688px;&quot; class=&quot;&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In August, we flew to Boston to celebrate Trish&apos;s Dad&apos;s 75th birthday. My parents joined us, we visited my Dad&apos;s
    family in New York and took the kids to the Big Apple. They loved the &lt;a
        href=&quot;https://www.facebook.com/photo.php?fbid=10152192418746712&amp;l=8ecc4d288d&quot;&gt;Statue of Liberty&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Abbie started middle school (6th grade) in mid-August and Jack started 4th grade. They looked great on their &lt;a
    href=&quot;//raibledesigns.com/rd/entry/the_first_day_of_school3&quot;&gt;first day of school&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-href=&quot;https://www.flickr.com/photos/mraible/14959942801&quot;
       href=&quot;https://farm6.staticflickr.com/5555/14959942801_f77e1b2539_c.jpg&quot;
       title=&quot;First Day of School 2014 by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;https://farm6.staticflickr.com/5555/14959942801_f77e1b2539.jpg&quot; width=&quot;313&quot; alt=&quot;First Day of School 2014&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We were pumped about our &lt;a href=&quot;https://www.flickr.com/photos/mraible/sets/72157646475691716/&quot;&gt;new engine&lt;/a&gt; in
    the Syncro when we left Denver for &lt;a href=&quot;//raibledesigns.com/rd/entry/rafting_the_green_river_through&quot;&gt;Rafting
        the Green River through Desolation Canyon&lt;/a&gt;. We celebrated Jack&apos;s 10th birthday on that trip and had a very
    memorable expedition with some really cool people.&lt;/p&gt;
&lt;p&gt;Trish&apos;s photo from our last night on the river makes me want do it all again.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm4.staticflickr.com/3874/15057533280_553792dd0b_c.jpg&quot;
       title=&quot;My favorite night shot by Trish McGinity, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mcginityphoto/15057533280&quot;&gt;&lt;img
        src=&quot;https://farm4.staticflickr.com/3874/15057533280_553792dd0b.jpg&quot; width=&quot;500&quot; alt=&quot;My favorite night shot&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;In October, I started considering health over wealth when we embarked on a &lt;a
    href=&quot;//raibledesigns.com/rd/entry/the_21_day_sugar_detox&quot;&gt;21-day Sugar Detox&lt;/a&gt;. I&apos;m proud to say that, as a
    result, I&apos;m off blood pressure medication and continue to lose weight and feel better. We&apos;re cooking at home more
    than ever, exercising daily and I&apos;ve lost almost 20 pounds in the process.&lt;/p&gt;
&lt;p&gt;Medallion, the horse that Trish and Abbie were leasing (and almost ready to buy) got sick with &lt;a
    href=&quot;http://en.wikipedia.org/wiki/Horse_colic&quot;&gt;colic&lt;/a&gt; on Friday, October 10. I remembered the day without
    looking at a calendar because Trish called me to tell me about his illness. She was out of town on a business trip and was
    absolutely distraught. She told me about the situation and asked me to visit Medallion while he endured extreme
    pain. I worked out of my van at the stables that day, checking on him every couple hours. They had to put him down
    that evening. Abbie took it pretty well when I told her a couple hours later, but there were heaps of tears later
    that night.&lt;/p&gt;
&lt;p&gt;Our little girl &lt;a href=&quot;//raibledesigns.com/rd/entry/happy_birthday_abbie8&quot;&gt;turned 12&lt;/a&gt; a few weeks later.
    The kids put on some dark costumes for Halloween.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;//farm6.staticflickr.com/5602/15102098834_11f2245aaf_c.jpg&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/15102098834&quot;
       title=&quot;Abbie and Jack - Halloween 2014 by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;&gt;&lt;img
        src=&quot;//farm6.staticflickr.com/5602/15102098834_11f2245aaf.jpg&quot; width=&quot;500&quot; alt=&quot;Abbie and Jack - Halloween 2014&quot;
        style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;A week later, I visited my parents in Montana. We played cribbage, ate scrumptious meals and trounced around the
    woods looking for bucks. I marveled at the &lt;a href=&quot;//raibledesigns.com/rd/entry/the_house&quot;&gt;beauty of my parents&apos;
        retirement home&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm8.staticflickr.com/7478/15796548721_d411c4540c_c.jpg&quot;
       title=&quot;The House by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/15796548721&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7478/15796548721_d411c4540c_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;The House&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm6.staticflickr.com/5613/15613589540_00b4e688cb_c.jpg&quot;
       title=&quot;Front Door by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/15613589540&quot;&gt;&lt;img
        src=&quot;https://farm6.staticflickr.com/5613/15613589540_00b4e688cb_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Front Door&quot;
        style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm8.staticflickr.com/7514/15798430545_eb55462d2a_c.jpg&quot;
       title=&quot;The Porch by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/15798430545&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7514/15798430545_eb55462d2a_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;The Porch&quot;
        style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm6.staticflickr.com/5613/15613591370_95ed96861b_c.jpg&quot;
       title=&quot;Sweet Railings by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/15613591370&quot;&gt;&lt;img
        src=&quot;https://farm6.staticflickr.com/5613/15613591370_95ed96861b_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot;
        alt=&quot;Sweet Railings&quot; style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I neglected to blog or tweet about my self-caused Syncro accidents in Q4 of 2014. Long story short: it&apos;s been getting
    body work done for quite some time (two accidents!) and I look forward to getting it back in tip-top-shape next
    week. Thank goodness for USAA insurance.&lt;/p&gt;
&lt;p&gt;The biggest event of the year happened just before Christmas: &lt;a
    href=&quot;//raibledesigns.com/rd/entry/the_bus_is_painted_holy&quot;&gt;THE BUS IS PAINTED!! HOLY CHRISTMAS PRESENT BATMAN!&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm8.staticflickr.com/7517/15887916088_ff0e2e5088_c.jpg&quot;
       title=&quot;JAMES VERHEY - WITH THE BEST CHRISTMAS PRESENT EVER! by Matt Raible, on Flickr&quot; rel=&quot;lightbox[2014yearinreview]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/15887916088&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7517/15887916088_ff0e2e5088.jpg&quot; width=&quot;500&quot;
        alt=&quot;JAMES VERHEY - WITH THE BEST CHRISTMAS PRESENT EVER!&quot; style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h2 id=&quot;2015&quot;&gt;2015&lt;/h2&gt;
&lt;p&gt;It&apos;s hard to believe that 2015 could possibly top 2014. I started the year heli-skiing and ended it with a painted
    bus. &lt;em&gt;However&lt;/em&gt;, the bus isn&apos;t done yet. Last year, I wrote:&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
    My goal for 2014 is singular: &lt;em&gt;finish The Bus.&lt;/em&gt;
&lt;/blockquote&gt;
&lt;p&gt;I continue that mission this year. I&apos;ve negotiated a deal with &lt;a href=&quot;http://www.reincarnationauto.com/&quot;&gt;ReinCARnation&lt;/a&gt;
    to have it done by April 1st. Yes, it seems strange that April Fools is the &lt;em&gt;finished bus&lt;/em&gt; delivery date.
    However, I&apos;m confident they&apos;ll make it happen. This could be the year I&apos;ve dreamed about since I was in high school.
    It was in 1991 that I first fantasized about putting a 911 engine in a VW Bus.
&lt;/p&gt;
&lt;p&gt;
    This year, I hope to be cruise around Colorado in two running VW Busses. From there, I plan to surround myself with the laughter of our children, the enthusiasm of our border collies and the warmness of Trish&apos;s love. It&apos;s gonna be a &lt;em&gt;really&lt;/em&gt; great year! &lt;img src=&quot;//raibledesigns.com/images/smileys/grin.gif&quot; class=&quot;smiley&quot; alt=&quot;:-D&quot; title=&quot;:-D&quot;&gt;
&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/integrating_node_js_ruby_and</id>
        <title type="html">Integrating Node.js, Ruby and Spring with Okta&apos;s SAML Support</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/integrating_node_js_ruby_and"/>
        <published>2015-01-08T11:43:47-07:00</published>
        <updated>2015-01-08T17:52:39-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="node.js" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ruby" scheme="http://roller.apache.org/ns/tags/" />
        <category term="okta" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jruby" scheme="http://roller.apache.org/ns/tags/" />
        <category term="saml" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
&lt;a href=&quot;http://www.okta.com&quot;&gt;&lt;img src=&quot;//raibledesigns.com/repository/images/logo_okta.png&quot; alt=&quot;Okta&quot; width=&quot;131&quot; height=&quot;37&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
Security has always piqued my interest, ever since I first developed &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; and figured out how to make J2EE
    security work back in 2004.
    I &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_refactorings_part_iii_remember&quot;&gt;hacked AppFuse to have Remember Me functionality&lt;/a&gt;,
    then moved onto Acegi/Spring Security. Spring Security
    had the features I needed, even if it did require almost 100 lines of XML to configure it. These days, it&apos;s much
    better and its JavaConfig - combined with Spring Boot - is pretty slick.&lt;/p&gt;
&lt;p&gt;That was the first part of my security life. The second phase began the night I met Trish, and learned she sold
    security products. She knew of OWASP and their top 10 rules. It was Trish that inspired me to write my &lt;a
        href=&quot;http://www.slideshare.net/mraible/java-web-application-security-denver-jug-2013&quot;&gt;Java Web Application
        Security presentation&lt;/a&gt;. I really enjoyed writing that presentation, comparing Apache Shiro, Spring Security
    and Java EE&apos;s security frameworks. I followed up the &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part&quot;&gt;first time I presented it&lt;/a&gt; with a
    number of &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part4&quot;&gt;blog posts and
        screencasts&lt;/a&gt;. &lt;em&gt;Hmmmm, maybe I should update the presentation/screencasts to use Java configuration only
    (&lt;a href=&quot;https://twitter.com/search?q=%23NoXML&quot;&gt;#NoXML&lt;/a&gt;) and submit it to a couple conferences this year?&lt;/em&gt; I digress.
&lt;/p&gt;
&lt;p&gt;I had to do a security-related spike over the last couple weeks. I was trying to get SAML authentication working with
    &lt;a href=&quot;https://www.okta.com/&quot;&gt;Okta&lt;/a&gt; and my client&apos;s Active Directory server. Luckily, someone setup the AD
    integration so all I had to do was try a few different languages/frameworks. I searched and found ThoughtWorks&apos; &lt;a
        href=&quot;https://github.com/ThoughtWorksInc/okta-samples&quot;&gt;okta-samples&lt;/a&gt;, which includes examples using Node.js
    and Sinatra (Ruby + JRuby). I also found a &lt;a href=&quot;https://github.com/vdenotaris/spring-boot-security-saml-sample&quot;&gt;Spring
        SAML&lt;/a&gt; example that includes one of my favorite things in JavaLand: Java-based configuration.&lt;/p&gt;
&lt;p&gt;I&apos;m happy to report I was able to get all of these applications working with my client&apos;s Okta setup. This article
    will tell you how I did it. For each application, I created a new application on Okta using its &quot;Template SAML
    2.0 Application&quot; and added myself in the application&apos;s &quot;People&quot; tab. Each section below contains the configuration
    I used for Okta. The instructions below assume you&apos;re similar to me, a developer that has Java 8, Node and Ruby
    installed, but none of the specific frameworks. As I write this, I have everything working on my Mac with Yosemite,
    but I wrote the instructions below using one of my old laptops, fresh after a Yosemite upgrade.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;
&lt;a href=&quot;http://www.okta.com&quot;&gt;&lt;img src=&quot;//raibledesigns.com/repository/images/logo_okta.png&quot; alt=&quot;Okta&quot; width=&quot;131&quot; height=&quot;37&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
Security has always piqued my interest, ever since I first developed &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; and figured out how to make J2EE
    security work back in 2004.
    I &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_refactorings_part_iii_remember&quot;&gt;hacked AppFuse to have Remember Me functionality&lt;/a&gt;,
    then moved onto Acegi/Spring Security. Spring Security
    had the features I needed, even if it did require almost 100 lines of XML to configure it. These days, it&apos;s much
    better and its JavaConfig - combined with Spring Boot - is pretty slick.&lt;/p&gt;
&lt;p&gt;That was the first part of my security life. The second phase began the night I met Trish, and learned she sold
    security products. She knew of OWASP and their top 10 rules. It was Trish that inspired me to write my &lt;a
        href=&quot;http://www.slideshare.net/mraible/java-web-application-security-denver-jug-2013&quot;&gt;Java Web Application
        Security presentation&lt;/a&gt;. I really enjoyed writing that presentation, comparing Apache Shiro, Spring Security
    and Java EE&apos;s security frameworks. I followed up the &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part&quot;&gt;first time I presented it&lt;/a&gt; with a
    number of &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part4&quot;&gt;blog posts and
        screencasts&lt;/a&gt;. &lt;em&gt;Hmmmm, maybe I should update the presentation/screencasts to use Java configuration only
    (&lt;a href=&quot;https://twitter.com/search?q=%23NoXML&quot;&gt;#NoXML&lt;/a&gt;) and submit it to a couple conferences this year?&lt;/em&gt; I digress.
&lt;/p&gt;
&lt;p&gt;I had to do a security-related spike over the last couple weeks. I was trying to get SAML authentication working with
    &lt;a href=&quot;https://www.okta.com/&quot;&gt;Okta&lt;/a&gt; and my client&apos;s Active Directory server. Luckily, someone setup the AD
    integration so all I had to do was try a few different languages/frameworks. I searched and found ThoughtWorks&apos; &lt;a
        href=&quot;https://github.com/ThoughtWorksInc/okta-samples&quot;&gt;okta-samples&lt;/a&gt;, which includes examples using Node.js
    and Sinatra (Ruby + JRuby). I also found a &lt;a href=&quot;https://github.com/vdenotaris/spring-boot-security-saml-sample&quot;&gt;Spring
        SAML&lt;/a&gt; example that includes one of my favorite things in JavaLand: Java-based configuration.&lt;/p&gt;
&lt;p&gt;I&apos;m happy to report I was able to get all of these applications working with my client&apos;s Okta setup. This article
    will tell you how I did it. For each application, I created a new application on Okta using its &quot;Template SAML
    2.0 Application&quot; and added myself in the application&apos;s &quot;People&quot; tab. Each section below contains the configuration
    I used for Okta. The instructions below assume you&apos;re similar to me, a developer that has Java 8, Node and Ruby
    installed, but none of the specific frameworks. As I write this, I have everything working on my Mac with Yosemite,
    but I wrote the instructions below using one of my old laptops, fresh after a Yosemite upgrade.&lt;/p&gt;
&lt;p&gt;The first thing I did was checkout ThoughtWorks samples.&lt;/p&gt;
&lt;pre&gt;git clone https://github.com/ThoughtWorksInc/okta-samples.git&lt;/pre&gt;
&lt;h3 id=&quot;node&quot;&gt;Node.js&lt;/h3&gt;
&lt;p&gt;I started by getting the Node.js sample working. For Okta&apos;s configuration, I used:&lt;/p&gt;
&lt;table class=&quot;comparison&quot;&gt;
    &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Setting&lt;/th&gt;
        &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;Application label&lt;/td&gt;
        &lt;td&gt;Okta Node.js Example&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Force Authentication&lt;/td&gt;
        &lt;td&gt;false&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Post Back URL&lt;/td&gt;
        &lt;td&gt;http://localhost:3000/login/callback&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Name ID Format&lt;/td&gt;
        &lt;td&gt;EmailAddress&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Recipient&lt;/td&gt;
        &lt;td&gt;http://localhost:3000/&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Audience Restriction&lt;/td&gt;
        &lt;td&gt;http://localhost:3000/&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;authnContextClassRef&lt;/td&gt;
        &lt;td&gt;PasswordProtectedTransport&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Response&lt;/td&gt;
        &lt;td&gt;Signed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Assertion&lt;/td&gt;
        &lt;td&gt;Signed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Request&lt;/td&gt;
        &lt;td&gt;Compressed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Destination&lt;/td&gt;
        &lt;td&gt;http://localhost:3000/login/callback&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Attribute Statements&lt;/td&gt;
        &lt;td&gt;email|${user.email},firstName|${user.firstName}&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The Node.js sample uses &lt;a href=&quot;https://www.npmjs.com/package/express&quot;&gt;express&lt;/a&gt;, as well as &lt;a
    href=&quot;https://www.npmjs.com/package/passport&quot;&gt;passport&lt;/a&gt; and
    &lt;a href=&quot;https://www.npmjs.com/package/passport-saml&quot;&gt;passport-saml&lt;/a&gt;. The passport packages are used to
    handle the SAML authentication and &lt;a href=&quot;https://www.npmjs.com/package/connect&quot;&gt;connect&lt;/a&gt; is used to
    compress the requests from your local server.&lt;/p&gt;
&lt;p&gt;The only thing I needed to do to make the Node.js app work was to paste the X509 cert string and target URL into its
    &lt;code&gt;config.json&lt;/code&gt; from the Okta app. In Okta&apos;s Admin interface, I clicked on the &quot;Sign On&quot; tab and clicked
    its
    &quot;View Setup Instructions&quot; button. I copied the &quot;Redirect Login URL&quot; value and copied it into config.json&apos;s
    &lt;strong&gt;entryPoint&lt;/strong&gt; value. I then downloaded the certificate and opened it in vi. I ran the following
    two commands to remove ^M and line endings (more
    &lt;a href=&quot;http://stackoverflow.com/questions/811193/how-to-convert-the-m-linebreak-to-normal-linebreak-in-a-file-opened-in-vim&quot;&gt;details
        here&lt;/a&gt;).
&lt;/p&gt;
&lt;pre&gt;
:%s/&amp;lt;Ctrl-V&gt;&amp;lt;Ctrl-M&gt;//g
:%s/\n//g
&lt;/pre&gt;
&lt;p&gt;Next, I copied everything between &lt;code&gt;-----BEGIN CERTIFICATE-----&lt;/code&gt; and &lt;code&gt;-----END CERTIFICATE-----&lt;/code&gt;
    and
    pasted it into the &lt;strong&gt;cert&lt;/strong&gt; value of config.json. I had to remove the comments from config.json for
    everything to work.&lt;/p&gt;
&lt;p&gt;After making these changes, I was able to run &quot;npm install&quot; and &quot;npm start&quot; and successfully login at
    http://localhost:3000.&lt;/p&gt;
&lt;h3 id=&quot;ruby&quot;&gt;Ruby&lt;/h3&gt;
&lt;p&gt;The Ruby sample uses &lt;a href=&quot;http://www.sinatrarb.com/&quot;&gt;Sinatra&lt;/a&gt;, &lt;a
    href=&quot;https://github.com/intridea/omniauth/wiki&quot;&gt;omniauth&lt;/a&gt; and &lt;a
    href=&quot;https://github.com/PracticallyGreen/omniauth-saml&quot;&gt;omniauth-saml&lt;/a&gt;. To run the okta-ruby-sinatra application, I had to start by installing Bundler.
&lt;/p&gt;
&lt;pre&gt;sudo gem install bundler&lt;/pre&gt;
&lt;p&gt;Then I installed all the required gems for this project using the following command.&lt;/p&gt;
&lt;pre&gt;bundle install&lt;/pre&gt;
&lt;p&gt;This resulted in the following error:&lt;/p&gt;
&lt;pre&gt;
An error occurred while installing nokogiri (1.6.1), and Bundler cannot continue.
Make sure that `gem install nokogiri -v &apos;1.6.1&apos;` succeeds before bundling
&lt;/pre&gt;
&lt;p&gt;I tried Bundler&apos;s suggestion, but it failed:&lt;/p&gt;
&lt;pre&gt;
Gem::Installer::ExtensionBuildError: ERROR: Failed to build gem native extension.

    /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby extconf.rb
mkmf.rb can&apos;t find header files for ruby at /System/Library/Frameworks/Ruby.
framework/Versions/2.0/usr/lib/ruby/include/ruby.h
&lt;/pre&gt;
&lt;p&gt;I then tried upgrading to Xcode 6.1.1. I received the same error and running &quot;bundle update sinatra&quot; and &quot;sudo gem
    update --system&quot; didn&apos;t help anything. I found an &lt;a
        href=&quot;http://stackoverflow.com/questions/19580685/installing-rails-on-mavericks&quot;&gt;old Stack Overflow answer&lt;/a&gt;
    that suggested running &quot;xcode-select --install&quot; to install Xcode&apos;s Command Line Developer Tools. After doing so, I
    ran &quot;sudo gcc&quot; to accept to all Apple&apos;s licensing agreements. I ran &quot;bundle install&quot; again and this time it failed
    with the following error:&lt;/p&gt;
&lt;pre&gt;
-----
libxml2 is missing.  please visit http://nokogiri.org/tutorials/installing_nokogiri.html for help with installing dependencies.
-----
...
An error occurred while installing nokogiri (1.6.1), and Bundler cannot continue.
Make sure that `gem install nokogiri -v &apos;1.6.1&apos;` succeeds before bundling.
&lt;/pre&gt;
&lt;p&gt;I tried Bundler&apos;s suggested again: &quot;sudo gem install nokogiri -v &apos;1.6.1&apos;&quot;. This didn&apos;t work, so I tried &quot;bundle
    update&quot; and it finally worked.
    I ran &quot;bundle install&quot; for the final time, followed by &quot;ruby app.rb&quot;. WEBrick started and I created a &quot;Okta Ruby
    Example&quot; application on Okta with the following settings.
&lt;table class=&quot;comparison&quot;&gt;
    &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Setting&lt;/th&gt;
        &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;Application label&lt;/td&gt;
        &lt;td&gt;Okta Ruby Example&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Force Authentication&lt;/td&gt;
        &lt;td&gt;false&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Post Back URL&lt;/td&gt;
        &lt;td&gt;http://localhost:4567/auth/saml/callback&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Name ID Format&lt;/td&gt;
        &lt;td&gt;EmailAddress&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Recipient&lt;/td&gt;
        &lt;td&gt;http://localhost:4567&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Audience Restriction&lt;/td&gt;
        &lt;td&gt;http://localhost:4567&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;authnContextClassRef&lt;/td&gt;
        &lt;td&gt;PasswordProtectedTransport&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Response&lt;/td&gt;
        &lt;td&gt;Signed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Assertion&lt;/td&gt;
        &lt;td&gt;Signed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Request&lt;/td&gt;
        &lt;td&gt;Compressed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Destination&lt;/td&gt;
        &lt;td&gt;http://localhost:4567/auth/saml/callback&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Attribute Statements&lt;/td&gt;
        &lt;td&gt;email|${user.email},firstName|${user.firstName}&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;To configure Sinatra with Otka&apos;s settings, I started by renaming the &lt;code&gt;config.yml.sample&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;mv config.yml.sample config.yml&lt;/pre&gt;
In Otka&apos;s Admin UI for the application, I clicked on the &quot;Sign On&quot; tab and clicked its
&quot;View Setup Instructions&quot; button. I copied the &quot;Redirect Login URL&quot; value and copied it into config.yml&apos;s
&lt;strong&gt;target_url&lt;/strong&gt; value. I then downloaded the certificate and ran the the following command in the directory I downloaded it to.&lt;/p&gt;
&lt;pre&gt;openssl x509 -noout -fingerprint -in &quot;okta.cert&quot;&lt;/pre&gt;
&lt;p&gt;I copied the fingerprint into config.yml&apos;s &lt;strong&gt;fingerprint&lt;/strong&gt; value and restarted the app. I opened
    http://localhost:4567 in my browser and was able to successfully login.&lt;/p&gt;
&lt;h3 id=&quot;jruby&quot;&gt;JRuby&lt;/h3&gt;
&lt;p&gt;To start with JRuby, I first read the project&apos;s README. It mentioned issues with &quot;nokogiri&quot; and explains the project
    contains a patched release of nokogiri 1.6.0. Since I knew there was a later release, I modified
    &lt;code&gt;Gemfile&lt;/code&gt; and removed the version and path information from the last line. I copied the
    &lt;code&gt;config.yml&lt;/code&gt; from the Ruby project and ran the following commands to install Bundler, the project&apos;s
    dependencies and start the app.&lt;/p&gt;
&lt;pre&gt;jruby -S gem install bundler
jruby -S bundle install&lt;/pre&gt;
&lt;p&gt;Running the second command resulted in the following error:&lt;/p&gt;
&lt;pre&gt;Your jruby version is 1.7.18, but your Gemfile specified jruby 1.7.4&lt;/pre&gt;
&lt;p&gt;I modified &lt;code&gt;Gemfile&lt;/code&gt; to specify &quot;1.7.18&quot; and tried again. This time it worked. I started the application
    using the following command:
&lt;pre&gt;jruby app.rb&lt;/pre&gt;
&lt;div class=&quot;alert alert-info&quot;&gt;
    &lt;strong&gt;NOTE:&lt;/strong&gt; If you see the the following in your browser window, it means you forgot to copy config.yml from the Ruby
    project.
    &lt;pre&gt;undefined method `auth&apos; for Sinatra::Application:Class&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;When I tried to login at &lt;a href=&quot;http://localhost:4567&quot;&gt;http://localhost:4567&lt;/a&gt;, I saw an infinite redirect and
    the following error in my console.&lt;/p&gt;
&lt;pre&gt;
W, [2015-01-08T08:53:22.514000 #56144]  WARN -- : attack prevented by Rack::Protection::SessionHijacking
0:0:0:0:0:0:0:1 - - [08/Jan/2015 08:53:22] &quot;GET / HTTP/1.1&quot; 302 - 0.0190
0:0:0:0:0:0:0:1 - - [08/Jan/2015:08:53:22 MST] &quot;GET / HTTP/1.1&quot; 302 0
&lt;/pre&gt;
&lt;p&gt;&lt;a
    href=&quot;http://stackoverflow.com/questions/10102893/sinatra-app-using-omniauth-gets-rackprotectionsessionhijacking-in-ie9&quot;&gt;Stack
    Overflow&lt;/a&gt; indicated this is a problem caused by an old version of &lt;a
    href=&quot;http://rkh.github.io/rack-protection/&quot;&gt;rack-protection&lt;/a&gt;. Running &quot;jruby -S bundle update rack-protection&quot;
    updated the project to use rack-protection 1.5.3 (was 1.5.1). After restarting and trying again, I received the
    following error:
&lt;/p&gt;
&lt;pre&gt;
I, [2015-01-08T08:59:32.679000 #56176]  INFO -- omniauth: (saml) Callback phase initiated.
E, [2015-01-08T08:59:34.747000 #56176] ERROR -- omniauth: (saml) Authentication failure! invalid_ticket: Onelogin::Saml::ValidationError, Digest mismatch
0:0:0:0:0:0:0:1 - - [08/Jan/2015:08:59:34 -0700] &quot;POST /auth/saml/callback HTTP/1.1&quot; 302 9 2.0760
0:0:0:0:0:0:0:1 - - [08/Jan/2015:08:59:34 -0700] &quot;GET /auth/failure?message=invalid_ticket&amp;strategy=saml HTTP/1.1&quot; 404 449 0.0080
0:0:0:0:0:0:0:1 - - [08/Jan/2015:08:59:34 MST] &quot;GET /auth/failure?message=invalid_ticket&amp;strategy=saml HTTP/1.1&quot; 404 449
- -&gt; /auth/failure?message=invalid_ticket&amp;strategy=saml
0:0:0:0:0:0:0:1 - - [08/Jan/2015:08:59:34 -0700] &quot;GET /__sinatra__/404.png HTTP/1.1&quot; 200 18893 0.0200
0:0:0:0:0:0:0:1 - - [08/Jan/2015:08:59:32 MST] &quot;POST /auth/saml/callback HTTP/1.1&quot; 302 9
- -&gt; /auth/saml/callback
0:0:0:0:0:0:0:1 - - [08/Jan/2015:08:59:34 MST] &quot;GET /__sinatra__/404.png HTTP/1.1&quot; 200 18893
http://localhost:4567/auth/failure?message=invalid_ticket&amp;strategy=saml -&gt; /__sinatra__/404.png
&lt;/pre&gt;
&lt;p&gt;At this point, the only thing different from my working version and my old laptop was the version of Java. My old
    laptop had &quot;build 1.8.0_05-b13&quot;, so I upgraded to the latest version of Java 8 (update 25). This didn&apos;t help, so I
    tried updating all bundles with &quot;jruby -S bundle update&quot;.
    This failed too, so I figured I&apos;d try to use the version of JRuby that was on my working laptop (version 1.7.16.1).
    I installed &lt;a href=&quot;http://brew.sh/&quot;&gt;Homebrew&lt;/a&gt;, ran &quot;brew install jruby&quot;, removed the newer version from my path
    and downgraded the version in &lt;code&gt;Gemfile&lt;/code&gt;. I had to re-install Bundler and the projects dependencies with
    the following commands.&lt;/p&gt;
&lt;pre&gt;jruby -S gem install bundler
jruby -S bundle install&lt;/pre&gt;
&lt;p&gt;Same error again. I reverted &lt;code&gt;Gemfile.lock&lt;/code&gt; and ran the only bundle update command I&apos;d run on my working
    laptop:&lt;/p&gt;
&lt;pre&gt;$ jruby -S bundle update sinatra&lt;/pre&gt;
&lt;p&gt;Unfortunately, this still didn&apos;t fix the issue. I copied the project from my working laptop and tried running that
    project. It failed, proving that it was an environment issue, not a project/code issue. I tried rebooting and when
    that didn&apos;t work, I gave up. It&apos;s pretty strange this didn&apos;t work on a fresh Yosemite install - it took me less than
    10 minutes to get it working originally.
&lt;h3 id=&quot;spring&quot;&gt;Spring&lt;/h3&gt;
&lt;p&gt;The Spring sample I got working with Okta was Vincenzo De Notaris&apos; &lt;a
    href=&quot;https://github.com/vdenotaris/spring-boot-security-saml-sample&quot;&gt;spring-boot-security-saml-sample&lt;/a&gt;. This
    project uses &lt;a href=&quot;http://projects.spring.io/spring-boot/&quot;&gt;Spring Boot&lt;/a&gt; and &lt;a
        href=&quot;http://projects.spring.io/spring-security-saml/&quot;&gt;Spring Security SAML&lt;/a&gt;. I created a &quot;Okta Spring Example&quot; application on Okta with the following settings.&lt;/p&gt;
&lt;table class=&quot;comparison&quot;&gt;
    &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Setting&lt;/th&gt;
        &lt;th&gt;Value&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;Application label&lt;/td&gt;
        &lt;td&gt;Okta Spring Example&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Force Authentication&lt;/td&gt;
        &lt;td&gt;false&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Post Back URL&lt;/td&gt;
        &lt;td&gt;http://localhost:8080/saml/SSO&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Name ID Format&lt;/td&gt;
        &lt;td&gt;EmailAddress&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Recipient&lt;/td&gt;
        &lt;td&gt;http://localhost:8080/saml/SSO&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Audience Restriction&lt;/td&gt;
        &lt;td&gt;com:vdenotaris:spring:sp&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;authnContextClassRef&lt;/td&gt;
        &lt;td&gt;PasswordProtectedTransport&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Response&lt;/td&gt;
        &lt;td&gt;Signed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Assertion&lt;/td&gt;
        &lt;td&gt;Signed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Request&lt;/td&gt;
        &lt;td&gt;Uncompressed&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Destination&lt;/td&gt;
        &lt;td&gt;http://localhost:8080/saml/SSO&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
        &lt;td&gt;Attribute Statements&lt;/td&gt;
        &lt;td&gt;email|${user.email},firstName|${user.firstName}&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The biggest thing I learned while trying to get these values correct was that &lt;a
    href=&quot;http://stackoverflow.com/questions/27713524/how-do-i-configure-spring-security-saml-to-work-with-okta&quot;&gt;Request
    needs to be set to &lt;strong&gt;Uncompressed&lt;/strong&gt;&lt;/a&gt;.
&lt;p&gt;After cloning the GitHub project to my hard drive, I added a new SSO provider by adding a new bean to &lt;code&gt;WebSecurityConfig.java&lt;/code&gt;.
    The URL I got from Okta&apos;s Admin UI: Sign On &gt; View Setup Instructions &gt; Public Link (near the bottom of the page).
&lt;pre class=&quot;brush: java&quot;&gt;
@Bean(name = &quot;idp-okta&quot;)
public ExtendedMetadataDelegate ssoOktaExtendedMetadataProvider()
      throws MetadataProviderException {
    @SuppressWarnings({ &quot;deprecation&quot;})
    HTTPMetadataProvider httpMetadataProvider
          = new HTTPMetadataProvider(&quot;https://client.okta.com/app/random-key-here/sso/saml/metadata&quot;, 5000);
    httpMetadataProvider.setParserPool(parserPool());
    ExtendedMetadataDelegate extendedMetadataDelegate =
          new ExtendedMetadataDelegate(httpMetadataProvider, extendedMetadata());
    extendedMetadataDelegate.setMetadataTrustCheck(false);
    extendedMetadataDelegate.setMetadataRequireSignature(false);
    return extendedMetadataDelegate;
}
&lt;/pre&gt;
&lt;p&gt;For the SSL connection to work, I had to download the certificate and import it into the application&apos;s keystore. To
    do this in Chrome, I went to https://client.okta.com, clicked on the lock icon in the address bar, then
    dragged/dropped the certificate image to my desktop. This resulted in a &lt;code&gt;*.okta.com.cer&lt;/code&gt; file on my
    desktop. I added it to the keystore using the following commands (thanks &lt;a
        href=&quot;http://stackoverflow.com/questions/4325263/how-to-import-a-cer-certificate-into-a-java-keystore&quot;&gt;Stack
        Overflow&lt;/a&gt;).&lt;/p&gt;
&lt;pre&gt;
keytool -importcert -file ~/Desktop/\*.okta.com.cer -keystore src/main/resources/saml/samlKeystore.jks
&lt;/pre&gt;
&lt;p&gt;When prompted for the password, I entered &quot;nalle123&quot;. This value is specified in WebSecurityConfig.java&apos;s &lt;code&gt;keyManager&lt;/code&gt;
    bean. I then added this provider to the list of providers in the &lt;code&gt;metadata&lt;/code&gt; bean.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Bean
@Qualifier(&quot;metadata&quot;)
public CachingMetadataManager metadata() throws MetadataProviderException {
        List&amp;lt;MetadataProvider&gt; providers = new ArrayList&amp;lt;MetadataProvider&gt;();
    providers.add(ssoOktaExtendedMetadataProvider());
    providers.add(ssoCircleExtendedMetadataProvider());
    return new CachingMetadataManager(providers);
}
&lt;/pre&gt;
&lt;p&gt;After making these changes, I started the application using &quot;mvn spring-boot:run&quot;. I navigated to
    http://localhost:8080, chose Okta as my Idp and logged in successfully!&lt;/p&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;This article shows you how I got Node.js, Ruby and Spring applications working with Okta&apos;s SAML support.
    My experience with this when I first tried it: Node was super-easy, Ruby was a bit more difficult, JRuby was
    a cinch and Spring took several days. As you can tell from this article, Ruby/JRuby were the most difficult to
    make work on a clean machine. 
&lt;/p&gt;
&lt;p&gt;All in all, working with Okta has been a pleasant experience so far. Hopefully this article helps make it a good experience for you as well.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_reduced</id>
        <title type="html">AppFuse, Reduced</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_reduced"/>
        <published>2014-12-16T06:03:31-07:00</published>
        <updated>2014-12-17T16:39:14-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maintenance" scheme="http://roller.apache.org/ns/tags/" />
        <category term="lessxml" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
In November, I had some time off between clients. To occupy my time, I exercised my body and brain a bit. I spent a couple hours a day exercising and a few hours a day working on
&lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. AppFuse isn&apos;t used to start projects nearly as much as it once was. This makes sense since there&apos;s been a ton of innovation on the JVM and there&apos;s lots of
&lt;em&gt;get-started-quickly&lt;/em&gt; frameworks now. Among my favorites are Spring Boot, JHipster, Grails and Play.
&lt;p&gt;
    You can see that AppFuse&apos;s community activity has decreased quite a bit over the years by looking at its mailing list
    traffic.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://appfuse.markmail.org/&quot;
       title=&quot;AppFuse Mailing List Traffic, December 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7525/15825430580_0531875e59.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Mailing List Traffic, December 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Even though there&apos;s not a lot of users talking on the mailing list, it still seems to get quite a few downloads from
    Maven Central.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://www.flickr.com/photos/mraible/16011987392&quot;
       title=&quot;AppFuse Maven Central Stats, November 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7534/16011987392_442236433b.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Maven Central Stats, November 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    I think the biggest value that AppFuse provides now is a learning tool for those who work on it. Also, it&apos;s a good place to
    show other developers how they can evolve with open source frameworks (e.g. Spring, Hibernate, JSF, Tapestry, Struts) over several years. Showing how
    we migrated to Spring MVC Test, for example, might be useful. The upcoming move to Spring Data instead of our
    Generic DAO solution might be interesting as well. 
&lt;/p&gt;
&lt;p&gt;
    Regardless of whether AppFuse is used a lot or not, it should be easy to maintain. Over the several weeks, I made some
    opinionated changes and achieved some pretty good progress on simplifying things and making the project easier to
    maintain. The previous structure has a lot of duplicate versions, properties and plugin configurations between
    different projects. I was able to leverage Maven&apos;s inheritance model to make a number of improvements:
&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;
In November, I had some time off between clients. To occupy my time, I exercised my body and brain a bit. I spent a couple hours a day exercising and a few hours a day working on
&lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. AppFuse isn&apos;t used to start projects nearly as much as it once was. This makes sense since there&apos;s been a ton of innovation on the JVM and there&apos;s lots of
&lt;em&gt;get-started-quickly&lt;/em&gt; frameworks now. Among my favorites are Spring Boot, JHipster, Grails and Play.
&lt;p&gt;
    You can see that AppFuse&apos;s community activity has decreased quite a bit over the years by looking at its mailing list
    traffic.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://appfuse.markmail.org/&quot;
       title=&quot;AppFuse Mailing List Traffic, December 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7525/15825430580_0531875e59.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Mailing List Traffic, December 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Even though there&apos;s not a lot of users talking on the mailing list, it still seems to get quite a few downloads from
    Maven Central.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://www.flickr.com/photos/mraible/16011987392&quot;
       title=&quot;AppFuse Maven Central Stats, November 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7534/16011987392_442236433b.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Maven Central Stats, November 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    I think the biggest value that AppFuse provides now is a learning tool for those who work on it. Also, it&apos;s a good place to
    show other developers how they can evolve with open source frameworks (e.g. Spring, Hibernate, JSF, Tapestry, Struts) over several years. Showing how
    we migrated to Spring MVC Test, for example, might be useful. The upcoming move to Spring Data instead of our
    Generic DAO solution might be interesting as well. 
&lt;/p&gt;
&lt;p&gt;
    Regardless of whether AppFuse is used a lot or not, it should be easy to maintain. Over the several weeks, I made some
    opinionated changes and achieved some pretty good progress on simplifying things and making the project easier to
    maintain. The previous structure has a lot of duplicate versions, properties and plugin configurations between
    different projects. I was able to leverage Maven&apos;s inheritance model to make a number of improvements:
&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Changed AppFuse&apos;s parent to be based on the &lt;a
        href=&quot;http://www.infoq.com/news/2014/07/springio-platform&quot;&gt;Spring IO Platform&lt;/a&gt;. This project
        is a dependency manager that defines version numbers for open source projects that work well with Spring.
    &lt;/li&gt;
    &lt;li&gt;Defined plugins, their versions and configurations in &lt;code&gt;&amp;lt;pluginManagement&gt;&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Defined dependencies, their versions and exclusions in &lt;code&gt;&amp;lt;dependencyManagement&gt;&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Simplified archetypes so new projects have minimal dependencies. For example, here&apos;s a basic project&apos;s &lt;code&gt;pom.xml&lt;/code&gt;:
    &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&amp;gt;

    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;groupId&amp;gt;com.company&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;springmvc-project&amp;lt;/artifactId&amp;gt;
    &amp;lt;packaging&amp;gt;war&amp;lt;/packaging&amp;gt;
    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;name&amp;gt;AppFuse Spring MVC Application&amp;lt;/name&amp;gt;

    &amp;lt;parent&amp;gt;
        &amp;lt;groupId&amp;gt;org.appfuse&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;appfuse-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;3.5.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;/parent&amp;gt;

    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;de.juplo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;hibernate4-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;dbunit-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;build-helper-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;

    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.appfuse&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;appfuse-${web.framework}&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;${appfuse.version}&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;

    &amp;lt;properties&amp;gt;
        &amp;lt;amp.genericCore&amp;gt;true&amp;lt;/amp.genericCore&amp;gt;
        &amp;lt;amp.fullSource&amp;gt;false&amp;lt;/amp.fullSource&amp;gt;
        &amp;lt;dao.framework&amp;gt;hibernate&amp;lt;/dao.framework&amp;gt;
        &amp;lt;db.name&amp;gt;mydatabase&amp;lt;/db.name&amp;gt;
        &amp;lt;web.framework&amp;gt;spring&amp;lt;/web.framework&amp;gt;

        &amp;lt;!-- Framework/Plugin versions --&amp;gt;
        &amp;lt;appfuse.version&amp;gt;3.5.0-SNAPSHOT&amp;lt;/appfuse.version&amp;gt;
        &amp;lt;java.version&amp;gt;1.7&amp;lt;/java.version&amp;gt;
    &amp;lt;/properties&amp;gt;

    &amp;lt;profiles&amp;gt;
        &amp;lt;profile&amp;gt;
            &amp;lt;id&amp;gt;itest&amp;lt;/id&amp;gt;
            &amp;lt;build&amp;gt;
                &amp;lt;plugins&amp;gt;
                    &amp;lt;plugin&amp;gt;
                        &amp;lt;groupId&amp;gt;org.codehaus.cargo&amp;lt;/groupId&amp;gt;
                        &amp;lt;artifactId&amp;gt;cargo-maven2-plugin&amp;lt;/artifactId&amp;gt;
                    &amp;lt;/plugin&amp;gt;
                    &amp;lt;plugin&amp;gt;
                        &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                        &amp;lt;artifactId&amp;gt;webtest-maven-plugin&amp;lt;/artifactId&amp;gt;
                    &amp;lt;/plugin&amp;gt;
                &amp;lt;/plugins&amp;gt;
            &amp;lt;/build&amp;gt;
        &amp;lt;/profile&amp;gt;
    &amp;lt;/profiles&amp;gt;

    &amp;lt;reporting&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;webtest-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/reporting&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;style type=&quot;text/css&quot;&gt;
    span.diffstat {
        white-space: nowrap;
        text-align: right;
        font-family: Helvetica, arial, freesans, clean, sans-serif, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;
        color: #666;
        font-weight: bold;
        font-size: 12px;
        cursor: default;
    }

    span.diffstat .lines-added, span.diffstat .lines-deleted {
        display: inline-block;
        margin-left: 3px;
        font-weight: bold;
    }
&lt;/style&gt;
&lt;p&gt;
    The pull request for these changes says it all:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/appfuse/appfuse/pull/20&quot;&gt;AppFuse&lt;/a&gt; &lt;span class=&quot;diffstat&quot;&gt;
          &lt;span class=&quot;lines-added&quot; style=&quot;color: #55a532&quot;&gt;
            &lt;span class=&quot;diffstat-icon&quot;&gt;+&lt;/span&gt;4,822
          &lt;/span&gt;
          &lt;span class=&quot;lines-deleted&quot; style=&quot;color: #bd2c00&quot;&gt;
            &lt;span class=&quot;diffstat-icon&quot;&gt;-&lt;/span&gt;14,369
          &lt;/span&gt;
        &lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/appfuse/appfuse-light/pull/1&quot;&gt;AppFuse Light&lt;/a&gt; &lt;span class=&quot;diffstat&quot;&gt;
              &lt;span class=&quot;lines-added&quot; style=&quot;color: #55a532&quot;&gt;
                &lt;span class=&quot;diffstat-icon&quot;&gt;+&lt;/span&gt;776
              &lt;/span&gt;
              &lt;span class=&quot;lines-deleted&quot; style=&quot;color: #bd2c00&quot;&gt;
                &lt;span class=&quot;diffstat-icon&quot;&gt;-&lt;/span&gt;4,687
              &lt;/span&gt;

            &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&apos;s right, I was able to eliminate a good chunk of code without affecting any of AppFuse&apos;s functionality&lt;sup&gt;&lt;a
    href=&quot;http://raibledesigns.com/rd/entry/appfuse_reduced#footnote1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.
    I think we can all agree that less code == easier maintenance. This theme will continue as we work on future
    releases.
&lt;/p&gt;

&lt;p&gt;Other improvements include migrating all tests to use JUnit4, integrating Spring MVC Test, and configuring the
    surefire plugin to run tests in parallel. I also The &lt;a href=&quot;http://mojo.codehaus.org/build-helper-maven-plugin/&quot;&gt;build-helper-maven-plugin&lt;/a&gt;
    is now used to find open ports for Cargo to run and a lot of testing was done to ensure you can build/test multiple
    AppFuse-derived projects at the same time. Finally, I migrated to the &lt;a href=&quot;http://juplo.de/hibernate4-maven-plugin/&quot;&gt;hibernate4-maven-plugin&lt;/a&gt; and upgraded to Tapestry 5.4.&lt;/p&gt;

&lt;p&gt;In the next version of AppFuse, I plan to remove as
    much XML as possible - moving all of the configuration to Spring&apos;s JavaConfig. We&apos;ll also be moving to Java 8 as a
    minimum. I&apos;m even considering getting rid of all the pom.xml files in favor of another build language that requires
    less code. &lt;/p&gt;
&lt;p&gt;In other words, the upcoming 3.5 release will be the last release that supports Java 7 and uses Spring&apos;s XML for configuration. AppFuse 4.0 will strive for #NoXML.
   &lt;a href=&quot;http://appfuse.org/display/APF/Roadmap&quot;&gt;The project&apos;s roadmap&lt;/a&gt; has more details on additional
    hopes and dreams.&lt;/p&gt;

&lt;p&gt;We&apos;d love to hear your feedback on these change. Do you like the simplification theme? Are you OK with having AppFuse
    as a parent in your projects?
&lt;/p&gt;
&lt;p class=&quot;footnotes&quot; style=&quot;border-top: 1px dotted silver; padding-top: 5px; font-size: .9em&quot;&gt;
    &lt;a name=&quot;footnote1&quot;&gt;&lt;/a&gt;1. For project
    and code stats, see &lt;a href=&quot;https://www.openhub.net/p/appfuse/analyses/latest/languages_summary&quot;&gt;AppFuse on Open
    Hub&lt;/a&gt;.
&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/developing_services_with_apache_camel3</id>
        <title type="html">Developing Services with Apache Camel - Part IV: Load Testing and Monitoring</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/developing_services_with_apache_camel3"/>
        <published>2014-10-15T10:04:01-06:00</published>
        <updated>2015-07-16T16:49:37-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="camel" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jhipster" scheme="http://roller.apache.org/ns/tags/" />
        <category term="scala" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apachecamel" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gatling" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hawtio" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring-boot" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
&lt;a href=&quot;http://gatling.io&quot;&gt;&lt;img src=&quot;//raibledesigns.com/repository/images/gatling.png&quot; width=&quot;150&quot; class=&quot;picture&quot; alt=&quot;Gatling&quot;&gt;&lt;/a&gt;
    Welcome to the final article in a series on my experience developing services with
    &lt;a href=&quot;http://camel.apache.org&quot;&gt;Apache Camel&lt;/a&gt;. I learned how to implement CXF endpoints using its
    Java DSL, made sure everything worked with its testing framework and integrated Spring Boot
    for external configuration. For previous articles, please see the following:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel
&quot;&gt;Part I: The Inspiration&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel1
&quot;&gt;Part II: Creating and Testing Routes&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel2
&quot;&gt;Part III: Integrating Spring 4 and Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
    This article focuses on load testing and tools for monitoring application performance. In late July, I was
    asked to look into load testing the new Camel-based services I&apos;d developed. My client&apos;s reason was simple:
    to make sure the new services were as fast as the old ones (powered by IBM Message Broker).
    I sent &lt;a href=&quot;http://camel.465427.n5.nabble.com/Load-Testing-Camel-Routes-td5754610.html&quot;&gt;an
    email&lt;/a&gt; to the Camel users mailing list asking for advice on load testing.
&lt;/p&gt;
&lt;div class=&quot;quote&quot;&gt;
    &lt;p style=&quot;margin-top: 0&quot;&gt;
        I&apos;m getting ready to put a Camel / CXF / Spring Boot application into production. Before I do, I want to load
        test and verify it has the same throughput as a the IBM Message Broker system it&apos;s replacing. Apparently, the
        old system can only do 6 concurrent connections because of remote database connectivity issues.
    &lt;/p&gt;

    &lt;p style=&quot;margin-bottom: 0&quot;&gt;
        I&apos;d like to write some tests that make simultaneous requests, with different data. Ideally, I could write them
        to point at the old system and find out when it falls over. Then I could point them at the new system and tune
        it accordingly. If I need to throttle because of remote connectivity issues, I&apos;d like to know before we go to
        production. Does JMeter or any Camel-related testing tools allow for this?
    &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
    In reply, I received suggestions for &lt;a href=&quot;http://httpd.apache.org/docs/2.2/programs/ab.html&quot;&gt;Apache&apos;s ab
    tool&lt;/a&gt;
    and &lt;a href=&quot;http://gatling.io/&quot;&gt;Gatling&lt;/a&gt;. I&apos;d heard of Gatling before, and decided to try it.
&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;TL;DR&lt;/h3&gt;

&lt;p&gt;This article shows how to use Gatling to load test a SOAP service and how to configure Log4j2 with Spring Boot. It
    also shows how hawtio can help monitor and configure a Camel application. I hope you enjoyed reading this series
    on what I learned about developing with Camel over the past several months. If you have stories about your experience with Camel (or similar integration frameworks), Gatling, hawtio or New Relic, I&apos;d love to hear them.
&lt;/p&gt;

&lt;p&gt;
It&apos;s been a great experience and I look forward to developing solid apps, built on open source, for my next client. I&apos;d like to
    get back into HTML5, AngularJS and mobile development. I&apos;ve had a good time with Spring Boot and JHipster this year
    and hope to use them again. I find myself using Java 8 more and more; my ideal next project would embrace it as a
    baseline. As for Scala and Groovy, I&apos;m still a big fan and believe I can develop great apps with them.
&lt;/p&gt;
&lt;p&gt;
    If you&apos;re looking for a UI/API Architect that can help accelerate your projects, please &lt;a href=&quot;http://raibledesigns.com/contact.jsp&quot;&gt;let me know&lt;/a&gt;! You can learn more about my extensive experience from &lt;a href=&quot;https://www.linkedin.com/in/mraible&quot;&gt;my LinkedIn profile&lt;/a&gt;.
&lt;/p&gt;
&lt;script type=&quot;text/javascript&quot;&gt;
function adjustWhereThingsAre() {
    var readMore = document.getElementById(&apos;readmore&apos;);
    document.getElementById(&apos;summary&apos;).insertAdjacentHTML(&apos;beforebegin&apos;, readMore.outerHTML);
    readMore.outerHTML = null;
}
window.setTimeout(adjustWhereThingsAre, 500);
&lt;/script&gt;
&lt;p id=&quot;readmore&quot;&gt;</summary>
        <content type="html">&lt;p&gt;
    Welcome to the final article in a series on my experience developing services with
    &lt;a href=&quot;http://camel.apache.org&quot;&gt;Apache Camel&lt;/a&gt;. I learned how to implement CXF endpoints using its
    Java DSL, made sure everything worked with its testing framework and integrated Spring Boot
    for external configuration. For previous articles, please see the following:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel
&quot;&gt;Part I: The Inspiration&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel1
&quot;&gt;Part II: Creating and Testing Routes&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel2
&quot;&gt;Part III: Integrating Spring 4 and Spring Boot&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
    This article focuses on load testing and tools for monitoring application performance. In late July, I was
    asked to look into load testing the new Camel-based services I&apos;d developed. My client&apos;s reason was simple:
    to make sure the new services were as fast as the old ones (powered by IBM Message Broker).
    I sent &lt;a href=&quot;http://camel.465427.n5.nabble.com/Load-Testing-Camel-Routes-td5754610.html&quot;&gt;an
    email&lt;/a&gt; to the Camel users mailing list asking for advice on load testing.
&lt;/p&gt;
&lt;div class=&quot;quote&quot;&gt;
    &lt;p style=&quot;margin-top: 0&quot;&gt;
        I&apos;m getting ready to put a Camel / CXF / Spring Boot application into production. Before I do, I want to load
        test and verify it has the same throughput as a the IBM Message Broker system it&apos;s replacing. Apparently, the
        old system can only do 6 concurrent connections because of remote database connectivity issues.
    &lt;/p&gt;

    &lt;p style=&quot;margin-bottom: 0&quot;&gt;
        I&apos;d like to write some tests that make simultaneous requests, with different data. Ideally, I could write them
        to point at the old system and find out when it falls over. Then I could point them at the new system and tune
        it accordingly. If I need to throttle because of remote connectivity issues, I&apos;d like to know before we go to
        production. Does JMeter or any Camel-related testing tools allow for this?
    &lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
    In reply, I received suggestions for &lt;a href=&quot;http://httpd.apache.org/docs/2.2/programs/ab.html&quot;&gt;Apache&apos;s ab
    tool&lt;/a&gt;
    and &lt;a href=&quot;http://gatling.io/&quot;&gt;Gatling&lt;/a&gt;. I&apos;d heard of Gatling before, and decided to try it.
&lt;/p&gt;

&lt;h3 id=&quot;gatling&quot;&gt;Gatling&lt;/h3&gt;

&lt;p&gt;
&lt;a href=&quot;http://gatling.io&quot;&gt;&lt;img src=&quot;//raibledesigns.com/repository/images/gatling.png&quot; width=&quot;150&quot; class=&quot;picture&quot; alt=&quot;Gatling&quot;&gt;&lt;/a&gt;
    I don&apos;t remember where I first heard of Gatling, but I knew it had a Scala DSL and used
    &lt;a href=&quot;http://akka.io&quot;&gt;Akka&lt;/a&gt; under the covers.
    I generated a new project using a &lt;a href=&quot;https://github.com/gatling/gatling-highcharts-maven-archetype&quot;&gt;Maven
    archetype&lt;/a&gt; and went to work developing my first test.
    My approach involved three steps:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Write tests to run against current system. Find the number of concurrent requests that make it fall over.&lt;/li&gt;
    &lt;li&gt;Run tests against new system and tune accordingly.&lt;/li&gt;
    &lt;li&gt;Throttle requests if there are remote connectivity issues with 3rd parties. If I needed to throttle requests, I was planning to use Camel&apos;s
    &lt;a href=&quot;http://camel.apache.org/throttler.html&quot;&gt;Throttler&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
    To develop the first test, I started with Gatling&apos;s &lt;a href=&quot;http://gatling.io/docs/2.0.1/quickstart.html#using-the-recorder&quot;&gt;
    Recorder.&lt;/a&gt; I set it to listen on port 8000, changed my &lt;code&gt;DrugServiceITest&lt;/code&gt; to use the same port and
    ran the integration test. This was a great way to get started because it recorded my requests as XML files, and used
    clean and concise code.
&lt;/p&gt;

&lt;p&gt;I ended up creating a parent class for all simulations and named it &lt;code&gt;AbstractSimulation&lt;/code&gt;. This was handy
    because it allowed me to pass in parameters for all the values I wanted to change.&lt;/p&gt;

&lt;pre class=&quot;brush: scala&quot;&gt;import io.gatling.core.scenario.Simulation
import io.gatling.http.Predef._

/**
 * Base Simulation class that allows passing in parameters.
 */
class AbstractSimulation extends Simulation {

  val host = System.getProperty(&quot;host&quot;, &quot;localhost:8080&quot;)
  val serviceType = System.getProperty(&quot;service&quot;, &quot;modern&quot;)
  val nbUsers = Integer.getInteger(&quot;users&quot;, 10).toInt
  val rampRate = java.lang.Long.getLong(&quot;ramp&quot;, 30L).toLong

  val httpProtocol = http
    .baseURL(&quot;http://&quot; + host)
    .acceptHeader(&quot;text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8&quot;)
    .doNotTrackHeader(&quot;1&quot;)
    .acceptLanguageHeader(&quot;en-US,en;q=0.5&quot;)
    .acceptEncodingHeader(&quot;gzip, deflate&quot;)
    .userAgentHeader(&quot;Gatling 2.0&quot;)

  val headers = Map(
    &quot;&quot;&quot;Cache-Control&quot;&quot;&quot; -&amp;gt; &quot;&quot;&quot;no-cache&quot;&quot;&quot;,
    &quot;&quot;&quot;Content-Type&quot;&quot;&quot; -&amp;gt; &quot;&quot;&quot;application/soap+xml; charset=UTF-8&quot;&quot;&quot;,
    &quot;&quot;&quot;Pragma&quot;&quot;&quot; -&amp;gt; &quot;&quot;&quot;no-cache&quot;&quot;&quot;)
}
&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;DrugServiceSimulation.scala&lt;/code&gt; class posts a SOAP request over HTTP.&lt;/p&gt;
&lt;pre class=&quot;brush: scala&quot;&gt;import io.gatling.core.Predef._
import io.gatling.http.Predef._

import scala.concurrent.duration._

class DrugServiceSimulation extends AbstractSimulation {

  val service = if (&quot;modern&quot;.equals(serviceType)) &quot;/api/drugs&quot; else &quot;/axis2/services/DrugService&quot;

  val scn = scenario(&quot;Drug Service :: findGpiByNdc&quot;)
    .exec(http(host)
    .post(service)
    .headers(headers)
    .body(RawFileBody(&quot;DrugServiceSimulation_request.xml&quot;)))

  setUp(scn.inject(ramp(nbUsers users) over (rampRate seconds))).protocols(httpProtocol)
}
&lt;/pre&gt;
&lt;p&gt;
    To run tests against the legacy drug service with 100 users over 60 seconds, I used the following command:
&lt;/p&gt;
&lt;pre&gt;mvn test -Dhost=legacy.server:7802 -Dservice=legacy -Dusers=100 -Dramp=60
&lt;/pre&gt;
&lt;p&gt;The &lt;em&gt;service&lt;/em&gt; property&apos;s default is &quot;modern&quot; and determines the service&apos;s URL. To run against the local drug
    service with 100 users over 30 seconds, I could rely on more defaults.&lt;/p&gt;
&lt;pre&gt;mvn test -Dusers=100
&lt;/pre&gt;
&lt;p&gt;The name of the simulation to run is configured in pom.xml:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;io.gatling&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;gatling-maven-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${gatling.version}&amp;lt;/version&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;simulationsFolder&amp;gt;src/test/scala&amp;lt;/simulationsFolder&amp;gt;
        &amp;lt;simulationClass&amp;gt;com.company.app.${service.name}Simulation&amp;lt;/simulationClass&amp;gt;
    &amp;lt;/configuration&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;phase&amp;gt;test&amp;lt;/phase&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;execute&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
    &amp;lt;/executions&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;When the simulations were done running, the console displayed a link to some pretty snazzy HTML reports. I ran
    simulations
    until things started falling over on the legacy server. That happened at around 400 requests per second (rps). When I ran
    them against
    a local instance on my fully-loaded 2013 MacBook Pro, errors started flying at 4000/rps while 3000/rps performed
    just fine.&lt;/p&gt;
&lt;h4 id=&quot;jenkins&quot;&gt;Jenkins&lt;/h4&gt;

&lt;p&gt;I configured simulations to run in Jenkins with the &lt;a href=&quot;https://wiki.jenkins-ci.org/display/JENKINS/Gatling+Plugin&quot;&gt;
    Gatling Plugin&lt;/a&gt;. It&apos;s a neat plugin that allows you to record and compare results over time. After initial
    setup, I found
    I didn&apos;t use it much. Instead, I created a Google Doc with my findings and created screenshots of results so my
    client had it in an easy-to-read format.
&lt;/p&gt;
&lt;h4 id=&quot;gatling-data-feeders&quot;&gt;Data Feeders&lt;/h4&gt;

&lt;p&gt;I knew the results of the simulations were likely skewed, since the same request was used for all users. I researched
    how to make dynamic requests with Gatling and found &lt;a href=&quot;http://gatling.io/docs/2.0.1/session/feeder.html&quot;&gt;Feeders&lt;/a&gt;.
    Using a JDBC Feeder I was able make all the requests contain unique data for each user. 
&lt;/p&gt;

&lt;p&gt;I added a feeder to &lt;code&gt;DrugServiceSimulation&lt;/code&gt;, added it to the scenario and changed to use an &lt;a href=&quot;http://stackoverflow.com/questions/21143077/gatling-2-mapping-values-to-template&quot;&gt;ELFileBody&lt;/a&gt; so
    the feeder would substitute a ${NDC} variable in the XML file.&lt;/p&gt;

&lt;pre class=&quot;brush: scala&quot;&gt;val feeder = jdbcFeeder(&quot;jdbc:db2://server:50002/database&quot;, &quot;username&quot;, &quot;password&quot;,
    &quot;SELECT NDC FROM GENERICS&quot;)

val scn = scenario(&quot;Drug Service&quot;)
        .feed(feeder)
        .exec(http(host)
        .post(service)
        .headers(headers)
        .body(ELFileBody(&quot;DrugServiceSimulation_request.xml&quot;)))
&lt;/pre&gt;
&lt;p&gt;I deployed the new services to a test server and ran simulations with 100 and 1000 users. &lt;/p&gt;

&lt;blockquote&gt;
    &lt;dl&gt;
        &lt;dt&gt;&lt;strong&gt;100 users over 30 seconds&lt;/strong&gt;&lt;/dt&gt;
        &lt;dd&gt;Neither service had any failures with 100 users. The max response time for the legacy service was 389 ms,
            while
            the new service was 172 ms. The mean response time was lower for the legacy services: 89 ms vs. 96 ms.
        &lt;/dd&gt;
        &lt;dt&gt;&lt;strong&gt;1000 users over 60 seconds&lt;/strong&gt;&lt;/dt&gt;
        &lt;dd&gt;
            When simulating 1000 users against the legacy services, 50% of the requests failed and the average response
            time was
            over 40 seconds. Against the new services, all requests succeeded and the mean response time was 100ms.
        &lt;/dd&gt;
    &lt;/dl&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was pumped to see the new services didn&apos;t need any additional performance enhancements. These results were enough to convince my client that Apache Camel was going to be a performant replacement for IBM Message Broker.&lt;/p&gt;

&lt;p&gt;I wrote more simulations for another service I developed. In doing so, I discovered I missed implementing a couple
    custom routes for some clients. The dynamic feeders made me stumble onto this because they executed simulations
    for all clients. After developing the routes, the dynamic data helped me uncover a few more bugs. Using real
    data to load test with was very helpful in figuring out the edge-cases our routes needed to handle.
&lt;/p&gt;

&lt;p&gt;Next, I started configuring logging for our new Camel services.&lt;/p&gt;
&lt;h3 id=&quot;logging&quot;&gt;Logging with Log4j2&lt;/h3&gt;

&lt;p&gt;Log4j 2.0 had &lt;a href=&quot;http://www.infoq.com/news/2014/07/apache-log4j2&quot;&gt;just been released&lt;/a&gt; and my experience &lt;a href=&quot;https://github.com/appfuse/appfuse/pull/18&quot;&gt;integrating it in AppFuse&lt;/a&gt; motivated me to use it for this project. I configured Spring to use Log4j 2.0 by specifying the following dependencies. Note: Spring Boot 1.2+ has &lt;a href=&quot;http://docs.spring.io/spring-boot/docs/1.2.0.M2/reference/htmlsingle/#howto-configure-log4j-for-logging&quot;&gt;support for Log4j2&lt;/a&gt;.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;log4j.version&amp;gt;2.0&amp;lt;/log4j.version&amp;gt;
...

&amp;lt;!-- logging --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.slf4j&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;slf4j-api&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.7.7&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;!-- Necessary to configure Spring logging with log4j2.xml --&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.logging.log4j&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;log4j-jcl&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${log4j.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.logging.log4j&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;log4j-slf4j-impl&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${log4j.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.logging.log4j&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;log4j-web&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${log4j.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I created a &lt;code&gt;src/main/resources/log4j2.xml&lt;/code&gt; file and configured a general log, as well as one for each
    route. I configured
    each route to use &quot;log:com.company.app.route.input&quot; and &quot;log:com.company.app.route.output&quot; instead of &quot;log:input&quot;
    and &quot;log:output&quot;. This
    allowed the log-file-per-route configuration you see below.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;Configuration&amp;gt;
    &amp;lt;Properties&amp;gt;
        &amp;lt;Property name=&quot;fileLogDir&quot;&amp;gt;/var/log/app-name&amp;lt;/Property&amp;gt;
        &amp;lt;Property name=&quot;fileLogPattern&quot;&amp;gt;%d %p %c: %m%n&amp;lt;/Property&amp;gt;
        &amp;lt;Property name=&quot;fileLogTriggerSize&quot;&amp;gt;1 MB&amp;lt;/Property&amp;gt;
        &amp;lt;Property name=&quot;fileLogRolloverMax&quot;&amp;gt;10&amp;lt;/Property&amp;gt;
    &amp;lt;/Properties&amp;gt;
    &amp;lt;Appenders&amp;gt;
        &amp;lt;Console name=&quot;Console&quot; target=&quot;SYSTEM_OUT&quot;&amp;gt;
            &amp;lt;PatternLayout pattern=&quot;%d [%-15.15t] %-5p %-30.30c{1} %m%n&quot;/&amp;gt;
        &amp;lt;/Console&amp;gt;
        &amp;lt;RollingFile name=&quot;File&quot; fileName=&quot;${fileLogDir}/all.log&quot;
                         filePattern=&quot;${fileLogDir}/all-%d{yyyy-MM-dd}-%i.log&quot;&amp;gt;
            &amp;lt;PatternLayout pattern=&quot;${fileLogPattern}&quot;/&amp;gt;
            &amp;lt;Policies&amp;gt;
                &amp;lt;SizeBasedTriggeringPolicy size=&quot;${fileLogTriggerSize}&quot;/&amp;gt;
            &amp;lt;/Policies&amp;gt;
            &amp;lt;DefaultRolloverStrategy max=&quot;${fileLogRolloverMax}&quot;/&amp;gt;
        &amp;lt;/RollingFile&amp;gt;
        &amp;lt;RollingFile name=&quot;DrugServiceFile&quot; fileName=&quot;${fileLogDir}/drug-service.log&quot;
                         filePattern=&quot;${fileLogDir}/drug-service-%d{yyyy-MM-dd}-%i.log&quot;&amp;gt;
            &amp;lt;PatternLayout pattern=&quot;${fileLogPattern}&quot;/&amp;gt;
            &amp;lt;Policies&amp;gt;
                &amp;lt;SizeBasedTriggeringPolicy size=&quot;${fileLogTriggerSize}&quot;/&amp;gt;
            &amp;lt;/Policies&amp;gt;
            &amp;lt;DefaultRolloverStrategy max=&quot;${fileLogRolloverMax}&quot;/&amp;gt;
        &amp;lt;/RollingFile&amp;gt;
        &amp;lt;!-- Add a RollingFile for each route --&amp;gt;
    &amp;lt;/Appenders&amp;gt;

    &amp;lt;Loggers&amp;gt;
        &amp;lt;Logger name=&quot;org.apache.camel&quot; level=&quot;info&quot;/&amp;gt;
        &amp;lt;Logger name=&quot;org.springframework&quot; level=&quot;error&quot;/&amp;gt;
        &amp;lt;Logger name=&quot;com.company.app&quot; level=&quot;info&quot;/&amp;gt;

        &amp;lt;Root level=&quot;error&quot;&amp;gt;
            &amp;lt;AppenderRef ref=&quot;Console&quot;/&amp;gt;
            &amp;lt;AppenderRef ref=&quot;File&quot;/&amp;gt;
        &amp;lt;/Root&amp;gt;

        &amp;lt;Logger name=&quot;com.company.app.drugs&quot; level=&quot;debug&quot;&amp;gt;
            &amp;lt;AppenderRef ref=&quot;DrugServiceFile&quot;/&amp;gt;
        &amp;lt;/Logger&amp;gt;
        &amp;lt;!-- Add a Logger for each route --&amp;gt;
    &amp;lt;/Loggers&amp;gt;
&amp;lt;/Configuration&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I did run into some issues with this configuration:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;The &lt;code&gt;/var/log/app-name&lt;/code&gt; directory has to exist or
        there&apos;s a stacktrace on startup and no logs are written.
    &lt;/li&gt;
    &lt;li&gt;When deploy from Jenkins, I ran into permissions issues between deploys. To fix this, I &lt;em&gt;chowned&lt;/em&gt; the
        directory before restarting Tomcat.
&lt;pre&gt;chown -R tomcat /var/log/app-name
/etc/init.d/tomcat start&lt;/pre&gt;
    &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;monitoring&quot;&gt;Monitoring&lt;/h3&gt;

&lt;p&gt;
&lt;a href=&quot;http://hawt.io&quot;&gt;&lt;img src=&quot;//raibledesigns.com/repository/images/hawtio-logo.png&quot; width=&quot;150&quot; class=&quot;picture&quot; alt=&quot;hawtio&quot; style=&quot;margin-top: -20px&quot;&gt;&lt;/a&gt;
    While I was configuring the new services on our test server, I also installed &lt;a href=&quot;http://hawt.io&quot;&gt;hawtio&lt;/a&gt; at
    /console.
    I had previously configured it to run in Tomcat when running &quot;mvn tomcat7:run&quot;:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.tomcat.maven&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;tomcat7-maven-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.2&amp;lt;/version&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;path&amp;gt;/&amp;lt;/path&amp;gt;
        &amp;lt;webapps&amp;gt;
            &amp;lt;webapp&amp;gt;
                &amp;lt;contextPath&amp;gt;/console&amp;lt;/contextPath&amp;gt;
                &amp;lt;groupId&amp;gt;io.hawt&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;hawtio-web&amp;lt;/artifactId&amp;gt;
                &amp;lt;version&amp;gt;1.4.19&amp;lt;/version&amp;gt;
                &amp;lt;type&amp;gt;war&amp;lt;/type&amp;gt;
                &amp;lt;asWebapp&amp;gt;true&amp;lt;/asWebapp&amp;gt;
            &amp;lt;/webapp&amp;gt;
        &amp;lt;/webapps&amp;gt;
    &amp;lt;/configuration&amp;gt;
    ...
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;

&lt;p&gt;
    hawtio has a &lt;a href=&quot;http://hawt.io/plugins/camel/&quot;&gt;Camel plugin&lt;/a&gt; that&apos;s pretty slick. It shows all your routes
    and their runtime metrics; you can even edit the source code for routes. Even though I used a Java DSL, my routes are
    only editable as XML in hawtio. &lt;a href=&quot;http://www.davsclaus.com/2014/09/more-metrics-in-apache-camel-214.html&quot;&gt;Claus Ibsen has a good post&lt;/a&gt; on Camel&apos;s new &lt;a href=&quot;http://camel.apache.org/metrics-component.html&quot;&gt;Metrics Component&lt;/a&gt;. I&apos;d like to learn how to build a custom dashboard for hawtio - Claus&apos;s example looks pretty nice.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm4.staticflickr.com/3929/15540039275_908787e992_c.jpg&quot; title=&quot;Route Metrics by Matt Raible, on Flickr&quot; rel=&quot;lightbox[camel4]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/15540039275&quot;&gt;&lt;img src=&quot;https://farm4.staticflickr.com/3929/15540039275_908787e992_q.jpg&quot; width=&quot;150&quot; height=&quot;150&quot; alt=&quot;Route Metrics&quot; style=&quot;border: 1px solid silver&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm6.staticflickr.com/5613/15353416019_6d60d5a233_c.jpg&quot; title=&quot;Camel Dashboard by Matt Raible, on Flickr&quot; rel=&quot;lightbox[camel4]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/15353416019&quot;&gt;&lt;img src=&quot;https://farm6.staticflickr.com/5613/15353416019_6d60d5a233_q.jpg&quot; width=&quot;150&quot; height=&quot;150&quot; alt=&quot;Camel Dashboard&quot; style=&quot;margin-left: 15px; border: 1px solid silver&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;The Spring Boot plugin for hawtio is not nearly as graphic intensive. Instead, it just displays metrics and their values in a
    table format.&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://farm6.staticflickr.com/5603/15353183979_00894810fb_c.jpg&quot; title=&quot;hawtio Spring Boot plugin by Matt Raible, on Flickr&quot; rel=&quot;lightbox[camel4]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/15353183979&quot;&gt;
        &lt;img src=&quot;https://farm6.staticflickr.com/5603/15353183979_00894810fb_n.jpg&quot; width=&quot;320&quot; alt=&quot;hawtio Spring Boot plugin&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;There&apos;s some good-looking Spring Boot Admin UIs out there, notably JHipster&apos;s and the one in
    &lt;a href=&quot;https://blog.codecentric.de/en/2014/09/spring-boot-admin-first-official-release/&quot;&gt;spring-boot-admin&lt;/a&gt;. I hope the hawtio Spring Boot plugin gets prettier as it matures.
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a href=&quot;https://farm4.staticflickr.com/3936/15516103636_c2218300d8_c.jpg&quot; title=&quot;JHipster Metrics by Matt Raible, on Flickr&quot; rel=&quot;lightbox[camel4]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/15516103636&quot;&gt;&lt;img src=&quot;https://farm4.staticflickr.com/3936/15516103636_c2218300d8_q.jpg&quot; width=&quot;150&quot; alt=&quot;JHipster Metrics&quot; style=&quot;border: 1px solid silver&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;https://farm4.staticflickr.com/3944/15354176680_4c8fd7902e_c.jpg&quot; title=&quot;Spring Boot Admin Metrics by Matt Raible, on Flickr&quot; rel=&quot;lightbox[camel4]&quot; data-href=&quot;https://www.flickr.com/photos/mraible/15354176680&quot;&gt;&lt;img src=&quot;https://farm4.staticflickr.com/3944/15354176680_4c8fd7902e_q.jpg&quot; width=&quot;150&quot; alt=&quot;Spring Boot Admin Metrics&quot; style=&quot;margin-left: 15px; border: 1px solid silver&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;I wanted more than just monitoring, I wanted alerts when something went wrong. For that, I installed &lt;a href=&quot;https://docs.newrelic.com/docs/agents/java-agent/getting-started/new-relic-java&quot;&gt;New Relic&lt;/a&gt; on our
    Tomcat server. I&apos;m fond of getting the Monday reports, but they only showed activity when I was load testing.
&lt;/p&gt;

&lt;p&gt;I believe all these monitoring tools will be very useful once the app is in production. My last day with this client
    is next Friday, October 24. I&apos;m trying to finish up the last couple of services this week and next. With any luck,
    their IBM Message Broker will be replaced this year.&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;This article shows how to use Gatling to load test a SOAP service and how to configure Log4j2 with Spring Boot. It
    also shows how hawtio can help monitor and configure a Camel application. I hope you enjoyed reading this series
    on what I learned about developing with Camel over the past several months. If you have stories about your experience with Camel (or similar integration frameworks), Gatling, hawtio or New Relic, I&apos;d love to hear them.
&lt;/p&gt;

&lt;p&gt;
It&apos;s been a great experience and I look forward to developing solid apps, built on open source, for my next client. I&apos;d like to
    get back into HTML5, AngularJS and mobile development. I&apos;ve had a good time with Spring Boot and JHipster this year
    and hope to use them again. I find myself using Java 8 more and more; my ideal next project would embrace it as a
    baseline. As for Scala and Groovy, I&apos;m still a big fan and believe I can develop great apps with them.
&lt;/p&gt;
&lt;p&gt;
    If you&apos;re looking for a UI/API Architect that can help accelerate your projects, please &lt;a href=&quot;http://raibledesigns.com/contact.jsp&quot;&gt;let me know&lt;/a&gt;! You can learn more about my extensive experience from &lt;a href=&quot;https://www.linkedin.com/in/mraible&quot;&gt;my LinkedIn profile&lt;/a&gt;.
&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/getting_started_with_jhipster_on</id>
        <title type="html">Getting Started with JHipster on OS X</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/getting_started_with_jhipster_on"/>
        <published>2014-09-08T11:30:33-06:00</published>
        <updated>2014-10-30T14:30:12-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="jhipster" scheme="http://roller.apache.org/ns/tags/" />
        <category term="mac" scheme="http://roller.apache.org/ns/tags/" />
        <category term="nvm" scheme="http://roller.apache.org/ns/tags/" />
        <category term="docker" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yeoman" scheme="http://roller.apache.org/ns/tags/" />
        <category term="npm" scheme="http://roller.apache.org/ns/tags/" />
        <category term="node" scheme="http://roller.apache.org/ns/tags/" />
        <category term="osx" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
&lt;a href=&quot;http://jhipster.github.io/&quot;&gt;&lt;img src=&quot;http://jhipster.github.io/images/logo-jhipster2x.png&quot; class=&quot;picture&quot; width=&quot;187&quot;&gt;&lt;/a&gt;
    Last week I was tasked with developing a quick prototype that used AngularJS for its client and Spring MVC
    for its server. A colleague developed the same application using Backbone.js and Spring MVC.
    At first, I considered using my &lt;a href=&quot;https://github.com/mraible/boot-ionic&quot;&gt;boot-ionic&lt;/a&gt;
    project as a starting point. Then I realized I didn&apos;t need to develop a native mobile app, but rather a
    responsive web app.&lt;/p&gt;

&lt;p&gt;
    My colleague mentioned he was going to use &lt;a href=&quot;http://resthub.org/&quot;&gt;RESThub&lt;/a&gt; as his starting point, so I
    figured I&apos;d use &lt;a href=&quot;http://jhipster.github.io/&quot;&gt;JHipster&lt;/a&gt; as mine. We allocated a day to get our
    environments setup with the tools we needed, then timeboxed our first feature spike to four hours.
&lt;/p&gt;

&lt;p&gt;
    My first experience with JHipster failed the &lt;em&gt;10-minute test&lt;/em&gt;. I spent a lot of time
    flailing about with various &quot;npm&quot; and &quot;yo&quot; commands, getting permissions issues along the way. After getting
    thinks to work with some &lt;em&gt;sudo&lt;/em&gt; action, I figured I&apos;d try its &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;
    development environment. This experience was no better.
&lt;/p&gt;

&lt;p&gt;
    JHipster seems like a nice project, so I figured I&apos;d try to find the causes of my issues. This article is designed
    to save you the pain I had. If you&apos;d rather just see the steps to get up and running quickly, skip to the
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/getting_started_with_jhipster_on#summary&quot;&gt;summary&lt;/a&gt;.
&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;
&lt;a href=&quot;http://jhipster.github.io/&quot;&gt;&lt;img src=&quot;http://jhipster.github.io/images/logo-jhipster2x.png&quot; class=&quot;picture&quot; width=&quot;187&quot;&gt;&lt;/a&gt;
    Last week I was tasked with developing a quick prototype that used AngularJS for its client and Spring MVC
    for its server. A colleague developed the same application using Backbone.js and Spring MVC.
    At first, I considered using my &lt;a href=&quot;https://github.com/mraible/boot-ionic&quot;&gt;boot-ionic&lt;/a&gt;
    project as a starting point. Then I realized I didn&apos;t need to develop a native mobile app, but rather a
    responsive web app.&lt;/p&gt;

&lt;p&gt;
    My colleague mentioned he was going to use &lt;a href=&quot;http://resthub.org/&quot;&gt;RESThub&lt;/a&gt; as his starting point, so I
    figured I&apos;d use &lt;a href=&quot;http://jhipster.github.io/&quot;&gt;JHipster&lt;/a&gt; as mine. We allocated a day to get our
    environments setup with the tools we needed, then timeboxed our first feature spike to four hours.
&lt;/p&gt;

&lt;p&gt;
    My first experience with JHipster failed the &lt;em&gt;10-minute test&lt;/em&gt;. I spent a lot of time
    flailing about with various &quot;npm&quot; and &quot;yo&quot; commands, getting permissions issues along the way. After getting
    thinks to work with some &lt;em&gt;sudo&lt;/em&gt; action, I figured I&apos;d try its &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt;
    development environment. This experience was no better.
&lt;/p&gt;

&lt;p&gt;
    JHipster seems like a nice project, so I figured I&apos;d try to find the causes of my issues. This article is designed
    to save you the pain I had. If you&apos;d rather just see the steps to get up and running quickly, skip to the
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/getting_started_with_jhipster_on#summary&quot;&gt;summary&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
    The &quot;npm&quot; and &quot;yo&quot; issues I had seemed to be caused by a bad node/npm installation. To fix this, I
    &lt;a href=&quot;http://stackoverflow.com/questions/11177954/how-do-i-completely-uninstall-node-js-and-reinstall-from-beginning-mac-os-x&quot;&gt;removed
        node&lt;/a&gt; and installed &lt;a href=&quot;https://github.com/creationix/nvm&quot;&gt;nvm&lt;/a&gt;. Here&apos;s the commands I needed to
    remove node and npm:
&lt;/p&gt;
&lt;pre&gt;
sudo rm -rf /usr/local/lib/node_modules
sudo rm -rf /usr/local/include/node
sudo rm /usr/local/bin/node

sudo rm -rf /usr/local/bin/npm
sudo rm /usr/local/share/man/man1/node.1
sudo rm -rf /usr/local/lib/dtrace/node.d
sudo rm -rf ~/.npm
&lt;/pre&gt;
&lt;p&gt;Next, I ran &quot;brew doctor&quot; to make sure Homebrew was still happy. It told me some things were broken:&lt;/p&gt;
&lt;pre&gt;
$ brew doctor
Warning: Broken symlinks were found. Remove them with `brew prune`:
  /usr/local/bin/yo
  /usr/local/bin/ionic
  /usr/local/bin/grunt
  /usr/local/bin/bower
&lt;/pre&gt;
&lt;p&gt;I ran &lt;code&gt;brew update &amp;&amp; brew prune&lt;/code&gt;, followed by &lt;code&gt;brew install nvm&lt;/code&gt;. Next, I added the following
    to my ~/.profile:&lt;/p&gt;
&lt;pre&gt;
source $(brew --prefix nvm)/nvm.sh
&lt;/pre&gt;
&lt;p&gt;To install the latest version of node, I ran the commands below and set the latest version as the default:&lt;/p&gt;
&lt;pre&gt;
nvm ls-remote
nvm install v0.11.13
nvm alias default v0.11.13
&lt;/pre&gt;
&lt;p&gt;
    Once I had a fresh version of Node.js, I was able to run JHipster&apos;s &lt;a
        href=&quot;http://jhipster.github.io/installation.html&quot;&gt;local installation&lt;/a&gt;
    instructions.
&lt;/p&gt;
&lt;pre&gt;
npm install -g yo
npm install -g generator-jhipster
&lt;/pre&gt;
&lt;p&gt;Then I created my project:&lt;/p&gt;
&lt;pre&gt;yo jhipster&lt;/pre&gt;
&lt;p&gt;
    I was disappointed to find this created all the project files in my current directory, rather than in a
    subdirectory. I&apos;d recommend you do the following instead:
&lt;/p&gt;
&lt;pre&gt;
mkdir ~/projectname &amp;&amp; cd ~/projectname &amp;&amp; yo jhipster
&lt;/pre&gt;
&lt;p&gt;Before creating your project, JHipster asks you a number of questions. To see what they are, see its documentation on
    &lt;a href=&quot;http://jhipster.github.io/creating_an_app.html&quot;&gt;creating an application&lt;/a&gt;. Two things to be aware of:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Hot reloading Java code doesn&apos;t work well (yet) with Java 8&lt;/li&gt;
    &lt;li&gt;Its &lt;a href=&quot;https://github.com/jhipster/generator-jhipster/issues/490&quot;&gt;OAuth2 implementation doesn&apos;t work with
        WebSockets&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In other words, I&apos;d recommend using Java 7 + (cookie-based authentication with websockets) or (oauth2 authentication
    w/o websockets).&lt;/p&gt;

&lt;p&gt;After creating my project, I was able to run it using &quot;mvn spring-boot:run&quot; and view it at &lt;a
        href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt;. To get hot-reloading for the client, I ran &quot;grunt
    server&quot;
    and opened my browser to &lt;a href=&quot;http://localhost:9000&quot;&gt;http://localhost:9000&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;&lt;a name=&quot;docker&quot;&gt;&lt;/a&gt;JHipster + Docker on OS X&lt;/h3&gt;

&lt;p&gt;I had no luck getting the Docker instructions to work initially. I spent a couple hours on it, then gave up.
    A couple of days ago, I decided to give it another good ol&apos; &lt;em&gt;college-try&lt;/em&gt;. To make sure I figured out
    everything
    from scratch, I started by
    &lt;a href=&quot;http://therealmarv.com/blog/how-to-fully-uninstall-the-offical-docker-os-x-installation/&quot;&gt;removing
        Docker&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;I re-installed Docker and pulled the JHipster image using the following:&lt;/p&gt;
&lt;pre&gt;
sudo docker pull jdubois/jhipster-docker
&lt;/pre&gt;
&lt;p&gt;The error I got from this was the following:&lt;/p&gt;
&lt;pre&gt;
2014/09/05 19:43:38 Post http:///var/run/docker.sock/images/create?fromImage=jdubois%2Fjhipster-docker&amp;tag=:
dial unix /var/run/docker.sock: no such file or directory
&lt;/pre&gt;
&lt;p&gt;After doing some research, I learned I needed to run &lt;code&gt;boot2docker init&lt;/code&gt; first. Next I ran &lt;code&gt;boot2docker
    up&lt;/code&gt; to start the Docker daemon.
    Then I copied/pasted &quot;export DOCKER_HOST=tcp://192.168.59.103:2375&quot; into my console and tried to run &lt;code&gt;docker
        pull&lt;/code&gt; again.&lt;/p&gt;

&lt;p&gt;It failed with the same error. The solution was simpler than you might think: don&apos;t use &lt;code&gt;sudo&lt;/code&gt;.
&lt;/p&gt;

&lt;pre&gt;
$ docker pull jdubois/jhipster-docker
Pulling repository jdubois/jhipster-docker
01bdc74025db: Pulling dependent layers
511136ea3c5a: Download complete
...
&lt;/pre&gt;
&lt;p&gt;
    The next command that JHipster&apos;s documentation recommends is to run the Docker image, forward ports and share
    folders. When you run it, the terminal seems to hang and trying to ssh into it doesn&apos;t work. Others have
    &lt;a href=&quot;http://stackoverflow.com/questions/25559542/docker-hangs-when-starting-jdubois-jhipster-container-in-os-x/25582833&quot;&gt;recently
        reported a similar issue&lt;/a&gt;. I discovered the hanging is caused by a missing &quot;-d&quot; parameter and ssh doesn&apos;t
    work because you need to &lt;a href=&quot;http://stackoverflow.com/a/23021012/65681&quot;&gt;
    add a portmap to the VM to expose the port to your host&lt;/a&gt;. You can fix this by running the following:
&lt;/p&gt;
&lt;pre&gt;
boot2docker down
VBoxManage modifyvm &quot;boot2docker-vm&quot; --natpf1 &quot;containerssh,tcp,,4022,,4022&quot;
VBoxManage modifyvm &quot;boot2docker-vm&quot; --natpf1 &quot;containertomcat,tcp,,8080,,8080&quot;
VBoxManage modifyvm &quot;boot2docker-vm&quot; --natpf1 &quot;containergruntserver,tcp,,9000,,9000&quot;
VBoxManage modifyvm &quot;boot2docker-vm&quot; --natpf1 &quot;containergruntreload,tcp,,35729,,35729&quot;
boot2docker start
&lt;/pre&gt;
&lt;p&gt;After making these changes, I was able to start the image and ssh into it.&lt;/p&gt;
&lt;pre&gt;
docker run -d -v ~/jhipster:/jhipster -p 8080:8080 -p 9000:9000 -p 35729:35729 -p 4022:22 -t jdubois/jhipster-docker
ssh -p 4022 jhipster@localhost
&lt;/pre&gt;
&lt;p&gt;I tried creating a new project within the VM (&lt;code&gt;cd /jhipster &amp;&amp; yo jhipster&lt;/code&gt;), but it failed with the
    following error:&lt;/p&gt;
&lt;pre&gt;
/usr/lib/node_modules/generator-jhipster/node_modules/yeoman-generator/node_modules/mkdirp/index.js:89
                    throw err0;
                          ^
Error: EACCES, permission denied &apos;/jhipster/src&apos;
&lt;/pre&gt;
&lt;p&gt;The fix was giving the &quot;jhipster&quot; user ownership of the directory.&lt;/p&gt;
&lt;pre&gt;
sudo chown jhipster /jhipster
&lt;/pre&gt;
&lt;p&gt;After doing this, I was able to generate an app and run it using &quot;mvn spring-boot:run&quot; and access it from my Mac at
    &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt;. I was also able to run &quot;grunt server&quot; and see it at
    &lt;a href=&quot;http://localhost:9000&quot;&gt;http://localhost:9000&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;However, I was puzzled to see that there was nothing in my ~/jhipster directory. After doing some searching, I
    found that the &lt;a href=&quot;https://github.com/docker/docker/issues/4023&quot;&gt;docker run -v /host/path:/container/path
        doesn&apos;t work on OS X&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;David Gageot&apos;s &lt;a href=&quot;http://blog.javabien.net/2014/06/05/a-better-boot2docker-on-osx/&quot;&gt;A Better Boot2Docker on OSX&lt;/a&gt;
led me to &lt;a href=&quot;https://github.com/SvenDowideit/dockerfiles/tree/master/samba&quot;&gt;svendowideit/samba&lt;/a&gt;, which solved this problem.
The specifics are documented in boot2docker&apos;s &lt;a href=&quot;https://github.com/boot2docker/boot2docker#folder-sharing&quot;&gt;folder
        sharing&lt;/a&gt; section.
&lt;/p&gt;
&lt;p&gt;I shutdown my docker container by running &quot;docker ps&quot;, grabbing the first two characters of the id and then running:
    &lt;/p&gt;
&lt;pre&gt;
docker stop [2chars]
&lt;/pre&gt;
&lt;p&gt;
    I started the JHipster container without the -v parameter, used &quot;docker ps&quot; to find its name
    (&lt;em&gt;backstabbing_galileo&lt;/em&gt; in this case), then used that to add samba support.
&lt;/p&gt;
&lt;pre&gt;
docker run -d -p 8080:8080 -p 9000:9000 -p 35729:35729 -p 4022:22 -t jdubois/jhipster-docker
docker run --rm -v /usr/local/bin/docker:/docker -v /var/run/docker.sock:/docker.sock svendowideit/samba backstabbing_galileo
&lt;/pre&gt;
&lt;p&gt;Then I was able to connect using Finder &gt; Go &gt; Connect to Server, using the following for the server address:
&lt;/p&gt;
&lt;pre&gt;cifs://192.168.59.103/jhipster&lt;/pre&gt;
&lt;p&gt;To make this volume appear in my regular development area, I created a symlink:&lt;/p&gt;
&lt;pre&gt;ln -s /Volumes/jhipster ~/dev/jhipster&lt;/pre&gt;
&lt;p&gt;After doing this, all the files
were marked as read-only. To fix, I ran &quot;chmod -R 777 .&quot; in the directory on the server. I noticed that this also worked
    if I ran it from my Mac&apos;s terminal, but it took quite a while to traverse all the files. I noticed a similar delay
    when loading the project into IntelliJ.&lt;/p&gt;
&lt;h3&gt;&lt;a name=&quot;summary&quot;&gt;&lt;/a&gt;Summary&lt;/h3&gt;
&lt;p&gt;Phew! That&apos;s a lot of information that can be condensed down into four JHipster + Docker on OS X tips.&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Make sure your npm installation doesn&apos;t require sudo rights. If it does, reinstall using nvm.&lt;/li&gt;
    &lt;li&gt;Add portmaps to your VM to expose ports 4022, 8080, 9000 and 35729 to your host.&lt;/li&gt;
    &lt;li&gt;Change ownership on the /jhipster in the Docker image: sudo chown jhipster /jhipster.&lt;/li&gt;
    &lt;li&gt;Use svendowideit/samba to share your VM&apos;s directories with OS X.&lt;/li&gt;
&lt;/ol&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/why_i_prefer_intellij_idea</id>
        <title type="html">Why I prefer IntelliJ IDEA over Eclipse</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/why_i_prefer_intellij_idea"/>
        <published>2014-07-21T13:33:55-06:00</published>
        <updated>2014-11-06T20:03:50-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webdevelopment" scheme="http://roller.apache.org/ns/tags/" />
        <category term="intellij" scheme="http://roller.apache.org/ns/tags/" />
        <category term="idea" scheme="http://roller.apache.org/ns/tags/" />
        <category term="eclipse" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Over the last couple months, I&apos;ve received a few emails asking why I prefer &lt;a href=&quot;http://www.jetbrains.com/idea/&quot;&gt;IntelliJ IDEA&lt;/a&gt; over &lt;a href=&quot;https://www.eclipse.org/&quot;&gt;Eclipse&lt;/a&gt;. They usually go something like this:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
I keep seeing you recommending IntelliJ. I keep trying it intermittently with using Eclipse, but I feel like I&apos;m missing something obvious that makes so many people think it&apos;s better. 
Granted having the usual plugins incorporated is nice, but other things like the build process and debugger sometimes seems a step back from Eclipse. Could you please blog a &apos;10 reasons why I love IntelliJ&apos; or point me to something that would clue me in?
&lt;/p&gt;
&lt;p&gt;
I grew to love IntelliJ for a few reasons. It all started in 2006 when I decided to migrate &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; from Ant to Maven. Before that, I was a huge Eclipse fan (2002 - 2006). Before Eclipse, I used HomeSite, an HTML Editor to write all my Java code (1999-2002). Eclipse was the first IDE that didn&apos;t hog all my system&apos;s memory and was pleasant to work with.
&lt;/p&gt;
&lt;p&gt;
The reason I started using IntelliJ in 2006 was because of it&apos;s multi-module Maven support. Eclipse&apos;s Maven support was terrible, and m2e hasn&apos;t gotten a whole lot better in recent years AFAIK. 
&lt;/p&gt;
&lt;p&gt;
Back then, I used to think everything should be built and run from the command line. A couple years later, I realized it was better to run tests and debug from an IDE. Now I&apos;m more concerned with the ability to run tests and debug in an IDE than I am from the build system.
&lt;/p&gt;
&lt;p&gt;
In 2009, I started doing a lot more front-end work: writing HTML, CSS and JavaScript. I also started digging into alternate languages for these: Jade, GWT, CoffeeScript, LESS, SASS - even Scala. I found IntelliJ&apos;s support, and plugins, to be outstanding for these languages and really enjoyed how it would tell me I had invalid JavaScript, HTML and CSS. 
&lt;/p&gt;
&lt;p&gt;
My original passion in software was HTML and JavaScript and I found that hasn&apos;t changed in the last 15 years. AFAIK, Eclipse still has terrible web tools support; it excels at Java (and possibly C++ support). Even today, I write most of my HTML code (&lt;a href=&quot;http://www.infoq.com/author/Matt-Raible&quot;&gt;for InfoQ&lt;/a&gt; and this blog) in IntelliJ.
&lt;/p&gt;
&lt;p&gt;
In reality, it probably doesn&apos;t matter which IDE you use, as long as you&apos;re productive with it. Once you learn one IDE well, the way others do things will likely seem backwards. I&apos;m so familiar with debugging in IntelliJ, that when I tried to use Eclipse&apos;s debugger a few weeks ago, it seemed backwards to me. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;In a nutshell: the technologies I&apos;ve worked with have been better embraced by IntelliJ. Has this happened to you? Have certain technologies caused you to use one IDE over another?&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/this_site_now_powered_by</id>
        <title type="html">This site now powered by Java 8, Tomcat 7 and Wufoo Forms</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/this_site_now_powered_by"/>
        <published>2014-04-09T07:37:59-06:00</published>
        <updated>2014-05-08T20:09:00-06:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="tomcat7" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wufoo" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java8" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ssl" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apacheroller" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;I recently upgraded this site to use the latest version of &lt;a href=&quot;http://roller.apache.org/&quot;&gt;Apache Roller&lt;/a&gt;. It was a minor release (5.0.3), but I figured I&apos;d document the steps in case &quot;early onset&quot; comes soon. First of all, to download raibledesigns.com and get it running locally, I perform the following steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Backup everything using ~/bin/backup.sh on raibledesigns.com&lt;/li&gt;
&lt;li&gt;scp backup file to local hard drive and expand&lt;/li&gt;
&lt;li&gt;Copy ROOT, skins and repository directories to local webapps&lt;/li&gt;
&lt;li&gt;Make sure activation, mail, mysql and jta JARs are in $CATALINA_HOME/lib&lt;/li&gt;
&lt;li&gt;Copy roller-custom.properties from raibledesigns.com&apos;s $CATALINA_HOME/lib&lt;/li&gt;
&lt;li&gt;Copy context files from hosted $CATALINA_HOME/conf/Catalina to local directory&lt;/li&gt;
&lt;li&gt;Import database and change roller-custom.properties to match local credentials&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, to upgrade to the latest Roller release, I do the following:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download latest Roller release and expand&lt;/li&gt;
&lt;li&gt;Copy JARs (from WEB-INF/lib) to existing install (to upgrade dependencies)&lt;/li&gt;
&lt;li&gt;Delete any lower-versioned JARS from WEB-INF/lib directory&lt;/li&gt;
&lt;li&gt;Copy JSPs (from WEB-INF/jsps) to existing install&lt;/li&gt;
&lt;li&gt;Run database migration scripts from WEB-INF/classes/dbscripts&lt;/li&gt;
&lt;li&gt;Use a diff tool (like SmartSynchronize) to compare new vs. existing&lt;/li&gt;
&lt;li&gt;Test and troubleshoot (if there&apos;s startup errors)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This process has worked well for the last 10 years, and it&apos;s been in my head the whole time. It&apos;s bound to escape someday.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contact Form Enhancements&lt;/strong&gt;&lt;br/&gt;
In addition to upgrading Roller, I also upgraded Tomcat 6 to Tomcat 7.0.52. In doing so, I found &lt;a href=&quot;http://tomcat.markmail.org/thread/3jbtasxiaekzgi62&quot;&gt;Jakarta&apos;s Mailer Taglib doesn&apos;t work with Tomcat 7&lt;/a&gt;. As you can tell from the aforementioned thread, I&apos;ve known this for several years. That&apos;s the only thing that&apos;s stopped me from upgrading Tomcat the past couple years. 
&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;I recently upgraded this site to use the latest version of &lt;a href=&quot;http://roller.apache.org/&quot;&gt;Apache Roller&lt;/a&gt;. It was a minor release (5.0.3), but I figured I&apos;d document the steps in case &quot;early onset&quot; comes soon. First of all, to download raibledesigns.com and get it running locally, I perform the following steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Backup everything using ~/bin/backup.sh on raibledesigns.com&lt;/li&gt;
&lt;li&gt;scp backup file to local hard drive and expand&lt;/li&gt;
&lt;li&gt;Copy ROOT, skins and repository directories to local webapps&lt;/li&gt;
&lt;li&gt;Make sure activation, mail, mysql and jta JARs are in $CATALINA_HOME/lib&lt;/li&gt;
&lt;li&gt;Copy roller-custom.properties from raibledesigns.com&apos;s $CATALINA_HOME/lib&lt;/li&gt;
&lt;li&gt;Copy context files from hosted $CATALINA_HOME/conf/Catalina to local directory&lt;/li&gt;
&lt;li&gt;Import database and change roller-custom.properties to match local credentials&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Next, to upgrade to the latest Roller release, I do the following:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Download latest Roller release and expand&lt;/li&gt;
&lt;li&gt;Copy JARs (from WEB-INF/lib) to existing install (to upgrade dependencies)&lt;/li&gt;
&lt;li&gt;Delete any lower-versioned JARS from WEB-INF/lib directory&lt;/li&gt;
&lt;li&gt;Copy JSPs (from WEB-INF/jsps) to existing install&lt;/li&gt;
&lt;li&gt;Run database migration scripts from WEB-INF/classes/dbscripts&lt;/li&gt;
&lt;li&gt;Use a diff tool (like SmartSynchronize) to compare new vs. existing&lt;/li&gt;
&lt;li&gt;Test and troubleshoot (if there&apos;s startup errors)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This process has worked well for the last 10 years, and it&apos;s been in my head the whole time. It&apos;s bound to escape someday.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Contact Form Enhancements&lt;/strong&gt;&lt;br/&gt;
In addition to upgrading Roller, I also upgraded Tomcat 6 to Tomcat 7.0.52. In doing so, I found &lt;a href=&quot;http://tomcat.markmail.org/thread/3jbtasxiaekzgi62&quot;&gt;Jakarta&apos;s Mailer Taglib doesn&apos;t work with Tomcat 7&lt;/a&gt;. As you can tell from the aforementioned thread, I&apos;ve known this for several years. That&apos;s the only thing that&apos;s stopped me from upgrading Tomcat the past couple years. 
&lt;/p&gt;
Rather than using my own code to send email, I figured I&apos;d &lt;a href=&quot;https://twitter.com/mraible/status/448227865889210368&quot;&gt;explore my options&lt;/a&gt;. I looked into &lt;a href=&quot;http://kontactr.com/&quot;&gt;Kontactr&lt;/a&gt;, &lt;a href=&quot;http://www.emailmeform.com/&quot;&gt;EmailMeForm&lt;/a&gt; and &lt;a href=&quot;http://www.wufoo.com/&quot;&gt;Wufoo&lt;/a&gt;. The first two allowed me to customize their colors, but Wufoo was the only one that had a transparent background feature. Because Wufoo form&apos;s are transparent, and I&apos;d &lt;a href=&quot;http://issues.appfuse.org/browse/APF-309&quot;&gt;copied their CSS for AppFuse&apos;s forms&lt;/a&gt; in the past, I decided to use it. To make it work with both of this site&apos;s themes (light and dark), I did need to create two forms on Wufoo and do some local JavaScript modifications. You can see the results on &lt;a href=&quot;http://raibledesigns.com/rd/page/contact&quot;&gt;my contact page&lt;/a&gt; (view-source to see the JavaScript). If you switch the theme (by clicking the little rectangles in the top-right corner), you can see how the form is redrawn with the proper color scheme.
&lt;/p&gt;
&lt;p&gt;If I&apos;d found it sooner, I likely would&apos;ve used &lt;a href=&quot;http://forms.brace.io/&quot;&gt;Brace Forms&lt;/a&gt; for my contact form.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Theme Improvements&lt;/strong&gt;&lt;br/&gt;
Ever since I &lt;a href=&quot;http://raibledesigns.com/rd/entry/new_look_and_feel_designed&quot;&gt;switched to a new look and feel&lt;/a&gt;, there&apos;s been improvements I wanted to make. &lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
The stylesheet switching doesn&apos;t happen as fast as I&apos;d hoped (there&apos;s a flash even if using cookies), so I&apos;ll likely be converting some theme-setting logic to the server-side. The HTML5 version of the FaceBook Like Button requires you to specify the &quot;data-colorscheme&quot; in markup so this further supports moving to the server.
&lt;/blockquote&gt;
&lt;p&gt;To fix this issue, I tried &lt;a href=&quot;http://markmail.org/message/jdhfplj4kd27ub7e&quot;&gt;creating a cookie-reader plugin&lt;/a&gt; for Roller. This worked, but not as well as I&apos;d hoped. The theme cookie was read the first time the page loaded, but then cached for subsequent requests. If a user changed their theme, the new value would not be read by the cached page. My solution now is putting the JavaScript &lt;em&gt;set-default-theme&lt;/em&gt; logic right after the stylesheet to set it before the body loads.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Powered by Java 8&lt;/strong&gt;&lt;br/&gt;
To make this site run on Java 8, I had to move to a new server. &lt;a href=&quot;http://kgbinternet.com&quot;&gt;Keith&lt;/a&gt; did a bunch of work on my old server to get Java 8 working, but found Linux JDK 7 code has dependancies on the 2.6 kernel. If you&apos;re reading this post, the DNS changes have propagated. This means I have my first Java 8 app in production! &lt;img src=&quot;//raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot;&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Secured by SSL&lt;/strong&gt;&lt;br/&gt;
The last change I made was to start using my SSL certificate on this site. You can read about the challenges I encountered &lt;a href=&quot;http://markmail.org/message/uorad3gme6hj3syy&quot;&gt;on the Roller mailing list&lt;/a&gt;. The final solution involved changing my Absolute URL to use https and then changing my theme to use the following for its base.&lt;/p&gt;
&lt;pre&gt;&amp;lt;base href=&quot;$absBaseURL.replace(&apos;https:&apos;, &apos;&apos;)&quot; /&gt;&lt;/pre&gt;
&lt;p&gt;I also had to change a number of iframes to use src=&quot;//...&quot; instead of src=&quot;//...&quot;. To force HTTPS for the admin pages, Keith configured Apache to do the redirect. Using Roller to redirect resulted in infinite loop errors. 
&lt;/p&gt;
&lt;p&gt;This means you can now access this site using &lt;a href=&quot;https://raibledesigns.com&quot;&gt;https://raibledesigns.com&lt;/a&gt; or &lt;a href=&quot;http://raibledesigns.com&quot;&gt;http://raibledesigns.com&lt;/a&gt;, whichever you prefer. Speaking of SSL, you might wonder if this new server is affected by &lt;a href=&quot;http://heartbleed.com/&quot;&gt;The Heartbleed Bug&lt;/a&gt;. According to Keith, it is not.
&lt;blockquote class=&quot;quote&quot;&gt;
This server is still running openSSL 1.0.0 which was shipped with Centos 6.1, and the Heartbleed vulnerability appeared in OpenSSL 1.0.1 which shipped Centos 6.5.&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
This site has undergone quite a few updates this month: Roller 5.0.3, Tomcat 7.0.52, &lt;a href=&quot;http://raible.kgbinternet.com/rd/page/contact&quot;&gt;a Wufoo contact form (+ recent tweets on the same page)&lt;/a&gt;, Java 8 and optional SSL. If you see any issues, please let me know.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;May 8, 2014 Update&lt;/strong&gt;: I decided to revert to &quot;http&quot; for the absolute URL instead of &quot;https&quot;. However, I&apos;ve updated all &quot;src&quot; attributes on &amp;lt;iframe&gt; and &amp;lt;img&gt; tags to use schema-less URLs (// instead of http://). This means that both secure and non-secure URLs should work.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/2013_a_year_in_review</id>
        <title type="html">2013 - A Year in Review</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/2013_a_year_in_review"/>
        <published>2014-01-31T08:53:10-07:00</published>
        <updated>2014-07-26T21:11:02-06:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yearinreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="2013" scheme="http://roller.apache.org/ns/tags/" />
        <category term="blogging" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;2013 was an amazing year:
    Trish and I got married, celebrated on a &apos;round-the-world honeymoon and invested in a new 4x4 VW Bus. I finally
    achieved my goal of vacationing 25% and I got to spend more than two months in the presence of my wonderful parents.
&lt;/p&gt;
&lt;p&gt;
    For this Year in Review post, I&apos;ll use the same format as I did &lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review&quot;&gt;last
        year&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#2014&quot;&gt;2014&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;
    For the last few years, I&apos;ve generally had one client per year. That changed this year when my contract with Oracle
    ended in May. Fortunately, I had the opportunity to develop a cool dashboard application before I finished. I
    wrote about it in a four-part series.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;2013 was an amazing year:
    Trish and I got married, celebrated on a &apos;round-the-world honeymoon and invested in a new 4x4 VW Bus. I finally
    achieved my goal of vacationing 25% and I got to spend more than two months in the presence of my wonderful parents.
&lt;/p&gt;
&lt;p&gt;
    For this &lt;a href=&quot;http://raibledesigns.com/rd/tags/yearinreview&quot;&gt;Year in Review&lt;/a&gt; post, I&apos;ll use the same format as I did &lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review&quot;&gt;last
        year&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
        &lt;ul&gt;
            &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
            &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2013_a_year_in_review#2014&quot;&gt;2014&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;
    For the last few years, I&apos;ve generally had one client per year. That changed this year when my contract with Oracle
    ended in May. Fortunately, I had the opportunity to develop a cool dashboard application before I finished. I
    wrote about it in a four-part series.&lt;/p&gt;
&lt;ul&gt;

    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_with_angularjs_part_i&quot;&gt;Developing with AngularJS - Part I:
        The Basics&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_with_angularjs_part_ii&quot;&gt;Developing with AngularJS - Part
        II: Dialogs and Data&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_with_angularjs_part_iii&quot;&gt;Developing with AngularJS - Part
        III: Services&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_with_angularjs_part_iv&quot;&gt; Developing with AngularJS - Part
        IV: Making it Pop&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
    I engaged in a month-long contract with &lt;a href=&quot;http://www.travelport.com/&quot;&gt;Travelport&lt;/a&gt;
    to keep me busy in June. They hired me to develop a portal consolidation prototype, which I did with AngularJS,
    Grails and LDAP. I showcased &lt;a href=&quot;http://vimeo.com/80314102&quot;&gt;that application&lt;/a&gt; at Devoxx in November.
&lt;/p&gt;
&lt;p&gt;In September, I started a new gig with &lt;a href=&quot;http://www.johnmuirhealth.com/&quot;&gt;John Muir Health&lt;/a&gt;. I was hired
    to help with their mobile architecture, and spent my first couple months doing front-end optimizing and helping get
    their MyJMH product released. Once the release was complete, I proposed a mobile architecture and started assisting
    with the development of their mobile application.
&lt;/p&gt;
&lt;p&gt;
    We&apos;re developing the Mobile API with &lt;a href=&quot;http://projects.spring.io/spring-boot/&quot;&gt;Spring Boot&lt;/a&gt;. I wrote about
    my initial experience in &lt;a href=&quot;http://raibledesigns.com/rd/entry/a_webapp_makeover_with_spring&quot;&gt;A Webapp Makeover
    with Spring 4 and Spring Boot&lt;/a&gt;. My contract with John Muir Health is through the end of March and I hope to
    start something new shortly after.
&lt;/p&gt;
&lt;p&gt;In October, I started &lt;a href=&quot;http://raibledesigns.com/rd/entry/writing_for_infoq&quot;&gt;Writing for InfoQ&lt;/a&gt; and I&apos;ve
    really enjoyed it so far. You can see the articles I&apos;ve written on &lt;a
            href=&quot;http://www.infoq.com/author/Matt-Raible&quot;&gt;my author page&lt;/a&gt; or by clicking the links below:&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://www.infoq.com/articles/javaone2013-roundup&quot;&gt;JavaOne 2013 Roundup: Java 8 is Revolutionary, Java
        is back&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://www.infoq.com/news/2013/11/netty4-twitter&quot;&gt;Netty 4 Reduces GC Overhead by 5x at Twitter&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://www.infoq.com/news/2013/12/spring4&quot;&gt;Spring 4 Enhances Support for Java 8, Java EE 7, REST and
        HTML5&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;speaking&quot;&gt;Speaking&lt;/h3&gt;
&lt;p&gt;I spoke at five events in 2013:&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Denver JUG on &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_modern_java_web_developer&quot;&gt;The Modern Java Web
        Developer and Java Web Security&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;Devoxx France on &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_france_a_great_conference&quot;&gt;Comparing JVM Web
        Frameworks and Play vs. Grails&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;HTML5 Denver on &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_bootstrap_presentation_from_html5&quot;&gt;Bootstrap&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;JavaOne: I &lt;a href=&quot;http://raibledesigns.com/rd/entry/javaone_2013 JavaOne 2013&quot;&gt;spoke for the first time&lt;/a&gt;
        and &lt;a href=&quot;http://raibledesigns.com/rd/entry/javaone_2013_videos_of_presentations&quot;&gt;received a Rock Star
            Award&lt;/a&gt;
    &lt;/li&gt;
    &lt;li&gt;Devoxx and a Nordic Countries Speaking Tour on &lt;a
            href=&quot;http://raibledesigns.com/rd/entry/devoxx_2013_a_nordic_countries&quot;&gt;The Modern Java Web Developer&lt;/a&gt;
    &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It seems that folks liked my presentations since they were in &lt;a href=&quot;http://www.slideshare.net/yearinreview/mraible/ycEAAA&quot;&gt;the top 1% of most viewed on SlideShare in 2013&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
    Trish took many &lt;a href=&quot;http://raibledesigns.com/rd/entry/paris_and_iceland_a_photographers&quot;&gt;beautiful
    photos&lt;/a&gt; as part of our trip to Devoxx France.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8615035109/&quot;
       href=&quot;http://farm9.staticflickr.com/8108/8615035109_cb5d88a4ed_c.jpg&quot;
       title=&quot;Our Lady Liberty and Eiffel Tower by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8108/8615035109_cb5d88a4ed_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;Our Lady Liberty and Eiffel Tower&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8615047387/&quot;
       href=&quot;http://farm9.staticflickr.com/8384/8615047387_93155b7fcc_c.jpg&quot;
       title=&quot;R&#233;cipon Quadrigas France by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8384/8615047387_93155b7fcc_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;R&#233;cipon Quadrigas France&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;


    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8616147874/&quot;
       href=&quot;http://farm9.staticflickr.com/8543/8616147874_8e0de9d7aa_c.jpg&quot;
       title=&quot;Boats Seine River Eiffel Tower by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8543/8616147874_8e0de9d7aa.jpg&quot; width=&quot;500&quot;
            alt=&quot;Boats Seine River Eiffel Tower&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8616151686/&quot;
       href=&quot;http://farm9.staticflickr.com/8266/8616151686_89d7bfdf75_c.jpg&quot;
       title=&quot;Statue Of LaFayette Cours La Reine Paris Frances by McGinityPhoto, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8266/8616151686_89d7bfdf75.jpg&quot;
                                             width=&quot;500&quot;
                                             alt=&quot;Statue Of LaFayette Cours La Reine Paris Frances&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
    We stopped in Iceland on the way home to see the &lt;a
        href=&quot;http://www.flickr.com/photos/mcginityphoto/sets/72157633161145490/&quot;&gt;Northern
    Lights&lt;/a&gt;.

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8617531184/&quot;
       href=&quot;http://farm9.staticflickr.com/8262/8617531184_a688cb0f88_c.jpg&quot;
       title=&quot;Northern Lights 19 by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8262/8617531184_a688cb0f88.jpg&quot; width=&quot;500&quot; alt=&quot;Northern Lights 19&quot;
            style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;h3 id=&quot;projects&quot;&gt;Projects&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;AppFuse:&lt;/strong&gt; I released &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_light_2_2_1&quot;&gt;AppFuse Light
    2.2.1&lt;/a&gt; in January and
    switched AppFuse from JSF&apos;s &lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to&quot;&gt;MyFaces to
        PrimeFaces&lt;/a&gt; in February. I blogged about &lt;a
            href=&quot;http://raibledesigns.com/rd/entry/integrating_gwt_into_appfuse&quot;&gt;AppFuse&apos;s GWT integration&lt;/a&gt; in March
    and
    celebrated the project&apos;s &lt;a href=&quot;http://raibledesigns.com/rd/entry/happy_10_year_appfuse&quot;&gt;10 year anniversary in
        April&lt;/a&gt;. AppFuse 3.0 was released &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_3_0_released&quot;&gt;just before
        Christmas&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;
    &lt;strong&gt;Roller:&lt;/strong&gt; I didn&apos;t contribute any code to the Roller project in 2013, but I did &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/responsive_design_with_css_media&quot;&gt;make this site responsive with CSS
    media queries&lt;/a&gt;.
&lt;/p&gt;
&lt;h2 id=&quot;personal&quot;&gt;Personal&lt;/h2&gt;
&lt;p&gt;
    Trish and I started our world travels in March with a trip to &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/magnificent_mexico&quot;&gt;Magnificent Mexico&lt;/a&gt;. We had a wonderful time
    playing with old friends and renting a house on the beach.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mraible/8491989219/&quot;
       href=&quot;https://farm9.staticflickr.com/8096/8491989219_5150a05565_c.jpg&quot; title=&quot;The Pool by mraible, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;https://farm9.staticflickr.com/8096/8491989219_5150a05565_q.jpg&quot;
                                             width=&quot;150&quot; alt=&quot;The Pool&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mraible/8491993847/&quot;
       href=&quot;https://farm9.staticflickr.com/8366/8491993847_a77a00081d_c.jpg&quot; title=&quot;My Love and I by mraible, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;https://farm9.staticflickr.com/8366/8491993847_a77a00081d_q.jpg&quot;
                                             width=&quot;150&quot; alt=&quot;My Love and I&quot;
                                             style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mraible/8491997899/&quot;
       href=&quot;https://farm9.staticflickr.com/8388/8491997899_190ec7bfd0_c.jpg&quot;
       title=&quot;Julie at Sunset by mraible, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;https://farm9.staticflickr.com/8388/8491997899_190ec7bfd0_q.jpg&quot;
                                             width=&quot;150&quot; alt=&quot;Julie at Sunset&quot;
                                             style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8525669404/&quot;
       href=&quot;http://farm9.staticflickr.com/8097/8525669404_4fc25f6bb8_c.jpg&quot;
       title=&quot;Chacala Sunset by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8097/8525669404_4fc25f6bb8.jpg&quot; width=&quot;500&quot;
            alt=&quot;Chacala Sunset&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8524458091/&quot;
       href=&quot;http://farm9.staticflickr.com/8368/8524458091_721ed22fe7_c.jpg&quot;
       title=&quot;What a great posse! by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8368/8524458091_721ed22fe7_q.jpg&quot; width=&quot;150&quot;
            alt=&quot;What a great posse!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8525571064/&quot;
       href=&quot;http://farm9.staticflickr.com/8243/8525571064_da036d44a7_c.jpg&quot;
       title=&quot;The Chacala gang! by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8243/8525571064_da036d44a7_q.jpg&quot; width=&quot;150&quot;
            alt=&quot;The Chacala gang!&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

    &lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8525569828/&quot;
       href=&quot;http://farm9.staticflickr.com/8521/8525569828_1eb8850118_c.jpg&quot;
       title=&quot;YAY Chacalas! by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8521/8525569828_1eb8850118_q.jpg&quot; width=&quot;150&quot;
            alt=&quot;YAY Chacalas!&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;

&lt;p&gt;Our trip to &lt;a href=&quot;http://raibledesigns.com/rd/entry/paris_and_iceland_a_photographers&quot;&gt;Paris and Iceland&lt;/a&gt; was a
    dream come true for Trish. Watching the Aurora Borealis dance in the sky is something I&apos;ll never forget.&lt;/p&gt;
&lt;p&gt;
    To end the ski season in April, we &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_trifecta_2013&quot;&gt;completed the
    trifecta&lt;/a&gt; (3 ski resorts in 3 days) with
    a fun family weekend.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm9.staticflickr.com/8246/8662516874_f2400ba9c6_c.jpg&quot; title=&quot;13&amp;quot; Powder Day at Copper!&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8246/8662516874_f2400ba9c6.jpg&quot;
                                             width=&quot;500&quot; alt=&quot;13&amp;quot; Powder Day at Copper!&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
    The last week of the ski season was epic, as I described in a &lt;a href=&quot;http://raibledesigns.com/rd/entry/life_update1&quot;&gt;life
    update&lt;/a&gt;.
&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;
    The last week in Winter Park was the best skiing of the year. The first (Tuesday) afternoon, I started skiing around
    1pm and it snowed all afternoon - resulting in several inches by the end of the day. The next day was smooth and
    empty, followed by a day of deep powder and knee-deep runs down Eagle Wind. I had one of the best runs of my life
    that day.
&lt;/p&gt;

&lt;p&gt;
    I wrote about the &apos;66 Bus Project and how I removed it from Motorworks Restorations after six years.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm9.staticflickr.com/8522/8615924358_c863705496_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/8615924358/&quot; title=&quot;Sweet Stance by mraible, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8522/8615924358_c863705496_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;Sweet Stance&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;http://farm9.staticflickr.com/8263/8615925190_80b016767b_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/8615925190/&quot; title=&quot;Love That Boy by mraible, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8263/8615925190_80b016767b_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;Love That Boy&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm8.staticflickr.com/7418/9032950835_57cf83c68f_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/9032950835/&quot; title=&quot;Leaving Motorworks by mraible, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm8.staticflickr.com/7418/9032950835_57cf83c68f_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;Leaving Motorworks&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;http://farm4.staticflickr.com/3679/9035175304_773922f83b_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/9035175304/&quot;
       title=&quot;Time to get this thing done! by mraible, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm4.staticflickr.com/3679/9035175304_773922f83b_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;Time to get this thing done!&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    We spent the first weekends in June &lt;a href=&quot;http://raibledesigns.com/rd/entry/father_s_day_weekend_on&quot;&gt;on the
    Colorado River&lt;/a&gt;.
    One of the biggest highlights for me was catching a 16&quot; Trout, right after Trish saw it jump and told me exactly
    where to cast my line. The fact that I was able to cast it to the precise spot was cool enough, but getting the fish
    on my line moments later was exhilarating. Shortly after, a majestic Bald Eagle flew over us and we all dropped our
    jaws in amazement.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-href=&quot;http://www.flickr.com/photos/mraible/9071726423/&quot;
       href=&quot;http://farm8.staticflickr.com/7332/9071726423_3d1faf669c_c.jpg&quot; title=&quot;My Crew&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7332/9071726423_3d1faf669c_m.jpg&quot;
                                             width=&quot;240&quot; alt=&quot;My Crew&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a data-href=&quot;http://www.flickr.com/photos/mraible/9071727141/&quot;
       href=&quot;http://farm4.staticflickr.com/3668/9071727141_b3ce9e3286_c.jpg&quot; title=&quot;Roasting Hot Dogs&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3668/9071727141_b3ce9e3286_m.jpg&quot;
                                             width=&quot;240&quot; alt=&quot;Roasting Hot Dogs&quot;
                                             style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-href=&quot;http://www.flickr.com/photos/mraible/9071648965/&quot;
       href=&quot;http://farm4.staticflickr.com/3725/9071648965_b142ae7f05_c.jpg&quot; title=&quot;16 Incher&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3725/9071648965_b142ae7f05.jpg&quot;
                                             width=&quot;500&quot; alt=&quot;16 Incher&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Trish and I started a two month sabbatical in July to &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/matrimony_in_montana&quot;&gt;get married in proper
    fashion&lt;/a&gt; in the town I grew up in. She looked absolutely stunning.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm8.staticflickr.com/7431/9624418537_21f624efcc_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9624418537/&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7431/9624418537_21f624efcc.jpg&quot;
                                             width=&quot;500&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;During the ceremony, I surprised her with a 162-page
    book I built with my words and her pictures.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm4.staticflickr.com/3775/9624416155_92cb67d722_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9624416155/&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3775/9624416155_92cb67d722_m.jpg&quot;
                                             width=&quot;240&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;http://farm4.staticflickr.com/3756/9627642486_c1c3cca8b2_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9627642486/&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3756/9627642486_c1c3cca8b2_m.jpg&quot;
                                             width=&quot;240&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
                                             style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    When asked if I&apos;d take her as my lawfully-wedded wife, I shouted as &quot;YES!&quot; at the top of my lungs. Trish agreed enthusiastically and we were pronounced husband and wife.
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm8.staticflickr.com/7348/9624417367_a672878836_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9624417367/&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7348/9624417367_a672878836_m.jpg&quot;
                                             width=&quot;240&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;http://farm8.staticflickr.com/7337/9624416939_a67bb07e70_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9624416939/&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7337/9624416939_a67bb07e70_m.jpg&quot;
                                             width=&quot;240&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
                                             style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a href=&quot;http://farm8.staticflickr.com/7442/9627648458_38de03b06a_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9627648458/&quot; title=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7442/9627648458_38de03b06a.jpg&quot;
                                             width=&quot;500&quot; alt=&quot;Raible &amp;amp; McGinity Wedding Photos&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;Our wedding week was an unbelievably fun experience with many, many friends and family. We look forward to
    celebrating it over and over again as long as we live.&lt;/p&gt;
&lt;p&gt;
    We had a day of rest following the wedding, then drove back to Denver to begin our &apos;round-the-world honeymoon
    without phones. We spent a month traveling to &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/around_the_world_honeymoon_1st&quot;&gt;Ireland&lt;/a&gt;,
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/around_the_world_honeymoon_2nd&quot;&gt;Italy&lt;/a&gt;,
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/around_the_world_honeymoon_3rd&quot;&gt;Thailand&lt;/a&gt; and
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/around_the_world_honeymoon_last&quot;&gt;Fiji&lt;/a&gt;. It was a wonderful journey
    and we greatly enjoyed all the people, places and experiences.

&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a href=&quot;http://farm8.staticflickr.com/7342/10322700916_88449ec9ea_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/10322700916/&quot;
       title=&quot;Ballynahinch Castle Ireland by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm8.staticflickr.com/7342/10322700916_88449ec9ea.jpg&quot; width=&quot;500&quot;
            alt=&quot;Ballynahinch Castle Ireland&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;http://farm8.staticflickr.com/7362/9902197834_90ef009fd8_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9902197834/&quot; rel=&quot;lightbox[2013yearinreview]&quot; title=&quot;View from hills
	just outside of La Morra Italy! by McGinityPhoto, on Flickr&quot;&gt;&lt;img
            src=&quot;//farm8.staticflickr.com/7362/9902197834_90ef009fd8.jpg&quot; width=&quot;500&quot;
            alt=&quot;View from hills just outside of La Morra Italy!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a data-href=&quot;http://www.flickr.com/photos/mcginityphoto/10076904953/&quot;
       href=&quot;http://farm3.staticflickr.com/2871/10076904953_34cb763f5c_c.jpg&quot;
       title=&quot;View of Ang Thong National Marine Park by McGinityPhoto, on Flickr&quot;
       rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img src=&quot;//farm3.staticflickr.com/2871/10076904953_34cb763f5c.jpg&quot;
                                             width=&quot;500&quot; alt=&quot;View of Ang Thong National Marine Park&quot;
                                             style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a href=&quot;http://farm6.staticflickr.com/5343/10177404544_1358494510_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/10177404544/&quot;
       title=&quot;Chillin&apos; in Qamea Fiji by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm6.staticflickr.com/5343/10177404544_1358494510.jpg&quot; width=&quot;500&quot; alt=&quot;Chillin&apos; in Qamea Fiji&quot;
            style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We arrived back in the US at the end of August, just in time to celebrate &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/happy_birthday_jack5&quot;&gt;Jack&apos;s 9th birthday&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    In September, we got loud at
    the Broncos Home Opener, and experienced beautiful Colorado fall weather with trips to Estes Park and Aspen. In
    October, we
    traveled to Minnesota for a best friend&apos;s wedding. We also visited Pennsylvania to spend some time with Trish&apos;s parents.
&lt;/p&gt;
&lt;p&gt;
    &lt;a href=&quot;http://farm4.staticflickr.com/3731/10424172085_fbf8ebb173_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/10424172085&quot;
       title=&quot;Right 3/4&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm4.staticflickr.com/3731/10424172085_fbf8ebb173_t.jpg&quot; width=&quot;100&quot; alt=&quot;Right 3/4&quot;
            style=&quot;border: 1px solid black&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;

    &lt;a href=&quot;http://raibledesigns.com/rd/entry/we_bought_a_ski_bus&quot;&gt;We Bought a Ski Bus&lt;/a&gt; in October and celebrated &lt;a
        href=&quot;http://raibledesigns.com/rd/entry/happy_birthday_abbie7&quot;&gt;Abbie&apos;s birthday&lt;/a&gt; in November. Shortly after,
    we
    departed on a whirlwind &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_2013_a_nordic_countries&quot;&gt;six-country
    speaking tour&lt;/a&gt; in Europe. We visited 14 countries in 2013. 
    &lt;!-- Mexico, France, Iceland, Ireland, Britain, Italy, Thailand, Fiji, Holland, Belgium, Sweden, Norway, Finland, Copenhagen --&gt;
&lt;/p&gt;
&lt;p&gt;
    In early December, we flew to
    Idaho to &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_syncro_rescue_road_trip&quot;&gt;pickup our new Syncro&lt;/a&gt;. We
    anticipated a few VW Adventures when we bought the bus and haven&apos;t been disappointed.


&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a href=&quot;http://farm4.staticflickr.com/3771/11318813023_0a33a869ef_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mraible/11318813023/&quot;
       title=&quot;Let the VW adventures begin! by mraible, on Flickr&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm4.staticflickr.com/3771/11318813023_0a33a869ef_n.jpg&quot; width=&quot;320&quot;
            alt=&quot;Let the VW adventures begin!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;

    The Syncro drove
    back to Denver just fine, but started experiencing cooling issues driving around town. We got it fixed and drove
    to Montana for Christmas. We broke down on Christmas Eve in Bozeman, tried to fix it, but eventually gave up and
    rented a car. Straightaway Motors replaced the thermostat over the next week and we were able to drive it back to
    Denver with no issues. It started overheating again a couple days later. We&apos;ve only recently got it running smoothly, with help from &lt;a
        href=&quot;http://www.rockymountainwesty.com/&quot;&gt;Rocky Mountain Westy&lt;/a&gt;. You can read the full story on &lt;a
        href=&quot;http://www.thesamba.com/vw/forum/viewtopic.php?t=580347&quot;&gt;
    thesamba.com&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    Christmas Vacation was spent at The Raible Homestead, enjoying my parents new retirement cabin and a
    &lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/sets/72157639816640594/&quot;&gt;sweet sledding hill&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://farm3.staticflickr.com/2845/11973497666_90c0414f3d_c.jpg&quot;
       data-href=&quot;http://www.flickr.com/photos/mcginityphoto/11973497666/&quot;
       title=&quot;Yee Haw!&quot; rel=&quot;lightbox[2013yearinreview]&quot;&gt;&lt;img
            src=&quot;//farm3.staticflickr.com/2845/11973497666_90c0414f3d.jpg&quot; width=&quot;500&quot;
            alt=&quot;Yee Haw!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;We finished the year skiing at &lt;a href=&quot;http://skiwhitefish.com/&quot;&gt;Big Mountain&lt;/a&gt;, where I learned how to downhill
    ski in grade school.&lt;/p&gt;

&lt;h2 id=&quot;2014&quot;&gt;2014&lt;/h2&gt;

&lt;p&gt;My goal for 2014 is singular: &lt;em&gt;finish The Bus&lt;/em&gt;. I finally found the restoration shop I wish I would&apos;ve found years ago.
    They&apos;re
    very quick and efficient, and send me daily (picture) updates of their progress. With any luck, it&apos;ll be done in a
    couple months (sound
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/when_is_the_bus_gonna&quot;&gt;familiar&lt;/a&gt;?).
&lt;/p&gt;
&lt;p&gt;Last year, I wanted to &lt;em&gt;slow down&lt;/em&gt; and I feel like I did that on our honeymoon. My wife scoffs at that notion.
    &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt; This year, I
    hope to simply take more time to do things, instead of trying to cram many things into tight timelines.&lt;/p&gt;
&lt;p&gt;
    I plan to spend less time traveling and speaking at conferences and more time at Volkswagen shows. With our 4x4 VW
    Syncro, we hope to camp, raft and spend quite a bit of time in the Rocky Mountains. We also hope to take the busses
    to a few art shows to show off Trish&apos;s majestic photos.
&lt;/p&gt;
&lt;p&gt;Professionally, I hope to continue developing HTML5 apps and APIs with JavaScript, CSS, Java and Groovy. I might dive back
    into Scala and I&apos;m intrigued by Node.js and Spring Boot. Since I won&apos;t be doing as many conferences, the
    technologies I
    use will likely be driven by client engagements. I expect 2014 to be a big year for HTTP/2.
&lt;/p&gt;
&lt;p&gt;Last year, and the year before, we watched the Broncos fail miserably in the NFL playoffs. This year, they&apos;re in the
    Super Bowl.
    With a kick-ass Ski Bus, a Porsche Bus on the way, awesome kids and a great wife - 2014 is destined to be
    spectacular. I hope the Broncos are too! &lt;img src=&quot;https://raibledesigns.com/images/smileys/smile.gif&quot; class=&quot;smiley&quot; alt=&quot;:)&quot; title=&quot;:)&quot; /&gt;
&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for</id>
        <title type="html">Using Grunt with AngularJS for Front End Optimization</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/using_grunt_with_angularjs_for"/>
        <published>2014-01-15T12:15:52-07:00</published>
        <updated>2014-01-15T22:11:46-07:00</updated> 
        <category term="/The Web" label="The Web" />
        <category term="angularjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="grunt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="pagespeed" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yslow" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;I&apos;m passionate about front end optimization and have been for years. My original inspiration was Steve Souders and his &lt;a href=&quot;http://raibledesigns.com/rd/entry/oscon_2008_even_faster_web&quot;&gt;Even Faster Web Sites talk at OSCON 2008&lt;/a&gt;. Since then, I&apos;ve &lt;a href=&quot;http://raibledesigns.com/rd/entry/javascript_and_css_concatenation&quot;&gt;optimized this blog&lt;/a&gt;, made it even faster &lt;a href=&quot;http://raibledesigns.com/rd/entry/new_look_and_feel_designed&quot;&gt;with a new design&lt;/a&gt;, doubled the speed of several apps for clients and showed how to &lt;a href=&quot;http://raibledesigns.com/rd/entry/improving_appfuse_s_pagespeed_with&quot;&gt;make AppFuse faster&lt;/a&gt;. As part of my &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_2013_a_nordic_countries&quot;&gt;Devoxx 2013 presentation&lt;/a&gt;, I showed &lt;a href=&quot;https://vimeo.com/mraible/page-speed-demo&quot;&gt;how to do page speed optimization in a Java webapp&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I developed a couple AngularJS apps last year. To concat and minify their stylesheets and scripts, I used mechanisms that already existed in the projects. On one project, it was Ant and its &lt;a href=&quot;https://ant.apache.org/manual/Tasks/concat.html&quot;&gt;concat task&lt;/a&gt;. On the other, it was part of a Grails application, so I used the &lt;a href=&quot;http://grails.org/plugin/resources&quot;&gt;resources&lt;/a&gt; and &lt;a href=&quot;http://grails.org/plugin/yui-minify-resources&quot;&gt;yui-minify-resources&lt;/a&gt; plugins.
&lt;/p&gt;
&lt;p&gt;The Angular project I&apos;m working on now will be published on a web server, as well as bundled in an iOS native app. Therefore, I turned to &lt;a href=&quot;http://gruntjs.com/&quot;&gt;Grunt&lt;/a&gt; to do the optimization this time. I found it to be quite simple, once I figured out &lt;a href=&quot;http://stackoverflow.com/questions/21056767/angular-and-grunt&quot;&gt;how to make it work with Angular&lt;/a&gt;. Based on my findings, I submitted a &lt;a href=&quot;https://github.com/angular/angular-seed/pull/131&quot;&gt;pull request to add Grunt to angular-seed&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;Below are the steps I used to add Grunt to my Angular project.&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;I&apos;m passionate about front end optimization and have been for years. My original inspiration was Steve Souders and his &lt;a href=&quot;http://raibledesigns.com/rd/entry/oscon_2008_even_faster_web&quot;&gt;Even Faster Web Sites talk at OSCON 2008&lt;/a&gt;. Since then, I&apos;ve &lt;a href=&quot;http://raibledesigns.com/rd/entry/javascript_and_css_concatenation&quot;&gt;optimized this blog&lt;/a&gt;, made it even faster &lt;a href=&quot;http://raibledesigns.com/rd/entry/new_look_and_feel_designed&quot;&gt;with a new design&lt;/a&gt;, doubled the speed of several apps for clients and showed how to &lt;a href=&quot;http://raibledesigns.com/rd/entry/improving_appfuse_s_pagespeed_with&quot;&gt;make AppFuse faster&lt;/a&gt;. As part of my &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_2013_a_nordic_countries&quot;&gt;Devoxx 2013 presentation&lt;/a&gt;, I showed &lt;a href=&quot;https://vimeo.com/mraible/page-speed-demo&quot;&gt;how to do page speed optimization in a Java webapp&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I developed a couple AngularJS apps last year. To concat and minify their stylesheets and scripts, I used mechanisms that already existed in the projects. On one project, it was Ant and its &lt;a href=&quot;https://ant.apache.org/manual/Tasks/concat.html&quot;&gt;concat task&lt;/a&gt;. On the other, it was part of a Grails application, so I used the &lt;a href=&quot;http://grails.org/plugin/resources&quot;&gt;resources&lt;/a&gt; and &lt;a href=&quot;http://grails.org/plugin/yui-minify-resources&quot;&gt;yui-minify-resources&lt;/a&gt; plugins.
&lt;/p&gt;
&lt;p&gt;The Angular project I&apos;m working on now will be published on a web server, as well as bundled in an iOS native app. Therefore, I turned to &lt;a href=&quot;http://gruntjs.com/&quot;&gt;Grunt&lt;/a&gt; to do the optimization this time. I found it to be quite simple, once I figured out &lt;a href=&quot;http://stackoverflow.com/questions/21056767/angular-and-grunt&quot;&gt;how to make it work with Angular&lt;/a&gt;. Based on my findings, I submitted a &lt;a href=&quot;https://github.com/angular/angular-seed/pull/131&quot;&gt;pull request to add Grunt to angular-seed&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;Below are the steps I used to add Grunt to my Angular project.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install Grunt&apos;s command line interface with &quot;sudo npm install -g grunt-cli&quot;.&lt;/li&gt;
&lt;li&gt;Edit package.json to include a version number (e.g. &quot;version&quot;: &quot;1.0.0&quot;).&lt;/li&gt;
&lt;li&gt;Add Grunt plugins in package.json to do concat/minify/asset versioning:
&lt;pre class=&quot;brush: js&quot;&gt;
    &quot;grunt&quot;: &quot;~0.4.1&quot;,
    &quot;grunt-contrib-concat&quot;: &quot;~0.3.0&quot;,
    &quot;grunt-contrib-uglify&quot;: &quot;~0.2.7&quot;,
    &quot;grunt-contrib-cssmin&quot;: &quot;~0.7.0&quot;,
    &quot;grunt-usemin&quot;: &quot;~2.0.2&quot;,
    &quot;grunt-contrib-copy&quot;: &quot;~0.5.0&quot;,
    &quot;grunt-rev&quot;: &quot;~0.1.0&quot;,
    &quot;grunt-contrib-clean&quot;: &quot;~0.5.0&quot;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Run &quot;sudo npm install&quot; to install the project&apos;s dependencies.&lt;/li&gt;
&lt;li&gt;Create a &lt;code&gt;Gruntfile.js&lt;/code&gt; that runs all the plugins.
&lt;pre class=&quot;brush: js&quot;&gt;
module.exports = function (grunt) {

    grunt.initConfig({
        pkg: grunt.file.readJSON(&apos;package.json&apos;),

        clean: [&quot;dist&quot;, &apos;.tmp&apos;],

        copy: {
            main: {
                expand: true,
                cwd: &apos;app/&apos;,
                src: [&apos;**&apos;, &apos;!js/**&apos;, &apos;!lib/**&apos;, &apos;!**/*.css&apos;],
                dest: &apos;dist/&apos;
            },
            shims: {
                expand: true,
                cwd: &apos;app/lib/webshim/shims&apos;,
                src: [&apos;**&apos;],
                dest: &apos;dist/js/shims&apos;
            }
        },

        rev: {
            files: {
                src: [&apos;dist/**/*.{js,css}&apos;, &apos;!dist/js/shims/**&apos;]
            }
        },

        useminPrepare: {
            html: &apos;app/index.html&apos;
        },

        usemin: {
            html: [&apos;dist/index.html&apos;]
        },

        uglify: {
            options: {
                report: &apos;min&apos;,
                mangle: false
            }
        }
    });

    grunt.loadNpmTasks(&apos;grunt-contrib-clean&apos;);
    grunt.loadNpmTasks(&apos;grunt-contrib-copy&apos;);
    grunt.loadNpmTasks(&apos;grunt-contrib-concat&apos;);
    grunt.loadNpmTasks(&apos;grunt-contrib-cssmin&apos;);
    grunt.loadNpmTasks(&apos;grunt-contrib-uglify&apos;);
    grunt.loadNpmTasks(&apos;grunt-rev&apos;);
    grunt.loadNpmTasks(&apos;grunt-usemin&apos;);

    // Tell Grunt what to do when we type &quot;grunt&quot; into the terminal
    grunt.registerTask(&apos;default&apos;, [
        &apos;copy&apos;, &apos;useminPrepare&apos;, &apos;concat&apos;, &apos;uglify&apos;, &apos;cssmin&apos;, &apos;rev&apos;, &apos;usemin&apos;
    ]);
};
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Add comments to app/index.html so usemin knows what files to process. The comments are the important part, your files will likely be different.
&lt;pre class=&quot;brush: html&quot;&gt;
&amp;lt;!-- build:css css/app-name.min.css --&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;lib/bootstrap/bootstrap.min.css&quot;/&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;lib/font-awesome/font-awesome.min.css&quot;/&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;lib/toaster/toaster.css&quot;/&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;css/app.css&quot;/&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;css/custom.css&quot;/&amp;gt;
&amp;lt;link rel=&quot;stylesheet&quot; href=&quot;css/responsive.css&quot;/&amp;gt;
&amp;lt;!-- endbuild --&amp;gt;
...

&amp;lt;!-- build:js js/app-name.min.js --&amp;gt;
&amp;lt;script src=&quot;lib/jquery/jquery-1.10.2.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/bootstrap/bootstrap.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/angular/angular.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/angular/angular-animate.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/angular/angular-cookies.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/angular/angular-resource.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/angular/angular-route.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/fastclick.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/toaster/toaster.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/webshim/modernizr.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;lib/webshim/polyfiller.min.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;js/app.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;js/services.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;js/controllers.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;js/filters.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;script src=&quot;js/directives.js&quot;&amp;gt;&amp;lt;/script&amp;gt;
&amp;lt;!-- endbuild --&amp;gt;
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A couple of things to note: 1) the &lt;em&gt;copy&lt;/em&gt; task copies the &quot;shims&quot; directory from &lt;a href=&quot;http://afarkas.github.io/webshim/demos/&quot;&gt;Webshims lib&lt;/a&gt; because it loads files dynamically and 2) setting &quot;mangle: false&quot; on the &lt;em&gt;uglify&lt;/em&gt; task is necessary for Angular&apos;s dependency injection to work. I tried to use &lt;a href=&quot;https://npmjs.org/package/grunt-ngmin&quot;&gt;grunt-ngmin&lt;/a&gt; with uglify and had no luck.&lt;/p&gt;
&lt;p&gt;After making these changes, I&apos;m able to run &quot;grunt&quot; and get an optimized version of my app in the &quot;dist&quot; folder of my project. For development, I continue to run the app from my &quot;app&quot; folder, so I don&apos;t currently have a need for watching and processing assets on-the-fly. That could change if I start using LESS or CoffeeScript.
&lt;/p&gt;
&lt;p&gt;The results speak for themselves: from 27 requests to 5 on initial load, and only 3 requests for less than 2K after that.&lt;/p&gt;
&lt;table class=&quot;comparison&quot; style=&quot;max-width: 600px&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;YSlow&lt;/th&gt;
&lt;th&gt;Page Speed&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;No optimization&lt;/td&gt;
&lt;td&gt;75 &lt;div style=&quot;float: right&quot;&gt;27 HTTP requests / 464K&lt;/div&gt;&lt;/td&gt;
&lt;td&gt;55/100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache optimization (gzip and expires headers)&lt;/td&gt;
&lt;td&gt;89
&lt;div style=&quot;float: right&quot;&gt;
initial load: 26 requests / 166K&lt;br/&gt;
primed cache: 4 requests / 40K 
&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;88/100&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Apache + concat/minified/versioned files&lt;/td&gt;
&lt;td&gt;98
&lt;div style=&quot;float: right&quot;&gt;
initial load: 5 requests / 136K&lt;br/&gt;
primed cache: 3 requests / 1.4K
&lt;/div&gt;
&lt;/td&gt;
&lt;td&gt;93/100&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Andreas Andreou has a &lt;a href=&quot;https://twitter.com/andyhot/status/423571136538877952&quot;&gt;nice tip&lt;/a&gt; on how to reduce the LOC in this example.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Add &quot;matchdep&quot; as a dependency in package.json (or run &quot;sudo npm install matchdep --save-dev&quot;).
&lt;pre class=&quot;brush: js; gutter: false&quot;&gt;
&quot;matchdep&quot;: &quot;~0.3.0&quot;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Replace all the &lt;code&gt;grunt.loadNpmTasks(...)&lt;/code&gt; calls with the following:
&lt;pre class=&quot;brush: js; gutter: false&quot;&gt;
require(&apos;matchdep&apos;).filterDev(&apos;grunt-*&apos;).forEach(grunt.loadNpmTasks);
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Thanks Andreas!&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_3_0_released</id>
        <title type="html">AppFuse 3.0 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_3_0_released"/>
        <published>2013-12-23T14:31:15-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="primefaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="bootstrap3" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring4" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;
&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//static.appfuse.org/images/appfuse-icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the release of AppFuse 3.0. This release is AppFuse&apos;s first release as a &lt;a href=&quot;http://raibledesigns.com/rd/entry/happy_10_year_appfuse&quot;&gt;10-year old&lt;/a&gt; and includes a whole slew of improvements.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Java 7 and Maven 3 are now minimal requirements&lt;/li&gt;
    &lt;li&gt;Replaced MyFaces and Tomahawk with PrimeFaces for JSF&lt;br&gt;
        &lt;ul&gt;
            &lt;li&gt;Removed SiteMesh in favor of JSF&apos;s built-in layout support&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Added Wicket support&lt;/li&gt;
    &lt;li&gt;Migrated from jMock to Mockito for tests&lt;/li&gt;
    &lt;li&gt;Integrated wro4j and WebJars&lt;/li&gt;
    &lt;li&gt;Migrated to Bootstrap 3 and defaulted to Bootswatch&apos;s &lt;a href=&quot;http://bootswatch.com/spacelab/&quot;&gt;Spacelab
        theme&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, this release includes upgrades to all dependencies to bring them up-to-date with their latest
    releases. Most notable are Spring 4, Spring Security 3.2 and Bootstrap 3. For more details on specific changes
    see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+3.0.0&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;&lt;strong&gt;What is AppFuse?&lt;/strong&gt;&lt;br&gt;

    AppFuse is a full-stack framework for building web applications on the JVM. It was
    originally developed to eliminate the ramp-up time when building new web applications. Over
    the years, it has matured into a very testable and secure system for creating Java-based
    webapps.
&lt;/p&gt;
&lt;p&gt;Demos for this release can be viewed at &lt;a href=&quot;http://demo.appfuse.org/&quot;&gt;http://demo.appfuse.org&lt;/a&gt;. Please see
    the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; style=&quot;font-weight: bold&quot;&gt;QuickStart Guide&lt;/a&gt; to
    get started with this release. &lt;/p&gt;

&lt;p&gt;If you have questions about AppFuse, please read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot;&gt;FAQ&lt;/a&gt; or join the
    &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;user mailing list&lt;/a&gt;. If you find any
    issues, please report them on the users mailing list. You can also post them to &lt;a href=&quot;http://stackoverflow.com/questions/tagged/appfuse&quot;&gt;Stack Overflow&lt;/a&gt; with the &quot;appfuse&quot; tag.&lt;/p&gt;

&lt;p&gt;Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing
    lists.&lt;/p&gt;

&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;We greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot;&gt;our
    sponsors&lt;/a&gt;, particularly &lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot;&gt;Atlassian&lt;/a&gt;,
    &lt;a href=&quot;http://contegix.com/&quot;&gt;Contegix&lt;/a&gt;, and &lt;a href=&quot;http://www.jetbrains.com/&quot;&gt;JetBrains&lt;/a&gt;.
    Atlassian and Contegix are especially awesome:
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_now_powered_by_contegix&quot;&gt;Atlassian has donated licenses to all
        its products and Contegix has donated an entire server&lt;/a&gt; to the AppFuse project. &lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/happy_10_year_appfuse</id>
        <title type="html">Happy 10 Year AppFuse!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/happy_10_year_appfuse"/>
        <published>2013-04-05T08:56:45-06:00</published>
        <updated>2014-05-08T19:47:26-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="anniversary" scheme="http://roller.apache.org/ns/tags/" />
        <category term="10years" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//raw.github.com/appfuse/appfuse/master/www/logo/appfuse_72_transparent.gif&quot; width=&quot;72&quot; height=&quot;72&quot; class=&quot;picture&quot; /&gt;&lt;/a&gt;
10 years ago yesterday, I released the &lt;a href=&quot;http://raibledesigns.com/rd/entry/announce_struts_resume_and_appfuse&quot;&gt;first version of AppFuse&lt;/a&gt;. It started with XDoclet generating ActionForms from POJOs and became very popular for Struts developers that wanted to use Hibernate. The project&apos;s popularity peaked in 2006, as you can see from the mailing list traffic below.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://appfuse.markmail.org&quot; title=&quot;AppFuse Mailing List Traffic&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8251/8621164287_0acb4af5de.jpg&quot; width=&quot;500&quot; height=&quot;162&quot; alt=&quot;AppFuse Mailing List Traffic&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;It&apos;s possible the decrease in traffic is because we re-wrote everything to be based on Maven. It&apos;s also possible it was because of more attractive full-stack frameworks like &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_vs_grails_vs_rails&quot;&gt;Grails and Rails&lt;/a&gt;. However, the real reason is likely that I stopped working on it all the time due to &lt;span style=&quot;text-decoration: line-through&quot;&gt;getting a divorce&lt;/span&gt; &lt;a href=&quot;http://raibledesigns.com/rd/entry/5_years&quot;&gt;becoming an awesome dad&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Below is a timeline of how the project evolved over its first 4 years.&lt;/p&gt;
&lt;p style=&quot;text-align: center; background: white&quot;&gt;
&lt;a href=&quot;http://static.raibledesigns.com/repository/images/appfuse-history.png&quot; rel=&quot;lightbox[appfuse-10yr]&quot; title=&quot;AppFuse History: 2003 - 2007&quot;&gt;&lt;img src=&quot;//static.raibledesigns.com/repository/images/appfuse-history.png&quot; alt=&quot;AppFuse History: 2003 - 2007&quot; width=&quot;500&quot;/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;AppFuse has been a great project for me to work on and it&apos;s been a large source of my knowledge about Java, Web Frameworks, Spring, Hibernate - as well as build systems like Ant and Maven. We started with CVS, moved to SVN and now we&apos;re &lt;a href=&quot;http://github.com/appfuse&quot;&gt;on GitHub&lt;/a&gt;. We&apos;ve experienced &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven&quot;&gt;migrating from Tapestry 4 to Tapestry 5&lt;/a&gt; (thanks Serge Eby!), upgrading to &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_to_jsf_2&quot;&gt;JSF 2&lt;/a&gt; and enjoyed the backwards compatibility of Spring and Struts 2 throughout the years. We&apos;ve also added REST support, a Web Services archetype and kept up with the latest Spring and Hibernate releases.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://appfuse.org/download/attachments/84/appfuse-history2.png?version=1&amp;amp;modificationDate=1356633078000&quot; rel=&quot;lightbox[appfuse-10yr]&quot; title=&quot;AppFuse History: 2007 - 2013&quot;&gt;&lt;img src=&quot;//appfuse.org/download/attachments/84/appfuse-history2.png?version=1&amp;amp;modificationDate=1356633078000&quot; width=&quot;500&quot; alt=&quot;AppFuse History: 2007 - 2013&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Last year, we &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_2_1_released&quot;&gt;added Bootstrap and jQuery&lt;/a&gt; as foundational front-end frameworks. For our next release, we&apos;re &lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to&quot;&gt;switching to PrimeFaces&lt;/a&gt;, adding Wicket and changing from jMock to Mockito. Most of these changes are already in source control, we just need to polish them up a bit and add &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+Maven+Plugin&quot; title=&quot;AppFuse Maven Plugin&quot;&gt;AMP&lt;/a&gt; support. I hope to release 3.0 &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157633155884796/&quot;&gt;before the bus is done&lt;/a&gt;. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Thanks to all the enthusiastic users of and contributors to AppFuse over the years. It&apos;s been a great ride! </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/integrating_gwt_into_appfuse</id>
        <title type="html">Integrating GWT into AppFuse</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/integrating_gwt_into_appfuse"/>
        <published>2013-03-07T18:49:28-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;https://developers.google.com/web-toolkit/images/gwt-logo.png&quot;&gt;&lt;img src=&quot;//developers.google.com/web-toolkit/images/gwt-logo.png&quot; class=&quot;picture&quot;  height=&quot;100&quot; width=&quot;100&quot;&gt;&lt;/a&gt;
I&apos;ve been interested in integrating &lt;a href=&quot;https://developers.google.com/web-toolkit/&quot;&gt;GWT&lt;/a&gt; into &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; ever since &lt;a href=&quot;http://raibledesigns.com/rd/entry/gwt_and_appfuse&quot;&gt;I blogged about it 4 years ago&lt;/a&gt;. A few months after that post, I wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/enhancing_evite_com_with_gwt&quot;&gt;Enhancing Evite.com with GWT and Grails&lt;/a&gt;. After Evite, I had a gig near Boston where I developed with GXT for the remainder of the year. When all was said and done, I ended up spending a year with GWT and really enjoyed my experience. I haven&apos;t used it much since.&lt;/p&gt;
&lt;p&gt;GWT is &lt;a href=&quot;http://appfuse.org/display/APF/Roadmap&quot;&gt;scheduled to be integrated into AppFuse&lt;/a&gt; in version 4.0. That&apos;s quite a ways off. The good news is you might not have to wait that long, thanks to &lt;a href=&quot;https://github.com/ivangsa&quot;&gt;Iv&#225;n Garc&#237;a Sainz-Aja&lt;/a&gt;. Iv&#225;n let us know about his work a couple weeks ago in an &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Creating-a-new-archetype-td4656359.html&quot;&gt;email to the appfuse-dev&lt;/a&gt; mailing list.&lt;/p&gt;
&lt;div class=&quot;quote&quot;&gt;
&lt;p&gt;
It&apos;s still work in progress but it has already most of AppFuse functionality.. 
&lt;/p&gt;&lt;p&gt;
If you want to give it a try 
&lt;/p&gt;&lt;p&gt;
&lt;a href=&quot;https://github.com/ivangsa/appfuse.git&quot;&gt;https://github.com/ivangsa/appfuse.git&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
the quickest way to have a go would be&lt;/p&gt;
&lt;pre&gt;
web/gwt&gt; mvn -P gwtDebug -Dgwt.inplace=true gwt:compile jetty:run  
&lt;/pre&gt;
&lt;p&gt;
at the moment it still requires this fork of gwt-bootstrap to be compiled first 
&lt;/p&gt;&lt;p&gt;
&lt;a href=&quot;https://github.com/ivangsa/gwt-bootstrap.git&quot;&gt;https://github.com/ivangsa/gwt-bootstrap.git&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
It needs a lot of testing yet but it&apos;s getting quite there 
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As you can imagine, I was very excited to hear about Iv&#225;n&apos;s work. So I cloned his repo, built gwt-bootstrap locally and checked it out. Functionality wise, it was great! However, when I dug into the source code, I found a whole lotta code. 
&lt;/p&gt;
&lt;p&gt;
To see how the GWT flavor compared to the other implementations in AppFuse, I &lt;a href=&quot;https://gist.github.com/mraible/5033218&quot;&gt;created a cloc report&lt;/a&gt; on the various web frameworks in AppFuse. I&apos;m sure these reports could be adjusted to be more accurate, but I believe they give a good general overview. I posted some graphs that displays my findings in visual form.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a href=&quot;http://farm9.staticflickr.com/8090/8538497066_be60cb73da_o.png&quot; title=&quot;Lines of Java&quot; rel=&quot;lightbox[appfuse-loc]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8090/8538497066_4f2a6ff71e_m.jpg&quot; width=&quot;240&quot; height=&quot;189&quot; alt=&quot;Lines of Java&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm9.staticflickr.com/8235/8537391497_deaa49c22d_o.png&quot; title=&quot;Number of Files by mraible, on Flickr&quot; rel=&quot;lightbox[appfuse-loc]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8235/8537391497_3bbafe2383_m.jpg&quot; width=&quot;240&quot; height=&quot;189&quot; alt=&quot;Number of Files&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;When I sent this to the mailing list, Ivan &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Creating-a-new-archetype-tt4656359.html#a4656374&quot;&gt;responded that it was a lot of code&lt;/a&gt; and estimated &lt;em&gt;12 new files&lt;/em&gt; would be needed to &lt;abbr title=&quot;Create, Retrieve, Update, Delete&quot;&gt;CRUD&lt;/a&gt; an entity. This sure seems like a lot to me, but he &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/GWT-RESTFull-backend-tt4656418.html&quot;&gt;defended this yesterday&lt;/a&gt; and noted that his implementation follows many of GWT&apos;s latest best 
practices: MVP pattern, Activities and Places, EventBus, Gin and Guice. He also shared a &lt;a href=&quot;https://github.com/ivangsa/appfuse/wiki&quot;&gt;wiki page&lt;/a&gt; with explanations and diagrams of how things work.&lt;/p&gt;
&lt;p&gt;The reason I&apos;m writing this post is to get more feedback on this implementation. First of all, &lt;em&gt;does GWT really require this much code&lt;/em&gt;? Secondly, are there other GWT implementations that reduce a lot of the boilerplate? &lt;a href=&quot;https://code.google.com/p/smartgwt/&quot;&gt;SmartGWT&lt;/a&gt;, &lt;a href=&quot;https://vaadin.com/home&quot;&gt;Vaadin&lt;/a&gt;* and &lt;a href=&quot;http://www.jboss.org/errai&quot;&gt;Errai&lt;/a&gt; come to mind. 
&lt;/p&gt;
&lt;p&gt;If you were starting a new GWT project and using AppFuse, how would &lt;em&gt;you&lt;/em&gt; want it implemented?&lt;/p&gt;
&lt;p style=&quot;font-size: .9em; border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;* Vaadin 7 claims it &lt;a href=&quot;http://www.infoq.com/news/2013/02/vaadin-7&quot;&gt;can be used as a drop-in replacement for GWT&lt;/a&gt;. I tried &lt;a href=&quot;https://gist.github.com/mraible/5113636&quot;&gt;replacing the gwt-servlet and gwt-user dependencies&lt;/a&gt; with Vaadin&apos;s, but it &lt;a href=&quot;https://gist.github.com/mraible/5113607&quot;&gt;didn&apos;t work&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to</id>
        <title type="html">Switching AppFuse from MyFaces to PrimeFaces</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to"/>
        <published>2013-02-06T12:19:34-07:00</published>
        <updated>2013-02-06T18:19:34-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="primefaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">When describing &lt;a href=&quot;http://raibledesigns.com/rd/entry/why_the_bias_against_jsf&quot;&gt;my bias against JSF&lt;/a&gt; back in November, I wrote:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
... there&apos;s a lot of folks praising JSF 2 (and &lt;a href=&quot;http://primefaces.org/&quot;&gt;PrimeFaces&lt;/a&gt; moreso). That&apos;s why I&apos;ll be integrating it (or merging your pull request) into the 2.3 release of AppFuse. Since PrimeFaces contains a Bootstrap theme, I hope this is a pleasant experience and my overall opinion of JSF improves.
&lt;/p&gt;
&lt;p&gt;Shortly after the &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_2_1_released&quot;&gt;AppFuse 2.2.1 release&lt;/a&gt; in December, Gilberto Andrade &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1351&quot;&gt;contributed a sample project&lt;/a&gt; that used &lt;a href=&quot;http://javaserverfaces.java.net/&quot;&gt;Mojarra&lt;/a&gt; (the JSF RI) and &lt;a href=&quot;http://primefaces.org&quot;&gt;PrimeFaces&lt;/a&gt; instead of &lt;a href=&quot;http://myfaces.apache.org/&quot;&gt;MyFaces&lt;/a&gt; and its  &lt;a href=&quot;http://myfaces.apache.org/tomahawk/index.html&quot;&gt;Tomahawk&lt;/a&gt; components. Last week, I spent a few hours integrating Gilberto&apos;s changes into AppFuse&apos;s master branch. You can see all the changes I made (which include a Jetty plugin upgrade and some cleanup) in &lt;a href=&quot;http://source.appfuse.org/cru/CR-3&quot;&gt;this Crucible review&lt;/a&gt;. Feel free to leave comments on ask questions in the review itself.&lt;/p&gt;
&lt;p&gt;
The first thing I noticed when integrating PrimeFaces is you have to add a custom repository in order to get its artifacts via Maven.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;repositories&amp;gt;
    &amp;lt;repository&amp;gt;
        &amp;lt;id&amp;gt;prime-repo&amp;lt;/id&amp;gt;
        &amp;lt;name&amp;gt;Prime Repo&amp;lt;/name&amp;gt;
        &amp;lt;url&amp;gt;http://repository.primefaces.org&amp;lt;/url&amp;gt;
    &amp;lt;/repository&amp;gt;
&amp;lt;/repositories&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This is unfortunate since all of AppFuse&apos;s other dependencies can be found in Maven Central. It means that if you&apos;re using a JSF archetype, the PrimeFaces repo will be checked for artifacts first, causing an unnecessary slowdown in artifact resolution. I hope the PrimeFaces developers fix this soon.&lt;/p&gt;
&lt;p&gt;While integrating these two frameworks, I ran into a number of issues.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#listener&quot;&gt;An IllegalStateException on startup when using &quot;mvn jetty:run&quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#button&quot;&gt;Conditionally rendering a button disables its click-ability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#bootstrap&quot;&gt;The PrimeFaces Bootstrap theme 404s on some images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#webtest&quot;&gt;Canoo WebTest doesn&apos;t work with fileUpload nor to set checkbox values&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#javax.faces.resource&quot;&gt;PrimeFaces resources served up at /javax.faces.resource/* not found&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;listener&quot;&gt;&lt;strong&gt;An IllegalStateException on startup when using &quot;mvn jetty:run&quot;&lt;/strong&gt;&lt;br/&gt;The first issue I encountered was that I was unable to run the app in Jetty. It worked fine in Tomcat but I got the following error in Jetty:
&lt;/p&gt;
&lt;pre&gt;
2013-01-31 22:28:07.683:WARN:/:unavailable
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:951)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:316)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:302)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:492)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:312)
&lt;/pre&gt;
&lt;p&gt;I &lt;a href=&quot;http://stackoverflow.com/questions/7886035/could-not-find-factory-javax-faces-context-facescontextfactory/7889899&quot;&gt;found the fix for this on  Stack Overflow&lt;/a&gt; and added the following listener to my web.xml to solve it.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;listener&amp;gt;
    &amp;lt;listener-class&amp;gt;com.sun.faces.config.ConfigureListener&amp;lt;/listener-class&amp;gt;
&amp;lt;/listener&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;button&quot;&gt;&lt;strong&gt;Conditionally rendering a button disables its click-ability&lt;/strong&gt;&lt;br/&gt;
The next thing I noticed was the Delete button didn&apos;t work when editing a user. It was hidden correctly when adding a user, but clicking on it to delete a user simply refreshes the page. Below is the code I used successfully with MyFaces. For some reason, this doesn&apos;t work with PrimeFaces.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;c:if test=&quot;${not empty userForm.user.id}&quot;&amp;gt;
&amp;lt;h:commandButton value=&quot;#{text&amp;#91;&apos;button.delete&apos;&amp;#93;}&quot; action=&quot;#{userForm.delete}&quot;
    styleClass=&quot;btn&quot; onclick=&quot;return confirmMessage(msgDelConfirm)&quot;/&amp;gt;
&amp;lt;/c:if&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I also tried the following, but no dice. This is currently an &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1366&quot;&gt;open issue&lt;/a&gt;.
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;h:commandButton rendered=&quot;${not empty userForm.user.id}&quot; value=&quot;#{text&amp;#91;&apos;button.delete&apos;&amp;#93;}&quot; 
    action=&quot;#{userForm.delete}&quot; styleClass=&quot;btn&quot; onclick=&quot;return confirmMessage(msgDelConfirm)&quot;/&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;bootstrap&quot;&gt;
&lt;strong&gt;The PrimeFaces Bootstrap theme 404s on some images&lt;/strong&gt;&lt;br/&gt;
After integrating PrimeFaces&apos; Bootstrap theme, the following error shows up in server logs.
&lt;/p&gt;
&lt;pre&gt;
[INFO] [talledLocalContainer] Feb 02, 2013 10:40:25 PM com.sun.faces.application.resource.ResourceHandlerImpl logMissingResource
[WARNING] [talledLocalContainer] WARNING: JSF1064: Unable to find or serve resource, images/ui-bg_highlight-hard_70_000000_1x100.png, from library, primefaces-bootstrap.
&lt;/pre&gt;
&lt;p&gt;This seems to have &lt;a href=&quot;http://forum.primefaces.org/viewtopic.php?f=9&amp;t=19250&amp;start=10&quot;&gt;happened before in previous releases&lt;/a&gt; and is currently an &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1367&quot;&gt;open issue&lt;/a&gt;. 
&lt;/p&gt;
&lt;p id=&quot;webtest&quot;&gt;&lt;strong&gt;Canoo WebTest doesn&apos;t work with fileUpload nor to set checkbox values&lt;/strong&gt;&lt;br/&gt;
We use &lt;a href=&quot;http://webtest.canoo.com/webtest/manual/WebTestHome.html&quot;&gt;Canoo WebTest&lt;/a&gt; to run integration tests on the UI in AppFuse. For some reason, performing file uploads and setting checkbox values works fine with MyFaces/Tomahawk, but not with Mojarra/PrimeFaces. I&apos;m not sure if this is caused by the JSF core or the component library, but it &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1368&quot;&gt;remains an open issue&lt;/a&gt;. For now, I&apos;ve just commented out the parts of tests that used to do this.
&lt;/p&gt;
&lt;p&gt;On a related note, getting the real path of a resource from the ServletContext worked fine before the switch, but results in a null value now.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
String uploadDir = getServletContext().getRealPath(&quot;/resources&quot;) + &quot;/&quot; + request.getRemoteUser() + &quot;/&quot;;
&lt;/pre&gt;
&lt;p id=&quot;javax.faces.resource&quot;&gt;&lt;strong&gt;PrimeFaces resources served up at /javax.faces.resource/* not found&lt;/strong&gt;&lt;br/&gt;While I didn&apos;t have problems with this in AppFuse, I did encounter it in AppFuse Light. I don&apos;t know why there was a difference between the two, but it turned out to be caused by the UrlRewriteFilter and my desire for &lt;a href=&quot;http://raibledesigns.com/rd/entry/extensionless_urls_in_java_web&quot;&gt;extensionless URLs&lt;/a&gt;. The outbound-rule to strip .xhtml from URLs was the culprit. Adding a condition to it solved the problem. Yeah, the condition seems backwards, but it works.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;outbound-rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;condition type=&quot;query-string&quot; operator=&quot;equal&quot;&amp;gt;ln=primefaces&amp;lt;/condition&amp;gt;
    &amp;lt;from&amp;gt;^(.*)\.xhtml(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;false&quot;&amp;gt;$1$2&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;summary&quot;&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
The initial switch to Mojarra/PrimeFaces was pretty easy thanks to Gilberto&apos;s sample project. However, the small issues encountered after that turned out to be quite frustrating and you can see that several are still not fixed. I guess it just goes to show that not all web frameworks are perfect. Hopefully we&apos;ll get these minor issues fixed before the next release. In the meantime, you can checkout the updated demos for &lt;a href=&quot;http://demo.appfuse.org/appfuse-jsf&quot;&gt;AppFuse JSF&lt;/a&gt; and &lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-jsf&quot;&gt;AppFuse Light JSF&lt;/a&gt;.
 </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_light_2_2_1</id>
        <title type="html">AppFuse Light 2.2.1 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_light_2_2_1"/>
        <published>2013-01-24T19:43:20-07:00</published>
        <updated>2013-01-25T01:47:18-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse-light" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">In December, the &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; Team &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_2_1_released&quot;&gt;released 2.2.1&lt;/a&gt;. Right before that release, I decided to wait on enhancing its &quot;light&quot; modules, a.k.a. &lt;a href=&quot;https://github.com/appfuse/appfuse-light&quot;&gt;AppFuse Light&lt;/a&gt;. I&apos;m glad I did, because it took some effort to get jQuery and Bootstrap integrated, as well as to make it more secure. 
&lt;/p&gt;
&lt;p&gt;
The good news is AppFuse Light 2.2.1 is released and it&apos;s sitting out on the &lt;a href=&quot;http://search.maven.org/#search%7Cga%7C1%7Cappfuse-light&quot;&gt;Central Repository&lt;/a&gt;. This release is a refactoring of all  archetypes to be up-to-date with the AppFuse 2.2.1 release. This means Java 7 compatibility, Servlet 3, Bootstrap/jQuery integration, Tapestry 5.3.6 upgrade and security improvements. I integrated Bootstrap and jQuery using &lt;a href=&quot;http://www.webjars.org/documentation&quot;&gt;WebJars Servlet 3 support&lt;/a&gt; since it was simple and straightforward. 
&lt;/p&gt;
&lt;p&gt;
You can create projects using AppFuse&apos;s light archetypes using a command such as the following:
&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes 
  -DarchetypeArtifactId=appfuse-light-spring-freemarker-archetype -DarchetypeVersion=2.2.1 
  -DgroupId=com.mycompany -DartifactId=myproject 
&lt;/pre&gt;
&lt;p&gt;
The list of archetypes is as follows:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;appfuse-light-jsf-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-spring-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-spring-freemarker-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-spring-security-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-stripes-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-struts-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-tapestry-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-wicket-archetype&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; will help you get setup and demos are available at the following links:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-jsf&quot;&gt;JSF 2 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-spring&quot;&gt;Spring MVC 3 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-spring-freemarker&quot;&gt;Spring MVC 3 + FreeMarker + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-spring-security&quot;&gt;Spring MVC 3 + Spring Security + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-stripes&quot;&gt;Stripes + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-struts&quot;&gt;Struts 2 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-tapestry&quot;&gt;Tapestry 5 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-wicket&quot;&gt;Wicket + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have questions about AppFuse, we invite you to ask them on the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;users mailing list&lt;/a&gt; or tweet using #appfuse. &lt;/p&gt;
&lt;p&gt;
For those enjoying &lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Bootstrap&lt;/a&gt; in your apps, I encourage you to check out &lt;a href=&quot;https://wrapbootstrap.com/&quot;&gt;{wrap}bootstrap&lt;/a&gt; and &lt;a href=&quot;http://bootswatch.com/&quot;&gt;Bootswatch&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/2012_a_year_in_review</id>
        <title type="html">2012 - A Year in Review</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/2012_a_year_in_review"/>
        <published>2013-01-08T13:15:24-07:00</published>
        <updated>2014-05-08T19:47:26-06:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="2012" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yearinreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <category term="blogging" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;I wrote my first &lt;a href=&quot;http://raibledesigns.com/rd/tags/yearinreview&quot;&gt;year in review&lt;/a&gt; blog entry way back in &lt;a href=&quot;http://raibledesigns.com/rd/entry/2005_a_year_in_review&quot;&gt;2005&lt;/a&gt;. That means this year&apos;s is number 8. Since they keep getting longer every year, I figured I&apos;d try something different this year and use sections similar to &lt;a href=&quot;http://remysharp.com/2012/12/31/my-2012/&quot;&gt;Remy Sharp&lt;/a&gt;. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#business&quot;&gt;Business&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#2013&quot;&gt;2013&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;I spent the entirety of the year with one client: Taleo. &lt;a href=&quot;http://www.businessweek.com/news/2012-02-10/oracle-buys-taleo-for-1-9-billion-adds-human-resource-tool.html&quot;&gt;Oracle bought them in February&lt;/a&gt;. In June, the transition to Oracle happened. My tasks and projects haven&apos;t changed much since the transition, but it has been a real pain to get paid on time. My contract with them is through the end of May. I hope to take July off (to get married) and August off (to honeymoon) and start a new gig in September.
&lt;/p&gt;
&lt;p&gt;I did minimal Java work throughout the year and spent most of my time doing CSS and JavaScript. I love doing front-end work much more than back-end, so day-to-day, it was very satisfying. 
&lt;/p&gt;</summary>
        <content type="html">I wrote my first &lt;a href=&quot;http://raibledesigns.com/rd/tags/yearinreview&quot;&gt;year in review&lt;/a&gt; blog entry way back in &lt;a href=&quot;http://raibledesigns.com/rd/entry/2005_a_year_in_review&quot;&gt;2005&lt;/a&gt;. That means this year&apos;s is number 8. Since they keep getting longer every year, I figured I&apos;d try something different this year and use sections similar to &lt;a href=&quot;http://remysharp.com/2012/12/31/my-2012/&quot;&gt;Remy Sharp&lt;/a&gt;. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#professional&quot;&gt;Professional&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#business&quot;&gt;Business&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#speaking&quot;&gt;Speaking&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#projects&quot;&gt;Projects&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#personal&quot;&gt;Personal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/2012_a_year_in_review#2013&quot;&gt;2013&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&quot;professional&quot;&gt;Professional&lt;/h2&gt;
&lt;p&gt;I spent the entirety of the year with one client: Taleo. &lt;a href=&quot;http://www.businessweek.com/news/2012-02-10/oracle-buys-taleo-for-1-9-billion-adds-human-resource-tool.html&quot;&gt;Oracle bought them in February&lt;/a&gt;. In June, the transition to Oracle happened. My tasks and projects haven&apos;t changed much since the transition, but it has been a real pain to get paid on time. My contract with them is through the end of May. I hope to take July off (to get married) and August off (to honeymoon) and start a new gig in September.
&lt;/p&gt;
&lt;p&gt;I did minimal Java work throughout the year and spent most of my time doing CSS and JavaScript. I love doing front-end work much more than back-end, so day-to-day, it was very satisfying. 
&lt;/p&gt;

&lt;h3 id=&quot;business&quot;&gt;Business&lt;/h3&gt;
&lt;p&gt;Raible Designs had a great year, our best ever financially. I hired Trish as an assistant in January, doubling the size of the company. We had our Annual Shareholders Meeting on a &lt;a href=&quot;http://raibledesigns.com/rd/entry/cruising_around_the_western_caribbean&quot;&gt;Disney Cruise&lt;/a&gt; in April. I have no plans to do increase the size of the company in 2013, mostly because I enjoy not having the responsibility of employees. I&apos;ve employed sub-contractors in the past and it always seems to create more of a headache than it&apos;s worth.&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;http://www.dailymile.com/people/mraible/training/2012/summary&quot; title=&quot;My Daily Mile 2012 Year End Report&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8227/8360832357_858f34a10e_t.jpg&quot; width=&quot;100&quot; height=&quot;52&quot; alt=&quot;Daily Mile 2012 Year End Report&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
We moved our offices from downtown Littleton to &lt;a href=&quot;http://www.businessatthrive.com/v3/&quot;&gt;Thrive&lt;/a&gt; (in LoDo) last April and I plan on staying there. It&apos;s an easy 6-mile bicycle commute and the guys there have been great to work with. I highly recommend it if you&apos;re looking for co-working space.&lt;/p&gt;

&lt;h3 id=&quot;speaking&quot;&gt;Speaking&lt;/h3&gt;
&lt;p&gt;I spoke at 5 events in 2012:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Silicon Valley Spring User Group on &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_what_s_new_in&quot;&gt;What&apos;s New in Spring 3.1&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;JFokus on &lt;a href=&quot;http://raibledesigns.com/rd/entry/comparing_web_frameworks_and_html5&quot;&gt;Comparing Web Frameworks and HTML5 with Play Scala&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Spring I/O on &lt;a href=&quot;http://www.youtube.com/watch?v=QlQMt3W9fpU&quot;&gt;Comparing JVM Web Frameworks&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;JavaPosse Roundup on &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_to_build_a_shot&quot;&gt;How to build a Shot-Ski&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&#220;berConf on &lt;a href=&quot;http://raibledesigns.com/rd/entry/play_vs_grails_smackdown_at&quot;&gt;Play vs. Grails&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Traveling to &lt;a href=&quot;http://raibledesigns.com/rd/entry/a_spectacular_trip_to_stockholm&quot;&gt;Stockholm and Madrid for JFokus and Spring I/O was spectacular&lt;/a&gt;. &lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8350765961/&quot; href=&quot;http://farm9.staticflickr.com/8357/8350765961_9eed5c5ee8.jpg&quot; title=&quot;James Ward and Enno Runne by Trish McGinity&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8357/8350765961_9eed5c5ee8_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;James Ward and Enno Runne by Trish McGinity&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8351826862/&quot; href=&quot;http://farm9.staticflickr.com/8233/8351826862_87c90d6990.jpg&quot; title=&quot;Juergen Hoeller&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8233/8351826862_87c90d6990_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Juergen Hoeller&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8351825042/&quot; href=&quot;http://farm9.staticflickr.com/8227/8351825042_0a15401fa8.jpg&quot; title=&quot;Speakers Dinner Singers by Trish McGinity&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8227/8351825042_0a15401fa8_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Speakers Dinner Singers&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8351823962/&quot; href=&quot;http://farm9.staticflickr.com/8091/8351823962_5b8c06859f.jpg&quot; title=&quot;Matt Raible James Ward Rickard Oberg Jfokus speakers dinner by Trish McGinity&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8091/8351823962_5b8c06859f_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Matt Raible James Ward Rickard Oberg Jfokus speakers dinner&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8351907734/&quot; href=&quot;http://farm9.staticflickr.com/8191/8351907734_28c5dd5e83.jpg&quot; title=&quot;Stockholm View by Trish McGinity&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8191/8351907734_28c5dd5e83.jpg&quot; width=&quot;500&quot; height=&quot;333&quot; alt=&quot;Stockholm View&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;/p&gt;
    
    &lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8355701252/&quot; href=&quot;http://farm9.staticflickr.com/8509/8355701252_3f507c646a.jpg&quot; title=&quot;Templo de Debod by Trish McGinity&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8509/8355701252_3f507c646a.jpg&quot; width=&quot;500&quot; height=&quot;333&quot; alt=&quot;Templo de Debod&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;&lt;/p&gt;
    
    &lt;p style=&quot;text-align: center&quot;&gt;

    &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8351930566/&quot; href=&quot;http://farm9.staticflickr.com/8366/8351930566_bb5f27f19a.jpg&quot; title=&quot;Iglesia San Gines by Trish McGinity&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8366/8351930566_bb5f27f19a_m.jpg&quot; width=&quot;240&quot; height=&quot;160&quot; alt=&quot;Iglesia San Gines&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8355691858/&quot; href=&quot;http://farm9.staticflickr.com/8050/8355691858_8878582d57.jpg&quot; title=&quot;Evening Commute Puerta de Alcala Madrid by Trish McGinity&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8050/8355691858_8878582d57_m.jpg&quot; width=&quot;240&quot; height=&quot;160&quot; alt=&quot;Evening Commute Puerta de Alcala Madrid&quot; style=&quot;margin-left: 15px; border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;/p&gt;
    
    
&lt;p&gt;I took the 2nd half of the year off from speaking, celebrating my temporary retirement at a &lt;a href=&quot;http://twitter.com/mraible/status/217459157689831424&quot;&gt;Def Leppard concert&lt;/a&gt; in June. When I decided to do this, I was planning on my VW Bus being finished. I was planning on switching from Java Conferences to VW Shows as a hobby. Unfortunately, now it&apos;s January and &lt;a href=&quot;http://raibledesigns.com/roller-ui/authoring/preview/rd/category/The+Bus&quot;&gt;The Bus&lt;/a&gt; still isn&apos;t done. I have high hopes for it being finished in 2013.
&lt;/p&gt;
&lt;p&gt;I paid for 2 conferences in 2012, the &lt;a href=&quot;http://raibledesigns.com/rd/entry/spring_break&quot;&gt;JavaPosse Roundup&lt;/a&gt; in March and &lt;a href=&quot;http://monktoberfest.com/&quot;&gt;Monktoberfest&lt;/a&gt; in October. While I enjoyed both, Monktoberfest will likely become a tradition. 
&lt;/p&gt;
&lt;h3 id=&quot;projects&quot;&gt;Projects&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;AppFuse:&lt;/strong&gt; I started the year by &lt;a href=&quot;http://raibledesigns.com/rd/entry/refreshing_appfuse_s_ui_with&quot;&gt;refreshing AppFuse&apos;s UI with Twitter Bootstrap&lt;/a&gt; and blogged about the &lt;a href=&quot;http://raibledesigns.com/rd/entry/twitter_s_open_source_summit&quot;&gt;Twitter&apos;s Summit on Bootstrap&lt;/a&gt; shortly after. At the same time, I was overhauling &lt;a href=&quot;http://raibledesigns.com/rd/entry/refreshing_taleo_s_ui_with&quot;&gt;Taleo&apos;s UI with HTML5, Bootstrap and CSS3&lt;/a&gt;, but waited until August to blog about it.&lt;/p&gt;
&lt;p&gt;In the fall, the AppFuse Team &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_news_github_hibernate_search&quot;&gt;migrated to GitHub and integrated Hibernate Search&lt;/a&gt;. &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_2_1_released&quot;&gt;AppFuse 2.2.1 was released&lt;/a&gt; in December.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Happy Trails:&lt;/strong&gt; In May and June, I worked on &lt;a href=&quot;https://github.com/jamesward/happytrails&quot;&gt;Happy Trails&lt;/a&gt; with James Ward as part of our &lt;a href=&quot;http://raibledesigns.com/rd/entry/play_vs_grails_smackdown_at&quot;&gt;Play vs. Grails Smackdown&lt;/a&gt;. This was a very enjoyable experience and I learned a lot about GitHub, Cloudbees and Heroku. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Play More:&lt;/strong&gt; In June, I wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_to_play_2_anorm&quot;&gt;Upgrading to Play 2: Anorm and Testing&lt;/a&gt;. A couple weeks later, I wrote about integrating &lt;a href=&quot;http://raibledesigns.com/rd/entry/migrating_to_play_2_and&quot;&gt;Validation and Secure Social&lt;/a&gt; into &lt;a href=&quot;http://play-more.com&quot;&gt;&lt;em&gt;Play More&lt;/em&gt;&lt;/a&gt;. In the aforementioned post, I also posted my &lt;a href=&quot;http://www.slideshare.net/mraible/html5-with-play-scala-coffeescript-and-jade-uberconf-2012&quot;&gt;&#220;berConf presentation&lt;/a&gt;, the &lt;a href=&quot;https://github.com/mraible/play-more&quot;&gt;source code&lt;/a&gt; and my thoughts on Play 2.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
I found Anorm and Scalate to be &lt;em&gt;huge&lt;/em&gt; time sinks and don&apos;t know if I&apos;d recommend using either one in a Play 2 project. I&apos;m sure Scalate will be easier to use as its Play 2 integration gets more refined, but I don&apos;t know if there&apos;s any hope for a JDBC abstraction that doesn&apos;t produce error messages when things go south.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Roller:&lt;/strong&gt; Although I didn&apos;t contribute much to &lt;a href=&quot;http://roller.apache.org&quot;&gt;Apache Roller&lt;/a&gt; in 2012, I do continue to use it frequently. This site celebrated its &lt;a href=&quot;http://raibledesigns.com/rd/entry/10_years_ago&quot;&gt;10-year anniversary&lt;/a&gt; in August. It got a &lt;a href=&quot;http://raibledesigns.com/rd/entry/new_look_and_feel_designed&quot;&gt;new look and feel&lt;/a&gt; shortly after.&lt;/p&gt; 
&lt;h2 id=&quot;personal&quot;&gt;Personal&lt;/h2&gt;
&lt;p&gt;Last year was a fantastic year for family time. Our &lt;a href=&quot;http://raibledesigns.com/rd/entry/cruising_around_the_western_caribbean&quot;&gt;cruise around the Western Caribbean&lt;/a&gt; was money well spent.&lt;/p&gt;&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8358223863/&quot; href=&quot;http://farm9.staticflickr.com/8092/8358223863_5b7c2d31eb.jpg&quot; title=&quot;Raible&apos;s and McGinity&apos;s welcome to our Disney Cruise! by Trish, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8092/8358223863_5b7c2d31eb.jpg&quot; width=&quot;500&quot; height=&quot;333&quot; alt=&quot;Raible&apos;s and McGinity&apos;s welcome to our Disney Cruise!&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8358600474/&quot; href=&quot;http://farm9.staticflickr.com/8213/8358600474_ea26b2cc90.jpg&quot; title=&quot;Raible and McGinity dinner by Trish, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8213/8358600474_ea26b2cc90.jpg&quot; width=&quot;500&quot; height=&quot;333&quot; alt=&quot;Raible and McGinity dinner&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;p&gt;My goal was to spend a month with my parents this year and we satisfied that by July. In total, we enjoyed their company for 8 weeks in 2012. 
&lt;/p&gt;
&lt;p&gt;
The worst ski season on record &lt;a href=&quot;http://raibledesigns.com/rd/entry/farewell_to_the_2011_2012&quot;&gt;ended in April&lt;/a&gt; and Trish and I headed for &lt;a href=&quot;http://raibledesigns.com/rd/entry/wine_tasting_in_napa_valley&quot;&gt;wine country&lt;/a&gt; in May.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://www.mcginityphoto.com/photos/i-cDtj2v6/1/M/i-cDtj2v6-M.jpg&quot; rel=&quot;lightbox[2012yearinreview]&quot; title=&quot;Cade Vineyard Cave Table&quot;&gt;
    &lt;img alt=&quot;Cade Vineyard Cave Table&quot; src=&quot;//www.mcginityphoto.com/photos/i-cDtj2v6/1/Th/i-cDtj2v6-Th.jpg&quot; width=&quot;150&quot; height=&quot;100&quot;  alt=&quot;Cade Vineyard Cave Table&quot; style=&quot;border: 1px solid black&quot;&gt;
    &lt;/a&gt;
    
    &lt;a href=&quot;http://www.mcginityphoto.com/photos/i-mCJJZR3/0/M/i-mCJJZR3-M.jpg&quot; rel=&quot;lightbox[2012yearinreview]&quot; title=&quot;Cade Vineyard Cask Row&quot;&gt;
    &lt;img src=&quot;//www.mcginityphoto.com/photos/i-mCJJZR3/0/Th/i-mCJJZR3-Th.jpg&quot; width=&quot;150&quot; height=&quot;99&quot;  alt=&quot;Cade Vineyard Cask Row&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;
    
    &lt;a href=&quot;http://www.mcginityphoto.com/photos/i-r4fmDX2/0/M/i-r4fmDX2-M.jpg&quot; rel=&quot;lightbox[2012yearinreview]&quot; title=&quot;Cade Flowers next to infinity pool&quot;&gt;
    &lt;img alt=&quot;Cade Flowers next to infinity pool&quot; src=&quot;//www.mcginityphoto.com/photos/i-r4fmDX2/0/Th/i-r4fmDX2-Th.jpg&quot; width=&quot;150&quot; height=&quot;100&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;/p&gt;
    &lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://www.mcginityphoto.com/photos/i-R9tmTz4/0/M/i-R9tmTz4-M.jpg&quot; rel=&quot;lightbox[2012yearinreview]&quot; title=&quot;Cade Winery&quot;&gt;
    &lt;img alt=&quot;Cade Winery&quot; src=&quot;//www.mcginityphoto.com/photos/i-R9tmTz4/0/S/i-R9tmTz4-S.jpg&quot; width=&quot;400&quot; height=&quot;266&quot; title=&quot;Cade Winery&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    
    &lt;/p&gt;
    
    &lt;/p&gt;
    &lt;p&gt;Abbie and Jack&apos;s school year &lt;a href=&quot;http://raibledesigns.com/rd/entry/school_s_out_for_summer&quot;&gt;ended&lt;/a&gt; on June 5th and we &lt;a href=&quot;http://raibledesigns.com/rd/entry/father_s_day_weekend_at&quot;&gt;celebrated Father&apos;s Day on the Oregon coast&lt;/a&gt;.&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a data-href=&quot;http://farm8.staticflickr.com/7284/9071981163_9ecc04ec8f_c.jpg&quot; title=&quot;View from Ecola State Park Oregon&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7284/9071981163_9ecc04ec8f.jpg&quot; width=&quot;500&quot; height=&quot;332&quot; alt=&quot;View from Ecola State Park Oregon&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9071962289/&quot; href=&quot;http://farm4.staticflickr.com/3675/9071962289_a7fc891f15_c.jpg&quot; title=&quot;Raible Family on the Oregon coast&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm4.staticflickr.com/3675/9071962289_a7fc891f15_q.jpg&quot; width=&quot;150&quot; height=&quot;150&quot; alt=&quot;Raible Family on the Oregon coast&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9074185440/&quot; href=&quot;http://farm8.staticflickr.com/7404/9074185440_eebccb9acf_c.jpg&quot; title=&quot;Abbie and Jack frolicking in the waves&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7404/9074185440_eebccb9acf_q.jpg&quot; width=&quot;150&quot; height=&quot;150&quot; alt=&quot;Abbie and Jack frolicking in the waves&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;

&lt;a data-href=&quot;http://www.flickr.com/photos/mcginityphoto/9074188854/&quot; href=&quot;http://farm3.staticflickr.com/2814/9074188854_f0b09a43ca_c.jpg&quot; title=&quot;Kalin and Joe on the beach&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm3.staticflickr.com/2814/9074188854_f0b09a43ca_q.jpg&quot; width=&quot;150&quot; height=&quot;150&quot; alt=&quot;Kalin and Joe on the beach&quot; style=&quot;border: 1px solid black; margin-left: 15px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;

    &lt;p&gt;Raible Road Trip #17 began in late June and we spent two weeks parading, rafting and golfing in Montana. From there, we flew to Maui for two weeks. I wrote about it all in &lt;a href=&quot;http://raibledesigns.com/rd/entry/summer_vacation_2012_in_montana&quot;&gt;Summer Vacation 2012 in Montana and Maui&lt;/a&gt;.
        &lt;/p&gt;
        &lt;p style=&quot;text-align: center&quot;&gt;

                        &lt;a title=&quot;Holland Lake Patio&quot; rel=&quot;lightbox[2012yearinreview]&quot; href=&quot;http://www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-rsL7ncX/0/M/DSC_4745-M.jpg&quot;&gt;
        &lt;img src=&quot;//www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-rsL7ncX/0/Ti/DSC_4745-Ti.jpg&quot;
             style=&quot;border: 1px solid black&quot; width=&quot;95&quot; height=&quot;95&quot; alt=&quot;Holland Lake Patio&quot;&gt;&lt;/a&gt;

      &lt;a title=&quot;The Girls at Double Arrow&quot; rel=&quot;lightbox[2012yearinreview]&quot; href=&quot;http://www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-sdLBDmF/0/M/DSC_4755-M.jpg&quot;&gt;
        &lt;img src=&quot;//www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-sdLBDmF/0/Ti/DSC_4755-Ti.jpg&quot;
             style=&quot;border: 1px solid black&quot; width=&quot;95&quot; height=&quot;95&quot; alt=&quot;The Girls at Double Arrow&quot;&gt;&lt;/a&gt;

      &lt;a title=&quot;Hard to believe I caused this guy to move to Montana in 1997&quot; rel=&quot;lightbox[2012yearinreview]&quot; href=&quot;http://www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-b5FCTrd/0/M/DSC_4845-2-M.jpg&quot;&gt;
        &lt;img src=&quot;//www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-b5FCTrd/0/Ti/DSC_4845-2-Ti.jpg&quot;
             style=&quot;border: 1px solid black&quot; width=&quot;95&quot; height=&quot;95&quot; alt=&quot;Hard to believe I caused this guy to move to Montana in 1997&quot;&gt;&lt;/a&gt;

      &lt;a title=&quot;Holland Lake Sunset&quot; rel=&quot;lightbox[2012yearinreview]&quot; href=&quot;http://www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-cH8CpGZ/0/M/HLL%20View-M.jpg&quot;&gt;
        &lt;img src=&quot;//www.mcginityphoto.com/Vacation/Montana-Summer-2012/i-cH8CpGZ/0/Ti/HLL%20View-Ti.jpg&quot;
             style=&quot;border: 1px solid black; margin-left: 1px&quot; width=&quot;95&quot; height=&quot;95&quot; alt=&quot;Holland Lake Sunset&quot;&gt;&lt;/a&gt;

                &lt;/p&gt;
                &lt;p style=&quot;text-align: center&quot;&gt;
&lt;a title=&quot;Api, Makao and Keaka. My Hawaiin name is Pualani&quot; rel=&quot;lightbox[2012yearinreview]&quot; href=&quot;http://www.mcginityphoto.com/Vacation/2012-Maui-Vacation/i-KHjFqdL/0/M/DSC_5402-M.jpg&quot;&gt;
        &lt;img src=&quot;//www.mcginityphoto.com/Vacation/2012-Maui-Vacation/i-KHjFqdL/0/S/DSC_5402-S.jpg&quot;
             width=&quot;400&quot; height=&quot;266&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Api, Makao and Keaka. My Hawaiin name is Pualani&quot;&gt;&lt;/a&gt;
                            &lt;/p&gt;
&lt;p&gt;
    After returning from Hawaii, we dropped the kids off at their Mom&apos;s and headed to my cousin&apos;s wedding in Beacon, NY for the weekend. From there, my parents, Trish and I rode the train to Boston, spent a few days in Cape Cod and returned home in time for the beginning of school.
    &lt;/p&gt;
    &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/7795952628/&quot; href=&quot;http://farm9.staticflickr.com/8294/7795952628_c0be6bc4ca.jpg&quot; title=&quot;Abbie and Jack on the First Day of School 2012 by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8294/7795952628_c0be6bc4ca_n.jpg&quot; width=&quot;209&quot; height=&quot;320&quot; alt=&quot;Abbie and Jack on the First Day of School 2012&quot; class=&quot;picture&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    
    The kids &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_first_day_of_school2&quot;&gt;started the school year in mid-August&lt;/a&gt; and we celebrated &lt;a href=&quot;http://raibledesigns.com/rd/entry/happy_birthday_jack4&quot;&gt;Jack&apos;s 8th birthday&lt;/a&gt; a couple weeks later.
    &lt;/p&gt;
&lt;p&gt;My lack of speaking engagements and work-related travel gave us more time to frolic in the Colorado mountains, so we &lt;a href=&quot;http://raibledesigns.com/rd/entry/we_bought_a_boat&quot;&gt;bought a boat&lt;/a&gt; for Labor Day weekend. That Saturday, we took it on its Maiden Voyage on the Colorado River, floating from Radium to Rancho del Rio. I guided and rowed the boat most of the time while our &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/7921929062/in/photostream/&quot; href=&quot;http://farm9.staticflickr.com/8460/7921929062_9bcf7d15f0.jpg&quot; rel=&quot;lightbox[2012yearinreview]&quot; title=&quot;The Maiden Voyage Crew&quot;&gt;7 passengers (and 2 dogs)&lt;/a&gt; enjoyed cold beverages, great scenery and relaxing in the sun. 
    &lt;/p&gt;
    &lt;p style=&quot;text-align: center&quot;&gt;
        &lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/7921917130/&quot; href=&quot;http://farm9.staticflickr.com/8041/7921917130_7389475dea.jpg&quot; title=&quot;Abbie with our new boat by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8041/7921917130_7389475dea_m.jpg&quot; width=&quot;240&quot; height=&quot;160&quot; alt=&quot;Abbie with our new boat&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;&lt;/p&gt;
    &lt;p&gt;The next day, Abbie played her first game of golf.&lt;/p&gt;
    &lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a rev=&quot;http://www.flickr.com/photos/mraible/7937704316/&quot; href=&quot;http://farm9.staticflickr.com/8317/7937704316_ee30d6bc55.jpg&quot; title=&quot;Nice form kiddo!&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8317/7937704316_ee30d6bc55_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Nice form kiddo!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

    &lt;a rev=&quot;http://www.flickr.com/photos/mraible/7937705606/&quot; href=&quot;http://farm9.staticflickr.com/8318/7937705606_9d754545de.jpg&quot; title=&quot;Great day of golf at Pole Creek. Got a sweet framed set of Abbie pics at the end too!&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8318/7937705606_9d754545de_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Great day of golf at Pole Creek. Got a sweet framed set of Abbie pics at the end too!&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

    &lt;/p&gt;
    &lt;p&gt;In October, I &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_deck_project&quot;&gt;finished our deck project&lt;/a&gt; and work continued on our kitchen remodel (started in July by &lt;a href=&quot;http://peppergc.com/&quot;&gt;Ted Pepper&lt;/a&gt;). Our kitchen was far enough along for us to host our 1st Annual Halloween Party.&lt;/p&gt;
    &lt;p&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/happy_birthday_abbie6&quot;&gt;Abbie turned 10&lt;/a&gt; the first week in November. That Friday, we headed to Kauai to &lt;a href=&quot;http://raibledesigns.com/rd/entry/happy_40th_anniversary_mom_and&quot;&gt;celebrate my parents&apos; 40th Anniversary&lt;/a&gt;. We spent &lt;a href=&quot;http://raibledesigns.com/rd/entry/november_travels_to_kauai_and#thanksgiving&quot;&gt;Thanksgiving in Wenatchee&lt;/a&gt;, Christmas in Boston/Vermont and &lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/sets/72157632448197212/&quot;&gt;New Years with good friends in Fraser&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8224084347/&quot; href=&quot;http://farm9.staticflickr.com/8341/8224084347_d146419dfd.jpg&quot; title=&quot;Our Lanai by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8341/8224084347_d146419dfd_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Our Lanai&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8224089763/&quot; href=&quot;http://farm9.staticflickr.com/8065/8224089763_03d7c6a657.jpg&quot; title=&quot;Hanalei Pier by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8065/8224089763_03d7c6a657_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Hanalei Pier&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8225168600/&quot; href=&quot;http://farm9.staticflickr.com/8059/8225168600_df36e98e1e.jpg&quot; title=&quot;Happy Family by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8059/8225168600_df36e98e1e_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Happy Family&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8225152842/&quot; href=&quot;http://farm9.staticflickr.com/8339/8225152842_6c987fae93.jpg&quot; title=&quot;Surf House by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8339/8225152842_6c987fae93_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Surf House&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a data-url=&quot;http://www.flickr.com/photos/mcginityphoto/8225154986/&quot; href=&quot;http://farm9.staticflickr.com/8480/8225154986_2641ec95bd.jpg&quot; title=&quot;St Regis Pool by McGinityPhoto, on Flickr&quot; rel=&quot;lightbox[2012yearinreview]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8480/8225154986_2641ec95bd_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;St Regis Pool&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;https://www.facebook.com/photo.php?fbid=10200109112597408&amp;amp;set=a.10200104543563185.2198356.1438065285&amp;amp;type=1&quot;&gt;
&lt;img alt=&quot;Mom and Dad in Kauai&quot; src=&quot;//sphotos-a.xx.fbcdn.net/hphotos-prn1/621352_10200109112597408_143056394_o.jpg&quot; style=&quot;width: 520px; height: 346px; border: 1px solid black&quot;&gt;
&lt;/a&gt;
&lt;/p&gt;
&lt;h2 id=&quot;2013&quot;&gt;2013&lt;/h2&gt;
&lt;p&gt;My goals for 2013 are to be happy and to &lt;em&gt;slow down&lt;/em&gt;. I don&apos;t plan on traveling any less, or spending less time with my family. I&apos;d just like to walk slower, smell the good ol&apos; Rocky Mountain air more and enjoy life. I believe our raft will help us facilitate this and we&apos;re already planning trips to the &lt;a href=&quot;http://www.tagalong.com/index.php?page=greeno&quot;&gt;Green River&lt;/a&gt; in Utah and &lt;a href=&quot;http://www.montanaliving.com/Outdoors/Schafer_Meadows_a_wilderness_trip_of_a_lifetime_97-097&quot;&gt;Schafer Meadows&lt;/a&gt; in the Bob.&lt;/p&gt;
&lt;p&gt;The big event for the year will be Trish and my wedding this summer. We&apos;ll be doing it in my hometown in Montana and we expect it to be quite the shindig. Afterward, we plan on &lt;a href=&quot;https://twitter.com/mraible/status/264452753596751874&quot;&gt;traveling the world&lt;/a&gt; for our honeymoon.&lt;/p&gt;
&lt;p&gt;Of course, if the bus gets finished, that&apos;s a huge bonus too.&lt;/p&gt;
&lt;p&gt;Professionally, I&apos;m starting an exciting project at Taleo that will involve heavy JavaScript, CSS3 and maybe even Canvas. I have speaking engagements lined up at &lt;a href=&quot;http://www.meetup.com/DenverJavaUsersGroup/events/93932082/&quot;&gt;Denver JUG in February&lt;/a&gt; and &lt;a href=&quot;http://www.meetup.com/HTML5-Denver-Users-Group/&quot;&gt;HTML5 Denver&lt;/a&gt; in April. Also, I just submitted a couple talks to &lt;a href=&quot;http://www.devoxx.com/display/FR13/Home&quot;&gt;Devoxx France&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;For AppFuse, I&apos;d love to get 3-4 releases out this year, but 2 is probably more realistic. The &lt;a href=&quot;http://appfuse.org/display/APF/Roadmap&quot;&gt;AppFuse Roadmap&lt;/a&gt; shows our future releases + features. I&apos;d also like to work a bit more on my Play 2 app; finishing the mobile client and possibly switching from Anorm to Slick or Spring Data.&lt;/p&gt;
&lt;p&gt;While Oracle has been good to me, I look forward to finding and working for a new client in September.&lt;/p&gt;
&lt;p&gt;Last year &lt;a href=&quot;http://raibledesigns.com/rd/entry/2011_a_year_in_review&quot;&gt;at this time&lt;/a&gt;, we watched the Broncos execute the &lt;em&gt;Mile High Miracle&lt;/em&gt; over the Steelers. With tickets to both this week&apos;s game (vs. The Ravens) and next week&apos;s game (vs. The Patriots), I wouldn&apos;t be surprised if January turns out to be a great month. However, with the Powder Days, The Super Bowl, the raft trips, the Bus Shows and The Wedding, there&apos;s a good chance that all the months in 2013 are epic. &lt;img src=&quot;https://raibledesigns.com/images/smileys/smile.gif&quot; class=&quot;smiley&quot; alt=&quot;:)&quot; title=&quot;:)&quot; /&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_2_2_1_released</id>
        <title type="html">AppFuse 2.2.1 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_2_2_1_released"/>
        <published>2012-12-11T15:21:44-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//static.appfuse.org/images/appfuse-icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the release of AppFuse 2.2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are Hibernate 4, Struts 2.3.7, Apache CXF 2.7.0 and Spring Security 3.1.3. In addition, we&apos;ve integrated HTML5, Twitter Bootstrap, jQuery and replaced Compass with Hibernate Search. Last but not least, we&apos;ve added full support for Java 7 and integrated many &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part4&quot;&gt;security improvements&lt;/a&gt;. For more details on specific changes see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.2.1&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;&lt;strong&gt;What is AppFuse?&lt;/strong&gt;&lt;br/&gt;AppFuse is a full-stack framework for building web applications on the JVM. It was originally developed to eliminate the ramp-up time when building new web applications. Over the years, it has matured into a very testable and secure system for creating Java-based webapps.
&lt;/p&gt;

&lt;p&gt;Demos for this release can be viewed at &lt;a href=&quot;http://demo.appfuse.org/&quot;&gt;http://demo.appfuse.org&lt;/a&gt;. Please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; style=&quot;font-weight: bold&quot;&gt;QuickStart Guide&lt;/a&gt; to get started with this release. &lt;/p&gt;

&lt;p&gt;A number of blog posts were written about features that went into this release while it was being developed:&lt;/p&gt;

&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/improving_appfuse_s_pagespeed_with&quot;&gt;Improving AppFuse&apos;s PageSpeed with Apache&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_news_liquibase_and_wro4j&quot;&gt;New Liquibase and wro4j Tutorials from J. Garc&#237;a&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_news_github_hibernate_search&quot;&gt;AppFuse News: GitHub, Hibernate Search and The Future&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/refreshing_appfuse_s_ui_with&quot;&gt;Refreshing AppFuse&apos;s UI with Twitter Bootstrap&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_security&quot;&gt;Upgrading AppFuse to Spring Security 3.1 and Spring 3.1&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/integrating_oauth_with_appfuse_and&quot;&gt;Integrating OAuth with AppFuse and its REST API&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;

&lt;p&gt;If you have questions about AppFuse, please read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot;&gt;FAQ&lt;/a&gt; or join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;mailing list&lt;/a&gt;. If you find any issues, please &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/ANN-AppFuse-2-2-1-Released-td4656067.html&quot;&gt;report them on the users mailing list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing lists.&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;We greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot; title=&quot;Sponsors&quot; style=&quot;color: #666&quot;&gt;our sponsors&lt;/a&gt;, particularly &lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot; style=&quot;color: #666&quot;&gt;Atlassian&lt;/a&gt;, &lt;a href=&quot;http://contegix.com&quot; style=&quot;color: #666&quot;&gt;Contegix&lt;/a&gt; and &lt;a href=&quot;http://www.jetbrains.com&quot; style=&quot;color: #666&quot;&gt;JetBrains&lt;/a&gt;. We highly recommend using the new &lt;a href=&quot;http://blogs.jetbrains.com/idea/2012/12/intellij-idea-12-is-available-for-download/&quot;&gt;IntelliJ IDEA 12&lt;/a&gt; for developing web applications.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/improving_appfuse_s_pagespeed_with</id>
        <title type="html">Improving AppFuse&apos;s PageSpeed with Apache</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/improving_appfuse_s_pagespeed_with"/>
        <published>2012-12-04T09:25:05-07:00</published>
        <updated>2012-12-05T02:34:08-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="contegix" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apache" scheme="http://roller.apache.org/ns/tags/" />
        <category term="pagespeed" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;One of the most important things when developing webapps is to make them &lt;em&gt;fast&lt;/em&gt;. With AppFuse, we&apos;ve tried to incorporate many of the &lt;a href=&quot;http://stevesouders.com/hpws/rules.php&quot;&gt;14 rules for faster-loading websites&lt;/a&gt;. We had a gzip filter before it was cool (2003) and replaced it with &lt;a href=&quot;http://ehcache.org/documentation/user-guide/web-caching&quot;&gt;the one from EhCache&lt;/a&gt;. However, users experienced issues with both of these, both &lt;a href=&quot;http://issues.appfuse.org/browse/APF-863&quot;&gt;with XFire/CXF&lt;/a&gt; and &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1037&quot;&gt;WebWork/Struts 2 and JSPs&lt;/a&gt;. Because of these issues, we disabled gzipping a few releases ago. &lt;/p&gt;

&lt;p&gt;This article is designed to show you how you can make your AppFuse webapp faster, without modifying any code. The good news is this applies to any webapp that you can deploy behind Apache. &lt;/p&gt;

&lt;p&gt;Last Friday, I sent an email to the good folks at &lt;a href=&quot;http://contegix.com&quot;&gt;Contegix&lt;/a&gt; to see if they could install &lt;a href=&quot;https://developers.google.com/speed/pagespeed/mod&quot;&gt;mod_pagespeed&lt;/a&gt; on the Apache server that sits in front of *.appfuse.org. My goal was to improve the YSlow and PageSpeed scores of the apps hosted on &lt;a href=&quot;http://demo.appfuse.or&quot;&gt;demo.appfuse.org&lt;/a&gt;. I discovered they were getting a dismal score of 24 and figured we could do a lot better. mod_pagespeed speeds up your site and reduces page load time by automatically applying web performance best practices. It seemed like an easy solution.
&lt;/p&gt;

&lt;p&gt;Unfortunately, we were unable to use mod_pagespeed. From the guys at Contegix:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;Attempting to install mod_pagespeed as you requested, we find that it requires Apache httpd 2.2 and libstdc++ 4.1.2, both of which are unsupported in RHEL4. To get mod_pagespeed to work on your present operating system basically means re-rolling the core components, which would make them unsupported. I&apos;m afraid mod_pagespeed is simply not an option on your present configuration.&lt;/p&gt;

&lt;p&gt;Since I still wanted to improve performance, I opted for another route instead: using mod_deflate (for gzipping) and mod_expires (for expires headers). I also turned on KeepAlive as recommended by &lt;a href=&quot;https://developers.google.com/speed/docs/insights/using_chrome&quot;&gt;PageSpeed Insights&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mod_deflate&lt;/strong&gt;&lt;br&gt;mod_deflate was already installed in Apache (version 2.0.52), so all I had to do was configure it. On RHEL4, Apache is installed at /etc/httpd and there&apos;s a &lt;em&gt;conf.d&lt;/em&gt; directory that contains all the configuration files. I created a file at &lt;em&gt;/etc/httpd/conf.d/deflate.conf&lt;/em&gt; and populated it with the following:&lt;/p&gt;

&lt;pre&gt;#
# mod_deflate configuration
#
&amp;lt;IfModule mod_deflate.c&gt;
    SetOutputFilter DEFLATE
    
    AddOutputFilterByType DEFLATE text/plain text/html text/xml text/css application/xml application/xhtml+xml application/rss+xml application/javascript application/x-javascript
    
    DeflateCompressionLevel 9
    
    BrowserMatch ^Mozilla/4 gzip-only-text/html
    BrowserMatch ^Mozilla/4\.0[678] no-gzip
    BrowserMatch \bMSIE !no-gzip !gzip-only-text/html
    
    DeflateFilterNote Input instream
    DeflateFilterNote Output outstream
    DeflateFilterNote Ratio ratio
    
    LogFormat &apos;&quot;%r&quot; %{outstream}n/%{instream}n (%{ratio}n%%)&apos; deflate
    
&amp;lt;/IfModule&gt;&lt;/pre&gt;

&lt;p&gt;At first, I had separate lines for all the different content types (as recommended by &lt;a href=&quot;http://www.g-loaded.eu/2008/05/10/use-mod_deflate-to-compress-web-content-delivered-by-apache/&quot;&gt;this article&lt;/a&gt;). The Contegix support crew figured out the solution (everything needed to be on one line) in 14 minutes, updated the config and verified it worked using &lt;a href=&quot;http://www.whatsmyip.org/http-compression-test/&quot;&gt;an http compression testing page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;mod_expires&lt;/strong&gt;&lt;br&gt;mod_expires was already installed, so I added a config file at &lt;em&gt;/etc/httpd/conf.d/expires.conf&lt;/em&gt;. I used &lt;a href=&quot;http://www.howtoforge.com/make-browsers-cache-static-files-with-mod_expires-on-apache2-debian-squeeze&quot;&gt;this howto&lt;/a&gt; and asked Contegix for help when it didn&apos;t work. Their response took quite a bit longer this time (49 minutes), but they once again figured it out:&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;It appears that FilesMatch does not like to play will JkMount. It does work using content type.&lt;/p&gt;

&lt;p&gt;My final config for &lt;em&gt;expires.conf&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;
&amp;lt;IfModule mod_expires.c&gt;
    ExpiresActive On
    
    &amp;lt;FilesMatch &quot;\.(jpe?g|png|gif|js|css)$&quot;&gt;
        ExpiresDefault &quot;access plus 1 week&quot;
    &amp;lt;/FilesMatch&gt;
    
    ExpiresByType image/jpeg &quot;access plus 1 week&quot;
    ExpiresByType image/png &quot;access plus 1 week&quot;
    ExpiresByType image/gif &quot;access plus 1 week&quot;
    ExpiresByType text/css &quot;access plus 1 week&quot;
    ExpiresByType application/javascript &quot;access plus 1 week&quot;
    ExpiresByType application/x-javascript &quot;access plus 1 week&quot;
&amp;lt;/IfModule&gt;
&lt;/pre&gt;

&lt;p&gt;I used &quot;1 week&quot; because we&apos;re changing things quite a bit right now and we haven&apos;t integrated &lt;a href=&quot;http://www.operatornew.com/2012/10/adding-web-resource-fingerprinting-to.html&quot;&gt;resource fingerprinting&lt;/a&gt; yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;KeepAlive&lt;br&gt;&lt;/strong&gt;The last thing I did to improve performance was to turn on KeepAlive by editing &lt;em&gt;/etc/httpd/conf/httpd.conf &lt;/em&gt;and changing &lt;em&gt;Off &lt;/em&gt;to &lt;em&gt;On&lt;/em&gt;.&lt;/p&gt;
&lt;pre&gt;#
# KeepAlive: Whether or not to allow persistent connections (more than
# one request per connection). Set to &quot;Off&quot; to deactivate.
#
KeepAlive On&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Summary&lt;br&gt;&lt;/strong&gt;As a result of these changes, our PageSpeed score went from 24 to 96 and YSlow went from a 90 to a 98. When I started this experiment, I was only trying to fix demo.appfuse.org. However, it also improved the speed of all the other *.appfuse.org sites, including &lt;a href=&quot;http://appfuse.org&quot;&gt;Confluence&lt;/a&gt;, &lt;a href=&quot;http://builds.appfuse.or&quot;&gt;Bamboo&lt;/a&gt;, &lt;a href=&quot;http://issues.appfuse.or&quot;&gt;JIRA&lt;/a&gt; and &lt;a href=&quot;http://source.appfuse.org&quot;&gt;FishEye&lt;/a&gt;. Thanks for all the help Contegix! There&apos;s a good chance you&apos;ve given me back a few minutes in each day.&lt;/p&gt;
&lt;p style=&quot;text-align: right; font-size: .95em; margin-top: -10px&quot;&gt;&lt;em&gt;Originally posted &lt;a href=&quot;http://appfuse.org/display/APF/2012/12/04/Improving+AppFuse%27s+PageSpeed+with+Apache&quot;&gt;on the AppFuse Blog&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_news_liquibase_and_wro4j</id>
        <title type="html">AppFuse News: Liquibase and wro4j Tutorials from J. Garc&#237;a</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_news_liquibase_and_wro4j"/>
        <published>2012-11-30T14:32:47-07:00</published>
        <updated>2012-11-30T20:35:01-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="liquibase" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wro4j" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;New committer &lt;a href=&quot;http://www.operatornew.com/&quot;&gt;J. Garc&#237;a&lt;/a&gt; has been doing a lot of work to improve i18n in AppFuse 2.2, as well as our Struts 2 support. In addition, he&apos;s written a couple articles that show
you how to integrate &lt;a href=&quot;http://www.liquibase.org/&quot;&gt;Liquibase&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/wro4j/&quot;&gt;wro4j&lt;/a&gt; in your AppFuse applications. Thanks for the
great documentation J!&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.operatornew.com/2012/10/adding-web-resource-fingerprinting-to.html&quot;&gt;Adding web resource fingerprinting to AppFuse with
wro4j&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.operatornew.com/2012/11/automatic-db-migration-for-java-web.html&quot;&gt;Automatic DB migration for Java web apps with
Liquibase&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The 2.2 release is coming along, and we&apos;re down to &lt;a href=&quot;http://issues.appfuse.org/secure/IssueNavigator.jspa?mode=hide&amp;amp;requestId=10190&quot;&gt;16
open issues&lt;/a&gt;. I&apos;ve updated the &lt;a href=&quot;http://appfuse.org/display/APF/Using+Hibernate&quot;&gt;Hibernate&lt;/a&gt;, &lt;a href=&quot;http://appfuse.org/display/APF/Using+JPA&quot;&gt;JPA&lt;/a&gt;, &lt;a
href=&quot;http://appfuse.org/display/APF/Services&quot;&gt;Services&lt;/a&gt; and &lt;a href=&quot;http://appfuse.org/display/APF/Web+Services&quot;&gt;Web Services&lt;/a&gt; tutorials and hope to finish the web
tutorials in the next week. You can try the latest code using the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; or check it out on the demo
site:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://demo.appfuse.org/appfuse-jsf&quot;&gt;http://demo.appfuse.org/appfuse-jsf&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href=&quot;http://demo.appfuse.org/appfuse-spring&quot;&gt;http://demo.appfuse.org/appfuse-spring&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://demo.appfuse.org/appfuse-struts&quot;
class=&quot;external-link&quot;&gt;http://demo.appfuse.org/appfuse-struts&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://demo.appfuse.org/appfuse-tapestry&quot;
class=&quot;external-link&quot;&gt;http://demo.appfuse.org/appfuse-tapestry&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Please see &lt;a
href=&quot;http://appfuse.547863.n4.nabble.com/AppFuse-2-2-Ready-for-Testing-td4655722.html&quot;&gt;this thread&lt;/a&gt; on the mailing list if you have any questions or suggestions.&lt;/p&gt;&lt;p&gt;In
related news, &lt;a href=&quot;http://www.captaindebug.com/&quot;&gt;Roger Hughes&lt;/a&gt; has a good article titled &lt;a
href=&quot;http://www.captaindebug.com/2012/11/a-list-of-things-you-can-do-with-spring.html&quot;&gt;Ten Things You Can Do With Spring Security&lt;/a&gt;. Since AppFuse uses Spring Security
extensively, hopefully you can use some of Roger&apos;s tips to improve the security of your app.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/why_the_bias_against_jsf</id>
        <title type="html">Why the bias against JSF?</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/why_the_bias_against_jsf"/>
        <published>2012-11-08T09:24:27-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">In my last post about &lt;a href=&quot;http://raibledesigns.com/rd/entry/infoq_s_top_20_web&quot;&gt;InfoQ&apos;s Top 20 Web Frameworks for the JVM&lt;/a&gt;, I received a thought-provoking &lt;a href=&quot;http://raibledesigns.com/rd/entry/infoq_s_top_20_web#comment-1352305197000&quot;&gt;comment&lt;/a&gt; from &lt;a href=&quot;http://henk53.wordpress.com/&quot;&gt;henk53&lt;/a&gt;:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
There is one little thing that does bother me in those presentations, and that&apos;s your fairly obvious bias against JSF. &lt;br/&gt;...&lt;br/&gt;
If you are presenting yourself as, more or less, an authority on comparing web frameworks, then having a fairly obvious biased against one of them is just peculiar. I, all of my team, and various clients distrust your ranking of JSF. We do look at your data if the choice is between other frameworks, but as soon as JSF comes into the picture we just look elsewhere.
&lt;br/&gt;&lt;br/&gt;
I&apos;m not really sure where this bias comes from. Yes, JSF 1.0 sucked and 1.2 was only marginally better, but 2.0 is really cool and productive and there are SUPERB component and utility libraries now like PrimeFaces and OmniFaces. As a researcher of this topic I think you should keep up the date and not stick to some old grudge.
&lt;/p&gt;
&lt;p&gt;This is true, I am biased against JSF. It all started with my &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_jsf_experience&quot;&gt;first JSF experience&lt;/a&gt; back in August 2004. If you remember correctly, 2004 was a big year: JSF 1.0, Spring 1.0 and Flex 1.0 were all released. The &quot;AJAX&quot; term was coined in &lt;a href=&quot;http://www.adaptivepath.com/ideas/ajax-new-approach-web-applications&quot;&gt;early 2005&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/4378559350/&quot; title=&quot;History of Web Frameworks by mraible, on Flickr&quot;&gt;&lt;img src=&quot;//farm5.staticflickr.com/4067/4378559350_13f0755403.jpg&quot; width=&quot;500&quot; height=&quot;234&quot; alt=&quot;History of Web Frameworks&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;By &lt;a href=&quot;http://raibledesigns.com/rd/entry/jsf_still_sucks&quot;&gt;2007&lt;/a&gt; and &lt;a href=&quot;http://raibledesigns.com/rd/entry/what_s_wrong_with_jsf&quot;&gt;2008&lt;/a&gt;, JSF still hadn&apos;t gotten any better. In late 2009, JSF 2.0 was released and &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_to_jsf_2&quot;&gt;I upgraded in March 2011&lt;/a&gt;. As you can see from the aforementioned post, I ran into quite a few issues upgrading. JSF was also the &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_extensionless_urls_with_tapestry&quot;&gt;hardest one to get working with extension-less URLs&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Most of my issues with JSF come from having maintained an application built with it since 2004. If I were to start a new application without any legacy migration issues, I imagine it wouldn&apos;t be as difficult. However, if you compare it to Struts 2 and Spring MVC, I&apos;ve had little-to-no issues upgrading those applications over the years. &lt;/p&gt;
&lt;p&gt;Also, I&apos;m not just biased against JSF, but most component-based web frameworks. Just ask the Tapestry and Wicket folks. They&apos;ve felt my criticisms over the years. My reason for preferring request-based frameworks like Struts 2/Spring MVC and Grails/Play has been because I&apos;ve never seen the appeal in component-based frameworks. Often I&apos;ve found that their components are just widgets that you can get from any decent JavaScript framework. And chances are that JavaScript framework can work with &lt;em&gt;any&lt;/em&gt; web framework. Also, I&apos;ve worked on a lot of high-traffic web applications that require statelessness for scalability.&lt;/p&gt;
&lt;p&gt;I see the value in component-based frameworks, I just don&apos;t think components should be authored on the server-side. Most of the Java-based component frameworks require 2+ files for components (one for the component, one for the view, possibly one for the config). I love GWT&apos;s component concept in that you can just extract a class and re-use it. With JS frameworks, you can often just include a script. These days, when I think of good component-based frameworks, I think of jQuery UI and Twitter Bootstrap.&lt;/p&gt;
&lt;p&gt;All that being said, there&apos;s a lot of folks praising JSF 2 (and &lt;a href=&quot;http://primefaces.org/&quot;&gt;PrimeFaces&lt;/a&gt; moreso). That&apos;s why I&apos;ll be integrating it (or merging your pull request) into the 2.3 release of AppFuse. Since PrimeFaces contains a Bootstrap theme, I hope this is a pleasant experience and my overall opinion of JSF improves.&lt;/p&gt;
&lt;p&gt;In other component-based frameworks in AppFuse news, Tapestry 5 has gotten &lt;em&gt;really fast&lt;/em&gt; in the last year. I imagine this is because we have a Tapestry expert, &lt;a href=&quot;http://www.linkedin.com/in/sergeeby&quot;&gt;Serge Eby&lt;/a&gt;, working on it. And we&apos;re planning on adding Wicket in the 2.3 release. &lt;/p&gt;
&lt;p&gt;So even though I &lt;em&gt;prefer&lt;/em&gt; request-based frameworks with REST support and Bootstrap, that doesn&apos;t mean everyone does. I&apos;ll do my best to be less-biased in the future. However, please remember that my view on web frameworks is as a developer, not an analyst. And aren&apos;t developers &lt;em&gt;supposed&lt;/em&gt; to be opinionated? &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/infoq_s_top_20_web</id>
        <title type="html">InfoQ&apos;s Top 20 Web Frameworks for the JVM</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/infoq_s_top_20_web"/>
        <published>2012-11-06T12:04:28-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="infoq" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Back in early October, InfoQ.com published a community research article titled &lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;Top 20 Web Frameworks for the JVM&lt;/a&gt;. Their goal seemed to be fairly simple:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Using the new community research tool, we at InfoQ want to get YOUR opinions on the relative importance and maturity of a variety of web frameworks that are targeted for the JVM. Please vote by dragging each practice across two dimensions &#8211; how important is the framework relative to the other frameworks, and how much is it actually used in real teams and projects.
&lt;/p&gt;
&lt;p&gt;When I first saw this article, I noticed some strange web frameworks listed. Namely, Netty, SiteMesh and Spark. I haven&apos;t heard of many folks using &lt;a href=&quot;https://netty.io/&quot;&gt;Netty&lt;/a&gt; for a web framework, but I&apos;m sure it&apos;s possible. SiteMesh is certainly not a web framework and I&apos;ve never even heard of Spark. And where is GWT and Vaadin? Regardless of the choices, I went ahead and voted.&lt;/p&gt;
&lt;p&gt;Last week, InfoQ posted their top content for October on Facebook. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;Top 20 Web Frameworks for the JVM&lt;/a&gt; 25,992 PV&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/news/2012/10/Ruby-on-Rails-Node-js-LinkedIn&quot;&gt;Ruby on Rails vs. Node.js at LinkedIn&lt;/a&gt; 11,904 PV&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/presentations/Mobile-Web-Development&quot;&gt;Mobile Webdev: The Horror&lt;/a&gt; 11,150 PV&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/articles/rest-introduction&quot;&gt;A Brief Introduction to REST&lt;/a&gt; 8,872 PV
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/minibooks/kanban-scrum-minibook&quot;&gt;Kanban and Scrum - making the most of both&lt;/a&gt; 7,665 PV&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First of all, it&apos;s interesting to see that JVM Web Frameworks is still a hot topic for developers. Whenever I do my Comparing JVM Web Frameworks talk at conferences, I always see a few jabs about &quot;he&apos;s &lt;em&gt;still&lt;/em&gt; doing that talk!?&quot; Yes, it seems strange that a talk I first did in 2004 is still in high demand. &lt;/p&gt;
&lt;p&gt;Secondly, I think InfoQ does good in showing how the frameworks ranked and showing their &lt;em&gt;heatmaps&lt;/em&gt;. Below are their rankings from 1109 participants. &lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/8161758257/&quot; title=&quot;InfoQ&apos;s Top 20 Web Frameworks for the JVM&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8197/8161758257_ef6d919f5d.jpg&quot; width=&quot;500&quot; height=&quot;395&quot; alt=&quot;InfoQ&apos;s Top 20 Web Frameworks for the JVM&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;According to this research, the top 5 web frameworks for the JVM are Spring MVC, Play, Grails, JSF and Struts (I hope those surveyed meant Struts 2, not Struts 1).&lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;http://www.slideshare.net/mraible/comparing-jvm-web-frameworks-jfokus-2012&quot;&gt;my research from last February&lt;/a&gt; (slide 21), I ranked them (with no particular weightings) as Grails, GWT, JRuby on Rails, Spring MVC and Vaadin. So I guess you could say I got 2 out of 5 right (Grails and Spring MVC). Not bad considering InfoQ didn&apos;t even consider GWT and Vaadin.&lt;/p&gt;
&lt;p&gt;Another intriguing data point in this study is each frameworks&apos; heatmap. For example, below are heatmaps for the top 4 frameworks. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161758501/&quot; href=&quot;http://farm8.staticflickr.com/7247/8161758501_151b1a839c.jpg&quot; title=&quot;Spring MVC Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7247/8161758501_151b1a839c_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;Spring MVC Heatmap&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161762845/&quot; href=&quot;http://farm8.staticflickr.com/7125/8161762845_12cfdc076c.jpg&quot; title=&quot;Grails Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7125/8161762845_12cfdc076c_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;Grails Heatmap&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161758399/&quot; href=&quot;http://farm8.staticflickr.com/7255/8161758399_505e8cf4db.jpg&quot; title=&quot;Play Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7255/8161758399_505e8cf4db_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;Play Heatmap&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161758341/&quot; href=&quot;http://farm8.staticflickr.com/7256/8161758341_7e1d37e1ea.jpg&quot; title=&quot;JSF Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7256/8161758341_7e1d37e1ea_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;JSF Heatmap&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Notice how Grails and Spring MVC are both &lt;em&gt;hotter&lt;/em&gt; in the bottom right corner? It seems the community&apos;s overall opinions of these two frameworks are more aligned than JSF and Play, which a fair amount of folks rank as hyped and unimportant. &lt;/p&gt;
&lt;p&gt;What I really like about this research is it&apos;s the community&apos;s opinions, visualized. It also confirms that some of my favorite frameworks are still on top. I don&apos;t know if JSF belongs as a top framework, however it seems a lot of folks do. I recently &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Drop-JSF-Support-td4655648.html&quot;&gt;thought about removing it from AppFuse&lt;/a&gt;, but decided to keep it (at least for the next release). I hope InfoQ does more research projects like this, especially if they get their list of web frameworks right. </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_news_github_hibernate_search</id>
        <title type="html">AppFuse News: GitHub, Hibernate Search and The Future</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_news_github_hibernate_search"/>
        <published>2012-09-25T10:42:14-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="github" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roadmap" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;It&apos;s been a while since I&apos;ve written anything about &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;, but since the project
  has had quite a bit of activity lately, now seems like a good time.&lt;/p&gt;&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt;&lt;br&gt;First of all,
  we moved the source code from java.net to &lt;a href=&quot;https://github.com/appfuse/appfuse&quot;&gt;GitHub&lt;/a&gt; way back
  in June. Thanks to &lt;a href=&quot;https://twitter.com/sdeby&quot;&gt;Serge&lt;/a&gt; for helping with
  this process and making it &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Migrating-to-GitHub-td4655148.html&quot;&gt;quick and
    painless&lt;/a&gt;. For some reason, shortly
  after moving, we started having quite a few build issues with &lt;a href=&quot;http://builds.appfuse.org&quot;&gt;Bamboo&lt;/a&gt;.
  I was able to diagnose the
  problem as not enough memory on our server. Thankfully, &lt;a href=&quot;http://www.contegix.com/&quot;&gt;Contegix&lt;/a&gt; was able to
  add another 2GB of
  RAM to our box and get everything back up-to-snuff.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;New Committer: J. Garcia&lt;/strong&gt;&lt;br&gt;
  J. Garcia has been a regular voice on the users and developers mailing list for several
  months. He&apos;s recently started contributing a lot of patches in JIRA and seems genuinely interested in the success of
  AppFuse. That&apos;s why we voted and &lt;a
        href=&quot;http://appfuse.547863.n4.nabble.com/VOTE-Add-J-Garcia-as-an-AppFuse-Committer-td4655395.html&quot;&gt;added him
    as a committer&lt;/a&gt;. To prove this was a smart move, he recently
  &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1298&quot;&gt;replaced Compass with
    Hibernate Search&lt;/a&gt; and &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1297&quot;&gt;upgraded to Hibernate 4&lt;/a&gt;.
  As part of this work, he removed iBATIS support, which brings me to my next point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Future&lt;/strong&gt;&lt;br&gt;

  In mid-August, I sent an email to the
  community, asking them &quot;&lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Anyone-using-iBATIS-td4655369.html&quot;&gt;Anyone using iBATIS?&lt;/a&gt;&quot;&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;I&apos;m thinking of replacing AppFuse&apos;s Data Tier with Spring Data, especially because it has NoSQL and REST support. There&apos;s a good intro on InfoQ today: &lt;br&gt;&lt;br&gt;&lt;a href=&quot;http://www.infoq.com/articles/spring-data-intro&quot;&gt;http://www.infoq.com/articles/spring-data-intro&lt;/span&gt;&lt;/a&gt;&lt;br&gt;&lt;br&gt;
Does anyone see an issue with this? The lack of iBATIS support could be an issue, but I doubt it since if we wanted to continue supporting it, we should move to MyBATIS.
&lt;/p&gt;

&lt;p&gt;Everyone agreed this was a good idea and it seemed like a logical time to remove iBATIS support. In
  addition, I posted a roadmap I jotted down in early May. Since we&apos;ve missed all the dates so far, I&apos;ve removed them
  from the listing below. We hope to get 1-2 releases done by the end of this year, with 2.2 in the next 2-3 weeks.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;2.2&lt;/strong&gt;&lt;br&gt;Hibernate 4&lt;br&gt;Hibernate Search&lt;br&gt;Bootstrap&lt;br&gt;H5BP&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2.3&lt;/strong&gt; &lt;br&gt;AMP for
  all light modules&lt;br&gt;Wicket&lt;br&gt;PrimeFaces&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2.4&lt;/strong&gt;&lt;br&gt;JSR 303 (might require removing or developing
  client-side support)&lt;br&gt;Mockito instead of jMock/EasyMock&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2.5&lt;/strong&gt;&lt;br&gt;AMP one-to-many&lt;br&gt;Spring Data&lt;br&gt;MyBatis
  (if there&apos;s interest in adding it back in)&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2.6&lt;/strong&gt;&lt;br&gt;wro4j for concatenation and minimizing JS and
  CSS&lt;br&gt;pjax - &lt;a href=&quot;https://github.com/defunkt/jquery-pjax&quot;&gt;https://github.com/defunkt/jquery-pjax&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;&lt;strong&gt;2.7&lt;/strong&gt;&lt;br&gt;Scala example&lt;br&gt;Gradle example&lt;br&gt;Article about examples&lt;/p&gt;&lt;p&gt;&lt;strong&gt;3.0&lt;/strong&gt;&lt;br&gt;GWT
&lt;/p&gt;
&lt;/blockquote&gt;

  &lt;p&gt;&lt;strong&gt;Maven Central Statistics&lt;/strong&gt;&lt;br&gt;To prove there&apos;s still a fair amount of folks using
    AppFuse, here&apos;s some statistic from Sonatype&apos;s &lt;a href=&quot;https://oss.sonatype.org&quot;&gt;OSS Repository Hosting
      Service&lt;/a&gt;.&lt;/p&gt;
  &lt;p style=&quot;text-align: center&quot;&gt;&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8023640406/&quot; href=&quot;http://farm9.staticflickr.com/8452/8023640406_6df4a3c6f8_o.png&quot; rel=&quot;lightbox[appfuse-201209]&quot;
                                        title=&quot;AppFuse Downloads&quot;&gt;&lt;img
        src=&quot;//farm9.staticflickr.com/8452/8023640406_a7e3613b94.jpg&quot; width=&quot;500&quot; height=&quot;188&quot;
        alt=&quot;AppFuse Downloads&quot;&gt;&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;From this screenshot, you can see that AppFuse artifacts are downloaded around 7,000 times per month. The
      following graph is even more interesting. Apparently, around 3,000 new projects are created with AppFuse
      archetypes each month.&lt;/p&gt;

    &lt;p style=&quot;text-align: center&quot;&gt;
      &lt;a rev=&quot;http://www.flickr.com/photos/mraible/8023642969/&quot; href=&quot;http://farm9.staticflickr.com/8182/8023642969_00801e1ce9_o.png&quot; rel=&quot;lightbox[appfuse-201209]&quot;
         title=&quot;AppFuse Archetype Downloads&quot;&gt;&lt;img
            src=&quot;//farm9.staticflickr.com/8182/8023642969_14111307ca.jpg&quot; width=&quot;500&quot; height=&quot;186&quot;
            alt=&quot;AppFuse Archetype Downloads&quot;&gt;&lt;/a&gt;&lt;/p&gt;

    &lt;p&gt;&lt;strong&gt;The AppFuse Name&lt;br&gt;&lt;/strong&gt;Finally, I &lt;a href=&quot;https://twitter.com/#!/search/?q=appfuse&quot;&gt;recently discovered&lt;/a&gt;
      that ShoreTel decided to &lt;a
            href=&quot;http://www.zdnet.com/shoretel-intros-appfuse-integrated-phone-system-aimed-at-salesforce-customers-7000004374/&quot;
            &gt;name a new product AppFuse&lt;/a&gt;. I guess this signifies two things: 1)
      it&apos;s a good name for a product and 2) someone didn&apos;t do their research before naming it. At this point, I&apos;m not
      too concerned, but it is an interesting development.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/twitter_s_open_source_summit</id>
        <title type="html">Twitter&apos;s Open Source Summit: Bootstrap 2.0 Edition</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/twitter_s_open_source_summit"/>
        <published>2012-02-01T11:28:40-07:00</published>
        <updated>2012-02-01T17:32:46-07:00</updated> 
        <category term="/The Web" label="The Web" />
        <category term="bootstrap" scheme="http://roller.apache.org/ns/tags/" />
        <category term="opensource" scheme="http://roller.apache.org/ns/tags/" />
        <category term="twitter" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ossummit" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hogan.js" scheme="http://roller.apache.org/ns/tags/" />
        <category term="nasa" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Every few months, &lt;a href=&quot;http://twitter.com&quot;&gt;Twitter&lt;/a&gt; hosts an Open Source Summit to talk about tools they&apos;re using. Since I happened to be near San Fransisco, I happily attended their latest &lt;a href=&quot;https://twitter.com/search?q=%23ossummit&quot;&gt;#ossummit&lt;/a&gt; to learn about &lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Bootstrap 2.0&lt;/a&gt;. Below are my notes from last night&apos;s event.
&lt;/p&gt;
&lt;p&gt;
95% of Twitter&apos;s infrastructure is powered by open source. They hope to contributing back to open source by doing 2-3 summits per year. Without open source, there would be no Twitter. You can find a bunch of Twitter&apos;s open source contributions at &lt;a href=&quot;http://twitter.github.com&quot;&gt;twitter.github.com&lt;/a&gt;. They&apos;re also big fans of Apache and commit to a wide variety of projects there.
&lt;/p&gt;
&lt;p id=&quot;bootstrap&quot;&gt;
&lt;strong&gt;Bootstrap&lt;/strong&gt;&lt;br/&gt;
Bootstrap is developed by two main guys: &lt;a href=&quot;http://twitter.com/mdo&quot;&gt;@mdo&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/fat&quot;&gt;@fat&lt;/a&gt;. 
Mark (@mdo) has been a designer at Twitter for 2 years. He started on the Revenue Team with ads, but has been working on redesign for last 4 months. Has been doing HTML and CSS for about 11 years. He used Notepad on Windows to build his GeoCities site. 
&lt;/p&gt;
&lt;p&gt;boot&amp;middot;strap: simple and flexible HTML, CSS, and JavaScript for popular user interface components and interactions.
&lt;/p&gt;
&lt;p&gt;
Work on Bootstrap started about a 1.5 years ago. Internal tools didn&apos;t get the proper attention they needed. They figured out there was a lot of people that wanted good looking UIs and interactions. It became Twitter Blueprint and was mostly used internally. Jacob (@fat) started shortly after first release and decided to add some JavaScript on top of it. The JavaScript for Bootstrap was &lt;a href=&quot;https://twitter.com/#!/pamelafox/status/164532457654329347&quot;&gt;originally the &quot;Twitter Internal Toolkit&quot; or &quot;TIT&quot;&lt;/a&gt; and was built on Moo Tools. Jacob was like &quot;we gotta open source this, it&apos;s gonna be huge!&quot; (he was right).
&lt;/p&gt;
&lt;p&gt;The 1.0 release supported Chrome, Safari and Firefox (everyone at Twitter was on Macs). 1.3 added cross-browser support and JavaScript plugins. 
&lt;/p&gt;
&lt;p&gt;
Now there&apos;s Bootstrap 2 (just released!). They rewrote all the documentation and components and removed legacy code. 
&lt;/p&gt;
&lt;p&gt;So, &lt;em&gt;what&apos;s new?&lt;/em&gt;
The biggest thing is the docs. Previously had live examples, now shows live examples and why you would do something, as well as additional options. The &quot;topbar&quot; has been renamed to &quot;navbar&quot;, but it&apos;s still got all the hotness. It&apos;s &lt;a href=&quot;http://www.alistapart.com/articles/responsive-web-design/&quot;&gt;responsive&lt;/a&gt; with CSS media queries for small devices, tablets, small desktops and large desktops. This means the layout &lt;em&gt;breaks&lt;/em&gt; at certain points and stacks elements to fit on smaller screens.
&lt;/p&gt;
&lt;p&gt;
CSS: smarter defaults, better classes. In 1.4, all forms were stacked. Now they can flow horizontally. Tables are now namespaced so Bootstrap&apos;s styles don&apos;t apply to all tables. The available table, form and navigation classes are as follows:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
// Tables
.table { ... }
.table-striped { ... }
.table-bordered { ... }
.table-condensed { ... }

// Forms
.form-inline { ... }
.form-search { ... }
.form-horizontal { ... }

// Nav
.nav { ... }
.nav-tabs { ... }
.nav-pills { ... }
&lt;/pre&gt;
&lt;p&gt;The goals with 2.0 are consistency, simplification and future-proofing styles. With 1.4, buttons used &quot;btn primary&quot; and it caused problems if you wanted to have a &quot;primary&quot; class in your project. With 2.0, buttons and all elements are namespaced to avoid collisions (now it&apos;s .btn-primary).
&lt;/p&gt;
&lt;p&gt;After Mark finished talking about the design of Bootstrap, Jacob (@fat) started talking about Bootstrap&apos;s JavaScript. Jacob works on The Platform Team at Twitter and claims he made a lot of mistakes with 1.x. However, thanks to semantic versioning, 2.0 is a new version and he got to start over!
&lt;/p&gt;
&lt;p&gt;The biggest change in 2.0 is the use of data attributes (a.k.a. data-*). They were using them in 1.x, but not to the full potential of what they can be and should be. The first class API for Bootstrap JavaScript is data attributes (or HTML), not JavaScript.
&lt;/p&gt;
&lt;p&gt;With 1.x, you could add an anchor to close modals and alerts.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
// 1.x closing modal/alerts
&amp;lt;a class=&quot;close&quot; href=&quot;#&quot;&gt;&amp;times;&amp;lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;However, if you put your alerts in your modals, you close them all when you likely only wanted to close one. 2.0 uses a &quot;data-dismiss&quot; attribute.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;a class=&quot;close&quot; data-dismiss=&quot;model&quot;&gt;&amp;times&amp;lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;This allows you to target what you want closed (modals or alerts, etc.). You know exactly what&apos;s going to happen just by reading the code. Another example is the &quot;href&quot; attribute of an anchor. Rather than using &quot;href&quot;, you can now use &quot;data-target&quot;. 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
// 1.x href = target
&amp;lt;a href=&quot;#myModal&quot; data-toggle=&quot;modal&quot;&gt;Launch&amp;lt;/a&gt;

// 2.x data-target = target
&amp;lt;a data-target=&quot;.fat&quot; data-toggle=&quot;modal&quot;&gt;Launch&amp;lt;/a&gt;
&lt;/pre&gt;
&lt;p&gt;If you&apos;d rather turn off the data attribute API, or just part of it, you can do so by using the following:
&lt;/p&gt;
&lt;pre class=&quot;brush: js&quot;&gt;
// Turn off all data-api
$(&apos;body&apos;).off(&apos;.data-api&apos;)

// Turn off alert data-api
$(&apos;body).off(&apos;.alert.data-api&apos;)
&lt;/pre&gt;
&lt;p&gt;2.0&apos;s JavaScript API has the same stuff, but better. You can turn off the data-api and do everything with JavaScript. They copied jQuery UI in a lot of ways (defaults, constructors, etc.). &lt;a href=&quot;http://twitter.github.com/bootstrap/javascript.html&quot;&gt;Bootstrap&apos;s JavaScript&lt;/a&gt; has 12 plugins. New ones include collapse, carousel and typeahead. &lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://twitter.github.com/bootstrap/download.html&quot;&gt;Customize&lt;/a&gt; - a new tab that lets you customize and download Bootstrap. It&apos;s basically an alternative to customizing .less files and allows you to choose components, select jQuery plugins, customize variables (colors, font-sizes, backgrounds) and download. &lt;/p&gt;

&lt;p&gt;What does the future hold? Internationalization, improving responsiveness, more new features and bug fixes. 
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 10px&quot;&gt;
After both Mark and Jacob gave their talks, they talked together about Community and how great it&apos;s been. Even if you&apos;re not into writing CSS and JavaScript, they mentioned they still wanted to hear from you. To give an example of great community contributions, one guy opened 50 issues in the last 2 days.&lt;/p&gt;
&lt;p&gt;Someone in the audience asked why they used LESS over SASS. Jacob said the main reason they use LESS is because they&apos;re good friends with the guy who invented it (&lt;a href=&quot;http://cloudhead.io/&quot;&gt;Alexis&lt;/a&gt;). SASS turns CSS into a programming language, but they wanted to maintain the approachability of CSS, which LESS does. There&apos;s no plans to do an official SASS port, but there is talk of doing one. One advantage of the current LESS compiler is they rewrote it to have better output so it&apos;s far more readable.
&lt;/p&gt;
&lt;p id=&quot;nasa&quot;&gt;&lt;strong&gt;NASA&lt;/strong&gt;&lt;br/&gt;
After Mark and Jacob finished, there was a 5 minute break to grab beers and snacks. Then Sean Herron (&lt;a href=&quot;http://twitter.com/seanherron&quot;&gt;@seanherron&lt;/a&gt;) (a.k.a. &quot;NASA Bro&quot;) talked about Bootstrap at NASA. He actually didn&apos;t talk about Bootstrap much, except that they used it for &lt;a href=&quot;http://code.nasa.gov&quot;&gt;code.NASA&lt;/a&gt;. He talked about NASA and how it&apos;s playing a key role in the movement towards open data, open source and open standards in our federal government. He mentioned how &lt;a href=&quot;http://data.nasa.gov/&quot;&gt;data.NASA&lt;/a&gt; was launched last August and that they helped develop &lt;a href=&quot;http://openstack.org/&quot;&gt;OpenStack&lt;/a&gt;. Finally, he mentioned &lt;a href=&quot;http://open.nasa.gov/&quot;&gt;open.NASA&lt;/a&gt;, which is a collaborative approach to open, direct and transparent communication about our space program.&lt;/p&gt;
&lt;/p&gt;
&lt;p id=&quot;hogan.js&quot;&gt;&lt;strong&gt;Hogan.js&lt;/strong&gt;&lt;br/&gt;
Next up, Rob Sayre (&lt;a href=&quot;http://twitter.com/sayrer&quot;&gt;@sayrer&lt;/a&gt;) talked about &lt;a href=&quot;http://twitter.github.com/hogan.js/&quot;&gt;Hogan.js&lt;/a&gt;. 
Rob has been at Twitter for a few months, before that he wrote JavaScript at other places. Hogan.js is a compiler for &lt;a href=&quot;http://mustache.github.com/&quot;&gt;Mustache templates&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Why Mustache?&lt;/em&gt; Because it&apos;s similar to HTML and easy to edit. You can mock data as JSON files and programmers are not required.
&lt;/p&gt;
&lt;p&gt;
At Twitter, designers can do the CSS and Mustache without connecting to the backend. It has cross-language support in Ruby, Java and JavaScript. However, client-side template compilation has performance problems, especially in IE7 on a Windows XP box with 4 viruses. 
&lt;/p&gt;
&lt;p&gt;So they had a few choices: work on mustache.js, or use Dust.js or Handlebars.js. The compilers are very nice for Dust.js and Handlebars.js, but they&apos;re huge. Handlebar&apos;s parser is 4000 lines. The entire Hogan.js file is 500 lines. They decided they were too large to send to the browser&apos;s of their users, so they chose to write a better compiler for Mustache.
&lt;/p&gt;
&lt;p&gt;
Hogan.js&apos;s main features:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Compile on the server&lt;/li&gt;
&lt;li&gt;Parser API&lt;/li&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Performance is &lt;em&gt;much&lt;/em&gt; better with Hogan.js than Mustache.js. On IE7 - Hogan is 5x faster than Mustache. On an iPhone, it&apos;s about the same (and an iPhone&apos;s browser is faster than IE7 on a decent computer). With modern browsers (Chrome 17, Safari 5 and Firefox 10), it&apos;s more than 10x faster.
&lt;/p&gt;
&lt;p&gt;Hogan.js is currently used at Twitter for Tweet embedding, the Bootstrap build process and soon, Twitter.com.
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 10px&quot;&gt;
It&apos;s been awhile since I got excited about an open source project. Bootstrap has helped me a lot recently, in my &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_html5_with_play_scala&quot;&gt;&lt;em&gt;Play More!&lt;/em&gt;&lt;/a&gt; mobile app, on some client projects and I&apos;m in the process of &lt;a href=&quot;http://raibledesigns.com/rd/entry/refreshing_appfuse_s_ui_with&quot;&gt;refreshing AppFuse&apos;s UI to use it&lt;/a&gt;. I love how you can add a class or two to an element and all of a sudden they pop with good looks. The main problem with Bootstrap at this point is that a lot of Bootstrapped apps look the same. There&apos;s talk of adding themes in a future release to help alleviate this problem. In the meantime, there&apos;s a lot to get excited about with 2.0.
&lt;/p&gt;
&lt;p&gt;Thanks to Twitter for hosting this event and kudos to Mark and Jacob (and the community!) for such a fantastic project. </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/refreshing_appfuse_s_ui_with</id>
        <title type="html">Refreshing AppFuse&apos;s UI with Twitter Bootstrap</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/refreshing_appfuse_s_ui_with"/>
        <published>2012-01-31T17:12:17-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="twitter" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="bootstrap" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ui" scheme="http://roller.apache.org/ns/tags/" />
        <category term="css" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">The last time AppFuse had an update done to its look and feel was in way back in 2006. I&apos;ve done a lot of consulting since then, which has included a fair bit of page speed optimization, HTML5 development and integrating smarter CSS. It was way back in &apos;05 when we first started looking at adding a CSS Framework to AppFuse.  It was Mike Stenhouse&apos;s &lt;a href=&quot;http://www.contentwithstyle.co.uk/content/a-css-framework/&quot;&gt;CSS Framework&lt;/a&gt; that provided the &lt;a href=&quot;http://raibledesigns.com/rd/entry/a_css_framework&quot;&gt;inspiration&lt;/a&gt; and my &lt;a href=&quot;http://raibledesigns.com/rd/entry/css_framework_design_contest_final&quot;&gt;CSS Framework Design Contest&lt;/a&gt; that provided its current themes (&lt;a href=&quot;http://css.appfuse.org/themes/puzzlewithstyle&quot;&gt;puzzlewithstyle&lt;/a&gt;, &lt;a href=&quot;http://css.appfuse.org/themes/andreas01&quot;&gt;andreas01&lt;/a&gt; and &lt;a href=&quot;http://css.appfuse.org/themes/simplicity&quot;&gt;simplicity&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;Since then, a lot of CSS Frameworks have been invented, including &lt;a href=&quot;http://www.blueprintcss.org/&quot;&gt;Blueprint&lt;/a&gt; in 2007 and &lt;a href=&quot;http://compass-style.org/&quot;&gt;Compass&lt;/a&gt; in 2008. However, neither has taken the world by storm like &lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Twitter Bootstrap&lt;/a&gt;. From &lt;a href=&quot;http://www.alistapart.com/articles/building-twitter-bootstrap/&quot;&gt;Building Twitter Bootstrap&lt;/a&gt;:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
A year-and-a-half ago, a small group of Twitter employees set out to improve our team&#8217;s internal analytical and administrative tools. After some early meetings around this one product, we set out with a higher ambition to create a toolkit for anyone to use within Twitter, and beyond. Thus, we set out to build a system that would help folks like us build new projects on top of it, and Bootstrap was conceived.&lt;br/&gt;
...&lt;br/&gt;
Today, it has grown to include dozens of components and has become the most popular project on GitHub with more than 13,000 watchers and 2,000 forks.&lt;/p&gt;
&lt;p&gt;&lt;p&gt;The fact that Bootstrap has become the most popular project on GitHub says a lot. For &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/AppFuse-next-td3634415.html&quot;&gt;AppFuse.next&lt;/a&gt;, I&apos;d like to integrate a lot of my learnings over the past few years, as well as support HTML5 and modern browsers as best we can. This means &lt;a href=&quot;http://code.google.com/speed/page-speed/docs/rules_intro.html&quot;&gt;page speed optimizations&lt;/a&gt;, getting rid of Prototype and Scriptaculous in favor of jQuery, adding &lt;a href=&quot;http://code.google.com/p/wro4j/&quot;&gt;wro4j&lt;/a&gt; for resource optimization and integrating &lt;a href=&quot;http://html5boilerplate.com/&quot;&gt;HTML5 Boilerplate&lt;/a&gt;. I&apos;ve used Twitter Bootstrap for my &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_html5_with_play_scala&quot;&gt;&lt;em&gt;Play More!&lt;/em&gt; app&lt;/a&gt;, as well as some recent client projects. Its excellent documentation has made it easy to use and I love the way you can simply add classes to elements to make them transform into something beautiful.
&lt;/p&gt;
&lt;p&gt;Last week, I spent a couple late nights integrating &lt;a href=&quot;http://thinkvitamin.com/design/twitter-bootstrap-2-0/&quot;&gt;Twitter Bootstrap 2.0&lt;/a&gt; into the Struts 2 and Spring MVC versions of AppFuse. The layout was pretty straightforward thanks to &lt;a href=&quot;http://markdotto.com/bs2/docs/scaffolding.html&quot;&gt;Scaffolding&lt;/a&gt;. Creating the Struts Menu Velocity template to produce &lt;a href=&quot;http://markdotto.com/bs2/docs/javascript.html#dropdowns&quot;&gt;dropdowns&lt;/a&gt; wasn&apos;t too difficult. I added &lt;a href=&quot;http://markdotto.com/bs2/docs/base-css.html#tables&quot;&gt;class=&quot;table table-condensed&quot;&lt;/a&gt; to the list screen tables, &lt;a href=&quot;http://markdotto.com/bs2/docs/base-css.html#forms&quot;&gt;class=&quot;well form-horizontal&quot;&lt;/a&gt; to forms and &lt;a href=&quot;http://markdotto.com/bs2/docs/base-css.html#buttons&quot;&gt;class=&quot;btn primary&quot;&lt;/a&gt; to buttons. 
&lt;/p&gt;
&lt;p&gt;  
I also added validation errors with the &quot;help-inline&quot; class. This is also where things got tricky with Struts and Spring MVC. For the form elements in Bootstrap, they recommend you use a &quot;control-group&quot; element that contains your label and a &quot;controls&quot; element. The control contains the input/select/textarea and also the error message if there is one. Here&apos;s a sample element waiting for data: 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div class=&quot;control-group&quot;&amp;gt;
    &amp;lt;label for=&quot;name&quot; class=&quot;control-label&quot;&amp;gt;Name&amp;lt;/label&amp;gt;
    &amp;lt;div class=&quot;controls&quot;&amp;gt;
        &amp;lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;name&quot;&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Below is what that element should look like to display a validation error:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div class=&quot;control-group error&quot;&amp;gt;
    &amp;lt;label for=&quot;name&quot; class=&quot;control-label&quot;&amp;gt;Name&amp;lt;/label&amp;gt;
    &amp;lt;div class=&quot;controls&quot;&amp;gt;
        &amp;lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;name&quot; value=&quot;&quot;&amp;gt;
        &amp;lt;span class=&quot;help-inline&quot;&amp;gt;Please enter your name.&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You can see this markup is pretty easy, you just need to add an &quot;error&quot; class to &lt;em&gt;control-group&lt;/em&gt; and span to show the error message. With Struts 2, this was pretty easy thanks to its customizable templates for its &lt;a href=&quot;http://struts.apache.org/2.x/docs/struts-tags.html&quot;&gt;tags&lt;/a&gt;. All I had to do was create a &quot;template/css_xhtml&quot; directory in &lt;em&gt;src/main/webapp&lt;/em&gt; and modify checkbox.ftl, controlfooter.ftl, controlheader-core.ftl and controlheader.ftl to match Bootstrap&apos;s conventions. 
&lt;/p&gt;
&lt;p&gt;
Spring MVC was a bit trickier. Since its tags don&apos;t have the concept of writing an entire control (label and field), I had to do a bit of finagling to get things to work. In the current implementation, Struts 2 forms have a single line for a &lt;em&gt;control-group&lt;/em&gt; and its &lt;em&gt;control-label&lt;/em&gt; and &lt;em&gt;controls&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;s:textfield key=&quot;user.firstName&quot; required=&quot;true&quot;/&gt;&lt;/pre&gt;
&lt;p&gt;With Spring MVC, it&apos;s a bit more complex:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;spring:bind path=&quot;user.firstName&quot;&amp;gt;
&amp;lt;fieldset class=&quot;control-group${(not empty status.errorMessage) ? &apos; error&apos; : &apos;&apos;}&quot;&amp;gt;
&amp;lt;/spring:bind&amp;gt;
    &amp;lt;appfuse:label styleClass=&quot;control-label&quot; key=&quot;user.firstName&quot;/&amp;gt;
    &amp;lt;div class=&quot;controls&quot;&amp;gt;
        &amp;lt;form:input path=&quot;firstName&quot; id=&quot;firstName&quot; maxlength=&quot;50&quot;/&amp;gt;
        &amp;lt;form:errors path=&quot;firstName&quot; cssClass=&quot;help-inline&quot;/&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/fieldset&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You could probably overcome this verbosity with &lt;a href=&quot;http://today.java.net/pub/a/today/2003/11/14/tagfiles.html&quot;&gt;Tag Files&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Figuring out if a &lt;em&gt;control-group&lt;/em&gt; needed an error class before the input tag was rendered was probably the hardest part of this exercise. This was mostly due to Bootstrap&apos;s great documentation and useful examples (viewed by inspecting the markup). Below are some screenshots of the old screens and new ones. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center; vertical-align: top&quot;&gt;
&lt;a href=&quot;http://farm8.staticflickr.com/7173/6787781357_c4c65c7c74_b.jpg&quot; title=&quot;Old UI - Login&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7173/6787781357_c4c65c7c74_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;Old UI - Login&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm8.staticflickr.com/7142/6787781421_0c7851b414_b.jpg&quot; title=&quot;Old UI - Users&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7142/6787781421_0c7851b414_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;Old UI - Users&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm8.staticflickr.com/7035/6787781725_3a1f0218c1_b.jpg&quot; title=&quot;Old UI - Edit Profile&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7035/6787781725_3a1f0218c1_t.jpg&quot; width=&quot;100&quot; height=&quot;82&quot; alt=&quot;Old UI - Edit Profile&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;p&gt;  
&lt;p style=&quot;text-align: center; vertical-align: top&quot;&gt;
&lt;a href=&quot;http://farm8.staticflickr.com/7025/6787781477_ec2ac7a93b_b.jpg&quot; title=&quot;New UI - Login&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7025/6787781477_ec2ac7a93b_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;New UI - Login&quot;&gt;&lt;/a&gt;
  
&lt;a href=&quot;http://farm8.staticflickr.com/7015/6787781597_6558d94bb5_b.jpg&quot; title=&quot;New UI - Users&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7015/6787781597_6558d94bb5_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;New UI - Users&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
  
  &lt;a href=&quot;http://farm8.staticflickr.com/7010/6787781681_81b7977414_b.jpg&quot; title=&quot;New UI - Edit Profile&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7010/6787781681_81b7977414_t.jpg&quot; width=&quot;100&quot; height=&quot;82&quot; alt=&quot;New UI - Edit Profile&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #666; text-align: center&quot;&gt;Check out the &lt;a style=&quot;color: #666&quot; href=&quot;http://www.flickr.com/photos/mraible/sets/72157629094630763/&quot;&gt;full set on Flickr&lt;/a&gt; if you&apos;d like a closer look.
  &lt;/p&gt;
  &lt;p&gt;
Even though I like the look of the old UI, I can&apos;t help but think a lot of the themes are designed for blogs and content sites, not webapps. The old &lt;a href=&quot;http://wufoo.com/&quot;&gt;Wufoo&lt;/a&gt; forms were a lot better looking though. And if you&apos;re going to develop &lt;a href=&quot;http://blogs.atlassian.com/2012/01/modern-principles-in-web-development/&quot;&gt;kick-ass webapps&lt;/a&gt;, you need to make them look good. Bootstrap goes a long way in doing this, but it certainly doesn&apos;t replace a good UX Designer. Bootstap simply helps you get into HTML5-land, start using CSS3 and it takes the pain out of making things work cross-browser. Its fluid layouts and responsive web design seems to work great for business applications, which I&apos;m guessing AppFuse is used for the most. 
&lt;/p&gt;
&lt;p&gt;
I can&apos;t thank the Bootstrap developers enough for helping me make this all look good. With Bootstrap 2 &lt;a href=&quot;http://www.markdotto.com/2012/01/24/bootstrap-2-ready-for-testing-and-feedback/&quot;&gt;dropping this week&lt;/a&gt;, I can see myself using this more and more on projects. In the near future, I&apos;ll be helping integrate Bootstrap into AppFuse&apos;s &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Tapestry-5-3-2-td4339578.html&quot;&gt;Tapestry 5 and JSF versions&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;What do you think of this CSS change? Do you change your CSS and layout a fair bit when starting with AppFuse archetypes? What can we do to make AppFuse apps look better out-of-the-box?
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I &lt;a href=&quot;http://source.appfuse.org/changelog/appfuse/?cs=3593&quot;&gt;updated&lt;/a&gt; AppFuse to the final &lt;a href=&quot;http://raibledesigns.com/rd/entry/twitter_s_open_source_summit&quot;&gt;Bootstrap 2.0 release&lt;/a&gt;. Also, Johannes Geppert wrote a &lt;a href=&quot;http://www.jgeppert.com/2012/02/new-struts2-bootstrap-plugin-released/&quot;&gt;Struts 2 Bootstrap Plugin&lt;/a&gt;. I hope to integrate this into AppFuse in the near future.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/2011_a_year_in_review</id>
        <title type="html">2011 - A Year in Review</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/2011_a_year_in_review"/>
        <published>2012-01-11T09:45:20-07:00</published>
        <updated>2014-07-26T21:04:50-06:00</updated> 
        <category term="/Roller" label="Roller" />
        <category term="yearinreview" scheme="http://roller.apache.org/ns/tags/" />
        <category term="2011" scheme="http://roller.apache.org/ns/tags/" />
        <category term="blogging" scheme="http://roller.apache.org/ns/tags/" />
        <category term="roller" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;a href=&quot;http://raibledesigns.com/rd/entry/2010_a_year_in_review&quot;&gt;2010 was an awesome year&lt;/a&gt;, but 2011 rocked the house! At the end of last year, I kept my goals simple:&lt;/p&gt;
&lt;p class=&quot;quote&quot; style=&quot;color: #666&quot;&gt;
In 2011, I plan on doing two main things: keep rockin&apos; it with Trish and finishing The Bus. Everything else is gravy. 
&lt;/p&gt;
&lt;p&gt;As predicted, it &lt;em&gt;was&lt;/em&gt; a spectacular year, but I only accomplished 50% of my goals. That is, Trish and I had a great time skiing (especially in Utah), moving in together, traveling the world and getting engaged in Versailles. I even satisfied some 5-year goals: building a sauna in my basement and getting a ski shack in the mountains.&lt;/p&gt;
&lt;p&gt;However, I didn&apos;t get much done with The Bus. Or rather, the guys at &lt;a href=&quot;http://www.motorworksrestorations.com/&quot;&gt;MotorWorks Restorations&lt;/a&gt; didn&apos;t drain me for all I&apos;m worth in 2011. We did make good progress with estimating the final cost and obtaining many hard-to-find parts though. I now have a Porsche 911 Engine (1983 3.0L 6 cylinder), a Porsche 901 5 speed transmission, Porsche &quot;Turbo Twist&quot; wheels and a &lt;a href=&quot;https://www.facebook.com/media/set/?set=a.10150332577286054.392700.672811053&amp;amp;type=1&quot;&gt;Custom Air Ride Front Beam&lt;/a&gt; from &lt;a href=&quot;http://www.franklinsvwwerks.com/&quot;&gt;Franklin&apos;s VW Works&lt;/a&gt;. The thing that slowed our progress the most was the custom beam, as it took almost 6 months from order to delivery. When it arrived in September, I decided to put things on hold. I didn&apos;t want to get my bus back in the midst of winter and not be able to drive it.&lt;/p&gt;</summary>
        <content type="html">&lt;a href=&quot;http://raibledesigns.com/rd/entry/2010_a_year_in_review&quot;&gt;2010 was an awesome year&lt;/a&gt;, but 2011 rocked the house! At the end of last year, I kept my goals simple:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
In 2011, I plan on doing two main things: keep rockin&apos; it with Trish and finishing The Bus. Everything else is gravy. 
&lt;/p&gt;
&lt;p&gt;As predicted, it &lt;em&gt;was&lt;/em&gt; a spectacular year, but I only accomplished 50% of my goals. That is, Trish and I had a great time skiing (especially in Utah), moving in together, traveling the world and getting engaged in Versailles. I even satisfied some 5-year goals: building a sauna in my basement and getting a ski shack in the mountains.
&lt;/p&gt;
&lt;p&gt;However, I didn&apos;t get much done with The Bus. Or rather, the guys at &lt;a href=&quot;http://www.motorworksrestorations.com/&quot;&gt;MotorWorks Restorations&lt;/a&gt; didn&apos;t drain me for all I&apos;m worth in 2011. We did make good progress with estimating the final cost and obtaining many hard-to-find parts though. I now have a Porsche 911 Engine (1983 3.0L 6 cylinder), a Porsche 901 5 speed transmission, Porsche &quot;Turbo Twist&quot; wheels and a &lt;a href=&quot;https://www.facebook.com/media/set/?set=a.10150332577286054.392700.672811053&amp;amp;type=1&quot;&gt;Custom Air Ride Front Beam&lt;/a&gt; from &lt;a href=&quot;http://www.franklinsvwwerks.com/&quot;&gt;Franklin&apos;s VW Works&lt;/a&gt;. The thing that slowed our progress the most was the custom beam, as it took almost 6 months from order to delivery. When it arrived in September, I decided to put things on hold. I didn&apos;t want to get my bus back in the midst of winter and not be able to drive it.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;http://farm5.staticflickr.com/4136/5396188811_13d0eab8ae.jpg&quot; title=&quot;Welcome to Alta&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm5.staticflickr.com/4136/5396188811_13d0eab8ae_t.jpg&quot; width=&quot;100&quot; height=&quot;74&quot; alt=&quot;Welcome to Alta&quot; class=&quot;picture&quot; style=&quot;margin-top: 5px; border: 1px solid black&quot;&gt;&lt;/a&gt;
  
In January, I started working at &lt;a href=&quot;http://overstock.com&quot;&gt;Overstock.com&lt;/a&gt; and flew out to Salt Lake City the first two weeks to ramp up. In setting up my development environment, I discovered some inefficiencies and wrote about how I fixed them in &lt;a href=&quot;http://raibledesigns.com/rd/entry/making_code_generation_smarter_with&quot;&gt;Making Code Generation Smarter with Maven&lt;/a&gt;. I also discovered that JRebel slowed my build process down by almost 50% and stopped using it as part of my daily process. Now I simply run in debug mode or use &lt;a href=&quot;http://www.playframework.org/&quot;&gt;fancy frameworks&lt;/a&gt; that allow instant reload.
&lt;/p&gt;
&lt;p&gt;At the end of the month, I &lt;a href=&quot;http://raibledesigns.com/rd/entry/alta&quot;&gt;skied Alta&lt;/a&gt; for the first time on a blue bird day. That night, I flew back to Denver, had a gorgeous &lt;a href=&quot;http://farm5.static.flickr.com/4119/5396080419_7cd9f5cb87.jpg&quot; rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Dear Denver: You&apos;re the best.&quot;&gt;lunch ride&lt;/a&gt; in 70&amp;deg;F weather on Friday afternoon, then picked up my lovely girlfriend, Trish, and drove to Crested Butte for a &lt;a href=&quot;http://raibledesigns.com/rd/entry/crested_butte&quot;&gt;weekend of skiing with James Ward and friends&lt;/a&gt;. It was my first time visiting Crested Butte and I can see why people call it Paradise.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a data-href=&quot;http://www.flickr.com/photos/mraible/5407159019&quot; href=&quot;http://farm6.staticflickr.com/5096/5407159019_f65b19983d.jpg&quot; title=&quot;Crested Butte, The Town&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.staticflickr.com/5096/5407159019_f65b19983d_m.jpg&quot; width=&quot;240&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Crested Butte, The Town&quot;&gt;&lt;/a&gt;
&lt;a data-href=&quot;http://www.flickr.com/photos/mraible/5407165843&quot; href=&quot;http://farm6.staticflickr.com/5094/5407165843_8c6328f2d9.jpg&quot; title=&quot;Top of Crested Butte&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.staticflickr.com/5094/5407165843_8c6328f2d9_m.jpg&quot; width=&quot;240&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Top of Crested Butte&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;As of February 1st, Trish and I both had 17 ski days. As I&apos;m writing this, we&apos;re both up to 14 for this season and very proud to say Abbie and Jack each have 10. Both kids are shredding like I&apos;ve always dreamed they would.
&lt;/p&gt;
&lt;p&gt;My parents (both retired) came to visit for the month of February and helped me start building a sauna in my basement. This was something I&apos;ve wanted to do for years, so it was a lot of fun getting things started. While we didn&apos;t finish construction, we did get the plumbing/electrical done, stove installed and walls framed. We also had a fun night with &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157626083451336/&quot;&gt;Chef Navarro and Friends&lt;/a&gt;.
&lt;p&gt;
The rest of my posts in February were purely technical. I wrote about how I &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_extensionless_urls_with_tapestry&quot;&gt;implemented extensionless URLs with Tapestry, Spring MVC, Struts 2 and JSF&lt;/a&gt;. Then I started delving into &lt;a href=&quot;http://raibledesigns.com/rd/entry/integration_testing_with_http_https&quot;&gt;security-related topics&lt;/a&gt;, largely motivated by a new feature I was working on at Overstock. When I wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery&quot;&gt;Implementing Ajax Authentication using jQuery, Spring Security and HTTPS&lt;/a&gt;, I explained what I was trying to accomplish.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
The feature hasn&apos;t been released yet, but basically boils down to allowing users to login without leaving a page. For example, if they want to leave a review on a product, they would click a link, be prompted to login, enter their credentials, then continue to leave their review. The login prompt and subsequent review would likely be implemented using a lightbox. While lightboxes are often seen in webapps these days because they look good, it&apos;s also possible Lightbox UIs provide a poor user experience.
&lt;/p&gt;
&lt;p&gt;I was able to get everything working, &lt;a href=&quot;http://demo.raibledesigns.com/ajax-login/&quot;&gt;posted a demo&lt;/a&gt; and wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/upcoming_conferences_tssjs_in_las&quot;&gt;upcoming conferences in Las Vegas and Krak&amp;#243;w&lt;/a&gt;. In that article, I described a new talk I was going to create: &lt;em&gt;Webapp Security: Develop. Penetrate. Protect. Relax.&lt;/em&gt; I ended the month with a post on &lt;a href=&quot;http://raibledesigns.com/rd/entry/fixing_xss_in_jsp_2&quot;&gt;how to fix XSS in JSP 2&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;On February 25th, I experienced &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_greatest_snow_on_earth&quot;&gt;The Greatest Snow on Earth&lt;/a&gt; with thigh-deep powder and face shots on every run.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe width=&quot;500&quot; height=&quot;311&quot; frameborder=&quot;0&quot; src=&quot;//www.youtube.com/embed/viBBPot4WKY?rel=0&amp;amp;hd=1&quot; title=&quot;YouTube video player&quot;&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;That night, we saw &lt;a href=&quot;http://www.hotbutteredrum.net/&quot;&gt;Hot Buttered Rum&lt;/a&gt; and woke up early for 27&quot; of fresh powder at Alta. The picture of Trish free-heeling at Alta is one of my favorites of the year.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm6.staticflickr.com/5216/5490614643_00cb94c020.jpg&quot; title=&quot;Free Heeling at Alta&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.staticflickr.com/5216/5490614643_00cb94c020.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Free Heeling at Alta&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;In early March, we experienced a &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157626199804847/&quot;&gt;suite night at the Avs game&lt;/a&gt;, then I kept it technical and &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgraded_to_apache_roller_5&quot;&gt;upgraded this blog to Apache Roller 5.0, RC4&lt;/a&gt;. I &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_to_jsf_2&quot;&gt;upgraded AppFuse to JSF 2&lt;/a&gt;, wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/jsr_303_and_web_framework&quot;&gt;JSR 303 and web framework support&lt;/a&gt; and &lt;a href=&quot;http://raibledesigns.com/rd/entry/adding_search_to_appfuse&quot;&gt;added search to AppFuse using Compass&lt;/a&gt;. When writing about JSF 2, I mentioned replacing Ajax4JSF with RichFaces. 9 months later, it seems like &lt;a href=&quot;http://primefaces.org/&quot;&gt;PrimeFaces&lt;/a&gt; has more momentum, so I may try that instead.
&lt;/p&gt;
&lt;p&gt;For St. Patrick&apos;s Day, we flew to Vegas for TSSJS and &lt;a href=&quot;http://raibledesigns.com/rd/entry/livin_it_up_in_vegas&quot;&gt;had a blast&lt;/a&gt;. Not only did my talks go well, but we had a bunch of friends in town and had much success gambling the nights away.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm6.static.flickr.com/5305/5550023760_e8f128457a.jpg&quot; title=&quot;Caesars Pool&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5305/5550023760_e8f128457a_m.jpg&quot; width=&quot;240&quot; height=&quot;159&quot; alt=&quot;Caesars Pool&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm6.static.flickr.com/5053/5550024190_b272c2f012.jpg&quot; title=&quot;The Bellagio Fountains&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5053/5550024190_b272c2f012_m.jpg&quot; width=&quot;240&quot; height=&quot;159&quot; alt=&quot;The Bellagio Fountains&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;After delivering my Comparing JVM Web Frameworks talk, I had a very interesting conversation with &lt;a href=&quot;http://macstrac.blogspot.com/&quot;&gt;James Strachan&lt;/a&gt;. He recommended I take a look at &lt;a href=&quot;http://coffeescript.org/&quot;&gt;CoffeeScript&lt;/a&gt; and &lt;a href=&quot;http://jade-lang.com/&quot;&gt;Jade&lt;/a&gt;. A couple months later, when I was thinking of talks for &lt;a href=&quot;http://devoxx.com&quot;&gt;Devoxx&lt;/a&gt;, I added these to my list of technologies to learn and submitted a talk about HTML5 with Play Scala, CoffeeScript and Jade.
&lt;/p&gt;
&lt;p&gt;That Friday, we returned to Denver, got a good night&apos;s sleep then headed on a &lt;a href=&quot;http://raibledesigns.com/rd/entry/peter_estin_hut_trip_in&quot;&gt;hut trip in Colorado&apos;s High Country&lt;/a&gt;. The name of the hut was &lt;a href=&quot;http://www.huts.org/hut_details/peter_estin_hut_details.html&quot;&gt;Peter Estin Hut&lt;/a&gt; and it was a bit of a hike to get to. My friend, Joe, set my expectations correctly when he warned me it&apos;d be a &lt;em&gt;5 hour death march&lt;/em&gt;. It took us 4 hours, 30 minutes and we skied up 2200 vertical feet of switchbacks.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Livin&apos; it up, hut style&quot; href=&quot;http://farm6.static.flickr.com/5251/5549474427_56d389dc71.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;66&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Livin&apos; it up, hut style&quot; src=&quot;//farm6.static.flickr.com/5251/5549474427_56d389dc71_t.jpg&quot;&gt;&lt;/a&gt;

&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;We made it!&quot; href=&quot;http://farm6.static.flickr.com/5027/5549475091_bcff5560a0.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;We made it!&quot; src=&quot;//farm6.static.flickr.com/5027/5549475091_bcff5560a0_t.jpg&quot;&gt;&lt;/a&gt;

&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;At the top of Charles Peak&quot; href=&quot;http://farm6.static.flickr.com/5025/5550058284_18d8a3b874.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;66&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;At the top of Charles Peak&quot; src=&quot;//farm6.static.flickr.com/5025/5550058284_18d8a3b874_t.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Trish and I started off April with a bang by moving in together, then embarking on a &lt;a href=&quot;http://raibledesigns.com/rd/entry/two_opening_days_with_a&quot;&gt;whirlwind trip of two opening days with a stopover in Krak&#243;w&lt;/a&gt;. We flew Business Class from Chicago to Munich (releasing &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_1_released&quot;&gt;AppFuse 2.1&lt;/a&gt; just before departing) and were very impressed with Krak&#243;w&apos;s Old Town upon arrival.
  &lt;p style=&quot;text-align: center&quot;&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;St. Mary&apos;s Basilica, Krak&#243;w&quot; href=&quot;http://farm6.static.flickr.com/5188/5618498585_0267da32ce.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;border: 1px solid black&quot; alt=&quot;St. Mary&apos;s Basilica, Krak&#243;w&quot; src=&quot;//farm6.static.flickr.com/5188/5618498585_0267da32ce_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Main Market Square&quot; href=&quot;http://farm6.static.flickr.com/5268/5618498729_613983abaf.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot; alt=&quot;Main Market Square&quot; src=&quot;//farm6.static.flickr.com/5268/5618498729_613983abaf_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;St. Mary&apos;s&quot; href=&quot;http://farm6.static.flickr.com/5101/5619084930_87a76dee6b.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot; alt=&quot;St. Mary&apos;s&quot; src=&quot;//farm6.static.flickr.com/5101/5619084930_87a76dee6b_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Flowers&quot; href=&quot;http://farm6.static.flickr.com/5030/5618499011_462ac088a6.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot; alt=&quot;Flowers&quot; src=&quot;//farm6.static.flickr.com/5030/5618499011_462ac088a6_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;/p&gt;
  &lt;p&gt;On that trip, I especially enjoyed meeting Trish&apos;s brother for the first time and watching the Red Sox win their first game of the year.&lt;/p&gt;
  &lt;p style=&quot;text-align: center&quot;&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Fenway Paak!&quot; href=&quot;http://farm6.static.flickr.com/5222/5618502949_cdfbc9d030.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Fenway Paak!&quot; src=&quot;//farm6.static.flickr.com/5222/5618502949_cdfbc9d030_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Morse and Kidder&quot; href=&quot;http://farm6.static.flickr.com/5263/5618503117_28b4b2b8cc.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot; alt=&quot;Morse and Kidder&quot; src=&quot;//farm6.static.flickr.com/5263/5618503117_28b4b2b8cc_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Happy Siblings&quot; href=&quot;http://farm6.static.flickr.com/5061/5618503321_c766f1e7bc.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot; alt=&quot;Happy Siblings&quot; src=&quot;//farm6.static.flickr.com/5061/5618503321_c766f1e7bc_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Erika and Julie&quot; href=&quot;http://farm6.static.flickr.com/5146/5619089798_4aca920bfb.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot; alt=&quot;Erika and Julie&quot; src=&quot;//farm6.static.flickr.com/5146/5619089798_4aca920bfb_s.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Red Sox Win!&quot; href=&quot;http://farm6.static.flickr.com/5145/5619090216_2198246d63.jpg&quot;&gt;&lt;img width=&quot;75&quot; height=&quot;75&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot; alt=&quot;Red Sox Win!&quot; src=&quot;//farm6.static.flickr.com/5145/5619090216_2198246d63_s.jpg&quot;&gt;&lt;/a&gt;
  &lt;/p&gt;
&lt;p&gt;After returning, I realized I lost a lot of data in my Roller 5 upgrade and &lt;a href=&quot;http://raibledesigns.com/rd/entry/be_careful_when_switching_mysql&quot;&gt;wrote about what happened and how I recovered it&lt;/a&gt;. Then we &lt;a href=&quot;http://raibledesigns.com/rd/entry/farewell_to_the_2010_2011&quot;&gt;bid farewell to the 2010-2011 ski season&lt;/a&gt; and got ready for mountain bike season.
  &lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
For next year, I think I&apos;ll keep my goal at 30 days. If everything works out as planned, we&apos;ll have a place in the mountains this fall and it&apos;ll be a bit easier to hit the slopes without sitting in traffic. For now, I&apos;m pumped about the beginning of mountain bike season.
&lt;/p&gt;
&lt;p&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; ref=&quot;http://farm3.staticflickr.com/2181/5712084350_217de950a5.jpg&quot; title=&quot;Door to Sauna&quot;&gt;&lt;img src=&quot;//farm3.staticflickr.com/2181/5712084350_217de950a5_t.jpg&quot; width=&quot;100&quot; height=&quot;75&quot; alt=&quot;Door to Sauna&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
  
May arrived and Trish and I started looking for a place in the mountains. We found an &lt;a href=&quot;https://www.facebook.com/media/set/?set=a.10150158165601712.292395.571296711&amp;amp;type=1&amp;amp;l=80b0b43473&quot;&gt;very cool cabin&lt;/a&gt;, but later decided it was &lt;em&gt;too&lt;/em&gt; nice and we&apos;d rather have a condo. I finished &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_basement_sauna_project&quot;&gt;The Basement Sauna Project&lt;/a&gt; and wrote about Java Web Application Security: &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part&quot;&gt;Java EE 6&lt;/a&gt;, &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part1&quot;&gt;Spring Security&lt;/a&gt; and &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part2&quot;&gt;Apache Shiro&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;On May 21st, we again visited Winter Park and Fraser to look at condos, then drove back to Denver for &lt;a href=&quot;http://www.denverpost.com/commented/ci_18114909&quot;&gt;U2 at Mile High Stadium&lt;/a&gt;. I&apos;m not a big fan of U2, but this was quite possibly the best concert I&apos;ve ever been to. The experience of 70,000+ fans, all screaming, doing the wave, and loving life was epic. We decided that night that we liked one of the condos more than the rest and put in an offer the following week. The kids headed off to Florida for a month with their Mom and we drove to Utah for &lt;a href=&quot;http://raibledesigns.com/rd/entry/music_mountain_biking_and_memories&quot;&gt;Desert Rocks and mountain biking in Moab&lt;/a&gt;. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;https://fbcdn-sphotos-f-a.akamaihd.net/hphotos-ak-ash3/253034_2099846942595_2382489_n.jpg&quot; title=&quot;La Sal Mountains from Desert Rocks&quot; rel=&quot;lightbox[desertrocks2011]&quot;&gt;&lt;img src=&quot;//fbcdn-photos-a.akamaihd.net/hphotos-ak-snc6/253034_2099846942595_1438065285_32404850_2382489_a.jpg&quot; width=&quot;180&quot; height=&quot;120&quot; alt=&quot;La Sal Mountains from Desert Rocks&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8358915594/&quot; href=&quot;http://farm9.staticflickr.com/8467/8358915594_e79cd2231d_c.jpg&quot; title=&quot;Scenic Byway&quot; rel=&quot;lightbox[desertrocks2011]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8467/8358915594_e79cd2231d.jpg&quot; width=&quot;180&quot; height=&quot;120&quot; alt=&quot;Scenic Byway&quot; style=&quot;border: 1px solid black; margin-left: 20px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a href=&quot;https://sphotos-a.xx.fbcdn.net/hphotos-frc1/250385_2099847942620_1801230_n.jpg&quot; title=&quot;Bar-B or Killer B?&quot; rel=&quot;lightbox[desertrocks2011]&quot;&gt;&lt;img src=&quot;//sphotos-a.xx.fbcdn.net/hphotos-frc1/p206x206/250385_2099847942620_1801230_n.jpg&quot; width=&quot;180&quot; height=&quot;120&quot; alt=&quot;Bar-B or Killer B?&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mcginityphoto/8359032204/&quot; href=&quot;http://farm9.staticflickr.com/8049/8359032204_ace553c370_c.jpg&quot; title=&quot;Three Gossips and Tower of Babel&quot; rel=&quot;lightbox[desertrocks2011]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8049/8359032204_ace553c370.jpg&quot; width=&quot;180&quot; height=&quot;120&quot; alt=&quot;Three Gossips and Tower of Babel&quot; style=&quot;border: 1px solid black; margin-left: 20px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;I &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgraded_to_roller_5_and&quot;&gt;Upgraded to Roller 5.0&lt;/a&gt; in June and showed how to add a &lt;a href=&quot;https://developers.facebook.com/docs/reference/plugins/like/&quot;&gt;Facebook Like button&lt;/a&gt;. Next, I transcribed a couple more Java Web Application Security articles: &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part3&quot;&gt;programmatic login APIs&lt;/a&gt; and &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part4&quot;&gt;penetrating with Zed Attack Proxy&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;The kids returned to us just before the &lt;a href=&quot;http://raibledesigns.com/rd/entry/good_times_on_the_annual&quot;&gt;annual Father&apos;s Day Camping Trip&lt;/a&gt;. We drove to Lake Granby and stayed at &lt;a href=&quot;http://campincolorado.com/federal/arapaho_roosevelt_nf/stillwater/stillwater.html&quot;&gt;Stillwater Campground&lt;/a&gt; for the weekend.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm6.static.flickr.com/5275/5850616117_57971bfd55.jpg&quot; title=&quot;Stillwater Campground Rocks!&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5275/5850616117_57971bfd55_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Stillwater Campground Rocks!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm4.static.flickr.com/3182/5851171484_b745090d35.jpg&quot; title=&quot;Beautiful Colorado&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm4.static.flickr.com/3182/5851171484_b745090d35_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Beautiful Colorado&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;From my Father&apos;s Day post:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;I really enjoyed spending so much time with my family this weekend. The good news is we get to do it again when I meet them at The Cabin in Montana next week. In the meantime, Trish and I are off to &lt;a href=&quot;http://jazoon.com/&quot;&gt;Jazoon&lt;/a&gt; for a few days of fun in Switzerland.
&lt;/p&gt;
&lt;p&gt;A few days later, we were &lt;a href=&quot;http://raibledesigns.com/rd/entry/a_sweet_trip_to_switzerland&quot;&gt;in Zurich for the first time&lt;/a&gt;, enjoying our accommodations and marveling at Switzerland&apos;s excellent transportation system.
I experienced an interesting situation while speaking, but quickly forgot when we visited Rhine Falls, celebrated our anniversary at Gruelich and played in the Swiss Alps.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a href=&quot;http://farm7.static.flickr.com/6030/5879428306_a793f2a67e.jpg&quot; title=&quot;View from Great Church&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.static.flickr.com/6030/5879428306_a793f2a67e_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;View from Great Church&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm6.static.flickr.com/5080/5879428652_e847f2ff0c.jpg&quot; title=&quot;Happy Couple in Z&#252;rich&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5080/5879428652_e847f2ff0c_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;Happy Couple in Z&#252;rich&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;a href=&quot;http://farm6.static.flickr.com/5108/5879429020_21dd2b6ddf.jpg&quot; title=&quot;Riding the Train&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5108/5879429020_21dd2b6ddf_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;Riding the Train&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;a href=&quot;http://farm7.static.flickr.com/6005/5879429424_275a73ac3d.jpg&quot; title=&quot;Rhine Falls!&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.static.flickr.com/6005/5879429424_275a73ac3d_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;Rhine Falls!&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a href=&quot;http://farm6.static.flickr.com/5112/5878867297_cac4cd43c9.jpg&quot; title=&quot;Whoa!&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5112/5878867297_cac4cd43c9_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Whoa!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm6.static.flickr.com/5183/5881479860_7ef4ba409e.jpg&quot; title=&quot;Rhine Falls Flowers&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5183/5881479860_7ef4ba409e_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Rhine Falls Flowers&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a href=&quot;http://farm6.static.flickr.com/5320/5880917345_38968f556c.jpg&quot; title=&quot;Olives and Sprouts&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5320/5880917345_38968f556c_t.jpg&quot; width=&quot;100&quot; height=&quot;75&quot; alt=&quot;Olives and Sprouts&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm6.static.flickr.com/5144/5880917787_cfcb0012ce.jpg&quot; title=&quot;Scallops and Tomato&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5144/5880917787_cfcb0012ce_t.jpg&quot; width=&quot;100&quot; height=&quot;75&quot; alt=&quot;Scallops and Tomato&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm7.static.flickr.com/6018/5878966083_8bef3238da.jpg&quot; title=&quot;Dessert at Greulich&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.static.flickr.com/6018/5878966083_8bef3238da_t.jpg&quot; width=&quot;100&quot; height=&quot;75&quot; alt=&quot;Dessert at Greulich&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm6.static.flickr.com/5151/5878966527_7634f8a94e.jpg&quot; title=&quot;Greulich&apos;s Backyard Trees&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5151/5878966527_7634f8a94e_t.jpg&quot; width=&quot;100&quot; height=&quot;75&quot; alt=&quot;Greulich&apos;s Backyard Trees&quot; style=&quot;margin-left: 10px; border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;We arrived back in Denver at 6pm on Sunday, June 26th and I flew to Montana at 8am the next morning. I worked from The Cabin that week and &lt;a href=&quot;http://raibledesigns.com/rd/entry/agile_hiring_book_review&quot;&gt;wrote a book review for Agile Hiring&lt;/a&gt;.
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
I think Sean [Landis] does a great job in showing how you can apply agile principles (people over process, tracking tools, failing fast, continuous improvement, constant feedback) to improve your hiring process. As a person that interviews often, I think it also gives great insights into how companies interview and what they&apos;re looking for. I&apos;ve often thought that being honest about my skills and what I&apos;m looking for is a good tactic and this book seems to confirm that.
&lt;/p&gt;
&lt;p&gt;That weekend, it was the &quot;90s Reunion&quot; for the Seeley Swan High School, which I attended my freshman and sophomore year of high school. There were several highlights of the trip, but one of my favorites was our float in the Swan Valley Parade. Abbie came up with the idea (Happy Birthday America) and we decorated an old trailer with streamers, balloons and a birthday cake to celebrate. Abbie made up a song and sang it throughout the entire parade (with a portable microphone and amp).
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Abbie singing &amp;quot;Happy Birthday America&amp;quot;&quot; href=&quot;http://farm7.static.flickr.com/6130/5934498303_10250c2760.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Abbie singing &amp;quot;Happy Birthday America&amp;quot;&quot; src=&quot;//farm7.static.flickr.com/6130/5934498303_10250c2760_t.jpg&quot;&gt;&lt;/a&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Abbie before getting dunked&quot; href=&quot;http://farm7.static.flickr.com/6020/5934498549_38f1793c46.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;margin-left: 0px; border: 1px solid black&quot; alt=&quot;Abbie before getting dunked&quot; src=&quot;//farm7.static.flickr.com/6020/5934498549_38f1793c46_t.jpg&quot;&gt;&lt;/a&gt;
&lt;a rel=&quot;lightbox[4thofjuly2011]&quot; title=&quot;Fiddlin&apos; Trish&quot; href=&quot;http://farm7.static.flickr.com/6002/5934499269_c40b347316.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;margin-left: 0px; border: 1px solid black&quot; alt=&quot;Fiddlin&apos; Trish&quot; src=&quot;//farm7.static.flickr.com/6002/5934499269_c40b347316_t.jpg&quot;&gt;&lt;/a&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Paddleboating&quot; href=&quot;http://farm7.static.flickr.com/6123/5935065040_59657b06fa.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;margin-left: 0px; border: 1px solid black&quot; alt=&quot;Paddleboating&quot; src=&quot;//farm7.static.flickr.com/6123/5935065040_59657b06fa_t.jpg&quot;&gt;&lt;/a&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Lake McDonald, Glacier National Park&quot; href=&quot;http://farm7.static.flickr.com/6006/5935068822_cfd7c86009.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;margin-left: 0px; border: 1px solid black&quot; alt=&quot;Lake McDonald, Glacier National Park&quot; src=&quot;//farm7.static.flickr.com/6006/5935068822_cfd7c86009_t.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I went swimming with my iPhone 4 that Sunday and Trish and her Dad showed up a few hours later. On the 4th, we had a blast celebrating the holiday with mine and my parents&apos; old friends. The next day, we adventured to Glacier National Park, where Trish shot an &lt;a href=&quot;http://www.mcginityphoto.com/Nature/Nature/4725995_JRpvJB/9/1373210164_W4mgd99#!i=1373210164&amp;amp;k=W4mgd99&quot;&gt;awesome sunrise at Lake McDonald&lt;/a&gt;.
She also captured a beautiful picture of The Cabin at sunset that week.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[4thofjuly2011]&quot; title=&quot;The Raible Cabin by Trish McGinity&quot; href=&quot;http://farm7.static.flickr.com/6122/5933924991_8dde37f131.jpg&quot;&gt;&lt;img width=&quot;500&quot; height=&quot;333&quot; style=&quot;border: 1px solid black&quot; alt=&quot;The Raible Cabin&quot; src=&quot;//farm7.static.flickr.com/6122/5933924991_8dde37f131.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;In between vacationing in Montana and writing about it, I wrote some technical posts:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/integrating_oauth_with_appfuse_and&quot;&gt;Integrating OAuth with AppFuse and its REST API&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/installing_openjdk_7_on_os&quot;&gt;Installing OpenJDK 7 on OS X&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We returned to Denver in mid-July and shipped the kids off to Florida just before my annual Birthday Golf Debacle. We teed off at Wellshire Golf Course and had one of the most well-behaved rounds in a few years. The next weekend, we closed on our &quot;Ski Shack&quot; in Fraser and I penned &lt;a href=&quot;http://raibledesigns.com/rd/entry/another_dream_realized_mountain_views&quot;&gt;Another Dream Realized: Mountain Views&lt;/a&gt;. Trish&apos;s &lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/6716291441&quot;&gt;October Sunset photo&lt;/a&gt; is one of my favorite glimpses of our view.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm8.staticflickr.com/7155/6716291441_c70eb5e378.jpg&quot; rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;October Sunset from our dock&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7155/6716291441_c70eb5e378.jpg&quot; alt=&quot;October Sunset in Fraser&quot; width=&quot;400&quot; height=&quot;269&quot; style=&quot;border: 1px solid black&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Next, I blogged about &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_do_you_get_started&quot;&gt;How do you get started in programming?&lt;/a&gt; and we headed to the airport a few hours later for a whirlwind trip from Oregon to Cape Cod. &lt;em&gt;That&lt;/em&gt; was a wonderful trip and it took me almost a month &lt;a href=&quot;http://raibledesigns.com/rd/entry/oregon_cape_cod_and_fun&quot;&gt;to write about it&lt;/a&gt;. We flew into Portland and spent the weekend hiking in Silver Falls and drinking good beer at the &lt;a href=&quot;http://www.oregonbrewfest.com/&quot;&gt;Oregon Brewers Festival&lt;/a&gt; and &lt;a href=&quot;http://www.mcmenamins.com/54-edgefield-home&quot;&gt;Edgefield&lt;/a&gt;. We stayed with my good friends Clint and Autumn (married in &lt;a href=&quot;http://raibledesigns.com/rd/entry/costa_rica_was_awesome&quot;&gt;Costa Rica in 2008&lt;/a&gt;), who had their first child only a few weeks after our visit (August 26th).
&lt;/p&gt;
&lt;p&gt;We had an awful early flight out of Portland to Boston that Sunday. On Monday afternoon, we picked up Abbie and Jack from the Boston airport. They flew up from West Palm Beach on their first unaccompanied minors flight. We drove them to Cape Cod and settled into Trish&apos;s parents house near the water. The rest of the week, we had a blast with our friends Chris and Julie and the entire McGinity clan. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Wheeee!!&quot; href=&quot;http://farm7.static.flickr.com/6022/6008443089_cc4f752c0f.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Wheeee!!&quot; src=&quot;//farm7.static.flickr.com/6022/6008443089_cc4f752c0f_t.jpg&quot;&gt;&lt;/a&gt;

&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Hercules!&quot; href=&quot;http://farm7.static.flickr.com/6006/6008999952_78fd13f415.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Hercules!&quot; src=&quot;//farm7.static.flickr.com/6006/6008999952_78fd13f415_t.jpg&quot;&gt;&lt;/a&gt;

&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Michael and Jack&quot; href=&quot;http://farm7.static.flickr.com/6125/6044153539_84019058e4.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Michael and Jack&quot; src=&quot;//farm7.static.flickr.com/6125/6044153539_84019058e4_t.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Monkey Shadows&quot; href=&quot;http://farm7.static.flickr.com/6133/6044703126_cb16505a0c.jpg&quot;&gt;&lt;img width=&quot;240&quot; height=&quot;180&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Monkey Shadows&quot; src=&quot;//farm7.static.flickr.com/6133/6044703126_cb16505a0c_m.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
We spent the rest of August going to concerts at Red Rocks, beer festivals in Winter Park, mountain biking, hiking, taking the kids to the Ski Shack and playing with Crazy Sagan. 
&lt;a href=&quot;http://farm7.staticflickr.com/6087/6044208823_60c83e67c9.jpg&quot; title=&quot;Crazy Sagan!&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6087/6044208823_60c83e67c9_t.jpg&quot; width=&quot;100&quot; height=&quot;75&quot; alt=&quot;Crazy Sagan!&quot; class=&quot;picture&quot; style=&quot;margin-top: 5px&quot;&gt;&lt;/a&gt;
In my only August post, I talked a lot about the Broncos, Hawaii, Devoxx and leaving Overstock.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
  That pretty much catches you up-to-date with the goings on in my life. As you can tell, it&apos;s been a &lt;em&gt;great&lt;/em&gt; summer so far. I&apos;m really looking forward to the fall too. Broncos season, a trip to Hawaii, learning new technologies, talking about them at Devoxx and a new gig.
  &lt;br/&gt;...&lt;br/&gt;
  Tomorrow is Jack&apos;s birthday. I gotta run ... it&apos;s time to go buy a bike, play a little golf, hit the pool and go to the BBQ before tonight&apos;s CD Release Party. 
&lt;/p&gt;
&lt;p&gt;We watched proudly as Jack turned 7 the next day and loved his excitement when he got his first mountain bike.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;&lt;a href=&quot;http://farm7.staticflickr.com/6173/6168228852_44f34ab78d.jpg&quot; title=&quot;7 Miles and ready for more&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6173/6168228852_44f34ab78d_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;7 Miles and ready for more&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
  &lt;/p&gt;
&lt;p&gt;September started with mountain breezes and &lt;a href=&quot;http://raibledesigns.com/rd/entry/labor_day_weekend_in_grand&quot;&gt;fishing at Lake Granby&lt;/a&gt;. Lots of friends, family and delicious food make for a heckuva 3-day weekend. Jack was the only one to catch a fish and you couldn&apos;t wipe the smile off his face for the rest of the day.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;The delicious fish that Jack caught at Lake Granby&quot; href=&quot;http://farm7.static.flickr.com/6189/6112833896_59bd8ecc99.jpg&quot;&gt;&lt;img width=&quot;500&quot; height=&quot;375&quot; style=&quot;border: 1px solid black&quot; alt=&quot;The delicious fish that Jack caught at Lake Granby&quot; src=&quot;//farm7.static.flickr.com/6189/6112833896_59bd8ecc99.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;I described my &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_digital_diet&quot;&gt;Digital Diet&lt;/a&gt; and wrote my first article related to my Devoxx talk: &lt;a href=&quot;http://raibledesigns.com/rd/entry/integrating_scalate_and_jade_with&quot;&gt;Integrating Scalate and Jade with Play 1.2.3&lt;/a&gt;. The 2nd weekend in September, we enjoyed a &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157627717258988/&quot;&gt;September Sports Weekend&lt;/a&gt;, going to two Rockies games and the Monday night Broncos Opener before heading to Kauai. While the Broncos didn&apos;t win that game, Trish&apos;s shot of Brett, Joe and I sums up many-a-game this season.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm7.staticflickr.com/6168/6185423596_e62d1e1efd.jpg&quot; title=&quot;Broncos Home Opener&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6168/6185423596_e62d1e1efd.jpg&quot; width=&quot;500&quot; height=&quot;333&quot; alt=&quot;Broncos Home Opener&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;As expected, &lt;a href=&quot;http://raibledesigns.com/rd/entry/mahalo_kauai&quot;&gt;Kauai blew our minds&lt;/a&gt;. We saw several spectacular sunsets, did some Stand Up Paddling (it&apos;s harder than it looks), played golf, took a doorless helicopter ride and kayaked along the Na Pali coast. &lt;/p&gt;
&lt;table style=&quot;margin: 0 auto 5px auto&quot; cellspacing=&quot;10&quot;&gt;
  &lt;tr&gt;
    &lt;td rowspan=&quot;3&quot;&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm7.staticflickr.com/6154/6174598580_f440fdfc48.jpg&quot; title=&quot;HDR Sunset next to the palm trees on the beach at Hanalei Bay by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6154/6174598580_f440fdfc48_m.jpg&quot; width=&quot;156&quot; height=&quot;240&quot; alt=&quot;HDR Sunset next to the palm trees on the beach at Hanalei Bay&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
  &lt;/td&gt;
  &lt;td&gt;
    &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm7.staticflickr.com/6153/6174087039_b3740f60b7.jpg&quot; title=&quot;Hanalei Bay Sunset HDR by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6153/6174087039_b3740f60b7_t.jpg&quot; width=&quot;100&quot; height=&quot;66&quot; alt=&quot;Hanalei Bay Sunset HDR&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm7.staticflickr.com/6159/6174622520_87c18de29c.jpg&quot; title=&quot;Makai Golf Club my pitch out of the sand is next to the pin.  Matt&apos;s is on the edge of the green :) by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6159/6174622520_87c18de29c_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Makai Golf Club my pitch out of the sand is next to the pin.  Matt&apos;s is on the edge of the green :)&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;
    &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm7.staticflickr.com/6154/6174624336_9065acfafa.jpg&quot; title=&quot;Bougainvillia on the Makai Golf course looking across Hanalei Bay by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6154/6174624336_9065acfafa_t.jpg&quot; width=&quot;100&quot; height=&quot;66&quot; alt=&quot;Bougainvillia on the Makai Golf course looking across Hanalei Bay&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm7.staticflickr.com/6153/6174630996_bee864d25d.jpg&quot; title=&quot;2 Blue Hawai&apos;i on the beach in Hanalei Bay by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6153/6174630996_bee864d25d_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;2 Blue Hawai&apos;i on the beach in Hanalei Bay&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;&lt;td&gt;
    &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm7.staticflickr.com/6178/6174149421_49cc20532c.jpg&quot; title=&quot;Rainbow to Kalalau Valley Napali Coast State Park by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6178/6174149421_49cc20532c.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Rainbow to Kalalau Valley Napali Coast State Park&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
    &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm7.staticflickr.com/6174/6174681482_01c2422fd3.jpg&quot; title=&quot;Wahooo That was Awesome! :) by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6174/6174681482_01c2422fd3_t.jpg&quot; width=&quot;100&quot; height=&quot;67&quot; alt=&quot;Wahooo That was Awesome! :)&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;p&gt;We never got bored of the view from our room.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Aloha in the morning at the St Regis Hanalei Bay by McGinityPhoto, on Flickr&quot; href=&quot;http://farm7.staticflickr.com/6157/6174599098_879e9d9aa4.jpg&quot;&gt;&lt;img width=&quot;500&quot; height=&quot;331&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Aloha in the morning at the St Regis Hanalei Bay&quot; src=&quot;//farm7.staticflickr.com/6157/6174599098_879e9d9aa4.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Upon our return, I &lt;a href=&quot;http://raibledesigns.com/rd/entry/trying_to_make_coffeescript_work&quot;&gt;tried to make CoffeeScript work with Scalate&lt;/a&gt; and 
&lt;a href=&quot;http://raibledesigns.com/rd/entry/integrating_html5_boilerplate_with_scalate&quot;&gt;integrated HTML5 Boilerplate with Play&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://fbcdn-photos-a.akamaihd.net/hphotos-ak-snc7/309585_10150334101446712_571296711_8306949_270832760_n.jpg&quot; title=&quot;Halloween&quot;&gt;&lt;img src=&quot;//fbcdn-photos-a.akamaihd.net/hphotos-ak-snc7/309585_10150334101446712_571296711_8306949_270832760_a.jpg&quot; alt=&quot;Halloween&quot; width=&quot;180&quot; height=&quot;139&quot; class=&quot;picture&quot; style=&quot;margin-top: 0; border: 1px solid black&quot;&gt;&lt;/a&gt;
October was a quiet month on this blog. I only wrote two articles, one about &lt;a href=&quot;http://raibledesigns.com/rd/entry/increasing_my_developer_happiness&quot;&gt;increasing my developer happiness&lt;/a&gt; and another about &lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_with_html5_coffeescript_and&quot;&gt;developing with HTML5, CoffeeScript and Twitter&apos;s Bootstrap&lt;/a&gt;. Watching the Broncos in October was painful at first, buy many rejoiced when Tebow started against Miami (10/23) and we had the amazing comeback to win. We went to the next game against the Lions and were quickly shown they had a long ways to go. We dressed up as the Scary Family for Halloween and had a ball.
&lt;/p&gt;
&lt;p&gt;I made up for October&apos;s lack of writing by writing 9 articles in November. I started with &lt;a href=&quot;http://raibledesigns.com/rd/entry/play_scala_s_anorm_heroku&quot;&gt;complaints about Play Scala&apos;s Anorm and PostgreSQL&lt;/a&gt;, then &lt;a href=&quot;http://raibledesigns.com/rd/entry/happy_9th_birthday_abbie&quot;&gt;celebrated Abbie&apos;s 9th Birthday&lt;/a&gt; with a &lt;a href=&quot;http://www.flickr.com/photos/mraible/6316702824&quot;&gt;Magic Show&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a href=&quot;http://farm7.staticflickr.com/6117/6316702372_40594e7cbf.jpg&quot; title=&quot;Happy Kids&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6117/6316702372_40594e7cbf_m.jpg&quot; width=&quot;240&quot; height=&quot;160&quot; alt=&quot;Happy Kids&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
  &lt;a href=&quot;http://farm7.staticflickr.com/6047/6316702824_e46bacdc72.jpg&quot; title=&quot;Birthday Crew&quot; rel=&quot;lightbox[yearinreview2011]&quot;&gt;&lt;img src=&quot;//farm7.staticflickr.com/6047/6316702824_e46bacdc72_m.jpg&quot; width=&quot;240&quot; height=&quot;160&quot; alt=&quot;Birthday Crew&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;The next week, I wrote about my &lt;a href=&quot;http://raibledesigns.com/rd/entry/new_macbook_pro_and_imac&quot;&gt;new MacBook Pro and iMac&lt;/a&gt; and &lt;a href=&quot;http://raibledesigns.com/rd/entry/more_scalate_goodness_for_play&quot;&gt;more Scalate goodness for Play&lt;/a&gt;. At this point, I was scrambling to finish up my &lt;em&gt;Play More!&lt;/em&gt; application for &lt;a href=&quot;http://www.devoxx.com/display/DV11/Home&quot;&gt;Devoxx&lt;/a&gt; and worked a lot of late nights. That weekend, I &lt;a href=&quot;http://raibledesigns.com/rd/entry/phonegap_to_the_rescue&quot;&gt;used PhoneGap&lt;/a&gt; to turn my webapp into a native app and finished everything in the nick of time. We flew to Paris that Monday, took the train to Antwerp on Tuesday and settled in for a memorable week of interesting talks.
&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/play_2_0_a_web&quot;&gt;Play 2.0, A web framework for a new era&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/phonegap_for_hybrid_app_development&quot;&gt;PhoneGap for Hybrid App Development&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/deploying_java_and_play_framework&quot;&gt;Deploying Java and Play Framework Apps to the Cloud with James Ward&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/my_html5_with_play_scala&quot;&gt;My HTML5 with Play Scala, CoffeeScript and Jade Presentation from Devoxx 2011&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Crew at Devoxx dinner by McGinity Photo&quot; href=&quot;http://farm8.staticflickr.com/7006/6448345655_df403b1cfd.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;67&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Matt Raible and Crew at Devoxx dinner&quot; src=&quot;//farm8.staticflickr.com/7006/6448345655_df403b1cfd_t.jpg&quot;&gt;&lt;/a&gt;

  
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;At Pelgrom by McGinity Photo&quot; href=&quot;http://farm8.staticflickr.com/7019/6448347213_5e9c59ba8c.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;67&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Matt Raible at Pelgrom&quot; src=&quot;//farm8.staticflickr.com/7019/6448347213_5e9c59ba8c_t.jpg&quot;&gt;&lt;/a&gt;

  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;James Ward speaking on Heroku at Devoxx by McGinity Photo&quot; href=&quot;http://farm8.staticflickr.com/7147/6448349163_313bc48dd5.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;67&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;James Ward speaking on Heroku at Devoxx&quot; src=&quot;//farm8.staticflickr.com/7147/6448349163_313bc48dd5_t.jpg&quot;&gt;&lt;/a&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Speaking at Devoxx Belgium 2011 by McGinity Photo&quot; href=&quot;http://farm8.staticflickr.com/7031/6448350561_e62da3327b.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;67&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Matt Raible speaking at Devoxx Belgium 2011&quot; src=&quot;//farm8.staticflickr.com/7031/6448350561_e62da3327b_t.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Antwerp Town Square by McGinity Photo&quot; href=&quot;http://farm8.staticflickr.com/7002/6716294395_28ce2c5f5b.jpg&quot;&gt;&lt;img width=&quot;240&quot; height=&quot;160&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Antwerp Town Square&quot; src=&quot;//farm8.staticflickr.com/7002/6716294395_28ce2c5f5b_m.jpg&quot;&gt;&lt;/a&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Riverside in Antwerp by McGinity Photo&quot; href=&quot;http://farm8.staticflickr.com/7010/6448353693_f63f7afee6.jpg&quot;&gt;&lt;img width=&quot;240&quot; height=&quot;160&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Riverside in Antwerp&quot; src=&quot;//farm8.staticflickr.com/7010/6448353693_f63f7afee6_m.jpg&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;That Saturday, we took the train back to Paris and checked into our hotel for a few days of romance. I proposed to Trish at Versailles on Sunday at sunset and we rolled around in our joy for a few days before we told any of our friends. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;The Versailles Orangerie&quot; href=&quot;http://farm8.staticflickr.com/7009/6402228135_6ffc860b9f.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black&quot; alt=&quot;The Versailles Orangerie&quot; src=&quot;//farm8.staticflickr.com/7009/6402228135_6ffc860b9f_t.jpg&quot;&gt;&lt;/a&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Ch&#226;teau de Versailles&quot; href=&quot;http://farm8.staticflickr.com/7141/6402228667_2e908c6fb0.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Ch&#226;teau de Versailles&quot; src=&quot;//farm8.staticflickr.com/7141/6402228667_2e908c6fb0_t.jpg&quot;&gt;&lt;/a&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Gardens of Versailles&quot; href=&quot;http://farm8.staticflickr.com/7161/6402229087_0d34f8f6f9.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Gardens of Versailles&quot; src=&quot;//farm8.staticflickr.com/7161/6402229087_0d34f8f6f9_t.jpg&quot;&gt;&lt;/a&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Trees in the Versailles Gardens&quot; href=&quot;http://farm8.staticflickr.com/7023/6402230475_9251f0664c.jpg&quot;&gt;&lt;img width=&quot;100&quot; height=&quot;75&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Trees in the Versailles Gardens&quot; src=&quot;//farm8.staticflickr.com/7023/6402230475_9251f0664c_t.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Bassin d&#8217;Apollon &amp;ndash; the Apollo Fountain by McGinity Photo&quot; href=&quot;http://farm8.staticflickr.com/7156/6716294893_7a8ed53bf5.jpg&quot;&gt;&lt;img width=&quot;500&quot; height=&quot;329&quot; alt=&quot;Bassin d&#8217;Apollon &amp;ndash; the Apollo Fountain&quot; src=&quot;//farm8.staticflickr.com/7156/6716294893_7a8ed53bf5.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;  
&lt;p&gt;
We flew back to the US the Wednesday before Christmas and spent the weekend in Boston with Trish&apos;s family. For full details of that trip, see &lt;a href=&quot;http://raibledesigns.com/rd/entry/our_engaging_trip_to_paris&quot;&gt;Our Engaging Trip to Paris and Antwerp&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Happy&quot; href=&quot;http://farm7.staticflickr.com/6031/6402231033_9a0f51938c.jpg&quot;&gt;&lt;img width=&quot;240&quot; height=&quot;180&quot; style=&quot;border: 1px solid black&quot; alt=&quot;Happy&quot; src=&quot;//farm7.staticflickr.com/6031/6402231033_9a0f51938c_m.jpg&quot;&gt;&lt;/a&gt;
&lt;a rel=&quot;lightbox[yearinreview2011]&quot; title=&quot;Versailles Sunset&quot; href=&quot;http://farm8.staticflickr.com/7018/6402232723_e61d57cc98.jpg&quot;&gt;&lt;img width=&quot;240&quot; height=&quot;180&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot; alt=&quot;Versailles Sunset&quot; src=&quot;//farm8.staticflickr.com/7018/6402232723_e61d57cc98_m.jpg&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;To end the year, I kept it light and only spun up one blog post in December: &lt;a href=&quot;http://raibledesigns.com/rd/entry/what_have_i_been_working&quot;&gt;What have I been working on at Taleo?&lt;/a&gt; A week after writing that post, we moved to the Ski Shack for 3 weeks and enjoyed a &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157628628439665/&quot;&gt;wonderful holiday break&lt;/a&gt; with &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157628725392081/&quot;&gt;many visitors&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm8.staticflickr.com/7150/6638934399_2fb67c7883.jpg&quot; title=&quot;Shredders&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7150/6638934399_2fb67c7883_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Shredders&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm8.staticflickr.com/7031/6638937219_8623aa8e63.jpg&quot; title=&quot;Happy New Year!&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7031/6638937219_8623aa8e63_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;Happy New Year!&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Yes, 2011 was a spectacular year. We traveled to four different countries, did a lot of camping and mountain biking and accomplished 2/3 of my 5 year goals (basement sauna and mountain views). I wrote a lot of technical blog posts in the 2nd half of the year; most inspired my extracurricular activities&lt;/a&gt;. I plan to continue that this year as I learn more about HTML5, Play Framework, Scala and CoffeeScript. At the end of last year&apos;s &lt;a href=&quot;http://raibledesigns.com/rd/entry/2010_a_year_in_review&quot;&gt;Year in Review&lt;/a&gt;, I wrote:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
In 2011, I plan on doing two main things: keep rockin&apos; it with Trish and finishing The Bus.
&lt;/p&gt;
&lt;p&gt;I think I can safely say I kept it rockin&apos; with Trish - we&apos;re living together, engaged and still amazed we found one another. As for The Bus, I think &lt;a href=&quot;http://www.motorworksrestorations.com/&quot;&gt;MotorWorks Restorations&lt;/a&gt; and I are in a good position to make a final push and finish the sucker. My hope is to have it done by May so I can start driving it and taking it to VW Shows. In the meantime, Trish has started working on &lt;a href=&quot;http://www.mcginityphoto.com/&quot;&gt;McGinity Photo&lt;/a&gt; full-time and loving it. We have trips planned to Stockholm (for &lt;a href=&quot;http://jfokus.se&quot;&gt;Jfokus&lt;/a&gt;), Madrid (for &lt;a href=&quot;http://www.springio.net/&quot;&gt;Spring I/O&lt;/a&gt;) and Paris (for &lt;a href=&quot;http://www.devoxx.fr/display/FR12/Accueil&quot;&gt;Devoxx Paris&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;Last weekend, we &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157628804308427/&quot;&gt;witnessed&lt;/a&gt; one of the greatest playoff games &lt;em&gt;ever&lt;/em&gt; when the Broncos beat the Steelers. I think the picture of Trish celebrating the final touchdown pretty much sums up 2011. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
  &lt;a rel=&quot;lightbox[yearinreview2011]&quot; href=&quot;http://farm8.staticflickr.com/7161/6671393297_d6f01b715f.jpg&quot; title=&quot;Broncos Win!&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7161/6671393297_d6f01b715f.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Broncos Win!&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
  &lt;/p&gt;
&lt;p&gt;I look forward to all the skiing, celebrating, camping, traveling and bus rides in 2012. It&apos;s gonna be a fantastic year.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_security</id>
        <title type="html">Upgrading AppFuse to Spring Security 3.1 and Spring 3.1</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_security"/>
        <published>2012-01-05T08:58:21-07:00</published>
        <updated>2012-01-05T15:03:03-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Before the holiday break, I spent some time upgrading &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; to use the latest releases of Spring and Spring Security. I started with Spring Security in early December and quickly discovered its 3.1 XSD required some changes. After changing to the &lt;a href=&quot;http://www.springframework.org/schema/security/spring-security-3.1.xsd&quot;&gt;3.1 XSD&lt;/a&gt; in my &lt;em&gt;security.xml&lt;/em&gt;, I had to change its &amp;lt;http&amp;gt; element to use &lt;code&gt;security=&quot;none&quot;&lt;/code&gt; instead of &lt;code&gt;filters=&quot;none&quot;&lt;/code&gt;. With Spring Security 3.0.5, I had:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;http auto-config=&quot;true&quot; lowercase-comparisons=&quot;false&quot;&gt;
    &amp;lt;intercept-url pattern=&quot;/images/**&quot; filters=&quot;none&quot;/&gt;
    &amp;lt;intercept-url pattern=&quot;/styles/**&quot; filters=&quot;none&quot;/&gt;
    &amp;lt;intercept-url pattern=&quot;/scripts/**&quot; filters=&quot;none&quot;/&gt;
&lt;/pre&gt;
After upgrading to 3.1, I had to change this to:
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;http pattern=&quot;/images/**&quot; security=&quot;none&quot;/&gt;
&amp;lt;http pattern=&quot;/styles/**&quot; security=&quot;none&quot;/&gt;
&amp;lt;http pattern=&quot;/scripts/**&quot; security=&quot;none&quot;/&gt;

&amp;lt;http auto-config=&quot;true&quot;&gt;
&lt;/pre&gt;
&lt;p&gt;The next thing I had to change was &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/service/src/main/java/org/appfuse/service/UserSecurityAdvice.java?r1=3329&amp;r2=3582&quot;&gt;UserSecurityAdvice.java&lt;/a&gt;. Instead of using &lt;code&gt;Collection&amp;lt;GrantedAuthority&amp;gt;&lt;/code&gt; for Authentication&apos;s &lt;em&gt;getAuthority()&lt;/em&gt; method, I had to change it to use &lt;code&gt;Collection&amp;lt;? extends GrantedAuthority&amp;gt;&lt;/code&gt;.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
Authentication auth = ctx.getAuthentication();
Collection&amp;lt;? extends GrantedAuthority&gt; roles = auth.getAuthorities();
&lt;/pre&gt;
&lt;p style=&quot;text-align: left&quot;&gt;Lastly, I discovered that &lt;code&gt;SPRING_SECURITY_CONTEXT_KEY&lt;/code&gt; &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/common/src/main/java/org/appfuse/webapp/listener/UserCounterListener.java?r1=3579&amp;r2=3582&quot;&gt;moved to  HttpSessionSecurityContextRepository&lt;/a&gt;. &lt;a href=&quot;http://source.appfuse.org/changelog/appfuse/?cs=3582&quot;&gt;Click here&lt;/a&gt; to see the changelog for this upgrade in AppFuse&apos;s FishEye.
&lt;/p&gt;
&lt;p&gt;You can read more about &lt;a href=&quot;http://www.infoq.com/news/2011/12/spring-security-3.1&quot;&gt;what&apos;s new in Spring Security 3.1 on InfoQ&lt;/a&gt;. I&apos;m especially pumped to see http-only cookie support for Servlet 3.0. I discovered Spring Security didn&apos;t support this when &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part4&quot;&gt;Pen-Testing with Zed Attack Proxy&lt;/a&gt;.
&lt;p id=&quot;spring-3.1&quot;&gt;&lt;strong&gt;Upgrading to Spring Framework 3.1&lt;/strong&gt;&lt;br/&gt;
Compared to the Spring Security upgrade, upgrading to Spring 3.1 &lt;a href=&quot;http://source.appfuse.org/changelog/appfuse/?cs=3585&quot;&gt;was a breeze&lt;/a&gt;. The first thing I discovered after changing my pom.xml&apos;s version was that Spring Security required some additional exclusions in order to get the latest Spring versions. Of course, this was communicated to me through the following cryptic error.
&lt;/p&gt;
&lt;pre&gt;
-------------------------------------------------------------------------------
Test set: org.appfuse.dao.LookupDaoTest
-------------------------------------------------------------------------------
Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.004 sec &lt;&lt;&lt; FAILURE!
testGetRoles(org.appfuse.dao.LookupDaoTest)  Time elapsed: 0.001 sec  &lt;&lt;&lt; ERROR!
java.lang.NoSuchMethodError: org.springframework.context.support.GenericApplicationContext.getEnvironment()Lorg/springframework/core/env/ConfigurableEnvironment;
	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:97)
	at org.springframework.test.context.support.AbstractGenericContextLoader.loadContext(AbstractGenericContextLoader.java:1)
	at org.springframework.test.context.support.DelegatingSmartContextLoader.loadContext(DelegatingSmartContextLoader.java:228)
	at org.springframework.test.context.TestContext.loadApplicationContext(TestContext.java:124)
	at org.springframework.test.context.TestContext.getApplicationContext(TestContext.java:148)
	at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:109)
&lt;/pre&gt;
&lt;p&gt;
Without these additional exclusions, Spring Security pulled in Spring 3.0.6. I had to exclude spring-expression, spring-context and spring-web from spring-security-taglibs to get the 3.1.0.RELEASE version of Spring.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-security-taglibs&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${spring.security.version}&amp;lt;/version&amp;gt;
    &amp;lt;exclusions&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-expression&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-context&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
    &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I also had to exclude spring-context from spring-security-config and spring-context and spring-expression from spring-security-core. &lt;em&gt;Isn&apos;t Maven wonderful?&lt;/em&gt;
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-security-core&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${spring.security.version}&amp;lt;/version&amp;gt;
    &amp;lt;exclusions&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-expression&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-context&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
    &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-security-config&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${spring.security.version}&amp;lt;/version&amp;gt;
    &amp;lt;exclusions&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-context&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
    &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;After making these changes, I got a bit further, but ended up being blocked by a &lt;a href=&quot;https://issues.apache.org/jira/browse/TAP5-1788&quot;&gt;bug in Tapestry 5&apos;s Spring support&lt;/a&gt;. Basically, after upgrading to Spring 3.1, I started seeing the following error:
&lt;/p&gt;
&lt;pre&gt;
java.lang.RuntimeException: Service id &apos;environment&apos; has already been defined by 
org.apache.tapestry5.services.TapestryModule.buildEnvironment(PerthreadManager) 
&lt;/pre&gt;
&lt;p&gt;Luckily, I was able to easily fix this with advice I &lt;a href=&quot;http://tapestry.1045711.n5.nabble.com/tapestry-5-2-4-and-spring-3-1M1-td4462226.html&quot;&gt;found on Tapestry&apos;s mailing list&lt;/a&gt;. Unfortunately, even though I submitted a fix on December 15th, it didn&apos;t make it into &lt;a href=&quot;http://tapestry.apache.org/2011/12/21/announcing-tapestry-531.html&quot;&gt;Tapestry&apos;s 5.3.1 release on December 21st&lt;/a&gt;. As soon as Tapestry 5.3.2 is released, I hope to get the AppFuse&apos;s build passing again (it&apos;s &lt;a href=&quot;http://builds.appfuse.org/browse/APF-TRUNK-535&quot;&gt;currently failing&lt;/a&gt;). 
&lt;/p&gt;
&lt;p&gt;I hope this article helps you upgrade your AppFuse-started applications to the latest versions of Spring and Spring Security. Over the next few weeks, I&apos;ll be exploring many of &lt;a href=&quot;http://blog.springsource.org/2011/12/13/spring-framework-3-1-goes-ga/&quot;&gt;Spring 3.1&apos;s new features&lt;/a&gt; and implementing them as I see fit. Right now, I&apos;m thinking environments/profiles, Servlet 3 / Java 7 support and Hibernate 4 support. These seem to be the best new features to learn about for &lt;a href=&quot;http://www.meetup.com/SV-SUG/events/43376082/&quot;&gt;my talk in a few weeks&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/installing_openjdk_7_on_os</id>
        <title type="html">Installing OpenJDK 7 on OS X</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/installing_openjdk_7_on_os"/>
        <published>2011-07-12T14:11:44-06:00</published>
        <updated>2012-10-11T16:05:10-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="osx" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="mac" scheme="http://roller.apache.org/ns/tags/" />
        <category term="openjdk" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java7" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last week, I &lt;a href=&quot;http://java.dzone.com/articles/introducing-java-7-moving&quot;&gt;scanned an article&lt;/a&gt; and saw there was a &lt;a href=&quot;http://www.oracle.com/webapps/events/ns/EventsDetail.jsp?p_eventId=134208&quot;&gt;Java 7 Webinar&lt;/a&gt;. At first, I thought Java 7 was released, but soon after realized it was a &lt;a href=&quot;http://jdk7.java.net/preview/&quot;&gt;Developer Preview&lt;/a&gt;. Unfortunately, the &lt;a href=&quot;http://jdk7.java.net/download.html&quot;&gt;download page&lt;/a&gt; doesn&apos;t have support for OS X. Since it took me a bit of work to figure out how to install OpenJDK 7 on OS X (I&apos;m running Snow Leopard 10.6.7), I figured I&apos;d write down how I did it.
&lt;/p&gt;
&lt;p&gt;I started off by downloading &quot;OpenJDK 1.7 universal (32/64 bits) from Mac OS/X branch&quot; from &lt;a href=&quot;http://code.google.com/p/openjdk-osx-build/downloads/list&quot;&gt;the openjdk-osx-build project&apos;s downloads&lt;/a&gt; (&lt;a href=&quot;http://openjdk-osx-build.googlecode.com/files/OpenJDK-OSX-1.7-universal-20110709.dmg&quot;&gt;direct link&lt;/a&gt;). After downloading, I installed the dmg as normal.
&lt;/p&gt;
&lt;div class=&quot;quote&quot;  style=&quot;background: #ddfbdd; border-color: #83f082; margin-left: 0; margin-bottom: 10px; color: #666&quot;&gt;&lt;p&gt;&lt;strong&gt;Update Jan 27, 2012:&lt;/strong&gt;&lt;br/&gt;After installing the dmg, add the following to your ~/.profile and you should be good to go. Thanks to &lt;a href=&quot;http://raibledesigns.com/rd/entry/installing_openjdk_7_on_os#comment-1311684547000&quot;&gt;Mark Beaty for the tip&lt;/a&gt;. &lt;/p&gt;
&lt;pre&gt;
function setjdk() { if [ $# -ne 0 ];then export JAVA_HOME=`/usr/libexec/java_home -v $@`; fi; java -version; }
&lt;/pre&gt;
&lt;p&gt;Continue with the instructions below if you don&apos;t like this technique for some reason.&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;I don&apos;t use Java Preferences to set my JDK, instead I use &lt;a href=&quot;http://blog.dblevins.com/&quot;&gt;David Blevin&apos;s&lt;/a&gt; handy &lt;a href=&quot;http://docs.codehaus.org/display/ninja/setjdk&quot;&gt;setjdk&lt;/a&gt; script. To make this script work with JDK 7 on OS X, I had to make one minor change. On line 40, I added &quot;Contents&quot; to the path for JAVA_HOME:
&lt;/p&gt;
&lt;pre&gt;
export JAVA_HOME=$vmdir/$ver/Contents/Home
&lt;/pre&gt;
&lt;p class=&quot;quote&quot; style=&quot;background: #ddf4fb; border-color: #82d6f0; color: #666&quot;&gt;&lt;strong&gt;Update Jan 27, 2012:&lt;/strong&gt; You no longer need to make this change.&lt;/p&gt;
&lt;p&gt;From there, I had to setup some symlinks so everything would work as expected:
&lt;/p&gt;
&lt;pre&gt;
cd /System/Library/Java/JavaVirtualMachines/
sudo ln -s /Library/Java/JavaVirtualMachines/1.7.0.jdk
&lt;/pre&gt;
&lt;div class=&quot;quote&quot;  style=&quot;background: #ddf4fb; border-color: #82d6f0; margin-left: 0; margin-bottom: 10px; color: #666&quot;&gt;&lt;p&gt;&lt;strong&gt;Update Jan 27, 2012:&lt;/strong&gt; The latest version installs at a different location so the symlink command above should be changed to:&lt;/p&gt;
&lt;pre&gt;
sudo ln -s /Library/Java/JavaVirtualMachines/1.7.0u.jdk 1.7.0.jdk
&lt;/pre&gt;
&lt;/div&gt;
&lt;p style=&quot;text-align: left&quot;&gt;Lastly, I had my JAVA_HOME set to &quot;/System/Library/Frameworks/JavaVM.framework/Home&quot;. I like the shorter (and seemingly more common) &quot;/Library/Java/Home&quot;, so I set it back to that in my ~/.profile:
&lt;/p&gt;
&lt;pre&gt;
export JAVA_HOME=/Library/Java/Home
&lt;/pre&gt;
&lt;p style=&quot;text-align: left&quot;&gt;On my system, /Library/Java/Home had a symlink to /System/Library/Frameworks/JavaVM.framework/Home, so I changed it to the CurrentJDK that Java Preferences and setjdk use.
&lt;/p&gt;
&lt;pre&gt;
cd /Library/Java
rm Home
ln -s /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Contents/Home
&lt;/pre&gt;
&lt;p&gt;Then I had to add a symlink for 1.7 in the Versions directory.&lt;/p&gt;
&lt;pre&gt;
cd /System/Library/Frameworks/JavaVM.framework/Versions
sudo ln -s /System/Library/Java/JavaVirtualMachines/1.7.0.jdk/Contents 1.7
&lt;/pre&gt;
&lt;p&gt;After making these changes, I was able to switch to JDK 7 easily.
&lt;/p&gt;
&lt;pre&gt;
$ setjdk 1.7
Setting this terminal&apos;s JDK to 1.7 ... openjdk version &quot;1.7.0-internal&quot;
OpenJDK Runtime Environment (build 1.7.0-internal-b00)
OpenJDK 64-Bit Server VM (build 21.0-b17, mixed mode)
&lt;/pre&gt;
&lt;p&gt;I was also able to switch back to JDK 6.
&lt;/p&gt;
&lt;pre&gt;
$ setjdk 1.6
Setting this terminal&apos;s JDK to 1.6 ... java version &quot;1.6.0_26&quot;
Java(TM) SE Runtime Environment (build 1.6.0_26-b03-384-10M3425)
Java HotSpot(TM) 64-Bit Server VM (build 20.1-b02-384, mixed mode)
&lt;/pre&gt;
&lt;p id=&quot;maven-issues&quot;&gt;&lt;strong&gt;Maven Issues&lt;/strong&gt;&lt;br/&gt;Next, I tried using JDK 7 to build &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. I ran into two issues when I tried to do this. The first was caused by the native2ascii plugin, which has been known to &lt;a href=&quot;http://maven.apache.org/general.html#tools-jar-dependency&quot;&gt;cause issues&lt;/a&gt; on non-Mac platforms. Adding the following profile seemed to solve the problem.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;profile&amp;gt;
    &amp;lt;activation&amp;gt;
        &amp;lt;jdk&amp;gt;1.7&amp;lt;/jdk&amp;gt;
    &amp;lt;/activation&amp;gt;
    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;native2ascii-maven-plugin&amp;lt;/artifactId&amp;gt;
                &amp;lt;dependencies&amp;gt;
                    &amp;lt;dependency&amp;gt;
                      &amp;lt;groupId&amp;gt;com.sun&amp;lt;/groupId&amp;gt;
                      &amp;lt;artifactId&amp;gt;tools&amp;lt;/artifactId&amp;gt;
                      &amp;lt;version&amp;gt;1.7.0&amp;lt;/version&amp;gt;
                      &amp;lt;scope&amp;gt;system&amp;lt;/scope&amp;gt;
                      &amp;lt;systemPath&amp;gt;${java.home}/../lib/tools.jar&amp;lt;/systemPath&amp;gt;
                    &amp;lt;/dependency&amp;gt;
                &amp;lt;/dependencies&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
&amp;lt;/profile&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The next issue was with &lt;a href=&quot;http://enunciate.codehaus.org&quot;&gt;Enunciate&lt;/a&gt; and its maven-enunciate-cxf-plugin. 
&lt;/p&gt;
&lt;pre&gt;
[INFO] ------------------------------------------------------------------------
[ERROR] FATAL ERROR
[INFO] ------------------------------------------------------------------------
[INFO] com/sun/mirror/apt/AnnotationProcessorFactory
com.sun.mirror.apt.AnnotationProcessorFactory
[INFO] ------------------------------------------------------------------------
[INFO] Trace
java.lang.NoClassDefFoundError: com/sun/mirror/apt/AnnotationProcessorFactory
&lt;/pre&gt;
&lt;p&gt;It seemed like adding a profile that included tools.jar would solve this, but &lt;a href=&quot;http://markmail.org/message/kshhtwjlsgtwlvu3&quot;&gt;it doesn&apos;t&lt;/a&gt;. When I add the dependency directly to the plugin itself, I get the following error:
&lt;/p&gt;
&lt;pre&gt;
warning: The apt tool and its associated API are planned to be
removed in the next major JDK release.  These features have been
superseded by javac and the standardized annotation processing API,
javax.annotation.processing and javax.lang.model.  Users are
recommended to migrate to the annotation processing features of
javac; see the javac man page for more information.
[WARNING] Validation result has errors.
error: [core] java.lang.StackTraceElement: A TypeDefinition must have a public no-arg constructor or be annotated with a factory method.
1 error
[INFO] ------------------------------------------------------------------------
[ERROR] BUILD ERROR
[INFO] ------------------------------------------------------------------------
&lt;/pre&gt;
&lt;p&gt;Hopefully this article helps you get started with Java 7 on OS X. If you have any additional tips, please leave a comment.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/integrating_oauth_with_appfuse_and</id>
        <title type="html">Integrating OAuth with AppFuse and its REST API</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/integrating_oauth_with_appfuse_and"/>
        <published>2011-07-05T10:56:48-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rest" scheme="http://roller.apache.org/ns/tags/" />
        <category term="oauth" scheme="http://roller.apache.org/ns/tags/" />
        <category term="enunciate" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">One of the new features in &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_1_released&quot;&gt;AppFuse 2.1&lt;/a&gt; is an &lt;a href=&quot;http://issues.appfuse.org/browse/APF-897&quot;&gt;appfuse-ws&lt;/a&gt; archetype. This archetype leverages &lt;a href=&quot;http://enunciate.codehaus.org/&quot;&gt;Enunciate&lt;/a&gt; and &lt;a href=&quot;http://cxf.apache.org/&quot;&gt;CXF&lt;/a&gt; to create a project with a REST API and generated HTML documentation. Enunciate is a very useful tool, allowing you to develop web services with JAX-RS and JAX-WS annotations and have all types of client libraries generated. For me, it seems very useful for developing the backend of &lt;abbr title=&quot;Service Oriented Front End Applications&quot;&gt;SOFEA&lt;/abbr&gt; (a.k.a. modern) applications. &lt;/p&gt;
&lt;p&gt;Back in March, &lt;a href=&quot;http://www.java.net/blogs/stoicflame/&quot;&gt;Ryan Heaton&lt;/a&gt; published a nice article on &lt;a href=&quot;http://docs.codehaus.org/display/ENUNCIATE/Securing+Web+Services&quot;&gt;Securing Web Services&lt;/a&gt; in an Enunciate application. I decided to take his tutorial a step further and not only secure my web services, but also to integrate with  OAuth 2. In this tutorial, I&apos;ll show you how to create a new application with AppFuse WS, secure it, add OAuth support, and then use a client app to authenticate and retrieve data.&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#create-appfuse-ws&quot;&gt;Create a New AppFuse WS Project&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#integrate-oauth&quot;&gt;Integrate Spring Security and OAuth&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#oauth-client&quot;&gt;Authenticate and Retrieve Data with Client&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;create-appfuse-ws&quot;&gt;
&lt;strong&gt;Create a New AppFuse WS Project&lt;/strong&gt;&lt;br/&gt;
To begin, I visited the &lt;a href=&quot;http://static.appfuse.org/archetypes.html&quot;&gt;Create AppFuse Archetypes&lt;/a&gt; page and created a new application using the &quot;Web Services Only&quot; option in the &lt;em&gt;Web Framework&lt;/em&gt; dropdown. Below is the command I used to create the &quot;appfuse-oauth&quot; project.
&lt;/p&gt;
&lt;pre&gt;
mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes \
-DarchetypeArtifactId=appfuse-ws-archetype -DarchetypeVersion=2.1.0 \
-DgroupId=org.appfuse.example -DartifactId=appfuse-oauth 
&lt;/pre&gt;
&lt;p&gt;After doing this, I started the app using &lt;strong&gt;mvn jetty:run&lt;/strong&gt; and confirmed it started OK. At this point, I was able to view the generated documentation for the application at &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt;. The screenshot below shows what the app looks like at this point.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm7.static.flickr.com/6004/5891597325_7f9829e158.jpg&quot; title=&quot;AppFuse WS Homepage&quot; rel=&quot;lightbox[appfuse-oauth]&quot;&gt;&lt;img src=&quot;//farm7.static.flickr.com/6004/5891597325_7f9829e158_m.jpg&quot; width=&quot;240&quot; height=&quot;198&quot; alt=&quot;AppFuse WS Homepage&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;font-weight: italic; color: #666; margin-left: 10px&quot;&gt;
NOTE: You might notice the REST endpoint of /{username}. This is &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1246&quot; style=&quot;color: #666&quot;&gt;a bug&lt;/a&gt; in AppFuse 2.1.0 and has been fixed in SVN. It does not affect this tutorial.&lt;/p&gt;
&lt;p id=&quot;integrate-oauth&quot;&gt;
&lt;strong&gt;Integrate Spring Security and OAuth&lt;/strong&gt;&lt;br/&gt;
I originally tried to integrate Spring Security with Enunciate&apos;s &lt;a href=&quot;http://docs.codehaus.org/display/ENUNCIATE/Securing+Web+Services&quot;&gt;Securing Web Services Tutorial&lt;/a&gt;. However, it only secures endpoints and doesn&apos;t do enough filtering for OAuth support, so I ended up using a custom web.xml. I put this file in &lt;em&gt;src/main/resources&lt;/em&gt; and loaded it in my &lt;em&gt;enunciate.xml&lt;/em&gt; file. I also upgraded Spring Security and imported my security.xml file.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
  &amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;
  &amp;lt;enunciate xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
             xsi:noNamespaceSchemaLocation=&quot;http://enunciate.codehaus.org/schemas/enunciate-1.22.xsd&quot;&amp;gt;
      ...
      &amp;lt;webapp mergeWebXML=&quot;src/main/resources/web.xml&quot;/&amp;gt;
      &amp;lt;modules&amp;gt;
      ...
          &amp;lt;spring-app disabled=&quot;false&quot; springVersion=&quot;3.0.5.RELEASE&quot;&amp;gt;
              &amp;lt;springImport uri=&quot;classpath:/applicationContext-resources.xml&quot;/&amp;gt;
              &amp;lt;springImport uri=&quot;classpath:/applicationContext-dao.xml&quot;/&amp;gt;
              &amp;lt;springImport uri=&quot;classpath:/applicationContext-service.xml&quot;/&amp;gt;
              &amp;lt;springImport uri=&quot;classpath:/applicationContext.xml&quot;/&amp;gt;
              &amp;lt;springImport uri=&quot;classpath:/security.xml&quot;/&amp;gt;
          &amp;lt;/spring-app&amp;gt;
      &amp;lt;/modules&amp;gt;
  &amp;lt;/enunciate&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Then I created &lt;em&gt;src/main/resources/web.xml&lt;/em&gt; with a filter for Spring Security and a DispatcherServlet for OAuth support.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;web-app xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
         xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd&quot;
         version=&quot;3.0&quot;&amp;gt;

    &amp;lt;filter&amp;gt;
        &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
        &amp;lt;filter-class&amp;gt;org.springframework.web.filter.DelegatingFilterProxy&amp;lt;/filter-class&amp;gt;
        &amp;lt;init-param&amp;gt;
            &amp;lt;param-name&amp;gt;targetBeanName&amp;lt;/param-name&amp;gt;
            &amp;lt;param-value&amp;gt;springSecurityFilterChain&amp;lt;/param-value&amp;gt;
        &amp;lt;/init-param&amp;gt;
    &amp;lt;/filter&amp;gt;

    &amp;lt;filter-mapping&amp;gt;
        &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/filter-mapping&amp;gt;

    &amp;lt;servlet&amp;gt;
        &amp;lt;servlet-name&amp;gt;appfuse-oauth&amp;lt;/servlet-name&amp;gt;
        &amp;lt;servlet-class&amp;gt;org.springframework.web.servlet.DispatcherServlet&amp;lt;/servlet-class&amp;gt;
        &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
    &amp;lt;/servlet&amp;gt;

    &amp;lt;servlet-mapping&amp;gt;
        &amp;lt;servlet-name&amp;gt;appfuse-oauth&amp;lt;/servlet-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/oauth/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/servlet-mapping&amp;gt;
&amp;lt;/web-app&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Next, I created a &lt;em&gt;src/main/resources/security.xml&lt;/em&gt; and used it to secure my API, specify a login page, supply the users and integrate OAuth (see the last 4 beans below). &lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;
             xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
             xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
             xmlns:oauth=&quot;http://www.springframework.org/schema/security/oauth2&quot;
             xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security.xsd
                           http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd&quot;&amp;gt;

    &amp;lt;http auto-config=&quot;true&quot;&amp;gt;
        &amp;lt;intercept-url pattern=&quot;/api/**&quot; access=&quot;ROLE_USER&quot;/&amp;gt;
        &amp;lt;intercept-url pattern=&quot;/oauth/**&quot; access=&quot;ROLE_USER&quot;/&amp;gt;
        &amp;lt;intercept-url pattern=&quot;/**&quot; access=&quot;IS_AUTHENTICATED_ANONYMOUSLY&quot;/&amp;gt;
        &amp;lt;form-login login-page=&quot;/login.jsp&quot; authentication-failure-url=&quot;/login.jsp?error=true&quot;
                    login-processing-url=&quot;/j_security_check&quot;/&amp;gt;
    &amp;lt;/http&amp;gt;

    &amp;lt;authentication-manager&amp;gt;
        &amp;lt;authentication-provider&amp;gt;
            &amp;lt;user-service&amp;gt;
                &amp;lt;user name=&quot;admin&quot; password=&quot;admin&quot; authorities=&quot;ROLE_USER,ROLE_ADMIN&quot;/&amp;gt;
                &amp;lt;user name=&quot;user&quot; password=&quot;user&quot; authorities=&quot;ROLE_USER&quot;/&amp;gt;
            &amp;lt;/user-service&amp;gt;
        &amp;lt;/authentication-provider&amp;gt;
    &amp;lt;/authentication-manager&amp;gt;

    &amp;lt;!--hook up the spring security filter chain--&amp;gt;
    &amp;lt;beans:alias name=&quot;springSecurityFilterChain&quot; alias=&quot;securityFilter&quot;/&amp;gt;

    &amp;lt;beans:bean id=&quot;tokenServices&quot;
                class=&quot;org.springframework.security.oauth2.provider.token.InMemoryOAuth2ProviderTokenServices&quot;&amp;gt;
        &amp;lt;beans:property name=&quot;supportRefreshToken&quot; value=&quot;true&quot;/&amp;gt;
    &amp;lt;/beans:bean&amp;gt;

    &amp;lt;oauth:provider client-details-service-ref=&quot;clientDetails&quot; token-services-ref=&quot;tokenServices&quot;&amp;gt;
        &amp;lt;oauth:verification-code user-approval-page=&quot;/oauth/confirm_access&quot;/&amp;gt;
    &amp;lt;/oauth:provider&amp;gt;

    &amp;lt;oauth:client-details-service id=&quot;clientDetails&quot;&amp;gt;
        &amp;lt;!--&amp;lt;oauth:client clientId=&quot;my-trusted-client&quot; authorizedGrantTypes=&quot;password,authorization_code,refresh_token&quot;/&amp;gt;
        &amp;lt;oauth:client clientId=&quot;my-trusted-client-with-secret&quot;
                      authorizedGrantTypes=&quot;password,authorization_code,refresh_token&quot; secret=&quot;somesecret&quot;/&amp;gt;
        &amp;lt;oauth:client clientId=&quot;my-less-trusted-client&quot; authorizedGrantTypes=&quot;authorization_code&quot;/&amp;gt;--&amp;gt;
        &amp;lt;oauth:client clientId=&quot;ajax-login&quot; authorizedGrantTypes=&quot;authorization_code&quot;/&amp;gt;
    &amp;lt;/oauth:client-details-service&amp;gt;
&amp;lt;/beans:beans&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I used the &lt;a href=&quot;http://static.springsource.org/spring-security/oauth/tutorial.html&quot;&gt;OAuth for Spring Security sample apps&lt;/a&gt; to figure this out. In this example, I used authorizedGrantTypes=&quot;authorization_code&quot;, but you can see from the commented &amp;lt;oauth:client&gt; elements above that there&apos;s a few different options. You should also note that the clientId is hard-coded to &quot;ajax-login&quot;, signifying I only want to allow a single application to authenticate.
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;At this point, I&apos;d like to give a shoutout to Ryan Heaton for creating &lt;em&gt;both&lt;/em&gt; Enunciate and Spring Security&apos;s OAuth support. Nice work Ryan!&lt;/p&gt;
&lt;p&gt;At this point, I needed to do a number of additional tasks to finish integrating oauth. The first was to modify the Jetty Plugin&apos;s configuration to 1) run on port 9000, 2) load my custom files and 3) allow jetty:run to recognize Enunciate&apos;s generated files. Below is the final configuration in my pom.xml.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;maven-jetty-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;6.1.26&amp;lt;/version&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;connectors&amp;gt;
            &amp;lt;connector implementation=&quot;org.mortbay.jetty.nio.SelectChannelConnector&quot;&amp;gt;
                &amp;lt;port&amp;gt;9000&amp;lt;/port&amp;gt;
                &amp;lt;maxIdleTime&amp;gt;60000&amp;lt;/maxIdleTime&amp;gt;
            &amp;lt;/connector&amp;gt;
        &amp;lt;/connectors&amp;gt;
        &amp;lt;webAppConfig&amp;gt;
            &amp;lt;baseResource implementation=&quot;org.mortbay.resource.ResourceCollection&quot;&amp;gt;
                &amp;lt;resourcesAsCSV&amp;gt;
                    ${basedir}/src/main/webapp,
                    ${project.build.directory}/${project.build.finalName}
                &amp;lt;/resourcesAsCSV&amp;gt;
            &amp;lt;/baseResource&amp;gt;
            &amp;lt;contextPath&amp;gt;/appfuse-oauth&amp;lt;/contextPath&amp;gt;
        &amp;lt;/webAppConfig&amp;gt;
        &amp;lt;webXml&amp;gt;${project.build.directory}/${project.build.finalName}/WEB-INF/web.xml&amp;lt;/webXml&amp;gt;
    &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Next, I added the necessary OAuth dependencies for Spring Security to my pom.xml. Since the latest release is a milestone release, I had to add Spring&apos;s milestone repo too. 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;repository&amp;gt;
    &amp;lt;id&amp;gt;spring-milestone&amp;lt;/id&amp;gt;
    &amp;lt;url&amp;gt;http://s3.amazonaws.com/maven.springframework.org/milestone&amp;lt;/url&amp;gt;
&amp;lt;/repository&amp;gt;
...
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.security&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-security-taglibs&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${spring.version}&amp;lt;/version&amp;gt;
    &amp;lt;exclusions&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-support&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
    &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.security.oauth&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-security-oauth&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0.M3&amp;lt;/version&amp;gt;
    &amp;lt;exclusions&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-beans&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-context&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-core&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
    &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-webmvc&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${spring.version}&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;javax.servlet&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;servlet-api&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.5&amp;lt;/version&amp;gt;
    &amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;javax.servlet&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jstl&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.1.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;taglibs&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;standard&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.1.2&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Since I named my DispatcherServlet &quot;appfuse-oauth&quot; in web.xml, I created a &lt;em&gt;src/main/webapp/WEB-INF/appfuse-oauth-servlet.xml&lt;/em&gt; to configure Spring MVC. I had to create the &lt;em&gt;src/main/webapp/WEB-INF&lt;/em&gt; directory. &lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans xmlns=&quot;http://www.springframework.org/schema/beans&quot;
       xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
       xmlns:context=&quot;http://www.springframework.org/schema/context&quot;
       xmlns:mvc=&quot;http://www.springframework.org/schema/mvc&quot;
       xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
                http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd&quot;&amp;gt;

    &amp;lt;!-- Scans the classpath of this application for @Components to deploy as beans --&amp;gt;
    &amp;lt;context:component-scan base-package=&quot;org.appfuse.examples.webapp&quot;/&amp;gt;

    &amp;lt;!-- Configures the @Controller programming model --&amp;gt;
    &amp;lt;mvc:annotation-driven/&amp;gt;

    &amp;lt;!-- Resolves view names to protected .jsp resources within the /WEB-INF/views directory --&amp;gt;
    &amp;lt;bean class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&quot;&amp;gt;
        &amp;lt;property name=&quot;viewClass&quot; value=&quot;org.springframework.web.servlet.view.JstlView&quot;/&amp;gt;
        &amp;lt;property name=&quot;prefix&quot; value=&quot;/&quot;/&amp;gt;
        &amp;lt;property name=&quot;suffix&quot; value=&quot;.jsp&quot;/&amp;gt;
    &amp;lt;/bean&amp;gt;
&amp;lt;/beans&amp;gt;
&lt;/pre&gt;
&lt;p&gt;In order to show the OAuth confirmation page, I needed to create &lt;em&gt;src/main/java/org/appfuse/examples/webapp/AccessConfirmationController.java&lt;/em&gt; and map it to /oauth/confirm_access. I copied this from one of the sample projects and modified to use Spring&apos;s annotations.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package org.appfuse.examples.webapp;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.oauth2.provider.ClientAuthenticationToken;
import org.springframework.security.oauth2.provider.ClientDetails;
import org.springframework.security.oauth2.provider.ClientDetailsService;
import org.springframework.security.oauth2.provider.verification.ClientAuthenticationCache;
import org.springframework.security.oauth2.provider.verification.DefaultClientAuthenticationCache;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.TreeMap;

/**
 * Controller for retrieving the model for and displaying the confirmation page
 * for access to a protected resource.
 *
 * @author Ryan Heaton
 */
@Controller
@RequestMapping(&quot;/confirm_access&quot;)
public class AccessConfirmationController {

    private ClientAuthenticationCache authenticationCache = new DefaultClientAuthenticationCache();
    @Autowired
    private ClientDetailsService clientDetailsService;

    @RequestMapping(method = RequestMethod.GET)
    protected ModelAndView confirm(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ClientAuthenticationToken clientAuth = authenticationCache.getAuthentication(request, response);
        if (clientAuth == null) {
            throw new IllegalStateException(&quot;No client authentication request to authorize.&quot;);
        }

        TreeMap&amp;lt;String, Object&amp;gt; model = new TreeMap&amp;lt;String, Object&amp;gt;();
        ClientDetails client = clientDetailsService.loadClientByClientId(clientAuth.getClientId());
        model.put(&quot;auth_request&quot;, clientAuth);
        model.put(&quot;client&quot;, client);

        return new ModelAndView(&quot;access_confirmation&quot;, model);
    }
}
&lt;/pre&gt;
&lt;p&gt;This controller delegates to &lt;em&gt;src/main/webapp/access_confirmation.jsp&lt;/em&gt;. I created this file and filled it with code to display Accept and Deny buttons.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;%@ page import=&quot;org.springframework.security.core.AuthenticationException&quot; %&amp;gt;
&amp;lt;%@ page import=&quot;org.springframework.security.oauth2.common.exceptions.UnapprovedClientAuthenticationException&quot; %&amp;gt;
&amp;lt;%@ page import=&quot;org.springframework.security.oauth2.provider.verification.BasicUserApprovalFilter&quot; %&amp;gt;
&amp;lt;%@ page import=&quot;org.springframework.security.oauth2.provider.verification.VerificationCodeFilter&quot; %&amp;gt;
&amp;lt;%@ page import=&quot;org.springframework.security.web.WebAttributes&quot; %&amp;gt;
&amp;lt;%@ taglib prefix=&quot;authz&quot; uri=&quot;http://www.springframework.org/security/tags&quot; %&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;
&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Confirm Access&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;all&quot;
          href=&quot;http://demo.appfuse.org/appfuse-struts/styles/simplicity/theme.css&quot;/&amp;gt;
    &amp;lt;style type=&quot;text/css&quot;&amp;gt;
        h1 {
            margin-left: -300px;
            margin-top: 50px
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;

&amp;lt;body&amp;gt;

&amp;lt;h1&amp;gt;Confirm Access&amp;lt;/h1&amp;gt;

&amp;lt;div id=&quot;content&quot;&amp;gt;

    &amp;lt;% if (session.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION) != null &amp;amp;&amp;amp; 
                 !(session.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION) instanceof UnapprovedClientAuthenticationException)) { %&amp;gt;
    &amp;lt;div class=&quot;error&quot;&amp;gt;
        &amp;lt;h2&amp;gt;Woops!&amp;lt;/h2&amp;gt;

        &amp;lt;p&amp;gt;Access could not be granted.
            (&amp;lt;%= ((AuthenticationException) session.getAttribute(WebAttributes.AUTHENTICATION_EXCEPTION)).getMessage() %&amp;gt;)&amp;lt;/p&amp;gt;
    &amp;lt;/div&amp;gt;
    &amp;lt;% } %&amp;gt;
    &amp;lt;c:remove scope=&quot;session&quot; var=&quot;SPRING_SECURITY_LAST_EXCEPTION&quot;/&amp;gt;

    &amp;lt;authz:authorize ifAnyGranted=&quot;ROLE_USER,ROLE_ADMIN&quot;&amp;gt;
        &amp;lt;h2&amp;gt;Please Confirm&amp;lt;/h2&amp;gt;

        &amp;lt;p&amp;gt;You hereby authorize &quot;&amp;lt;c:out value=&quot;${client.clientId}&quot; escapeXml=&quot;true&quot;/&amp;gt;&quot; to access your protected resources.&amp;lt;/p&amp;gt;

        &amp;lt;form id=&quot;confirmationForm&quot; name=&quot;confirmationForm&quot;
              action=&quot;&amp;lt;%=request.getContextPath() + VerificationCodeFilter.DEFAULT_PROCESSING_URL%&amp;gt;&quot; method=&quot;POST&quot;&amp;gt;
            &amp;lt;input name=&quot;&amp;lt;%=BasicUserApprovalFilter.DEFAULT_APPROVAL_REQUEST_PARAMETER%&amp;gt;&quot;
                   value=&quot;&amp;lt;%=BasicUserApprovalFilter.DEFAULT_APPROVAL_PARAMETER_VALUE%&amp;gt;&quot; type=&quot;hidden&quot;/&amp;gt;
            &amp;lt;label&amp;gt;&amp;lt;input name=&quot;authorize&quot; value=&quot;Authorize&quot; type=&quot;submit&quot;&amp;gt;&amp;lt;/label&amp;gt;
        &amp;lt;/form&amp;gt;
        &amp;lt;form id=&quot;denialForm&quot; name=&quot;denialForm&quot;
              action=&quot;&amp;lt;%=request.getContextPath() + VerificationCodeFilter.DEFAULT_PROCESSING_URL%&amp;gt;&quot; method=&quot;POST&quot;&amp;gt;
            &amp;lt;input name=&quot;&amp;lt;%=BasicUserApprovalFilter.DEFAULT_APPROVAL_REQUEST_PARAMETER%&amp;gt;&quot;
                   value=&quot;not_&amp;lt;%=BasicUserApprovalFilter.DEFAULT_APPROVAL_PARAMETER_VALUE%&amp;gt;&quot; type=&quot;hidden&quot;/&amp;gt;
            &amp;lt;label&amp;gt;&amp;lt;input name=&quot;deny&quot; value=&quot;Deny&quot; type=&quot;submit&quot;&amp;gt;&amp;lt;/label&amp;gt;
        &amp;lt;/form&amp;gt;
    &amp;lt;/authz:authorize&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Finally, I needed to create &lt;em&gt;src/main/webapp/login.jsp&lt;/em&gt; to allow users to login.&lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;%@ page language=&quot;java&quot; pageEncoding=&quot;UTF-8&quot; contentType=&quot;text/html;charset=utf-8&quot; %&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/fmt&quot; prefix=&quot;fmt&quot; %&amp;gt;
&amp;lt;%@ taglib uri=&quot;http://java.sun.com/jsp/jstl/core&quot; prefix=&quot;c&quot; %&amp;gt;

&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;Login&amp;lt;/title&amp;gt;
    &amp;lt;link rel=&quot;stylesheet&quot; type=&quot;text/css&quot; media=&quot;all&quot;
          href=&quot;http://demo.appfuse.org/appfuse-struts/styles/simplicity/theme.css&quot;/&amp;gt;
    &amp;lt;style type=&quot;text/css&quot;&amp;gt;
        h1 {
            margin-left: -300px;
            margin-top: 50px
        }
    &amp;lt;/style&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;Login&amp;lt;/h1&amp;gt;

&amp;lt;form method=&quot;post&quot; id=&quot;loginForm&quot; action=&quot;&amp;lt;c:url value=&apos;/j_security_check&apos;/&amp;gt;&quot;&amp;gt;
    &amp;lt;fieldset style=&quot;padding-bottom: 0&quot;&amp;gt;
        &amp;lt;ul&amp;gt;
            &amp;lt;c:if test=&quot;${param.error != null}&quot;&amp;gt;
                &amp;lt;li class=&quot;error&quot;&amp;gt;
                    ${sessionScope.SPRING_SECURITY_LAST_EXCEPTION.message}
                &amp;lt;/li&amp;gt;
            &amp;lt;/c:if&amp;gt;
            &amp;lt;li&amp;gt;
                &amp;lt;label for=&quot;j_username&quot; class=&quot;required desc&quot;&amp;gt;
                    Username &amp;lt;span class=&quot;req&quot;&amp;gt;*&amp;lt;/span&amp;gt;
                &amp;lt;/label&amp;gt;
                &amp;lt;input type=&quot;text&quot; class=&quot;text medium&quot; name=&quot;j_username&quot;
                       id=&quot;j_username&quot; tabindex=&quot;1&quot;/&amp;gt;
            &amp;lt;/li&amp;gt;

            &amp;lt;li&amp;gt;
                &amp;lt;label for=&quot;j_password&quot; class=&quot;required desc&quot;&amp;gt;
                    Password &amp;lt;span class=&quot;req&quot;&amp;gt;*&amp;lt;/span&amp;gt;
                &amp;lt;/label&amp;gt;
                &amp;lt;input type=&quot;password&quot; class=&quot;text medium&quot; name=&quot;j_password&quot;
                       id=&quot;j_password&quot; tabindex=&quot;2&quot;/&amp;gt;
            &amp;lt;/li&amp;gt;
            &amp;lt;li&amp;gt;
                &amp;lt;input type=&quot;submit&quot; class=&quot;button&quot; name=&quot;login&quot; value=&quot;Login&quot;
                       tabindex=&quot;3&quot;/&amp;gt;
            &amp;lt;/li&amp;gt;
        &amp;lt;/ul&amp;gt;
    &amp;lt;/fieldset&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/pre&gt;
&lt;p&gt;All the changes described in the above section are necessary to implement OAuth if you create a project with AppFuse WS 2.1. It may seem like a lot of code, but I was able to copy/paste and get it all working in an app in under 5 minutes. Hopefully you can do the same. I&apos;m also considering adding it by default to the next version of AppFuse. Now let&apos;s look at integrating OAuth into a client to authenticate and retrieve data from this application.
&lt;/p&gt;
&lt;p id=&quot;oauth-client&quot;&gt;&lt;strong&gt;Authenticate and Retrieve Data with Client&lt;/strong&gt;&lt;br/&gt;
I originally thought my &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_oauth_with_gwt&quot;&gt;GWT OAuth&lt;/a&gt; application would provide a nice client. However, after 30 minutes of trying to get GWT 1.7.1 and the GWT Maven plugin (1.1) working with my 64-bit Java 6 JDK on OS X, I gave up. So I opted to use the &lt;a href=&quot;https://github.com/mraible/ajax-login&quot;&gt;Ajax Login&lt;/a&gt; application I&apos;ve been using in my recent security tutorials.
&lt;/p&gt;
&lt;p&gt;In this example, I used OAuth2RestTemplate from Spring Security OAuth. While this works, and works well, I&apos;d still like to get things working with GWT (or jQuery) to demonstrate how to do it from a pure client-side perspective.
&lt;/p&gt;
&lt;p&gt;To begin, I got the latest source of Ajax Login from GitHub (as of this morning) and made some changes. First of all, I added the Spring Security OAuth dependencies to pom.xml:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;repository&amp;gt;
    &amp;lt;id&amp;gt;spring-milestone&amp;lt;/id&amp;gt;
    &amp;lt;url&amp;gt;http://s3.amazonaws.com/maven.springframework.org/milestone&amp;lt;/url&amp;gt;
&amp;lt;/repository&amp;gt;
...
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.security.oauth&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-security-oauth&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0.0.M3&amp;lt;/version&amp;gt;
    &amp;lt;exclusions&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-beans&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-context&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
        &amp;lt;exclusion&amp;gt;
            &amp;lt;groupId&amp;gt;org.springframework&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;spring-core&amp;lt;/artifactId&amp;gt;
        &amp;lt;/exclusion&amp;gt;
    &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Then I modified &lt;em&gt;src/main/webapp/WEB-INF/security.xml&lt;/em&gt; and added an OAuth Token Service and defined the location of the OAuth server.&lt;/p&gt; 
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;
             xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
             xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
             xmlns:oauth=&quot;http://www.springframework.org/schema/security/oauth2&quot;
             xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
              http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
              http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2.xsd&quot;&amp;gt;

...
    &amp;lt;oauth:client token-services-ref=&quot;oauth2TokenServices&quot;/&amp;gt;

    &amp;lt;beans:bean id=&quot;oauth2TokenServices&quot;
                class=&quot;org.springframework.security.oauth2.consumer.token.InMemoryOAuth2ClientTokenServices&quot;/&amp;gt;

    &amp;lt;oauth:resource id=&quot;appfuse&quot; type=&quot;authorization_code&quot; clientId=&quot;ajax-login&quot;
                    accessTokenUri=&quot;http://localhost:9000/appfuse-oauth/oauth/authorize&quot;
                    userAuthorizationUri=&quot;http://localhost:9000/appfuse-oauth/oauth/user/authorize&quot;/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Next, I created a Controller that uses OAuth2RestTemplate to make the request and get the data from the AppFuse OAuth application&apos;s API. I created &lt;em&gt;src/main/java/org/appfuse/examples/webapp/oauth/UsersApiController.java&lt;/em&gt; and filled it with the following code:&lt;/p&gt;
&lt;pre class=&quot;brush: java; auto-links: false&quot;&gt;
package org.appfuse.examples.webapp.oauth;

import org.appfuse.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.oauth2.common.exceptions.InvalidTokenException;
import org.springframework.security.oauth2.consumer.*;
import org.springframework.security.oauth2.consumer.token.OAuth2ClientTokenServices;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;
import java.util.List;

@RequestMapping(&quot;/appfuse/users&quot;)
@Controller
public class UsersApiController {

    private OAuth2RestTemplate apiRestTemplate;
    @Autowired
    private OAuth2ClientTokenServices tokenServices;

    private static final String REMOTE_DATA_URL = &quot;http://localhost:9000/appfuse-oauth/api/users&quot;;

    @Autowired
    public UsersApiController(OAuth2ProtectedResourceDetails resourceDetails) {
        this.apiRestTemplate = new OAuth2RestTemplate(resourceDetails);
    }

    @RequestMapping(method = RequestMethod.GET)
    @ResponseBody
    public List&amp;lt;User&amp;gt; getUsers() {
        try {
            List users = apiRestTemplate.getForObject(REMOTE_DATA_URL, List.class);
            return new ArrayList&amp;lt;User&amp;gt;(users);
        } catch (InvalidTokenException badToken) {
            //we&apos;ve got a bad token, probably because it&apos;s expired.
            OAuth2ProtectedResourceDetails resource = apiRestTemplate.getResource();
            OAuth2SecurityContext context = OAuth2SecurityContextHolder.getContext();
            if (context != null) {
                // this one is kind of a hack for this application
                // the problem is that the sparklr photos page doesn&apos;t remove the &apos;code=&apos; request parameter.
                ((OAuth2SecurityContextImpl) context).setVerificationCode(null);
            }
            //clear any stored access tokens...
            tokenServices.removeToken(SecurityContextHolder.getContext().getAuthentication(), resource);
            //go get a new access token...
            throw new OAuth2AccessTokenRequiredException(resource);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;At this point, I thought everything would work and I spent quite some time banging my head against the wall when it didn&apos;t. As I was composing an email to the Enunciate users mailing list, I realized the issue. It appeared to be working, but from the server side, and the redirect back to the client was not happening. The Ajax Login app uses UrlRewriteFilter (for pretty URLs) to redirect from /app/* to /$1 and this redirect was losing the code parameter in the URL. 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule&amp;gt;
    &amp;lt;from&amp;gt;/app/**&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;true&quot; type=&quot;redirect&quot;&amp;gt;%{context-path}/$1&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To fix this, I added use-query-string=&quot;true&quot; to the root element in &lt;em&gt;src/main/webapp/WEB-INF/urlrewrite.xml&lt;/em&gt;:
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;urlrewrite default-match-type=&quot;wildcard&quot; use-query-string=&quot;true&quot;&gt;
&lt;/pre&gt;
&lt;p&gt;After making all these changes, I ran &lt;strong&gt;mvn jetty:run&lt;/strong&gt; on both apps and opened &lt;a href=&quot;http://localhost:8080/appfuse/users&quot;&gt;http://localhost:8080/appfuse/users&lt;/a&gt; in my browser. It all worked and a smile crept across my face. I&apos;ve checked in the client changes into &lt;a href=&quot;https://github.com/mraible/ajax-login&quot;&gt;ajax-login on GitHub&lt;/a&gt; and the appfuse-oauth example into &lt;a href=&quot;http://code.google.com/p/appfuse-demos/&quot;&gt;AppFuse Demos on Google Code&lt;/a&gt;. If you&apos;d like to see this example in action, I&apos;d encourage you to checkout both projects and let me know if you find any issues.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/java_web_application_security_part2</id>
        <title type="html">Java Web Application Security - Part III: Apache Shiro Login Demo</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/java_web_application_security_part2"/>
        <published>2011-05-26T16:43:22-06:00</published>
        <updated>2015-07-07T01:37:14-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="presentation" scheme="http://roller.apache.org/ns/tags/" />
        <category term="web" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="apacheshiro" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ujug" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">A couple weeks ago, I wrote &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part1&quot;&gt;a tutorial on how to implement security with Spring Security&lt;/a&gt;. The week prior, I wrote a &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part&quot;&gt;similar tutorial for Java EE 6&lt;/a&gt;. This week, I&apos;d like to show you how to implement the same features using &lt;a href=&quot;http://shiro.apache.org&quot;&gt;Apache Shiro&lt;/a&gt;. As I mentioned in previous articles, I&apos;m writing this because I told the audience at April&apos;s &lt;a href=&quot;http://ujug.org&quot;&gt;UJUG&lt;/a&gt; that I would publish screencasts of the demos.
&lt;/p&gt;
&lt;p&gt;
Today, I&apos;ve finished the third screencast showing how to implement security with Apache Shiro. Below is the presentation (with the screencast embedded on slide 22) as well as a step-by-step tutorial.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/o4wwswiZck6bKS&quot; width=&quot;510&quot; height=&quot;420&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; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen&gt; &lt;/iframe&gt;
&lt;br/&gt;
&lt;div style=&quot;font-size: .9em; text-align: left&quot;&gt;* You can also &lt;a href=&quot;http://www.youtube.com/watch?v=YJByiDvOhsc&quot;&gt;watch the screencast on YouTube&lt;/a&gt; or &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Java_Web_Application_Security_UJUG2011.pdf&quot;&gt;download the presentation PDF&lt;/a&gt;.&lt;/div&gt;
&lt;/p&gt;

&lt;p id=&quot;apacheshiro-login-tutorial&quot;&gt;&lt;strong&gt;Apache Shiro Login Tutorial&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#download-run&quot;&gt;Download and Run the Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#secure-basic&quot;&gt;Implement Basic Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ssl&quot;&gt;Force SSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#form-authentication&quot;&gt;Implement Form-based Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jdbc&quot;&gt;Store Users in a Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#summary&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;download-run&quot;&gt;&lt;strong&gt;Download and Run the Application&lt;/strong&gt;&lt;br/&gt;

To begin, &lt;a href=&quot;http://static.raibledesigns.com/downloads/ajax-login-apacheshiro-tutorial-1.0.zip&quot;&gt;download the application&lt;/a&gt; you&apos;ll be implementing security in. This app is a stripped-down version of the Ajax Login application I wrote for my article on &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery&quot;&gt;Implementing Ajax Authentication using jQuery, Spring Security and HTTPS&lt;/a&gt;. You&apos;ll need Java 6 and Maven installed to run the app. Run it using &lt;strong&gt;mvn jetty:run&lt;/strong&gt; and open &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; in your browser. You&apos;ll see it&apos;s a simple CRUD application for users and there&apos;s no login required to add or delete users.&lt;/p&gt;

&lt;p id=&quot;secure-basic&quot;&gt;&lt;strong&gt;Implement Basic Authentication&lt;/strong&gt;&lt;br/&gt;
  
The first step is to protect the list screen so people have to login to view users. To do this, you&apos;ll need to create a shiro.ini file Shiro&apos;s configuration. Create &lt;em&gt;src/main/resources/shiro.ini&lt;/em&gt; and populate it with the contents below:
&lt;/p&gt;
&lt;pre&gt;
[main]

[users]
admin = admin, ROLE_ADMIN

[roles]
ROLE_ADMIN = *

[urls]
/app/users = authcBasic
&lt;/pre&gt;
&lt;p&gt;You can see this file has four sections and is pretty simple to read and understand. For more information about what each section is for, check out &lt;a href=&quot;http://shiro.apache.org/configuration.html#Configuration-INISections&quot;&gt;Shiro&apos;s configuration documentation&lt;/a&gt;.
&lt;p&gt;Next, open &lt;em&gt;src/main/webapp/WEB-INF/web.xml&lt;/em&gt; and add Shiro&apos;s IniShiroFilter:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;org.apache.shiro.web.servlet.IniShiroFilter&amp;lt;/filter-class&amp;gt;
    &amp;lt;!-- no init-param means load the INI config from classpath:shiro.ini --&amp;gt;
&amp;lt;/filter&amp;gt;
&lt;/pre&gt;
&lt;p&gt;And add its filter-mapping just after the rewriteFilter in the filter-mappings section (order is important!):
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;rewriteFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;FORWARD&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;INCLUDE&amp;lt;/dispatcher&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
Then add Shiro&apos;s &lt;em&gt;core&lt;/em&gt; and &lt;em&gt;web&lt;/em&gt; dependencies to your pom.xml:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.shiro&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;shiro-core&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.1.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.shiro&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;shiro-web&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.1.0&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
At this point, if you restart Jetty (Ctrl+C and jetty:run again), you should be prompted to login when you click on the &quot;Users&quot; tab. Enter admin/admin to login. Apache Shiro is easier to configure than Spring Security out-of-the-box, mostly because it doesn&apos;t require XML.
&lt;/p&gt;
&lt;p&gt;After logging in, you can try to logout by clicking the &quot;Logout&quot; link in the top-right corner. This calls a LogoutController with the following code that logs the user out.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public void logout(HttpServletResponse response) throws ServletException, IOException {
    request.getSession().invalidate();
    response.sendRedirect(request.getContextPath()); 
}
&lt;/pre&gt; 
&lt;p class=&quot;quote&quot; style=&quot;font-style: italic; color: #666&quot;&gt;NOTE: Shiro doesn&apos;t currently have a way to logout with its API. However, &lt;a href=&quot;https://issues.apache.org/jira/browse/SHIRO-284&quot;&gt;it will be added in the 1.2 release&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You&apos;ll notice that clicking this link doesn&apos;t log you out, even though the session is invalidated. The only way to logout with basic authentication is to close the browser. In order to get the ability to logout, as well as to have more control over the look-and-feel of the login, you can implement form-based authentication.
  Before you implement form-based authentication, I&apos;d like to show you how easy it is to force SSL with Apache Shiro.
&lt;/p&gt;
&lt;p id=&quot;ssl&quot;&gt;&lt;strong&gt;Force SSL&lt;/strong&gt;&lt;br/&gt;
Apache Shiro allows you to force SSL on a URL by simply adding &quot;ssl[&lt;em&gt;port&lt;/em&gt;]&quot; to a URL in the [urls] section. If you don&apos;t specify the port, it will use the default port (443). I&apos;m not sure if it allows you to switch back to http like Spring Security&apos;s &lt;em&gt;requires-channel&lt;/em&gt;, but I don&apos;t think it does. Modify the URLs section of your &lt;em&gt;shiro.ini&lt;/em&gt; to have the following:
&lt;/p&gt;
&lt;pre&gt;[urls]
/app/users = ssl[8443],authc
&lt;/pre&gt;
&lt;p&gt;In order for this to work, you have to configure Jetty to listen on an SSL port. Add the following just after the jetty-maven-plugin&apos;s &amp;lt;/webAppConfig&amp;gt; element in your pom.xml:
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;connectors&amp;gt;
    &amp;lt;connector implementation=&quot;org.eclipse.jetty.server.nio.SelectChannelConnector&quot;&amp;gt;
        &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
        &amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;
    &amp;lt;/connector&amp;gt;
    &amp;lt;connector implementation=&quot;org.eclipse.jetty.server.ssl.SslSelectChannelConnector&quot;&amp;gt;
        &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
        &amp;lt;port&amp;gt;8443&amp;lt;/port&amp;gt;
        &amp;lt;maxIdleTime&amp;gt;60000&amp;lt;/maxIdleTime&amp;gt;
        &amp;lt;keystore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystore&amp;gt;
        &amp;lt;password&amp;gt;appfuse&amp;lt;/password&amp;gt;
        &amp;lt;keyPassword&amp;gt;appfuse&amp;lt;/keyPassword&amp;gt;
    &amp;lt;/connector&amp;gt;
&amp;lt;/connectors&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The keystore must be generated for Jetty to start successfully, so add the keytool-maven-plugin just above the jetty-maven-plugin in pom.xml.
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;keytool-maven-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;phase&amp;gt;generate-resources&amp;lt;/phase&amp;gt;
            &amp;lt;id&amp;gt;clean&amp;lt;/id&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;clean&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;phase&amp;gt;generate-resources&amp;lt;/phase&amp;gt;
            &amp;lt;id&amp;gt;genkey&amp;lt;/id&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;genkey&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
    &amp;lt;/executions&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;keystore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystore&amp;gt;
        &amp;lt;dname&amp;gt;cn=localhost&amp;lt;/dname&amp;gt;
        &amp;lt;keypass&amp;gt;appfuse&amp;lt;/keypass&amp;gt;
        &amp;lt;storepass&amp;gt;appfuse&amp;lt;/storepass&amp;gt;
        &amp;lt;alias&amp;gt;appfuse&amp;lt;/alias&amp;gt;
        &amp;lt;keyalg&amp;gt;RSA&amp;lt;/keyalg&amp;gt;
    &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now if you restart Jetty, go to &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; and click on the &quot;Users&quot; tab, you&apos;ll be prompted to accept the Untrusted Certificate and then redirected to https://localhost:8443/users after logging in. 
&lt;/p&gt;
&lt;p&gt;Now let&apos;s look at how to have more control over the look-and-feel of the login screen, as well as how to make logout work with form-based authentication.&lt;/p&gt;
&lt;p id=&quot;form-authentication&quot;&gt;&lt;strong&gt;Implement Form-based Authentication&lt;/strong&gt;&lt;br/&gt;
To change from basic to form-based authentication, you simply have to add a few lines to shiro.ini. First of all, since I&apos;d rather not change the name of the input elements in login.jsp, override the default names in the [main] section:
&lt;/p&gt;
&lt;pre&gt;
# name of request parameter with username; if not present filter assumes &apos;username&apos;
authc.usernameParam = j_username
# name of request parameter with password; if not present filter assumes &apos;password&apos;
authc.passwordParam = j_password
authc.failureKeyAttribute = shiroLoginFailure
&lt;/pre&gt;
&lt;p&gt;Then change the [urls] section to filter on login.jsp and use &quot;authc&quot; instead of &quot;authcBasic&quot;:
&lt;pre&gt;[urls]
# The /login.jsp is not restricted to authenticated users (otherwise no one could log in!), but
# the &apos;authc&apos; filter must still be specified for it so it can process that url&apos;s
# login submissions. It is &apos;smart&apos; enough to allow those requests through as specified by the
# shiro.loginUrl above.
/login.jsp = authc
/app/users = ssl[8443],authc
&lt;/pre&gt;
&lt;p&gt;Then change login.jsp so the form&apos;s action is blank (causing it to submit to itself) instead of j_security_check:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;form action=&quot;&quot; id=&quot;loginForm&quot; method=&quot;post&quot;&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now, restart Jetty and you should be prompted to login with this JSP instead of the basic authentication dialog.
&lt;/p&gt;
&lt;p id=&quot;jdbc&quot;&gt;&lt;strong&gt;Store Users in a Database&lt;/strong&gt;&lt;br/&gt;
To store your users in a database instead of file, you&apos;ll need to add a few settings to shiro.ini to define your database and tables to use. Open &lt;em&gt;src/main/resources/shiro.ini&lt;/em&gt; and add the following lines under the [main] section.
&lt;/p&gt;
&lt;pre&gt;
jdbcRealm=org.apache.shiro.realm.jdbc.JdbcRealm
#jdbcRealm.permissionsLookupEnabled=false
# If not filled, subclasses of JdbcRealm assume &quot;select password from users where username = ?&quot;
jdbcRealm.authenticationQuery = select user_pass from users where user_name = ?
# If not filled, subclasses of JdbcRealm assume &quot;select role_name from user_roles where username = ?&quot;
jdbcRealm.userRolesQuery = select role_name from users_roles where user_name = ?

ds = com.mysql.jdbc.jdbc2.optional.MysqlDataSource
ds.serverName = localhost
ds.user = root
ds.databaseName = appfuse
jdbcRealm.dataSource = $ds
&lt;/pre&gt;
&lt;p class=&quot;quote&quot; style=&quot;margin-left: 0; color: #666&quot;&gt;This configuration is similar to what I did with the Java EE 6 tutorial where I&apos;m pointing to a database other than the H2 instance that&apos;s used by the application. I believe Shiro can talk to a DAO like Spring Security, but I have yet to explore that option.
&lt;/p&gt;
&lt;p&gt;While you&apos;re at it, add the following lines to enable password encryption.&lt;/p&gt;
&lt;pre&gt;
sha256Matcher = org.apache.shiro.authc.credential.Sha256CredentialsMatcher
jdbcRealm.credentialsMatcher = $sha256Matcher
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;You&apos;ll need to &lt;a href=&quot;http://dev.mysql.com/downloads/mysql/5.5.html&quot;&gt;install MySQL&lt;/a&gt; for this to work. After installing it, you should be able to create an &quot;appfuse&quot; database using the following command:
&lt;/p&gt;
&lt;pre&gt;
mysql -u root -p -e &apos;create database appfuse&apos;
&lt;/pre&gt;
&lt;p&gt;Then create the tables necessary and populate it with an &apos;admin&apos; user. Login using &quot;mysql -u root -p appfuse&quot; and execute the following SQL statements:&lt;/p&gt;
&lt;pre&gt;
create table users (
  user_name         varchar(30) not null primary key,
  user_pass         varchar(100) not null
);

create table user_roles (
  user_name         varchar(30) not null,
  role_name         varchar(30) not null,
  primary key (user_name, role_name)
);

insert into users values (&apos;admin&apos;, &apos;22f256eca1f336a97eef2b260773cb0d81d900c208ff26e94410d292d605fed8&apos;);
insert into user_roles values (&apos;admin&apos;, &apos;ROLE_ADMIN&apos;);
&lt;/pre&gt;
&lt;p&gt;Now if you restart Jetty, you should be able to login with admin/adminjdbc and view the list of users.
&lt;/p&gt;
&lt;p id=&quot;summary&quot;&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
In this tutorial, you learned how to implement authentication using Apache Shiro 1.1.0. I don&apos;t have a lot of experience with Apache Shiro, but I was able to get the basics working without too much effort. This tutorial doesn&apos;t show how to do Remember Me because I couldn&apos;t figure it out in 5 minutes, which means I have 5 more minutes before it fails the 10-minute test. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
Shiro was formerly named &lt;a href=&quot;http://www.jsecurity.org/&quot;&gt;JSecurity&lt;/a&gt; and has been an Apache project for less than a year. It seems to be more targeted towards non-web use, so its certainly something to look at if you&apos;re more interested in cryptography or non-web apps. I think there&apos;s a good chance this project will continue to grow and be used more as more developers learn about it. The Apache brand certainly doesn&apos;t hurt.
&lt;/p&gt;
&lt;p&gt;
I didn&apos;t include a slide about the limitations I found with Shiro, mostly because I haven&apos;t used it much. I&apos;ve used Java EE and Spring Security for several years. The main limitation I found was the lack of documentation, but I&apos;ve heard it&apos;s improving rapidly.
&lt;/p&gt;
  &lt;p&gt;In the next couple weeks, I&apos;ll post a &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part3&quot;&gt;Part IV&lt;/a&gt; on implementing programmatic login using the APIs of Java EE 6, Spring Security and Apache Shiro. I&apos;ll be presenting this topic at &lt;a href=&quot;http://jazoon.com&quot;&gt;Jazoon&lt;/a&gt; as well as the long-form version (with hacking) at &lt;a href=&quot;http://uberconf.com/conference/denver/2011/07/home&quot;&gt;&#220;berConf&lt;/a&gt;. Hopefully I&apos;ll see you at one of those conferences.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Thanks to help from &lt;a href=&quot;http://leshazlewood.com&quot;&gt;Les Hazlewood&lt;/a&gt;, I&apos;ve figured out how to implement Remember Me with Apache Shiro. In the [urls] section of shiro.ini, the second url (shown below) says to Shiro &quot;In order to visit the /app/users URL, you must be connecting via SSL on port 8443 and you must also be authenticated.&quot;
&lt;/p&gt;
&lt;pre&gt;
/app/users = ssl[8443],authc
&lt;/pre&gt;
&lt;p&gt;
Remembered users are not authenticated because their identity hasn&apos;t been proven during the current session.  What I want Shiro to say is &quot;In order to visit the /app/users URL, you must be connecting via SSL on 8443 and you must also be a known user.  If you&apos;re not, you should login first.&quot; Where a &lt;em&gt;known user&lt;/em&gt; is someone who has a recognized identity and has either authenticated during the current session or is known via RememberMe from a previous session.  The &lt;a href=&quot;http://shiro.apache.org/authentication.html#Authentication-Rememberedvs.Authenticated&quot;&gt;documentation&lt;/a&gt; gives a good example with Amazon.com for why Shiro makes this distinction.  It allows more control (usually necessary), but you can relax the control as you see fit.
&lt;p&gt;
So, to relax my configuration a bit to match what I want (&lt;em&gt;known users&lt;/em&gt;), I updated shiro.ini&apos;s [urls] section to be as follows:&lt;/p&gt;
&lt;pre&gt;
/app/users = ssl[8443],user
&lt;/pre&gt;
&lt;p&gt;
The key is that the /app/users url is now protected with the more relaxed &lt;a href=&quot;http://shiro.apache.org/static/current/apidocs/org/apache/shiro/web/filter/authc/UserFilter.html&quot;&gt;&lt;em&gt;user&lt;/em&gt; filter&lt;/a&gt; instead of the &lt;em&gt;authc&lt;/em&gt; filter.  However, you would typically want an account profile page (or credit card information page, or similar) protected with the authc filter instead to guarantee proof of identity for those sensitive operations.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/java_web_application_security_part1</id>
        <title type="html">Java Web Application Security - Part II: Spring Security Login Demo</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/java_web_application_security_part1"/>
        <published>2011-05-13T09:20:51-06:00</published>
        <updated>2015-07-07T01:36:15-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="presentation" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ujug" scheme="http://roller.apache.org/ns/tags/" />
        <category term="web" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last week, I wrote &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part&quot;&gt;a tutorial on how to implement Security in Java EE 6&lt;/a&gt;. This week, I&apos;d like to show you how to implement the same features using &lt;a href=&quot;http://static.springsource.org/spring-security/site/&quot;&gt;Spring Security&lt;/a&gt;. Before I begin, I&apos;d like to explain my reason for writing this article.
&lt;/p&gt;
&lt;p&gt;Last month, I presented a talk on Java Web Application Security at the &lt;a href=&quot;http://ujug.org&quot;&gt;Utah JUG&lt;/a&gt; (UJUG). As part of that presentation, I did a number of demos about how to implement security with Java EE 6, Spring Security and Apache Shiro. I told the audience that I would post the presentation and was planning on recording screencasts of the various demos so the online version of the presentation would make more sense. 
&lt;/p&gt;
&lt;p&gt;
Today, I&apos;ve finished the second screencast showing how to implement security with Spring Security. Below is the presentation (with the screencast embedded on slide 16) as well as a step-by-step tutorial.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/o4wwswiZck6bKS&quot; width=&quot;510&quot; height=&quot;420&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; margin-bottom:5px; max-width: 100%;&quot; allowfullscreen&gt; &lt;/iframe&gt;
&lt;br/&gt;
&lt;div style=&quot;font-size: .9em; text-align: left&quot;&gt;* You can also &lt;a href=&quot;http://www.youtube.com/watch?v=K5Hf-2bKYu8&quot;&gt;watch the screencast on YouTube&lt;/a&gt; or &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Java_Web_Application_Security_UJUG2011.pdf&quot;&gt;download the presentation PDF&lt;/a&gt;.&lt;/div&gt;
&lt;/p&gt;

&lt;p id=&quot;springsecurity-login-tutorial&quot;&gt;&lt;strong&gt;Spring Security Login Tutorial&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#download-run&quot;&gt;Download and Run the Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#secure-basic&quot;&gt;Implement Basic Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#ssl&quot;&gt;Force SSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#form-authentication&quot;&gt;Implement Form-based Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#remember-me&quot;&gt;Add Remember Me&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#jdbc&quot;&gt;Store Users in a Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#summary&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;download-run&quot;&gt;&lt;strong&gt;Download and Run the Application&lt;/strong&gt;&lt;br/&gt;

To begin, &lt;a href=&quot;http://static.raibledesigns.com/downloads/ajax-login-springsecurity-tutorial-1.0.zip&quot;&gt;download the application&lt;/a&gt; you&apos;ll be implementing security in. This app is a stripped-down version of the Ajax Login application I wrote for my article on &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery&quot;&gt;Implementing Ajax Authentication using jQuery, Spring Security and HTTPS&lt;/a&gt;. You&apos;ll need Java 6 and Maven installed to run the app. Run it using &lt;strong&gt;mvn jetty:run&lt;/strong&gt; and open &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; in your browser. You&apos;ll see it&apos;s a simple CRUD application for users and there&apos;s no login required to add or delete users.&lt;/p&gt;

&lt;p id=&quot;secure-basic&quot;&gt;&lt;strong&gt;Implement Basic Authentication&lt;/strong&gt;&lt;br/&gt;
  
The first step is to protect the list screen so people have to login to view users. To do this, you&apos;ll need to create a Spring context file that contains Spring Security&apos;s configuration. Create &lt;em&gt;src/main/webapp/WEB-INF/security.xml&lt;/em&gt; and populate it with the contents below:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; auto-links: false&quot;&gt;
  &amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
  &amp;lt;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;
               xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
               xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
               xsi:schemaLocation=&quot;http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
                http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd&quot;&amp;gt;

      &amp;lt;!-- New in Spring Security 3.1 --&amp;gt;
      &amp;lt;!-- &amp;lt;http pattern=&quot;/css/**&quot; security=&quot;none&quot;/&amp;gt; --&amp;gt;

      &amp;lt;http auto-config=&quot;true&quot;&amp;gt;
          &amp;lt;intercept-url pattern=&quot;/app/users&quot; access=&quot;ROLE_USER,ROLE_ADMIN&quot;/&amp;gt;
          &amp;lt;http-basic/&amp;gt;
      &amp;lt;/http&amp;gt;

      &amp;lt;authentication-manager alias=&quot;authenticationManager&quot;&amp;gt;
          &amp;lt;authentication-provider&amp;gt;
              &amp;lt;password-encoder hash=&quot;sha&quot;/&amp;gt;
              &amp;lt;user-service&amp;gt;
                  &amp;lt;user name=&quot;user&quot; password=&quot;12dea96fec20593566ab75692c9949596833adc9&quot; authorities=&quot;ROLE_USER&quot;/&amp;gt;
                  &amp;lt;user name=&quot;admin&quot; password=&quot;d033e22ae348aeb5660fc2140aec35850c4da997&quot; authorities=&quot;ROLE_ADMIN&quot;/&amp;gt;
              &amp;lt;/user-service&amp;gt;
          &amp;lt;/authentication-provider&amp;gt;
      &amp;lt;/authentication-manager&amp;gt;

      &amp;lt;!-- Override userSecurityAdvice bean in appfuse-service to allow any role to update a user. --&amp;gt;
      &amp;lt;beans:bean id=&quot;userSecurityAdvice&quot; class=&quot;org.appfuse.examples.webapp.security.UserSecurityAdvice&quot;/&amp;gt;
  &amp;lt;/beans:beans&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
The last bean, userSecurityAdvice, is an aspect that&apos;s needed to override some behavior in &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. You won&apos;t need this normally when implementing Spring Security. 
&lt;/p&gt;
&lt;p&gt;Next, open &lt;em&gt;src/main/webapp/WEB-INF/web.xml&lt;/em&gt; and add Spring&apos;s DelegatingFilterProxy:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;filter&amp;gt;
    &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;filter-class&amp;gt;org.springframework.web.filter.DelegatingFilterProxy&amp;lt;/filter-class&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;targetBeanName&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;springSecurityFilterChain&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
&amp;lt;/filter&amp;gt;
&lt;/pre&gt;
&lt;p&gt;And add its filter-mapping just after the rewriteFilter in the filter-mappings section (order is important!):
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;rewriteFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;FORWARD&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;INCLUDE&amp;lt;/dispatcher&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
You don&apos;t need to add any dependencies in your pom.xml is because this project depends on AppFuse, which already contains these dependencies.
&lt;/p&gt;
&lt;p&gt;
At this point, if you restart Jetty (Ctrl+C and jetty:run again), you should be prompted to login when you click on the &quot;Users&quot; tab. Enter admin/admin to login. Spring Security is a bit easier to configure than Java EE 6 out-of-the-box, mostly because it doesn&apos;t require you to configure your container.
&lt;/p&gt;
&lt;p&gt;After logging in, you can try to logout by clicking the &quot;Logout&quot; link in the top-right corner. This calls a LogoutController with the following code that logs the user out.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public void logout(HttpServletResponse response) throws ServletException, IOException {
    request.getSession().invalidate();
    response.sendRedirect(request.getContextPath()); 
}
&lt;/pre&gt; 
&lt;p class=&quot;quote&quot; style=&quot;font-style: italic; color: #666&quot;&gt;NOTE: Spring Security has a way to configure &quot;logout&quot; to match a URL and get rid of a class like LogoutController. Since it was already in the project, I don&apos;t cover that in this tutorial.&lt;/p&gt;
&lt;p&gt;You&apos;ll notice that clicking this link doesn&apos;t log you out, even though the session is invalidated. The only way to logout with basic authentication is to close the browser. In order to get the ability to logout, as well as to have more control over the look-and-feel of the login, you can implement form-based authentication.
  Before you implement form-based authentication, I&apos;d like to show you how easy it is to force SSL with Spring Security.
&lt;/p&gt;
&lt;p id=&quot;ssl&quot;&gt;&lt;strong&gt;Force SSL&lt;/strong&gt;&lt;br/&gt;
Spring Security allows you to switch between secure (https) and non-secure (http) protocols using a simple &lt;em&gt;requires-channel&lt;/em&gt; attribute on the &amp;lt;intercept-url&amp;gt; element. Possible values are &quot;http&quot;, &quot;https&quot; and &quot;any&quot;. Add &lt;em&gt;requires-channel=&quot;https&quot;&lt;/em&gt; to your security.xml file:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;intercept-url pattern=&quot;/app/users&quot; access=&quot;ROLE_USER,ROLE_ADMIN&quot; requires-channel=&quot;https&quot;/&amp;gt;
&lt;/pre&gt;
&lt;p&gt;In order for this to work, you have to configure Jetty to listen on an SSL port. Add the following just after the jetty-maven-plugin&apos;s &amp;lt;/webAppConfig&amp;gt; element in your pom.xml:
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;connectors&amp;gt;
    &amp;lt;connector implementation=&quot;org.eclipse.jetty.server.nio.SelectChannelConnector&quot;&amp;gt;
        &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
        &amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;
    &amp;lt;/connector&amp;gt;
    &amp;lt;connector implementation=&quot;org.eclipse.jetty.server.ssl.SslSelectChannelConnector&quot;&amp;gt;
        &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
        &amp;lt;port&amp;gt;8443&amp;lt;/port&amp;gt;
        &amp;lt;maxIdleTime&amp;gt;60000&amp;lt;/maxIdleTime&amp;gt;
        &amp;lt;keystore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystore&amp;gt;
        &amp;lt;password&amp;gt;appfuse&amp;lt;/password&amp;gt;
        &amp;lt;keyPassword&amp;gt;appfuse&amp;lt;/keyPassword&amp;gt;
    &amp;lt;/connector&amp;gt;
&amp;lt;/connectors&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The keystore must be generated for Jetty to start successfully, so add the keytool-maven-plugin just above the jetty-maven-plugin in pom.xml.
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;keytool-maven-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;phase&amp;gt;generate-resources&amp;lt;/phase&amp;gt;
            &amp;lt;id&amp;gt;clean&amp;lt;/id&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;clean&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;phase&amp;gt;generate-resources&amp;lt;/phase&amp;gt;
            &amp;lt;id&amp;gt;genkey&amp;lt;/id&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;genkey&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
    &amp;lt;/executions&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;keystore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystore&amp;gt;
        &amp;lt;dname&amp;gt;cn=localhost&amp;lt;/dname&amp;gt;
        &amp;lt;keypass&amp;gt;appfuse&amp;lt;/keypass&amp;gt;
        &amp;lt;storepass&amp;gt;appfuse&amp;lt;/storepass&amp;gt;
        &amp;lt;alias&amp;gt;appfuse&amp;lt;/alias&amp;gt;
        &amp;lt;keyalg&amp;gt;RSA&amp;lt;/keyalg&amp;gt;
    &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now if you restart Jetty, go to &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; and click on the &quot;Users&quot; tab, you&apos;ll be prompted to accept the Untrusted Certificate and then redirected to https://localhost:8443/users after logging in. This is an 
  improvement on Java EE&apos;s user-data-constraint for two reasons:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;You can switch between http and https protocols. With Java EE, you can only force https. You have to write a custom filter to switch back to http.&lt;/li&gt;
    &lt;li&gt;Redirecting to https actually works. With Java EE (on Jetty at least), a 403 is returned instead of redirecting the request.&lt;/li&gt;
  &lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;Now let&apos;s look at how to have more control over the look-and-feel of the login screen, as well as how to make logout work with form-based authentication.&lt;/p&gt;
&lt;p id=&quot;form-authentication&quot;&gt;&lt;strong&gt;Implement Form-based Authentication&lt;/strong&gt;&lt;br/&gt;
To change from basic to form-based authentication, you simply have to add a &amp;lt;form-login&amp;gt; element in security.xml&apos;s &amp;lt;http&amp;gt; element:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;http auto-config=&quot;true&quot;&amp;gt;
    &amp;lt;intercept-url pattern=&quot;/app/users&quot; access=&quot;ROLE_USER,ROLE_ADMIN&quot; requires-channel=&quot;https&quot;/&amp;gt;
    &amp;lt;form-login login-page=&quot;/login&quot; authentication-failure-url=&quot;/login?error=true&quot;
                login-processing-url=&quot;/j_security_check&quot;/&amp;gt;
    &amp;lt;http-basic/&amp;gt;
&amp;lt;/http&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
  You can leave the &amp;lt;http-basic&amp;gt; element since Spring Security is smart enough to serve up the form for browsers and use Basic Authentication for clients such as web services.
  
  The login.jsp page (that /login forwards to) already exists in the project, in the &lt;em&gt;src/main/webapp&lt;/em&gt; directory. The forwarding is done by the &lt;a href=&quot;http://www.tuckey.org/urlrewrite/&quot;&gt;UrlRewriteFilter&lt;/a&gt; with the following configuration in &lt;em&gt;src/main/webapp/WEB-INF/urlrewrite.xml&lt;/em&gt;. 
  
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule&amp;gt;
    &amp;lt;from&amp;gt;/login&amp;lt;/from&amp;gt;
    &amp;lt;to&amp;gt;/login.jsp&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&lt;/pre&gt;  
&lt;p&gt;
  This JSP has 3 important elements: 1) a form that submits to &quot;/j_security_check&quot;, 2) an input element named &quot;j_username&quot; and 3) an input element named &quot;j_password&quot;. If you restart Jetty, you&apos;ll now be prompted to login with this JSP instead of the basic authentication dialog.
&lt;/p&gt;
&lt;p id=&quot;remember-me&quot;&gt;&lt;strong&gt;Add Remember Me&lt;/strong&gt;&lt;br/&gt;
Remember Me is a feature you see in many web applications today. It&apos;s usually a checkbox on the login form that allows you to auto-login the next time you visit a site. This feature doesn&apos;t exist in Java EE security, but it does exist in Spring Security. To enable it, add the following just below &amp;lt;form-login&amp;gt; in security.xml:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;remember-me user-service-ref=&quot;userDao&quot; key=&quot;e37f4b31-0c45-11dd-bd0b-0800200c9a66&quot;/&gt;
&lt;/pre&gt;
&lt;p&gt;Next, open &lt;em&gt;src/main/webapp/login.jsp&lt;/em&gt; and change the name of the &quot;remember me&quot; checkbox to be &lt;strong&gt;_spring_security_remember_me&lt;/strong&gt;:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;input type=&quot;checkbox&quot; name=&quot;_spring_security_remember_me&quot; id=&quot;rememberMe&quot;/&gt;
&lt;/pre&gt;
&lt;p&gt;After making these changes, you should be able to restart Jetty, go to &lt;a href=&quot;http://localhost:8080/users&quot;&gt;http://localhost:8080/users&lt;/a&gt;, enter admin/adminjdbc, check the Remember Me checkbox and login. Then close your browser, and repeat the process. This time, you won&apos;t be prompted to login. For more information on this feature, see &lt;a href=&quot;http://static.springsource.org/spring-security/site/docs/3.0.x/reference/remember-me.html&quot;&gt;Spring Security&apos;s Remember Me documentation&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
While storing usernames and passwords in a file is convenient for demos, it&apos;s not very real-world-ish. The next section shows you how to configure Spring Security to use a database for its user store.
&lt;/p&gt;
&lt;p id=&quot;jdbc&quot;&gt;&lt;strong&gt;Store Users in a Database&lt;/strong&gt;&lt;br/&gt;
To store your users in a database instead of file, you&apos;ll need to add a &lt;em&gt;user-service-ref&lt;/em&gt; attribute to the &amp;lt;authentication-provider&amp;gt; element. You can also delete the &amp;lt;user-service&amp;gt; element. 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;authentication-manager alias=&quot;authenticationManager&quot;&amp;gt;
    &amp;lt;authentication-provider user-service-ref=&quot;userDao&quot;&amp;gt;
        &amp;lt;password-encoder hash=&quot;sha&quot;/&amp;gt;
    &amp;lt;/authentication-provider&amp;gt;
&amp;lt;/authentication-manager&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The &quot;userDao&quot; bean is provided by AppFuse and its &lt;a href=&quot;http://static.appfuse.org/appfuse-data/appfuse-hibernate/xref/org/appfuse/dao/hibernate/UserDaoHibernate.html&quot;&gt;UserDaoHibernate.java&lt;/a&gt; class. This 
  class implements Spring Security&apos;s &lt;a href=&quot;http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/core/userdetails/UserDetailsService.html&quot;&gt;UserDetailsService&lt;/a&gt; interface.
  With Java EE, I had to configure a database connection and make sure the JDBC Driver was in my container&apos;s classpath. With Spring Security, you can talk to the database you already have configured in your application.
&lt;/p&gt;
&lt;div class=&quot;quote&quot; style=&quot;margin-left: 0; color: #666&quot;&gt;Of course, you could do this with Java EE too. One thing I neglected to show in my last tutorial was that 1) the app uses H2 and 2) I had to configure Java EE&apos;s database to be MySQL. This was because when I tried to access my H2 instance, I got an error about two threads trying to access it at once.
&lt;pre style=&quot;margin-top: 10px; margin-bottom: 0&quot;&gt;
2011-05-13 08:47:29.081:WARN::UserRealm Java EE Login could not connect to database; will try later
org.h2.jdbc.JdbcSQLException: Database may be already in use: &quot;Locked by another process&quot;. 
        Possible solutions: close all other connection(s); use the server mode [90020-154]
	at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
	at org.h2.message.DbException.get(DbException.java:167)
	at org.h2.message.DbException.get(DbException.java:144)
	at org.h2.store.FileLock.getExceptionAlreadyInUse(FileLock.java:443)
	at org.h2.store.FileLock.lockFile(FileLock.java:338)
	at org.h2.store.FileLock.lock(FileLock.java:134)
	at org.h2.engine.Database.open(Database.java:535)
	at org.h2.engine.Database.openDatabase(Database.java:218)
&lt;/pre&gt;
&lt;/div&gt;
&lt;/p&gt;
&lt;!-- Figure out exact error from H2 --&gt;
&lt;p&gt;The password for the &quot;admin&quot; user is configured in &lt;em&gt;src/test/resources/sample-data.xml&lt;/em&gt; and it&apos;s loaded by &lt;a href=&quot;http://dbunit.sourceforge.net/&quot;&gt;DbUnit&lt;/a&gt; before the application starts. 
  You can view your pom.xml and the dbunit-maven-plugin&apos;s configuration if you&apos;re interested in learning how this is done. The password is currently configured to &quot;adminjdbc&quot;, but you can reset it by
  &lt;a href=&quot;http://darrenfauth.com/generators/sha1&quot;&gt;generating a new password&lt;/a&gt; and modifying sample-data.xml.
&lt;/p&gt;
&lt;p&gt;Now if you restart Jetty, you should be able to login with admin/adminjdbc and view the list of users.
&lt;/p&gt;
&lt;p id=&quot;summary&quot;&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
In this tutorial, you learned how to implement authentication using Spring Security 3.0.5. In addition to the basic XML configuration, Spring Security also provides a AOP support and annotations you can use to secure methods. It also has many more features than standard Java EE Security. In my opinion, it&apos;s the most mature security framework we have in Java today. Currently, I think its &lt;a href=&quot;http://static.springsource.org/spring-security/site/docs/3.0.x/reference/springsecurity.html&quot;&gt;reference documentation&lt;/a&gt; is the best place to learn more.
&lt;/p&gt;
There are a few limitations I found with Spring Security:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;The authentication mechanism (file, database, ldap, etc.) is contained in the WAR&lt;/li&gt;
&lt;li&gt;Securing methods only works on Spring beans&lt;/li&gt;
&lt;li&gt;Remember Me doesn&apos;t work in my screencast (because I forgot to rename the checkbox in login.jsp)&lt;/li&gt;
&lt;/ul&gt;
&lt;/ul&gt;&lt;p&gt;Of course, you can configure Spring to load its configuration from outside the WAR (e.g. a file or JNDI), but it&apos;s not as easy as including the configuration in your app.
  &lt;/p&gt;
  &lt;p&gt;In the next couple weeks, I&apos;ll post &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part2&quot;&gt;Part III&lt;/a&gt; of this series, where I&apos;ll show you how to implement this same set of features using Apache Shiro. In the meantime, please let me know if you have any questions.
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;
I created the screencasts with &lt;a href=&quot;http://www.techsmith.com/camtasia/&quot; style=&quot;color: #666&quot;&gt;Camtasia&lt;/a&gt;. For small screens, and embedding in the presentation, I created it at 50% and used the SmartFocus feature to zoom in and out during the demo. For larger screens, I published &lt;a href=&quot;http://www.youtube.com/watch?v=poc5dyImbig&quot; style=&quot;color: #666&quot;&gt;another screencast at 100%, in HD&lt;/a&gt;. If you have a preference for which screencast is better, I&apos;d love to hear about it.&lt;/p&gt;
&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/java_web_application_security_part</id>
        <title type="html">Java Web Application Security - Part I: Java EE 6 Login Demo</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/java_web_application_security_part"/>
        <published>2011-05-05T16:58:00-06:00</published>
        <updated>2022-08-22T14:56:40-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="ujug" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="web" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="presentation" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;Back in February, I &lt;a href=&quot;http://raibledesigns.com/rd/entry/upcoming_conferences_tssjs_in_las&quot;&gt;wrote about my upcoming conferences&lt;/a&gt;:&lt;/p&gt;
&lt;p style=&quot;color: #666; border-top: 1px dotted silver; padding-top: 10px; margin-top: -5px&quot;&gt;
In addition to Vegas and Poland, there&apos;s a couple other events I might speak at in the next few months: the &lt;a href=&quot;http://www.ujug.org/&quot;&gt;Utah Java Users Group&lt;/a&gt; (possibly in April), &lt;a href=&quot;http://jazoon.com/&quot;&gt;Jazoon&lt;/a&gt; and &lt;a href=&quot;http://uberconf.com/conference/denver/2011/07/home&quot;&gt;&#220;berConf&lt;/a&gt; (if my proposals are accepted). For these events, I&apos;m hoping to present the following talk:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
&lt;strong&gt;Webapp Security: Develop. Penetrate. Protect. Relax.&lt;/strong&gt;&lt;br&gt;
In this session, you&apos;ll learn how to implement authentication in your Java web applications using Spring Security, Apache Shiro and good ol&apos; Java EE Container Managed Authentication. You&apos;ll also learn how to secure your REST API with OAuth and lock it down with SSL.
&lt;br&gt;&lt;br&gt;
After learning how to develop authentication, I&apos;ll introduce you to OWASP, the OWASP Top 10, its Testing Guide and its Code Review Guide. From there, I&apos;ll discuss using WebGoat to verify your app is secure and commercial tools like webapp firewalls and accelerators.&lt;/p&gt;
&lt;p&gt;Fast forward a couple months and I&apos;m happy to say that I&apos;ve completed my talk at the Utah JUG and it&apos;s been accepted at Jazoon and &#220;ber Conf. For this talk, I created a presentation that primarily consists of demos implementing basic, form and Ajax authentication using &lt;a href=&quot;http://download.oracle.com/javaee/6/tutorial/doc/gkbaa.html&quot;&gt;Java EE 6&lt;/a&gt;, &lt;a href=&quot;http://static.springsource.org/spring-security/site/&quot;&gt;Spring Security&lt;/a&gt; and &lt;a href=&quot;http://shiro.apache.org/&quot;&gt;Apache Shiro&lt;/a&gt;. In the process of creating the demos, I learned (or re-educated myself) how to do a number of things in all 3 frameworks:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Implement Basic Authentication&lt;/li&gt;
&lt;li&gt;Implement Form-based Authentication&lt;/li&gt;
&lt;li&gt;Implement Ajax HTTP -&gt; HTTPS Authentication (with programmatic APIs)&lt;/li&gt;
&lt;li&gt;Force SSL for certain URLs&lt;/li&gt;
&lt;li&gt;Implement a file-based store of users and passwords (in Jetty/Maven and Tomcat standalone)&lt;/li&gt;
&lt;li&gt;Implement a database store of users and passwords (in Jetty/Maven and Tomcat standalone)&lt;/li&gt;
&lt;li&gt;Encrypt Passwords&lt;/li&gt;
&lt;li&gt;Secure methods with annotations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For the demos, I showed the audience how to do almost all of these, but skipped Tomcat standalone and securing methods in the interest of time. In July, when I do this talk at &#220;berConf, I plan on adding 1) hacking the app (to show security holes) and 2) fixing it to protect it against vulnerabilities. 
&lt;/p&gt;
&lt;p&gt;I told the audience at UJUG that I would post the presentation and was planning on recording screencasts of the various demos so the online version of the presentation would make more sense. Today, I&apos;ve finished the first screencast showing how to implement security with Java EE 6. Below is the presentation (with the screencast embedded on slide 10) as well as a step-by-step tutorial.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;object id=&quot;__sse7850034&quot; width=&quot;510&quot; height=&quot;426&quot;&gt; &lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=javawebapplicationsecurityujug2011-110505121131-phpapp02&amp;stripped_title=java-web-application-security-utah-jug-2011&amp;userName=mraible&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;embed name=&quot;__sse7850034&quot; src=&quot;//static.slidesharecdn.com/swf/ssplayer2.swf?doc=javawebapplicationsecurityujug2011-110505121131-phpapp02&amp;stripped_title=java-web-application-security-utah-jug-2011&amp;userName=mraible&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;510&quot; height=&quot;426&quot;&gt;&lt;/embed&gt; &lt;/object&gt;
&lt;br/&gt;
&lt;div style=&quot;font-size: .9em; text-align: left&quot;&gt;* You can also &lt;a href=&quot;http://www.youtube.com/watch?v=4LD4mF5ex2U&quot;&gt;watch the screencast on YouTube&lt;/a&gt; or &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Java_Web_Application_Security_UJUG2011.pdf&quot;&gt;download the presentation PDF&lt;/a&gt;.&lt;/div&gt;
&lt;/p&gt;
&lt;p id=&quot;javaee6-login-tutorial&quot;&gt;&lt;strong&gt;Java EE 6 Login Tutorial&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://raibledesigns.com/rd/entry/java_web_application_security_part#download-run&quot;&gt;Download and Run the Application&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://raibledesigns.com/rd/entry/java_web_application_security_part#secure-basic&quot;&gt;Implement Basic Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://raibledesigns.com/rd/entry/java_web_application_security_part#form-authentication&quot;&gt;Implement Form-based Authentication&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://raibledesigns.com/rd/entry/java_web_application_security_part#ssl&quot;&gt;Force SSL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://raibledesigns.com/rd/entry/java_web_application_security_part#jdbc&quot;&gt;Store Users in a Database&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://raibledesigns.com/rd/entry/java_web_application_security_part#summary&quot;&gt;Summary&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;download-run&quot;&gt;&lt;strong&gt;Download and Run the Application&lt;/strong&gt;&lt;br/&gt;

To begin, &lt;a href=&quot;http://static.raibledesigns.com/downloads/ajax-login-javaee-tutorial-1.0.zip&quot;&gt;download the application&lt;/a&gt; you&apos;ll be implementing security in. This app is a stripped-down version of the Ajax Login application I wrote for my article on &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery&quot;&gt;Implementing Ajax Authentication using jQuery, Spring Security and HTTPS&lt;/a&gt;. You&apos;ll need Java 6 and Maven installed to run the app. Run it using &lt;strong&gt;mvn jetty:run&lt;/strong&gt; and open &lt;a href=&quot;http://localhost:8080&quot;&gt;http://localhost:8080&lt;/a&gt; in your browser. You&apos;ll see it&apos;s a simple CRUD application for users and there&apos;s no login required to add or delete users.&lt;/p&gt;

&lt;p id=&quot;secure-basic&quot;&gt;&lt;strong&gt;Implement Basic Authentication&lt;/strong&gt;&lt;br/&gt;
  
The first step is to protect the list screen so people have to login to view users. To do this, add the following to the bottom of &lt;em&gt;src/main/webapp/WEB-INF/web.xml&lt;/em&gt;:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;security-constraint&amp;gt;
    &amp;lt;web-resource-collection&amp;gt;
        &amp;lt;web-resource-name&amp;gt;users&amp;lt;/web-resource-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;/users&amp;lt;/url-pattern&amp;gt;
        &amp;lt;http-method&amp;gt;GET&amp;lt;/http-method&amp;gt;
        &amp;lt;http-method&amp;gt;POST&amp;lt;/http-method&amp;gt;
    &amp;lt;/web-resource-collection&amp;gt;
    &amp;lt;auth-constraint&amp;gt;
        &amp;lt;role-name&amp;gt;ROLE_ADMIN&amp;lt;/role-name&amp;gt;
    &amp;lt;/auth-constraint&amp;gt;
&amp;lt;/security-constraint&amp;gt;

&amp;lt;login-config&amp;gt;
    &amp;lt;auth-method&amp;gt;BASIC&amp;lt;/auth-method&amp;gt;
    &amp;lt;realm-name&amp;gt;Java EE Login&amp;lt;/realm-name&amp;gt;
&amp;lt;/login-config&amp;gt;

&amp;lt;security-role&amp;gt;
    &amp;lt;role-name&amp;gt;ROLE_ADMIN&amp;lt;/role-name&amp;gt;
&amp;lt;/security-role&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
At this point, if you restart Jetty (Ctrl+C and jetty:run again), you&apos;ll get an error about a missing LoginService. This happens because Jetty doesn&apos;t know where the &quot;Java EE Login&quot; realm is located. Add the following to &lt;em&gt;pom.xml&lt;/em&gt;, just after &amp;lt;/webAppConfig&gt; in the Jetty plugin&apos;s configuration.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;loginServices&amp;gt;
    &amp;lt;loginService implementation=&quot;org.eclipse.jetty.security.HashLoginService&quot;&amp;gt;
        &amp;lt;name&amp;gt;Java EE Login&amp;lt;/name&amp;gt;
        &amp;lt;config&amp;gt;${basedir}/src/test/resources/realm.properties&amp;lt;/config&amp;gt;
    &amp;lt;/loginService&amp;gt;
&amp;lt;/loginServices&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The realm.properties file already exists in the project and contains user names and passwords. Start the app again using &lt;strong&gt;mvn jetty:run&lt;/strong&gt; and you should be prompted to login when you click on the &quot;Users&quot; tab. Enter admin/admin to login.
&lt;/p&gt;
&lt;p&gt;After logging in, you can try to logout by clicking the &quot;Logout&quot; link in the top-right corner. This calls a LogoutController with the following code that logs the user out.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public void logout(HttpServletResponse response) throws ServletException, IOException {
    request.getSession().invalidate();
    response.sendRedirect(request.getContextPath());
}
&lt;/pre&gt; 
&lt;p&gt;You&apos;ll notice that clicking this link doesn&apos;t log you out, even though the session is invalidated. The only way to logout with basic authentication is to close the browser. In order to get the ability to logout, as well as to have more control over the look-and-feel of the login, you can implement form-based authentication.
&lt;/p&gt;
&lt;p id=&quot;form-authentication&quot;&gt;&lt;strong&gt;Implement Form-based Authentication&lt;/strong&gt;&lt;br/&gt;
To change from basic to form-based authentication, you simply have to replace the &amp;lt;login-config&amp;gt; in your web.xml with the following:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;login-config&amp;gt;
    &amp;lt;auth-method&amp;gt;FORM&amp;lt;/auth-method&amp;gt;
    &amp;lt;form-login-config&amp;gt;
        &amp;lt;form-login-page&amp;gt;/login.jsp&amp;lt;/form-login-page&amp;gt;
        &amp;lt;form-error-page&amp;gt;/login.jsp?error=true&amp;lt;/form-error-page&amp;gt;
    &amp;lt;/form-login-config&amp;gt;
&amp;lt;/login-config&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The login.jsp page already exists in the project, in the &lt;em&gt;src/main/webapp&lt;/em&gt; directory. This JSP has 3 important elements: 1) a form that submits to &quot;${contextPath}/j_security_check&quot;, 2) an input element named &quot;j_username&quot; and 3) an input element named &quot;j_password&quot;. If you restart Jetty, you&apos;ll now be prompted to login with this JSP instead of the basic authentication dialog.
&lt;/p&gt;
&lt;p id=&quot;ssl&quot;&gt;&lt;strong&gt;Force SSL&lt;/strong&gt;&lt;br/&gt;
Another thing you might want to implement to secure your application is forcing SSL for certain URLs. To do this on the same &amp;lt;security-constraint&amp;gt; you already have in web.xml, add the following after &amp;lt;/auth-constraint&gt;:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;user-data-constraint&amp;gt;
    &amp;lt;transport-guarantee&amp;gt;CONFIDENTIAL&amp;lt;/transport-guarantee&amp;gt;
&amp;lt;/user-data-constraint&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To configure Jetty to listen on an SSL port, add the following just after &amp;lt;/loginServices&amp;gt; in your pom.xml:
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;connectors&amp;gt;
    &amp;lt;connector implementation=&quot;org.eclipse.jetty.server.nio.SelectChannelConnector&quot;&amp;gt;
        &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
        &amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;
    &amp;lt;/connector&amp;gt;
    &amp;lt;connector implementation=&quot;org.eclipse.jetty.server.ssl.SslSelectChannelConnector&quot;&amp;gt;
        &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
        &amp;lt;port&amp;gt;8443&amp;lt;/port&amp;gt;
        &amp;lt;maxIdleTime&amp;gt;60000&amp;lt;/maxIdleTime&amp;gt;
        &amp;lt;keystore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystore&amp;gt;
        &amp;lt;password&amp;gt;appfuse&amp;lt;/password&amp;gt;
        &amp;lt;keyPassword&amp;gt;appfuse&amp;lt;/keyPassword&amp;gt;
    &amp;lt;/connector&amp;gt;
&amp;lt;/connectors&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The keystore must be generated for Jetty to start successfully, so add the keytool-maven-plugin just above the jetty-maven-plugin in pom.xml.
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;keytool-maven-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;1.0&amp;lt;/version&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;phase&amp;gt;generate-resources&amp;lt;/phase&amp;gt;
            &amp;lt;id&amp;gt;clean&amp;lt;/id&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;clean&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;phase&amp;gt;generate-resources&amp;lt;/phase&amp;gt;
            &amp;lt;id&amp;gt;genkey&amp;lt;/id&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;genkey&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
        &amp;lt;/execution&amp;gt;
    &amp;lt;/executions&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;keystore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystore&amp;gt;
        &amp;lt;dname&amp;gt;cn=localhost&amp;lt;/dname&amp;gt;
        &amp;lt;keypass&amp;gt;appfuse&amp;lt;/keypass&amp;gt;
        &amp;lt;storepass&amp;gt;appfuse&amp;lt;/storepass&amp;gt;
        &amp;lt;alias&amp;gt;appfuse&amp;lt;/alias&amp;gt;
        &amp;lt;keyalg&amp;gt;RSA&amp;lt;/keyalg&amp;gt;
    &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now if you restart Jetty, go to http://localhost:8080 and click on the &quot;Users&quot; tab, you&apos;ll get a 403. What the heck?! When this first happened to me, it took me a while to figure out. It turns out that Jetty doesn&apos;t redirect to HTTPS when using Java EE authentication, so you have to manually type in &lt;a href=&quot;https://localhost:8443/&quot;&gt;https://localhost:8443/&lt;/a&gt; (or add a filter to redirect for you). If you deployed this same application on Tomcat (after &lt;a href=&quot;http://tomcat.apache.org/tomcat-7.0-doc/ssl-howto.html&quot;&gt;enabling SSL&lt;/a&gt;), it would redirect for you.
&lt;/p&gt;
&lt;p id=&quot;jdbc&quot;&gt;&lt;strong&gt;Store Users in a Database&lt;/strong&gt;&lt;br/&gt;
Finally, to store your users in a database instead of file, you&apos;ll need to change the &amp;lt;loginService&amp;gt; in the Jetty plugin&apos;s configuration. Replace the existing &amp;lt;loginService&amp;gt; element with the following:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;loginServices&amp;gt;
    &amp;lt;loginService implementation=&quot;org.eclipse.jetty.security.JDBCLoginService&quot;&amp;gt;
        &amp;lt;name&amp;gt;Java EE Login&amp;lt;/name&amp;gt;
        &amp;lt;config&amp;gt;${basedir}/src/test/resources/jdbc-realm.properties&amp;lt;/config&amp;gt;
    &amp;lt;/loginService&amp;gt;
&amp;lt;/loginServices&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The jdbc-realm.properties file already exists in the project and contains the database settings and table/column names for the user and role information.
&lt;/p&gt;
&lt;pre&gt;
jdbcdriver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost/appfuse
username = root
password =
usertable = app_user
usertablekey = id
usertableuserfield = username
usertablepasswordfield = password
roletable = role
roletablekey = id
roletablerolefield = name
userroletable = user_role
userroletableuserkey = user_id
userroletablerolekey = role_id
cachetime = 300
&lt;/pre&gt;
&lt;p&gt;Of course, you&apos;ll need to &lt;a href=&quot;http://dev.mysql.com/downloads/mysql/5.5.html&quot;&gt;install MySQL&lt;/a&gt; for this to work. After installing it, you should be able to create an &quot;appfuse&quot; database and populate it using the following commands:
&lt;/p&gt;
&lt;pre&gt;
mysql -u root -p -e &apos;create database appfuse&apos;
curl https://gist.github.com/raw/958091/ceecb4a6ae31c31429d5639d0d1e6bfd93e2ea42/create-appfuse.sql &gt; create-appfuse.sql
mysql -u root -p appfuse &amp;lt; create-appfuse.sql
&lt;/pre&gt;
&lt;p&gt;Next you&apos;ll need to configure Jetty so it has MySQL&apos;s JDBC Driver in its classpath. To do this, add the following dependency just after the &amp;lt;configuration&amp;gt; element (before &amp;lt;executions&amp;gt;) in pom.xml:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependencies&amp;gt;
    &amp;lt;!-- MySQL for JDBC Realm --&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;mysql&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;mysql-connector-java&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;5.1.14&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Now run the &lt;em&gt;jetty-password.sh&lt;/em&gt; file in the root directory of the project to generate a password of your choosing. For example:&lt;/p&gt;
&lt;pre&gt;
$ sh jetty-password.sh javaeelogin
javaeelogin
OBF:1vuj1t2v1wum1u9d1ugo1t331uh21ua51wts1t3b1vur
MD5:53b176e6ce1b5183bc970ef1ebaffd44
&lt;/pre&gt;&lt;p&gt;The last two lines are obfuscated and MD5 versions of the password. Update the &lt;strong&gt;admin&lt;/strong&gt; user&apos;s password to this new value. You can do this with the following SQL statement.
&lt;/p&gt;
&lt;pre&gt;
UPDATE app_user SET password=&apos;MD5:53b176e6ce1b5183bc970ef1ebaffd44&apos; WHERE username = &apos;admin&apos;;
&lt;/pre&gt;
&lt;p&gt;Now if you restart Jetty, you should be able to login with admin/javaeelogin and view the list of users.
&lt;/p&gt;
&lt;p id=&quot;summary&quot;&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
In this tutorial, you learned how to implement authentication using standard Java EE 6. In addition to the basic XML configuration, there&apos;s also some new methods in HttpServletRequest for Java EE 6 and Servlet 3.0:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;authenticate(response)&lt;/li&gt;
&lt;li&gt;login(user, pass)&lt;/li&gt;
&lt;li&gt;logout()&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;This tutorial doesn&apos;t show you how to use them, but I did play with them a bit as part of my UJUG demo when implementing Ajax authentication. I found that login() did work, but it didn&apos;t persist the authentication for the users session. I also found that after calling logout(), I still needed to invalidate the session to completely logout the user. There are some additional limitations I found with Java EE authentication, namely:
&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;No error messages for failed logins&lt;/li&gt;
&lt;li&gt;No Remember Me&lt;/li&gt;
&lt;li&gt;No auto-redirect from HTTP to HTTPS&lt;/li&gt;
&lt;li&gt;Container has to be configured&lt;/li&gt;
&lt;li&gt;Doesn&#8217;t support regular expressions for URLs&lt;/li&gt;
&lt;/ul&gt;&lt;p&gt;Of course, no error messages indicating why login failed is probably a good thing (you don&apos;t want to tell users why their credentials failed). However, when you&apos;re trying to figure out if your container is configured properly, the lack of container logging can be a pain.
  &lt;/p&gt;
  &lt;p&gt;In the next couple weeks, I&apos;ll post &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_application_security_part1&quot;&gt;Part II&lt;/a&gt; of this series, where I&apos;ll show you how to implement this same set of features using Spring Security. In the meantime, please let me know if you have any questions.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_2_1_released</id>
        <title type="html">AppFuse 2.1 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_2_1_released"/>
        <published>2011-04-04T09:38:05-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ibatis" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse-light" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jpa" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//static.appfuse.org/images/appfuse-icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the release of AppFuse 2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are JPA 2, JSF 2, Tapestry 5 and Spring 3. In addition, we&apos;ve migrated from XFire to CXF and enabled REST for web services. There&apos;s even a new &lt;b&gt;appfuse-ws&lt;/b&gt; archetype that leverages &lt;a href=&quot;http://enunciate.codehaus.org&quot;&gt;Enunciate&lt;/a&gt; to generate web service endpoints, documentation and downloadable clients. This release fixes many issues with archetypes, improving startup time and allowing jetty:run to be used for quick turnaround while developing. For more details on specific changes see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.1.0&quot; title=&quot;Release Notes 2.1.0&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is AppFuse?&lt;/strong&gt;&lt;br/&gt;AppFuse is an open source project and application that uses open source frameworks to help you develop Web applications with Java quickly and efficiently. It was originally developed to eliminate the ramp-up time when building new web applications. At its core, AppFuse is a project skeleton, similar to the one that&apos;s created by your IDE when you click through a wizard to create a new web project. If you use &lt;a href=&quot;http://appfuse.org/display/APF/Using+JRebel+with+IntelliJ+IDEA&quot;&gt;JRebel with IntelliJ&lt;/a&gt;, you can achieve zero-turnaround in your project and develop features without restarting the server.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Release Details&lt;/b&gt;&lt;br/&gt;
&lt;a href=&quot;http://static.appfuse.org/archetypes.html&quot;&gt;Archetypes&lt;/a&gt; now include all the source for the web modules so using jetty:run and your IDE will work much smoother now. The backend is still embedded in JARs, enabling you to choose with persistence framework (Hibernate, iBATIS or JPA) you&apos;d like to use. If you want to modify the source for that, &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+Core+Classes&quot;&gt;add the core classes to your project&lt;/a&gt; or run &quot;appfuse:full-source&quot;. &lt;/p&gt;

&lt;p&gt;AppFuse comes in a number of different flavors. It offers &quot;light&quot;, &quot;basic&quot; and &quot;modular&quot; and archetypes. Light archetypes use an embedded H2 database and contain a simple CRUD example. Light archetypes allow code generation and full-source features, but do not currently support Stripes or Wicket. Basic archetypes have web services using CXF, authentication from Spring Security and features including signup, login, file upload and CSS theming. Modular archetypes are similar to basic archetypes, except they have multiple modules which allows you to separate your services from your web project.&lt;/p&gt;

&lt;p&gt;AppFuse provides archetypes for JSF, Spring MVC, Struts 2 and Tapestry 5. The light archetypes are available for these frameworks, as well as for Spring MVC + FreeMarker, Stripes and Wicket. You can see demos of these archetypes at &lt;a href=&quot;http://demo.appfuse.org&quot;&gt;http://demo.appfuse.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For information on creating a new project, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you have questions about AppFuse, please read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot;&gt;FAQ&lt;/a&gt; or join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;user mailing list&lt;/a&gt;. If you find any issues, please report them on the mailing list or &lt;a href=&quot;http://issues.appfuse.org/secure/CreateIssue%21default.jspa&quot;&gt;create an issue in JIRA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing lists.&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;We greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot; title=&quot;Sponsors&quot; style=&quot;color: #666&quot;&gt;our sponsors&lt;/a&gt;, particularly &lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot; style=&quot;color: #666&quot;&gt;Atlassian&lt;/a&gt;, &lt;a href=&quot;http://contegix.com&quot; style=&quot;color: #666&quot;&gt;Contegix&lt;/a&gt; and &lt;a href=&quot;http://www.jetbrains.com&quot; style=&quot;color: #666&quot;&gt;JetBrains&lt;/a&gt;. Atlassian and Contegix are especially awesome: &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_now_powered_by_contegix&quot; style=&quot;color: #666&quot;&gt;Atlassian has donated licenses to all its products and Contegix has donated an entire server&lt;/a&gt; to the AppFuse project.&lt;/p&gt;&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/adding_search_to_appfuse</id>
        <title type="html">Adding Search to AppFuse with Compass</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/adding_search_to_appfuse"/>
        <published>2011-03-15T17:11:12-06:00</published>
        <updated>2012-11-08T14:19:27-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="search" scheme="http://roller.apache.org/ns/tags/" />
        <category term="compass" scheme="http://roller.apache.org/ns/tags/" />
        <category term="elasticsearch" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Over 5 years ago, I recognized that &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; needed to have a search feature and &lt;a href=&quot;http://issues.appfuse.org/browse/APF-267&quot;&gt;entered an issue in JIRA&lt;/a&gt;. Almost 4 years later, a &lt;a href=&quot;http://code.google.com/p/pagingappfuse/wiki/CompassSearching&quot;&gt;Compass Tutorial&lt;/a&gt; was created and shortly after &lt;a href=&quot;http://www.kimchy.org/&quot;&gt;Shay Banon&lt;/a&gt; (Compass Founder), sent in a &lt;a href=&quot;http://issues.appfuse.org/browse/APF-267?focusedCommentId=12620&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12620&quot;&gt;patch&lt;/a&gt;. From the message he sent me:&lt;/p&gt;
&lt;div class=&quot;quote&quot; style=&quot;margin-left: 0; margin-bottom: 10px&quot;&gt;
&lt;p&gt;A quick breakdown of enabling search:
&lt;/p&gt;
&lt;ol style=&quot;margin-bottom: 0&quot;&gt;
&lt;li&gt;Added Searchable annotations to the User and Address.&lt;/li&gt;
&lt;li&gt;Defined Compass bean, automatically scanning the model package for mapped searchable classes. It also automatically integrates with Spring transaction manager, and stores the index on the file system ([work dir]/target/test-index).&lt;/li&gt;
&lt;li&gt;Defined CompassTemplate (similar in concept to HibernateTemplate).&lt;/li&gt;
&lt;li&gt;Defined CompassSearchHelper. Really helps to perform search since it does pagination and so on.&lt;/li&gt;
&lt;li&gt;Defined CompassGps, basically it allows for index operation allowing to completely reindex the data from the database. JPA and Hiberante also automatically mirror changes done through their API to the index. iBatis uses AOP. &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;Fast forward 2 years and I finally found the time/desire to put a UI on the backend Compass implementation that Shay provided. Yes, I realize that &lt;a href=&quot;http://www.kimchy.org/the_future_of_compass/&quot;&gt;Compass is being replaced by ElasticSearch&lt;/a&gt;. I may change to use ElasticSearch in the future; now that the search feature exists, I hope to see it evolve and improve.
&lt;/p&gt;
&lt;p&gt;Since Shay&apos;s patch integrated the necessary Spring beans for indexing and searching, the only thing I had to do was to implement the UI. Rather than having an &quot;all objects&quot; results page, I elected to implement it so you could search on an entity&apos;s list screen. I started with Spring MVC and added a search() method to the UserController:
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@RequestMapping(method = RequestMethod.GET)
public ModelAndView handleRequest(@RequestParam(required = false, value = &quot;q&quot;) String query) throws Exception {
    if (query != null &amp;&amp; !&quot;&quot;.equals(query.trim())) {
        return new ModelAndView(&quot;admin/userList&quot;, Constants.USER_LIST, search(query));
    } else {
        return new ModelAndView(&quot;admin/userList&quot;, Constants.USER_LIST, mgr.getUsers());
    }
}

public List&amp;lt;User&amp;gt; search(String query) {
    List&amp;lt;User&amp;gt; results = new ArrayList&amp;lt;User&amp;gt;();
    CompassDetachedHits hits = compassTemplate.findWithDetach(query);
    log.debug(&quot;No. of results for &apos;&quot; + query + &quot;&apos;: &quot; + hits.length());
    for (int i = 0; i &amp;lt; hits.length(); i++) {
        results.add((User) hits.data(i));
    }
    return results;
}
&lt;/pre&gt;
&lt;p&gt;At first, I used &lt;em&gt;compassTemplate.find()&lt;/em&gt;, but got an error because I wasn&apos;t using an OpenSessionInViewFilter. I decided to go with findWithDetach() and added the following search form to the top of the userList.jsp page:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;form method=&quot;get&quot; action=&quot;${ctx}/admin/users&quot; id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;input type=&quot;text&quot; size=&quot;20&quot; name=&quot;q&quot; id=&quot;query&quot; value=&quot;${param.q}&quot;
           placeholder=&quot;Enter search terms&quot;/&amp;gt;
    &amp;lt;input type=&quot;submit&quot; value=&quot;&amp;lt;fmt:message key=&quot;button.search&quot;/&amp;gt;&quot;/&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p style=&quot;color: #666; margin-left: 20px&quot;&gt;&lt;em&gt;NOTE: I tried using HTML5&apos;s &amp;lt;input type=&quot;search&quot;&amp;gt;, but found &lt;a href=&quot;http://lists.canoo.com/pipermail/webtest/2011q1/013697.html&quot; style=&quot;color: #666&quot;&gt;Canoo WebTest doesn&apos;t support it.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Next, I wrote a unit test to verify everything worked as expected. I found I had to call compassGps.index() as part of my test to make sure my index was created and up-to-date.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public class UserControllerTest extends BaseControllerTestCase {
    @Autowired
    private CompassGps compassGps;
    @Autowired
    private UserController controller;

    public void testSearch() throws Exception {
        compassGps.index();
        ModelAndView mav = controller.handleRequest(&quot;admin&quot;);
        Map m = mav.getModel();
        List results = (List) m.get(Constants.USER_LIST);
        assertNotNull(results);
        assertTrue(results.size() &amp;gt;= 1);
        assertEquals(&quot;admin/userList&quot;, mav.getViewName());
    }
}
&lt;/pre&gt;
&lt;p&gt;After getting this working, I started integrating similar code into AppFuse&apos;s other web framework modules (Struts, JSF and Tapestry). When I was finished, they all looked pretty similar from a UI perspective.
&lt;/p&gt;
&lt;p&gt;&lt;strong style=&quot;color: #666&quot;&gt;Struts:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;form method=&quot;get&quot; action=&quot;${ctx}/admin/users&quot; id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;input type=&quot;text&quot; size=&quot;20&quot; name=&quot;q&quot; id=&quot;query&quot; value=&quot;${param.q}&quot;
           placeholder=&quot;Enter search terms...&quot;/&amp;gt;
    &amp;lt;input type=&quot;submit&quot; value=&quot;&amp;lt;fmt:message key=&quot;button.search&quot;/&amp;gt;&quot;/&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong style=&quot;color: #666&quot;&gt;JSF:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;h:form id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;h:inputText id=&quot;q&quot; name=&quot;q&quot; size=&quot;20&quot; value=&quot;#{userList.query}&quot;/&amp;gt;
    &amp;lt;h:commandButton value=&quot;#{text&amp;#91;&apos;button.search&apos;&amp;#93;}&quot; action=&quot;#{userList.search}&quot;/&amp;gt;
&amp;lt;/h:form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong style=&quot;color: #666&quot;&gt;Tapestry:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;t:form method=&quot;get&quot; t:id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;t:textfield size=&quot;20&quot; name=&quot;q&quot; t:id=&quot;q&quot;/&amp;gt;
    &amp;lt;input t:type=&quot;submit&quot; value=&quot;${message:button.search}&quot;/&amp;gt;
&amp;lt;/t:form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;One frustrating thing I found was that &lt;a href=&quot;http://tapestry.1045711.n5.nabble.com/Is-there-any-way-to-render-the-quot-get-quot-method-of-form-td2643651.html&quot;&gt;Tapestry doesn&apos;t support method=&quot;get&quot;&lt;/a&gt; and AFAICT, neither does JSF 2. With JSF, I had to make my UserList bean session-scoped or the query parameter would be null when it listed the results. Tapestry took me the longest to implement, mainly because I had issues figuring out how it&apos;s easy-to-understand-once-you-know onSubmit() handlers worked and I had the proper @Property and @Persist annotations on my &quot;q&quot; property. &lt;a href=&quot;http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/&quot;&gt;This tutorial&lt;/a&gt; was the greatest help for me. Of course, now that it&apos;s all finished, the code looks pretty intuitive.&lt;/p&gt;
&lt;p&gt;Feeling proud of myself for getting this working, I started integrating this feature into AppFuse&apos;s code generation and found I had to add quite a bit of code to the generated list pages/controllers. 
&lt;/p&gt;
&lt;p&gt;
So I went on a bike ride...&lt;/p&gt;
&lt;p&gt;While riding, I thought of a much better solution and added the following search method to AppFuse&apos;s GenericManagerImpl.java. In the code I added to pages/controllers previously, I&apos;d already refactored to use CompassSearchHelper and I continued to do so in the service layer implementation.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Autowired
private CompassSearchHelper compass;

public List&amp;lt;T&amp;gt; search(String q, Class clazz) {
    if (q == null || &quot;&quot;.equals(q.trim())) {
        return getAll();
    }

    List&amp;lt;T&amp;gt; results = new ArrayList&amp;lt;T&amp;gt;();

    CompassSearchCommand command = new CompassSearchCommand(q);
    CompassSearchResults compassResults = compass.search(command);
    CompassHit&amp;#91;&amp;#93; hits = compassResults.getHits();

    if (log.isDebugEnabled() &amp;amp;&amp;amp; clazz != null) {
        log.debug(&quot;Filtering by type: &quot; + clazz.getName());
    }

    for (CompassHit hit : hits) {
        if (clazz != null) {
            if (hit.data().getClass().equals(clazz)) {
                results.add((T) hit.data());
            }
        } else {
            results.add((T) hit.data());
        }
    }

    if (log.isDebugEnabled()) {
        log.debug(&quot;Number of results for &apos;&quot; + q + &quot;&apos;: &quot; + results.size());
    }

    return results;
}
&lt;/pre&gt;
&lt;p&gt;This greatly simplified my page/controller logic because now all I had to do was call manager.search(query, User.class) instead of doing the Compass login in the controller. Of course, it&apos;d be great if I didn&apos;t have to pass in the Class to filter by object, but that&apos;s the &lt;a href=&quot;http://javanotepad.blogspot.com/2007/09/instanceof-doesnt-work-with-generics.html&quot;&gt;nature of generics and type erasure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Other things I learned along the way:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To index on startup, I added compassGps.index() to the StartupListener.&lt;/a&gt;.
&lt;li&gt;In unit tests that leveraged transactions around methods, I had to call compassGps.index() before any transactions started.&lt;/li&gt;
&lt;li&gt;To scan multiple packages for searchable classes, I had to add a &lt;a href=&quot;http://forum.compass-project.org/thread.jspa?threadID=216821&amp;tstart=0&quot;&gt;LocalCompassBeanPostProcessor&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But more than anything, I was reminded it always helps to take a bike ride when you don&apos;t like the design of your code. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
This feature and many more will be in AppFuse 2.1, which I hope to &lt;a href=&quot;http://issues.appfuse.org/secure/IssueNavigator.jspa?mode=hide&amp;requestId=10160&quot; title=&quot;Open Issues for 2.1&quot;&gt;finish by the end of the month&lt;/a&gt;. In the meantime, please feel free to try out the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;latest snapshot&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/upgrading_to_jsf_2</id>
        <title type="html">Upgrading to JSF 2</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/upgrading_to_jsf_2"/>
        <published>2011-03-07T13:24:53-07:00</published>
        <updated>2011-03-07T19:30:33-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="urlrewritefilter" scheme="http://roller.apache.org/ns/tags/" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="richfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tomahawk" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="facelets" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last week, I spent a few hours upgrading &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; from JSF 1.2 to JSF 2.0. In reality, I upgraded from &lt;a href=&quot;http://myfaces.apache.org&quot;&gt;MyFaces&lt;/a&gt; 1.2.7 to 2.0.4, but all JSF implementations should be the same, right? All in all, it was a pretty easy upgrade with a few minor AppFuse-specific things. My goal in upgrading was to do the bare minimum to get things working and to leave integration of JSF 2 features for a later date.&lt;/p&gt;

&lt;p&gt;In addition to upgrading MyFaces, I had to upgrade Tomahawk by changing the dependency&apos;s artifactId to &lt;strong&gt;tomahawk20&lt;/strong&gt;. I was also able to remove the following listener from my web.xml:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;listener&gt;
    &amp;lt;listener-class&gt;org.apache.myfaces.webapp.StartupServletContextListener&amp;lt;/listener-class&gt;
&amp;lt;listener&gt;
&lt;/pre&gt;
&lt;p&gt;After that, I discovered that MyFaces uses a new URI (/javax.faces.resource/) for serving up some of its resource files. I kindly asked Spring Security to ignore these requests by adding the following to my security.xml file.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;intercept-url pattern=&quot;/javax.faces.resource/**&quot; filters=&quot;none&quot;/&gt;
&lt;/pre&gt;
&lt;p&gt;Since JSF 2 includes Facelets by default, I tried removing Facelets as a dependency. After doing this, I received the following error:
&lt;/p&gt;
&lt;pre&gt;
ERROR [308855416@qtp-120902214-7] ViewHandlerWrapper.fillChain(158) | Error instantiation parent Faces ViewHandler
java.lang.ClassNotFoundException: com.sun.facelets.FaceletViewHandler
        at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:401)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:363)
        at org.ajax4jsf.framework.ViewHandlerWrapper.fillChain(ViewHandlerWrapper.java:144)
        at org.ajax4jsf.framework.ViewHandlerWrapper.calculateRenderKitId(ViewHandlerWrapper.java:68)
        at org.apache.myfaces.lifecycle.DefaultRestoreViewSupport.isPostback(DefaultRestoreViewSupport.java:179)
        at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:113)
        at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171)
        at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
&lt;/pre&gt;
&lt;p&gt;Figuring this was caused by the following element in my web.xml ...
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;context-param&amp;gt;
    &amp;lt;param-name&amp;gt;org.ajax4jsf.VIEW_HANDLERS&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;com.sun.facelets.FaceletViewHandler&amp;lt;/param-value&amp;gt;
&amp;lt;/context-param&amp;gt;
&lt;/pre&gt;
&lt;p&gt;... I removed it and tried again. This time I received a NoClassDefFoundError:&lt;/p&gt;
&lt;pre&gt;
java.lang.NoClassDefFoundError: com/sun/facelets/tag/TagHandler
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:392)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:363)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at org.apache.myfaces.shared_impl.util.ClassUtils.classForName(ClassUtils.java:184)
        at org.apache.myfaces.view.facelets.util.ReflectionUtil.forName(ReflectionUtil.java:67)
&lt;/pre&gt;
&lt;p&gt;Since everything seemed to work with Facelets in the classpath, I decided to save this headache for a later date. I entered two issues in AppFuse&apos;s JIRA, one for &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1234&quot;&gt;removing Facelets&lt;/a&gt; and one for &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1233&quot;&gt;replacing Ajax4JSF with RichFaces&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;The next issue I encountered was redirecting from AppFuse&apos;s password hint page. The navigation-rule for this page is as follows:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;navigation-rule&amp;gt;
    &amp;lt;from-view-id&amp;gt;/passwordHint.xhtml&amp;lt;/from-view-id&amp;gt;
    &amp;lt;navigation-case&amp;gt;
        &amp;lt;from-outcome&amp;gt;success&amp;lt;/from-outcome&amp;gt;
        &amp;lt;to-view-id&amp;gt;/login&amp;lt;/to-view-id&amp;gt;
        &amp;lt;redirect/&amp;gt;
    &amp;lt;/navigation-case&amp;gt;
&amp;lt;/navigation-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;With JSF 2.0, the rule changes the URL to /login.xhtml when redirecting (where it was left as /login with 1.2) and it was caught by the security setting in my web.xml that prevents users from viewing raw templates.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;security-constraint&amp;gt;
    &amp;lt;web-resource-collection&amp;gt;
        &amp;lt;web-resource-name&amp;gt;Protect XHTML Templates&amp;lt;/web-resource-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;*.xhtml&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/web-resource-collection&amp;gt;
    &amp;lt;auth-constraint/&amp;gt;
&amp;lt;/security-constraint&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To solve this issue, I had to make a couple of changes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Comment out the security-constraint in web.xml and move it to Spring Security&apos;s security.xml file.
&lt;pre class=&quot;brush: xml; toolbar: false&quot; style=&quot;margin: 5px 0 0 0&quot;&gt;
&amp;lt;intercept-url pattern=&quot;/**/*.xhtml&quot; access=&quot;ROLE_NOBODY&quot;/&gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Add a rule to urlrewrite.xml that redirects back to login (since login.xhtml doesn&apos;t exist and I&apos;m using extensionless URLs).
&lt;pre class=&quot;brush: xml&quot; style=&quot;margin: 5px 0 0 0&quot;&gt;
&amp;lt;rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^/login.xhtml$&amp;lt;/from&amp;gt;
    &amp;lt;to type=&quot;redirect&quot;&amp;gt;%{context-path}/login&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After getting the Password Hint feature passing in the browser, I tried running the integration tests (powered by &lt;a href=&quot;http://webtest.canoo.com&quot;&gt;Canoo WebTest&lt;/a&gt;). The Password Hint test kept failing with the following error:
&lt;/p&gt;
&lt;pre&gt;
[ERROR] /Users/mraible/dev/appfuse/web/jsf/src/test/resources/web-tests.xml:51: JavaScript error loading
page http://localhost:9876/appfuse-jsf-2.1.0-SNAPSHOT/passwordHint?username=admin: syntax error (http://
localhost:9876/appfuse-jsf-2.1.0-SNAPSHOT/javax.faces.resource/oamSubmit.js.jsf?ln=org.apache.myfaces#122)
&lt;/pre&gt;
&lt;p&gt;Figuring this was caused by my hack to &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/passwordHint.xhtml?r=2866&quot;&gt;submit the form when the page was loaded&lt;/a&gt;, I turned to &lt;a href=&quot;http://ocpsoft.com/prettyfaces/&quot;&gt;Pretty Faces&lt;/a&gt;, which allows you to call a method directly from a URL. After adding the Pretty Faces dependencies to my pom.xml, I created a src/main/webapp/WEB-INF/pretty-config.xml file with the following XML:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;url-mapping&amp;gt;
    &amp;lt;pattern value=&quot;/editProfile&quot;/&amp;gt;
    &amp;lt;view-id value=&quot;/userForm.jsf&quot;/&amp;gt;
    &amp;lt;action&amp;gt;#{userForm.edit}&amp;lt;/action&amp;gt;
&amp;lt;/url-mapping&amp;gt;

&amp;lt;url-mapping&amp;gt;
    &amp;lt;pattern value=&quot;/passwordHint/#{username}&quot;/&amp;gt;
    &amp;lt;view-id value=&quot;/passwordHint.jsf&quot;/&amp;gt;
    &amp;lt;action&amp;gt;#{passwordHint.execute}&amp;lt;/action&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This allowed me to remove both editProfile.xhtml and passwordHint.xhtml, both of which simply auto-submitted forms.&lt;/p&gt;
&lt;p&gt;At this point, I figured I&apos;d be good to go and ran my integration tests again. The first thing I discovered was that &quot;.jsf&quot; was being tacked onto my pretty URL, most likely by the UrlRewriteFilter. Adding the following to my PasswordHint.java class solved this.
&lt;/p&gt;
&lt;pre class=&quot;brush: java; toolbar: false&quot;&gt;
if (username.endsWith(&quot;.jsf&quot;)) {
    username = username.substring(0, username.indexOf(&quot;.jsf&quot;));
}
&lt;/pre&gt;
&lt;p&gt;The next thing was a cryptic error that took me a while to figure out.&lt;/p&gt;
&lt;pre&gt;
DEBUG [1152467051@qtp-144702232-0] PasswordHint.execute(38) | Processing Password Hint...
2011-03-05 05:48:52.471:WARN::/passwordHint/admin
com.ocpsoft.pretty.PrettyException: Exception occurred while processing &amp;lt;:#{passwordHint.execute}&gt; null
        at com.ocpsoft.pretty.faces.beans.ActionExecutor.executeActions(ActionExecutor.java:71)
        at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.processEvent(PrettyPhaseListener.java:214)
        at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.afterPhase(PrettyPhaseListener.java:108)
        at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:111)
        at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:185)
        at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
&lt;/pre&gt;
&lt;p&gt;Digging into the bowels of MyFaces, I discovered a class was looking for a viewId with an extension and no view-id was being set. Adding the following to the top of my execute() method solved this.
&lt;/p&gt;
&lt;pre class=&quot;brush: java; toolbar: false&quot;&gt;
getFacesContext().getViewRoot().setViewId(&quot;/passwordHint.xhtml&quot;);
&lt;/pre&gt;
&lt;p&gt;After making this change, all AppFuse&apos;s integration tests are passing and the upgrade seems complete. The only other issues I encountered were logging-related. The first is an error about Tomahawk that doesn&apos;t seem to affect anything.
&lt;/p&gt;
&lt;pre&gt;
Mar 5, 2011 6:44:01 AM com.sun.facelets.compiler.TagLibraryConfig loadImplicit
SEVERE: Error Loading Library: jar:file:/Users/mraible/.m2/repository/org/apache/myfaces/tomahawk/tomahawk20/1.1.10/tomahawk20-1.1.10.jar!/META-INF/tomahawk.taglib.xml
java.io.IOException: Error parsing [jar:file:/Users/mraible/.m2/repository/org/apache/myfaces/tomahawk/tomahawk20/1.1.10/tomahawk20-1.1.10.jar!/META-INF/tomahawk.taglib.xml]: 
        at com.sun.facelets.compiler.TagLibraryConfig.create(TagLibraryConfig.java:410)
        at com.sun.facelets.compiler.TagLibraryConfig.loadImplicit(TagLibraryConfig.java:431)
        at com.sun.facelets.compiler.Compiler.initialize(Compiler.java:87)
        at com.sun.facelets.compiler.Compiler.compile(Compiler.java:104)
&lt;/pre&gt;
&lt;p&gt;The second is excessive logging from MyFaces. As far as I can tell, this is because MyFaces switched to java.util.logging instead of commons logging. With all the frameworks that AppFuse leverages, I think it has all the logging frameworks in its classpath now. I was hoping to fix this by &lt;a href=&quot;http://old.nabble.com/Turn-down-logging-in-2.0.4--td31068698.html&quot;&gt;posting a message to the mailing list&lt;/a&gt;, but haven&apos;t received a reply yet.
&lt;/p&gt;
&lt;pre&gt;
[WARNING] [talledLocalContainer] Mar 5, 2011 6:50:25 AM org.apache.myfaces.config.annotation.TomcatAnnotationLifecycleProvider newInstance
[WARNING] [talledLocalContainer] INFO: Creating instance of org.appfuse.webapp.action.BasePage
[WARNING] [talledLocalContainer] Mar 5, 2011 6:50:25 AM org.apache.myfaces.config.annotation.TomcatAnnotationLifecycleProvider destroyInstance
[WARNING] [talledLocalContainer] INFO: Destroy instance of org.appfuse.webapp.action.BasePage
&lt;/pre&gt;
&lt;p&gt;After successfully upgrading AppFuse, I turned to AppFuse Light, where things were &lt;a href=&quot;http://source.appfuse.org/changelog/appfuse-light/?cs=243&quot;&gt;much easier&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Now that AppFuse uses JSF 2, I hope to start leveraging some of its &lt;a href=&quot;http://www.ibm.com/developerworks/java/library/j-jsf2fu1/index.html&quot;&gt;new features&lt;/a&gt;. If you&apos;re yearning to get started with them today, I invite you to &lt;a href=&quot;http://appfuse.org/display/APF/Source+Repository&quot;&gt;grab the source&lt;/a&gt; and start integrating them yourself.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/fixing_xss_in_jsp_2</id>
        <title type="html">Fixing XSS in JSP 2</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/fixing_xss_in_jsp_2"/>
        <published>2011-02-28T14:08:46-07:00</published>
        <updated>2012-11-11T02:00:40-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="tomcat" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsp" scheme="http://roller.apache.org/ns/tags/" />
        <category term="xss" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appsec" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Way back in 2007, I wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_frameworks_and_xss&quot;&gt;Java Web Frameworks and XSS&lt;/a&gt;. My main point was that JSP EL &lt;a href=&quot;http://www.sleberknight.com/blog/sleberkn/entry/20060721&quot;&gt;doesn&apos;t bother to handle XSS&lt;/a&gt;. &lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Of course, the whole problem with JSP EL could be solved if Tomcat (and other containers) would allow a flag to turn on XML escaping by default. IMO, it&apos;s badly needed to make JSP-based webapps safe from XSS. &lt;/p&gt;
&lt;p&gt;A couple months later, I &lt;a href=&quot;http://raibledesigns.com/rd/entry/proposed_tomcat_enhancement_add_flag&quot;&gt;proposed a Tomcat enhancement to escape JSP&apos;s EL by default&lt;/a&gt;. I also entered an &lt;a href=&quot;http://issues.apache.org/bugzilla/show_bug.cgi?id=43497&quot;&gt;enhancement request&lt;/a&gt; for this feature and attached a patch. That issue has remained open and unfixed for 3 and 1/2 years. 
&lt;/p&gt;
&lt;p&gt;Yesterday, Chin Huang posted a handy-dandy &lt;a href=&quot;http://pukkaone.github.com/2011/01/03/jsp-cross-site-scripting-elresolver.html&quot;&gt;ELResolver that XML-escapes EL values&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I tried Chin&apos;s resolver in AppFuse today and it works as well as advertised. To do this, I copied his &lt;a href=&quot;https://github.com/pukkaone/webappenhance/tree/master/src/com/github/pukkaone/jsp&quot;&gt;EscapeXML*.java files&lt;/a&gt; into my project, changed the JSP API&apos;s Maven coordinates from javax.servlet:jsp-api:2.0 to javax.servlet.jsp:jsp-api:2.1 and added the listener to web.xml. 
&lt;/p&gt;
&lt;p&gt;
With Struts 2 and Spring MVC, I was previously able to have ${param.xss} and pass in ?xss=&amp;lt;script&amp;gt;alert(&apos;gotcha&apos;)&amp;lt;/script&gt; and it would show a JavaScript alert. After using Chin&apos;s ELResolver, it prints the string on the page instead of displaying an alert.&lt;/p&gt;
&lt;p&gt;Thanks to Chin Huang for this patch! If you&apos;re using JSP, I highly recommend you add this to your projects as well.
    
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/upcoming_conferences_tssjs_in_las</id>
        <title type="html">Upcoming Conferences: TSSJS in Las Vegas and 33rd Degree in Krak&#243;w, Poland</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/upcoming_conferences_tssjs_in_las"/>
        <published>2011-02-25T15:14:59-07:00</published>
        <updated>2012-11-08T14:31:01-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="ujug" scheme="http://roller.apache.org/ns/tags/" />
        <category term="uberconf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tssjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="conference" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vegas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="poland" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jazoon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="33degree" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">It&apos;s that time of year again - the beginning of Conference Season. I generally like to speak at a few conferences a year and 2011 is no different. For March Madness, I&apos;ll be heading to Las Vegas to speak at &lt;a href=&quot;http://javasymposium.techtarget.com&quot;&gt;TheServerSide Java Symposium&lt;/a&gt;. I&apos;ll be giving updated talks similar to the ones I gave at last year&apos;s &lt;a href=&quot;http://www.therichwebexperience.com/conference/fort_lauderdale/2010/11/speakers/matt_raible&quot;&gt;Rich Web Experience&lt;/a&gt; in Fort Lauderdale:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/my_everything_you_ever_wanted&quot;&gt;Everything You Ever Wanted To Know About Online Video&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks&quot;&gt;Comparing JVM Web Frameworks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You might remember my Comparing JVM Web Frameworks talk from &lt;a href=&quot;http://raibledesigns.com/rd/entry/an_awesome_trip_to_amsterdam&quot;&gt;Devoxx 2010&lt;/a&gt; and some of the &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_i_calculated_ratings_for&quot;&gt;interesting debate&lt;/a&gt; it caused. I&apos;ve done some minor updates to my video presentation and some updates to my JVM Web Frameworks presentation as well. Most notably, I&apos;ll be including some findings from &lt;a href=&quot;http://ptrthomas.wordpress.com&quot;&gt;Peter Thomas&apos;s&lt;/a&gt; &lt;a href=&quot;http://code.google.com/p/perfbench/&quot;&gt;perfbench project&lt;/a&gt;. I also hope to update &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; to JSF 2 and integrate extensionless URLs in AppFuse Light. Marcin Zajaczkowski was nice enough to provide an upgrade to &lt;a href=&quot;http://issues.appfuse.org/browse/EQX-209&quot;&gt;Wicket 1.4.15&lt;/a&gt;, so it&apos;ll be interesting to see how well Wicket supports extensionless URLs. 
&lt;/p&gt;
&lt;p&gt;In April, I&apos;ll be presenting Comparing JVM Web Frameworks at the &lt;a href=&quot;http://33degree.org/&quot;&gt;33rd Degree Conference&lt;/a&gt; in Krak&#243;w, Poland. While I studied in Russia a couple summers in college, I&apos;ve never been to Poland, so I&apos;m really looking forward to this trip. With any luck, I&apos;ll have AppFuse 2.1 released by then and my knowledge of all its web frameworks&apos; latest versions will be update-to-date. As you know, it&apos;s unlikely I&apos;ll recommend a &lt;em&gt;best&lt;/em&gt; web framework (because there isn&apos;t one), but I hope to provide some techniques you can use to decide the best framework for your particular needs.&lt;/p&gt;
&lt;p&gt;In addition to Vegas and Poland, there&apos;s a couple other events I might speak at in the next few months: the &lt;a href=&quot;http://www.ujug.org/&quot;&gt;Utah Java Users Group&lt;/a&gt; (possibly in April), &lt;a href=&quot;http://jazoon.com/&quot;&gt;Jazoon&lt;/a&gt; and &lt;a href=&quot;http://uberconf.com/conference/denver/2011/07/home&quot;&gt;&#220;ber Conf&lt;/a&gt; (if my proposals are accepted). For these events, I&apos;m hoping to present the following talk:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
&lt;strong&gt;Webapp Security: Develop. Penetrate. Protect. Relax.&lt;/strong&gt;&lt;br/&gt;
In this session, you&apos;ll learn how to implement authentication in your Java web applications using Spring Security, Apache Shiro and good ol&apos; Java EE Container Managed Authentication. You&apos;ll also learn how to secure your REST API with OAuth and lock it down with SSL.
&lt;br/&gt;&lt;br/&gt;
After learning how to develop authentication, I&apos;ll introduce you to OWASP, the OWASP Top 10, its Testing Guide and its Code Review Guide. From there, I&apos;ll discuss using WebGoat to verify your app is secure and commercial tools like webapp firewalls and accelerators.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;If you&apos;re planning on attending &lt;a href=&quot;http://javasymposium.techtarget.com&quot;&gt;TSSJS&lt;/a&gt; or &lt;a href=&quot;http://33degree.org/&quot;&gt;33rd Degree&lt;/a&gt;, hopefully I&apos;ll see you there. </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery</id>
        <title type="html">Implementing Ajax Authentication using jQuery, Spring Security and HTTPS</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery"/>
        <published>2011-02-23T16:55:55-07:00</published>
        <updated>2012-11-11T02:00:40-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jquery" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="owasp" scheme="http://roller.apache.org/ns/tags/" />
        <category term="authentication" scheme="http://roller.apache.org/ns/tags/" />
        <category term="overstock.com" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ajax" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse-light" scheme="http://roller.apache.org/ns/tags/" />
        <category term="https" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">I&apos;ve always had a keen interest in implementing security in webapps. I implemented container-managed authentication (CMA) in &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; in 2002, watched &lt;a href=&quot;http://raibledesigns.com/rd/entry/container_managed_authentication_enhancements_in&quot;&gt;Tomcat improve it&apos;s implementation in 2003&lt;/a&gt; and &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_refactorings_part_iii_remember&quot;&gt;implemented Remember Me with CMA&lt;/a&gt; in 2004. In 2005, I &lt;a href=&quot;http://raibledesigns.com/rd/entry/ann_appfuse_1_8_released&quot;&gt;switched from CMA to Acegi Security&lt;/a&gt; (now &lt;a href=&quot;http://static.springsource.org/spring-security/site/&quot;&gt;Spring Security&lt;/a&gt;) and never looked back. I&apos;ve been very happy with Spring Security over the years, but also hope to learn more about &lt;a href=&quot;http://shiro.apache.org/&quot;&gt;Apache Shiro&lt;/a&gt; and &lt;a href=&quot;http://www.quora.com/Is-OAuth-the-best-way-to-implement-security-for-a-JavaScript-API&quot;&gt;implementing OAuth to protect JavaScript APIs&lt;/a&gt; in the near future.
&lt;/p&gt;
&lt;p&gt;I was recently re-inspired to learn more about security when working on a new feature at &lt;a href=&quot;http://www.overstock.com&quot;&gt;Overstock.com&lt;/a&gt;. The feature hasn&apos;t been released yet, but basically boils down to allowing users to login without leaving a page. For example, if they want to leave a review on a product, they would click a link, be prompted to login, enter their credentials, then continue to leave their review. The login prompt and subsequent review would likely be implemented using a lightbox. While lightboxes are often seen in webapps these days because they look good, it&apos;s also possible &lt;a href=&quot;http://uxexchange.com/questions/1877/the-usability-of-lightbox-uis&quot;&gt;Lightbox UIs provide a poor user experience&lt;/a&gt;. User experience aside, I think it&apos;s interesting to see what&apos;s required to implement such a feature.
&lt;/p&gt;
&lt;p&gt;To demonstrate how we did it, I whipped up an example using AppFuse Light, jQuery and Spring Security. The source is available in my &lt;a href=&quot;https://github.com/mraible/ajax-login&quot;&gt;ajax-login&lt;/a&gt; project on GitHub. To begin, I wanted to accomplish a number of things to replicate the Overstock environment:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Force HTTPS for authentication.&lt;/li&gt;
&lt;li&gt;Allow testing HTTPS without installing a certificate locally.&lt;/li&gt;
&lt;li&gt;Implement a RESTful LoginService that allows users to login.&lt;/li&gt;
&lt;li&gt;Implement login with Ajax, with the request coming from an insecure page.&lt;/li&gt;
&lt;/ol&gt;
&lt;p id=&quot;force-https&quot;&gt;&lt;strong&gt;Forcing HTTPS with Spring Security&lt;/strong&gt;&lt;br/&gt;
The first feature was fairly easy to implement thanks to Spring Security. Its configuration supports a &lt;a href=&quot;http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-requires-channel&quot;&gt;requires-channel&lt;/a&gt; attribute that can be used for this. I used this to force HTTPS on the &quot;users&quot; page and it subsequently causes the login to be secure.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;intercept-url pattern=&quot;/app/users&quot; access=&quot;ROLE_ADMIN&quot; requires-channel=&quot;https&quot;/&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;testing-https&quot;&gt;&lt;strong&gt;Testing HTTPS without adding a certificate locally&lt;/strong&gt;&lt;br/&gt;
After making the above change in &lt;a href=&quot;https://github.com/mraible/ajax-login/blob/master/src/main/webapp/WEB-INF/security.xml&quot;&gt;security.xml&lt;/a&gt;, I had to modify my &lt;a href=&quot;https://github.com/mraible/ajax-login/blob/master/src/test/java/org/appfuse/examples/web/UserWebTest.java&quot;&gt;jWebUnit test&lt;/a&gt; to work with SSL. In reality, I didn&apos;t have to modify the test, I just had to modify the configuration that ran the test. In my &lt;a href=&quot;http://raibledesigns.com/rd/entry/integration_testing_with_http_https&quot;&gt;last post&lt;/a&gt;, I wrote about &lt;a href=&quot;http://blogs.sun.com/gc/entry/unable_to_find_valid_certification&quot;&gt;adding my &apos;untrusted&apos; cert to my JVM keystore&lt;/a&gt;. For some reason, this works for HttpClient, but not for jWebUnit/HtmlUnit. The good news is I figured out an easier solution - adding the trustStore and trustStore password as system properties to the maven-failsafe-plugin configuration.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;artifactId&amp;gt;maven-failsafe-plugin&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;2.7.2&amp;lt;/version&amp;gt;
&amp;lt;configuration&amp;gt;
    &amp;lt;includes&amp;gt;
        &amp;lt;include&amp;gt;**/*WebTest.java&amp;lt;/include&amp;gt;
    &amp;lt;/includes&amp;gt;
    &amp;lt;systemPropertyVariables&amp;gt;
      &amp;lt;javax.net.ssl.trustStore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/javax.net.ssl.trustStore&amp;gt;
      &amp;lt;javax.net.ssl.trustStorePassword&amp;gt;appfuse&amp;lt;/javax.net.ssl.trustStorePassword&amp;gt;
    &amp;lt;/systemPropertyVariables&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The disadvantage to doing things this way is you&apos;ll have to pass these in as arguments when running unit tests in your IDE.&lt;/p&gt;
&lt;p id=&quot;login-service&quot;&gt;&lt;strong&gt;Implementing a LoginService&lt;/strong&gt;&lt;br/&gt;
Next, I set about implementing a LoginService as a Spring MVC Controller that returns JSON thanks to the &lt;a href=&quot;http://blog.springsource.com/2010/01/25/ajax-simplifications-in-spring-3-0/&quot;&gt;@ResponseBody annotation and Jackson&lt;/a&gt;.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package org.appfuse.examples.web;

import org.appfuse.model.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(&quot;/api/login.json&quot;)
public class LoginService {

  @Autowired
  @Qualifier(&quot;authenticationManager&quot;)
  AuthenticationManager authenticationManager;

  @RequestMapping(method = RequestMethod.GET)
  @ResponseBody
  public LoginStatus getStatus() {
    Authentication auth = SecurityContextHolder.getContext().getAuthentication();
    if (auth != null &amp;&amp; !auth.getName().equals(&quot;anonymousUser&quot;) &amp;&amp; auth.isAuthenticated()) {
      return new LoginStatus(true, auth.getName());
    } else {
      return new LoginStatus(false, null);
    }
  }

  @RequestMapping(method = RequestMethod.POST)
  @ResponseBody
  public LoginStatus login(@RequestParam(&quot;j_username&quot;) String username,
                           @RequestParam(&quot;j_password&quot;) String password) {

    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
    User details = new User(username);
    token.setDetails(details);

    try {
      Authentication auth = authenticationManager.authenticate(token);
      SecurityContextHolder.getContext().setAuthentication(auth);
      return new LoginStatus(auth.isAuthenticated(), auth.getName());
    } catch (BadCredentialsException e) {
      return new LoginStatus(false, null);
    }
  }

  public class LoginStatus {

    private final boolean loggedIn;
    private final String username;

    public LoginStatus(boolean loggedIn, String username) {
      this.loggedIn = loggedIn;
      this.username = username;
    }

    public boolean isLoggedIn() {
      return loggedIn;
    }

    public String getUsername() {
      return username;
    }
  }
}
&lt;/pre&gt;
&lt;p&gt;To verify this class worked as expected, I wrote a unit test using JUnit and &lt;a href=&quot;http://mockito.org/&quot;&gt;Mockito&lt;/a&gt;. I used Mockito because Overstock is transitioning to it from EasyMock and I&apos;ve found it very simple to use.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package org.appfuse.examples.web;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Matchers;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.authentication.TestingAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.context.SecurityContextImpl;

import static org.junit.Assert.*;
import static org.mockito.Mockito.*;

public class LoginServiceTest {

  LoginService loginService;
  AuthenticationManager authenticationManager;

  @Before
  public void before() {
    loginService = new LoginService();
    authenticationManager = mock(AuthenticationManager.class);
    loginService.authenticationManager = authenticationManager;
  }

  @After
  public void after() {
    SecurityContextHolder.clearContext();
  }

  @Test
  public void testLoginStatusSuccess() {
    Authentication auth = new TestingAuthenticationToken(&quot;foo&quot;, &quot;bar&quot;);
    auth.setAuthenticated(true);
    SecurityContext context = new SecurityContextImpl();
    context.setAuthentication(auth);
    SecurityContextHolder.setContext(context);

    LoginService.LoginStatus status = loginService.getStatus();
    assertTrue(status.isLoggedIn());
  }

  @Test
  public void testLoginStatusFailure() {
    LoginService.LoginStatus status = loginService.getStatus();
    assertFalse(status.isLoggedIn());
  }

  @Test
  public void testGoodLogin() {
    Authentication auth = new TestingAuthenticationToken(&quot;foo&quot;, &quot;bar&quot;);
    auth.setAuthenticated(true);
    when(authenticationManager.authenticate(Matchers.&amp;lt;Authentication&amp;gt;anyObject())).thenReturn(auth);
    LoginService.LoginStatus status = loginService.login(&quot;foo&quot;, &quot;bar&quot;);
    assertTrue(status.isLoggedIn());
    assertEquals(&quot;foo&quot;, status.getUsername());
  }

  @Test
  public void testBadLogin() {
    Authentication auth = new TestingAuthenticationToken(&quot;foo&quot;, &quot;bar&quot;);
    auth.setAuthenticated(false);
    when(authenticationManager.authenticate(Matchers.&lt;Authentication&gt;anyObject()))
        .thenThrow(new BadCredentialsException(&quot;Bad Credentials&quot;));
    LoginService.LoginStatus status = loginService.login(&quot;foo&quot;, &quot;bar&quot;);
    assertFalse(status.isLoggedIn());
    assertEquals(null, status.getUsername());
  }
}
&lt;/pre&gt;
&lt;p id=&quot;ajax-login&quot;&gt;&lt;strong&gt;Implement login with Ajax&lt;/strong&gt;&lt;br/&gt;
The last feature was the hardest to implement and still isn&apos;t fully working as I&apos;d hoped. I used jQuery and jQuery UI to implement a dialog that opens the login page on the same page rather than redirecting to the login page. The &quot;#demo&quot; locator refers to a button in the page.
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Passing in the &quot;ajax=true&quot; parameter disables SiteMesh decoration on the login page, something that&apos;s described in my &lt;a href=&quot;http://raibledesigns.com/rd/entry/ajaxified_body&quot;&gt;Ajaxified Body&lt;/a&gt; article.
&lt;/p&gt;
&lt;pre class=&quot;brush: js&quot;&gt;
var dialog = $(&apos;&amp;lt;div&gt;&amp;lt;/div&gt;&apos;);

$(document).ready(function() {
    $.get(&apos;/login?ajax=true&apos;, function(data) {
        dialog.html(data);
        dialog.dialog({
            autoOpen: false,
	       title: &apos;Authentication Required&apos;
        });
    });

    $(&apos;#demo&apos;).click(function() {
      dialog.dialog(&apos;open&apos;);
      // prevent the default action, e.g., following a link
      return false;
    });
});
&lt;/pre&gt;
&lt;p class=&quot;quote&quot;&gt;
Instead of adding a click handler to a specific id, it&apos;s probably better to use a CSS class that indicates authentication is required for a link, or -- even better -- use Ajax to see if the link is secured.
&lt;/p&gt;
&lt;p&gt;The login page then has the following JavaScript to add a click handler to the &quot;login&quot; button that submits the request securely to the LoginService.
&lt;/p&gt;
&lt;pre class=&quot;brush: js&quot;&gt;
var getHost = function() {
    var port = (window.location.port == &quot;8080&quot;) ? &quot;:8443&quot; : &quot;&quot;;
    return ((secure) ? &apos;https://&apos; : &apos;http://&apos;) + window.location.hostname + port;
};

var loginFailed = function(data, status) {
    $(&quot;.error&quot;).remove();
    $(&apos;#username-label&apos;).before(&apos;&amp;lt;div class=&quot;error&quot;&gt;Login failed, please try again.&amp;lt;/div&gt;&apos;);
};

$(&quot;#login&quot;).live(&apos;click&apos;, function(e) {
    e.preventDefault();
    $.ajax({url: getHost() + &quot;/api/login.json&quot;,
        type: &quot;POST&quot;,
        data: $(&quot;#loginForm&quot;).serialize(),
        success: function(data, status) {
            if (data.loggedIn) {
                // success
                dialog.dialog(&apos;close&apos;);
                location.href= getHost() + &apos;/users&apos;;
            } else {
                loginFailed(data);
            }
        },
        error: loginFailed
    });
});
&lt;/pre&gt;
&lt;p&gt;The biggest secret to making this all work (the HTTP -&gt; HTTPS communication, which is considered cross-domain), is the &lt;a href=&quot;http://www.sitepen.com/blog/2008/07/22/windowname-transport/&quot;&gt;window.name Transport&lt;/a&gt; and the &lt;a href=&quot;http://friedcellcollective.net/outbreak/jsjquerywindownameplugin/&quot;&gt;jQuery plugin&lt;/a&gt; that implements it. To make this plugin work with Firefox 3.6, I had to implement a Filter that adds Access-Control headers. &lt;a href=&quot;http://stackoverflow.com/questions/1099787/jquery-ajax-post-sending-options-as-request-method-in-firefox&quot;&gt;A question on Stackoverflow&lt;/a&gt; helped me figure this out.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public class OptionsHeadersFilter implements Filter {

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
            throws IOException, ServletException {
        HttpServletResponse response = (HttpServletResponse) res;

        response.setHeader(&quot;Access-Control-Allow-Origin&quot;, &quot;*&quot;);
        response.setHeader(&quot;Access-Control-Allow-Methods&quot;, &quot;GET,POST&quot;);
        response.setHeader(&quot;Access-Control-Max-Age&quot;, &quot;360&quot;);
        response.setHeader(&quot;Access-Control-Allow-Headers&quot;, &quot;x-requested-with&quot;);

        chain.doFilter(req, res);
    }

    public void init(FilterConfig filterConfig) {
    }

    public void destroy() {
    }
}
&lt;/pre&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Issues&lt;/strong&gt;&lt;br/&gt;
I encountered a number of issues when implementing this in the &lt;a href=&quot;https://github.com/mraible/ajax-login&quot;&gt;ajax-login&lt;/a&gt; project. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If you try to run this with ports (e.g. 8080 and 8443) in your URLs, you&apos;ll get a 501 (Not Implemented) response. Removing the ports by fronting with &lt;a href=&quot;http://raibledesigns.com/rd/entry/apache_2_on_os_x&quot;&gt;Apache and mod_proxy&lt;/a&gt; solves this problem.
&lt;li&gt;If you haven&apos;t accepted the certificate in your browser, the Ajax request will fail. In the example, I solved this by clicking on the &quot;Users&quot; tab to make a secure request, then going back to the homepage to try and login.&lt;/li&gt;
&lt;li&gt;The jQuery window.name version 0.9.1 doesn&apos;t work with jQuery 1.5.0. The error is &quot;$.httpSuccess function not found.&quot;&lt;/li&gt;
&lt;li&gt;Finally, even though I was able to authenticate successfully, I was &lt;a href=&quot;http://stackoverflow.com/questions/5087137/is-it-possible-to-programmatically-authenticate-with-spring-security-and-make-it&quot;&gt;unable to make the authentication persist&lt;/a&gt;.  I tried adding the following to persist the updated SecurityContext to the session, but it doesn&apos;t work. I expect the solution is to create a secure JSESSIONID cookie somehow.
&lt;pre class=&quot;brush: java&quot;&gt;
@Autowired
SecurityContextRepository repository;

@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public LoginStatus login(@RequestParam(&quot;j_username&quot;) String username,
                         @RequestParam(&quot;j_password&quot;) String password,
                         HttpServletRequest request, HttpServletResponse response) {

    UsernamePasswordAuthenticationToken token = new UsernamePasswordAuthenticationToken(username, password);
    ...

    try {
        Authentication auth = authenticationManager.authenticate(token);
        SecurityContextHolder.getContext().setAuthentication(auth);
        // save the updated context to the session
        repository.saveContext(SecurityContextHolder.getContext(), request, response);
        return new LoginStatus(auth.isAuthenticated(), auth.getName());
    } catch (BadCredentialsException e) {
        return new LoginStatus(false, null);
    }
}
&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;
This article has shown you how to force HTTPS for login, how to do integration testing with a self-generated certificate, how to implement a LoginService with Spring MVC and Spring Security, as well as how to use jQuery to talk to a service cross-domain with the window.name Transport. While I don&apos;t have everything working as much as I&apos;d like, I hope this helps you implement a similar feature in your applications. 
&lt;/p&gt;
&lt;p&gt;
One thing to be aware of is with lightbox/dialog logins and HTTP -&gt; HTTPS is that users won&apos;t see a secure icon in their address bar. If your app has sensitive data, you might want to force https for your entire app. OWASP&apos;s &lt;a href=&quot;http://www.owasp.org/index.php/SSL_Best_Practices#Secure_Login_Pages&quot;&gt;Secure Login Pages&lt;/a&gt; has a lot of good tips in this area.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I&apos;ve posted a &lt;a href=&quot;http://demo.raibledesigns.com/ajax-login/&quot;&gt;demo of the ajax-login webapp&lt;/a&gt;. Thanks to &lt;a href=&quot;http://www.contegix.com/&quot;&gt;Contegix&lt;/a&gt; for hosting the demo and helping obtain/install an SSL certificate so quickly.
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/integration_testing_with_http_https</id>
        <title type="html">Integration Testing with HTTP, HTTPS and Maven</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/integration_testing_with_http_https"/>
        <published>2011-02-11T15:54:16-07:00</published>
        <updated>2012-11-11T02:00:40-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="cargo" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jetty" scheme="http://roller.apache.org/ns/tags/" />
        <category term="overstock.com" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ssl" scheme="http://roller.apache.org/ns/tags/" />
        <category term="http" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tomcat" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="https" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Earlier this week, I was tasked with getting automated integration tests working in my project at &lt;a href=&quot;http://overstock.com&quot;&gt;Overstock.com&lt;/a&gt;. By &lt;em&gt;automated&lt;/em&gt;, I mean that ability to run &quot;mvn install&quot; and have the following process cycled through: 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start a container&lt;/li&gt;
&lt;li&gt;Deploy the application&lt;/li&gt;
&lt;li&gt;Run all integration tests&lt;/li&gt;
&lt;li&gt;Stop the container&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since it makes sense for integration tests to run in Maven&apos;s &lt;em&gt;integration-test&lt;/em&gt; phase, I first configured the maven-surefire-plugin to skip tests in the &lt;em&gt;test&lt;/em&gt; phase and execute them in the &lt;em&gt;integration-test&lt;/em&gt; phase. I used the &amp;lt;id&gt;&lt;strong&gt;default-&lt;/strong&gt;&lt;em&gt;phase&lt;/em&gt;&amp;lt;/id&gt; syntax to override the plugins&apos; usual behavior.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
  &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
  &amp;lt;executions&amp;gt;
    &amp;lt;execution&amp;gt;
      &amp;lt;id&amp;gt;default-test&amp;lt;/id&amp;gt;
      &amp;lt;configuration&amp;gt;
        &amp;lt;excludes&amp;gt;
          &amp;lt;exclude&amp;gt;**/*Test*.java&amp;lt;/exclude&amp;gt;
        &amp;lt;/excludes&amp;gt;
      &amp;lt;/configuration&amp;gt;
    &amp;lt;/execution&amp;gt;
    &amp;lt;execution&amp;gt;
      &amp;lt;id&amp;gt;default-integration-test&amp;lt;/id&amp;gt;
      &amp;lt;phase&amp;gt;integration-test&amp;lt;/phase&amp;gt;
      &amp;lt;goals&amp;gt;
        &amp;lt;goal&amp;gt;test&amp;lt;/goal&amp;gt;
      &amp;lt;/goals&amp;gt;
      &amp;lt;configuration&amp;gt;
        &amp;lt;includes&amp;gt;
          &amp;lt;include&amp;gt;**/*Test.java&amp;lt;/include&amp;gt;
        &amp;lt;/includes&amp;gt;
        &amp;lt;excludes&amp;gt;
          &amp;lt;exclude&amp;gt;none&amp;lt;/exclude&amp;gt;
          &amp;lt;exclude&amp;gt;**/TestCase.java&amp;lt;/exclude&amp;gt;
        &amp;lt;/excludes&amp;gt;
      &amp;lt;/configuration&amp;gt;
    &amp;lt;/execution&amp;gt;
  &amp;lt;/executions&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;After I had this working, I moved onto getting the container started and stopped properly. In the past, I&apos;ve &lt;a href=&quot;http://raibledesigns.com/rd/entry/integrating_selenium_with_maven_2&quot;&gt;done this&lt;/a&gt; using &lt;a href=&quot;http://cargo.codehaus.org&quot;&gt;Cargo&lt;/a&gt; and it&apos;s always worked well for me. Apart from the usual setup I use in AppFuse archetypes (&lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/archetypes/appfuse-basic-struts/src/pom.xml?r=HEAD#l496&quot;&gt;example pom.xml&lt;/a&gt;), I added a couple additional items:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Added &amp;lt;timeout&gt;180000&amp;lt;/timeout&gt; so the container would wait up to 3 minutes for the WAR to deploy.&lt;/li&gt;
&lt;li&gt;In configuration/properties, specified &amp;lt;context.path&gt;ROOT&amp;lt;/context.path&gt; so the app would deploy at the / context path.&lt;/li&gt;
&lt;li&gt;In configuration/properties, specified &amp;lt;cargo.protocol&gt;https&amp;lt;/cargo.protocol&gt; since many existing unit tests made requests to secure resources.
&lt;/ul&gt;
&lt;p&gt;I started by using Cargo with Tomcat and had to &lt;a href=&quot;http://tomcat.apache.org/tomcat-6.0-doc/ssl-howto.html&quot;&gt;create certificate keystore&lt;/a&gt; in order to get Tomcat to start with SSL enabled. After getting it to start, I found the tests failed with the following errors in the logs:
&lt;/p&gt;
&lt;pre&gt;
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: 
PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: 
unable to find valid certification path to requested target
	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:174)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.fatal(SSLSocketImpl.java:1649)
&lt;/pre&gt;
&lt;p&gt;Co-workers told me this was easily solved by &lt;a href=&quot;http://blogs.sun.com/gc/entry/unable_to_find_valid_certification&quot;&gt;adding my &apos;untrusted&apos; cert to my JVM keystore&lt;/a&gt;. Once all this was working, I thought I was good to go, but found that some tests were still failing. The failures turned out to be because they were talking to http and https was the only protocol enabled. After doing some research, I discovered that Cargo &lt;a href=&quot;http://jira.codehaus.org/browse/CARGO-574&quot;&gt;doesn&apos;t support starting on both http and https ports&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So back to the drawing board I went. I ended up turning to the &lt;a href=&quot;http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin&quot;&gt;maven-jetty-plugin&lt;/a&gt; and the &lt;a href=&quot;http://mojo.codehaus.org/tomcat-maven-plugin/&quot;&gt;tomcat-maven-plugin&lt;/a&gt; to get the functionality I was looking for. I also automated the certificate keystore generation using the &lt;a href=&quot;http://mrhaki.blogspot.com/2009/05/configure-maven-jetty-plugin-for-ssl.html&quot;&gt;keytool-maven-plugin&lt;/a&gt;. Below is the extremely-verbose 95-line profiles section of my pom.xml that allows either container to be used.
&lt;/p&gt;
&lt;p style=&quot;margin-left: 20px&quot;&gt;&lt;em&gt;Sidenote: I wonder how this same setup would look using &lt;a href=&quot;http://www.gradle.org&quot;&gt;Gradle&lt;/a&gt;?&lt;/em&gt;
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;profiles&amp;gt;
  &amp;lt;profile&amp;gt;
    &amp;lt;id&amp;gt;jetty&amp;lt;/id&amp;gt;
    &amp;lt;activation&amp;gt;
      &amp;lt;activeByDefault&amp;gt;true&amp;lt;/activeByDefault&amp;gt;
    &amp;lt;/activation&amp;gt;
    &amp;lt;build&amp;gt;
      &amp;lt;plugins&amp;gt;
        &amp;lt;plugin&amp;gt;
          &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;
          &amp;lt;artifactId&amp;gt;maven-jetty-plugin&amp;lt;/artifactId&amp;gt;
          &amp;lt;version&amp;gt;6.1.26&amp;lt;/version&amp;gt;
          &amp;lt;configuration&amp;gt;
            &amp;lt;contextPath&amp;gt;/&amp;lt;/contextPath&amp;gt;
            &amp;lt;connectors&amp;gt;
              &amp;lt;connector implementation=&quot;org.mortbay.jetty.nio.SelectChannelConnector&quot;&amp;gt;
                &amp;lt;!-- forwarded == true interprets x-forwarded-* headers --&amp;gt;
                &amp;lt;!-- http://docs.codehaus.org/display/JETTY/Configuring+mod_proxy --&amp;gt;
                &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
                &amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;
                &amp;lt;maxIdleTime&amp;gt;60000&amp;lt;/maxIdleTime&amp;gt;
              &amp;lt;/connector&amp;gt;
              &amp;lt;connector implementation=&quot;org.mortbay.jetty.security.SslSocketConnector&quot;&amp;gt;
                &amp;lt;forwarded&amp;gt;true&amp;lt;/forwarded&amp;gt;
                &amp;lt;port&amp;gt;8443&amp;lt;/port&amp;gt;
                &amp;lt;maxIdleTime&amp;gt;60000&amp;lt;/maxIdleTime&amp;gt;
                &amp;lt;keystore&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystore&amp;gt;
                &amp;lt;password&amp;gt;overstock&amp;lt;/password&amp;gt;
                &amp;lt;keyPassword&amp;gt;overstock&amp;lt;/keyPassword&amp;gt;
              &amp;lt;/connector&amp;gt;
            &amp;lt;/connectors&amp;gt;
            &amp;lt;stopKey&amp;gt;overstock&amp;lt;/stopKey&amp;gt;
            &amp;lt;stopPort&amp;gt;9999&amp;lt;/stopPort&amp;gt;
          &amp;lt;/configuration&amp;gt;
          &amp;lt;executions&amp;gt;
            &amp;lt;execution&amp;gt;
              &amp;lt;id&amp;gt;start-jetty&amp;lt;/id&amp;gt;
              &amp;lt;phase&amp;gt;pre-integration-test&amp;lt;/phase&amp;gt;
              &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;run-war&amp;lt;/goal&amp;gt;
              &amp;lt;/goals&amp;gt;
              &amp;lt;configuration&amp;gt;
                &amp;lt;daemon&amp;gt;true&amp;lt;/daemon&amp;gt;
              &amp;lt;/configuration&amp;gt;
            &amp;lt;/execution&amp;gt;
            &amp;lt;execution&amp;gt;
              &amp;lt;id&amp;gt;stop-jetty&amp;lt;/id&amp;gt;
              &amp;lt;phase&amp;gt;post-integration-test&amp;lt;/phase&amp;gt;
              &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;stop&amp;lt;/goal&amp;gt;
              &amp;lt;/goals&amp;gt;
            &amp;lt;/execution&amp;gt;
          &amp;lt;/executions&amp;gt;
        &amp;lt;/plugin&amp;gt;
      &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
  &amp;lt;/profile&amp;gt;
  &amp;lt;profile&amp;gt;
    &amp;lt;id&amp;gt;tomcat&amp;lt;/id&amp;gt;
    &amp;lt;build&amp;gt;
      &amp;lt;plugins&amp;gt;
        &amp;lt;plugin&amp;gt;
          &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
          &amp;lt;artifactId&amp;gt;tomcat-maven-plugin&amp;lt;/artifactId&amp;gt;
          &amp;lt;version&amp;gt;1.1&amp;lt;/version&amp;gt;
          &amp;lt;configuration&amp;gt;
            &amp;lt;addContextWarDependencies&amp;gt;true&amp;lt;/addContextWarDependencies&amp;gt;
            &amp;lt;fork&amp;gt;true&amp;lt;/fork&amp;gt;
            &amp;lt;path&amp;gt;/&amp;lt;/path&amp;gt;
            &amp;lt;port&amp;gt;8080&amp;lt;/port&amp;gt;
            &amp;lt;httpsPort&amp;gt;8443&amp;lt;/httpsPort&amp;gt;
            &amp;lt;keystoreFile&amp;gt;${project.build.directory}/ssl.keystore&amp;lt;/keystoreFile&amp;gt;
            &amp;lt;keystorePass&amp;gt;overstock&amp;lt;/keystorePass&amp;gt;
          &amp;lt;/configuration&amp;gt;
          &amp;lt;executions&amp;gt;
            &amp;lt;execution&amp;gt;
              &amp;lt;id&amp;gt;start-tomcat&amp;lt;/id&amp;gt;
              &amp;lt;phase&amp;gt;pre-integration-test&amp;lt;/phase&amp;gt;
              &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;run-war&amp;lt;/goal&amp;gt;
              &amp;lt;/goals&amp;gt;
            &amp;lt;/execution&amp;gt;
            &amp;lt;execution&amp;gt;
              &amp;lt;id&amp;gt;stop-tomcat&amp;lt;/id&amp;gt;
              &amp;lt;phase&amp;gt;post-integration-test&amp;lt;/phase&amp;gt;
              &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;shutdown&amp;lt;/goal&amp;gt;
              &amp;lt;/goals&amp;gt;
            &amp;lt;/execution&amp;gt;
          &amp;lt;/executions&amp;gt;
        &amp;lt;/plugin&amp;gt;
      &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;
  &amp;lt;/profile&amp;gt;
&amp;lt;/profiles&amp;gt;
&lt;/pre&gt;
&lt;p&gt;With this setup in place, I was able to automate running our integration tests by simply typing &quot;mvn install&quot; (for Jetty) or &quot;mvn install -Ptomcat&quot; (for Tomcat). For running in Hudson, it&apos;s possible I&apos;ll have to further enhance things to randomize the port and pass that into tests as a system property. The &lt;a href=&quot;http://mojo.codehaus.org/build-helper-maven-plugin/&quot;&gt;build-helper-maven-plugin&lt;/a&gt; and its &lt;em&gt;reserve-network-port&lt;/em&gt; goal is a nice way to do this. Note: if you want to run more than one instance of Tomcat at a time, you might have to randomize the ajp and rmi ports to avoid collisions.
&lt;/p&gt;
&lt;p&gt;The final thing I encountered was our app didn&apos;t shutdown gracefully. Luckily, this was fixed in a newer version of our core framework and upgrading fixed the problem. Here&apos;s the explanation from an architect on the core framework team.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
The hanging problem was caused by the way the framework internally
aggregated statistics related to database connection usage and page
response times.  The aggregation runs on a separate thread but not as a
daemon thread.  Previously, the aggregation threads weren&apos;t being
terminated on shutdown so the JVM would hang waiting for them to finish.
In the new frameworks, the aggregation threads are terminated on shutdown.
&lt;/p&gt;
&lt;p&gt;Hopefully this post helps you test your secure and unsecure applications at the same time. At the same time, I&apos;m hoping it motivates the Cargo developers to add simultaneous http and https support. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; In the comments, Ron Piterman recommended I use the &lt;a href=&quot;http://maven.apache.org/plugins/maven-failsafe-plugin/&quot;&gt;Maven Failsafe Plugin&lt;/a&gt; because its designed to run integration tests while Surefire Plugin is for unit tests. I changed my configuration to the following and everything still passes. Thanks Ron!
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
  &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;2.7.2&amp;lt;/version&amp;gt;
  &amp;lt;configuration&amp;gt;
    &amp;lt;skipTests&amp;gt;true&amp;lt;/skipTests&amp;gt;
  &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&amp;lt;plugin&amp;gt;
  &amp;lt;artifactId&amp;gt;maven-failsafe-plugin&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;2.7.2&amp;lt;/version&amp;gt;
  &amp;lt;configuration&amp;gt;
    &amp;lt;includes&amp;gt;
      &amp;lt;include&amp;gt;**/*Test.java&amp;lt;/include&amp;gt;
    &amp;lt;/includes&amp;gt;
    &amp;lt;excludes&amp;gt;
      &amp;lt;exclude&amp;gt;**/TestCase.java&amp;lt;/exclude&amp;gt;
    &amp;lt;/excludes&amp;gt;
  &amp;lt;/configuration&amp;gt;
  &amp;lt;executions&amp;gt;
    &amp;lt;execution&amp;gt;
      &amp;lt;id&amp;gt;integration-test&amp;lt;/id&amp;gt;
      &amp;lt;phase&amp;gt;integration-test&amp;lt;/phase&amp;gt;
      &amp;lt;goals&amp;gt;
        &amp;lt;goal&amp;gt;integration-test&amp;lt;/goal&amp;gt;
      &amp;lt;/goals&amp;gt;
    &amp;lt;/execution&amp;gt;
    &amp;lt;execution&amp;gt;
      &amp;lt;id&amp;gt;verify&amp;lt;/id&amp;gt;
      &amp;lt;phase&amp;gt;verify&amp;lt;/phase&amp;gt;
      &amp;lt;goals&amp;gt;
        &amp;lt;goal&amp;gt;verify&amp;lt;/goal&amp;gt;
      &amp;lt;/goals&amp;gt;
    &amp;lt;/execution&amp;gt;
  &amp;lt;/executions&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; In addition to application changes to solve hanging issues, I also had to change my Jetty Plugin configuration to use a different SSL connector implementation. This also required adding the jetty-sslengine dependency, which has been &lt;a href=&quot;http://stackoverflow.com/questions/2215550/mavens-jetty-plugin-ssl-configuration-issue&quot;&gt;renamed to jetty-ssl for Jetty 7&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;connector implementation=&quot;org.mortbay.jetty.security.SslSelectChannelConnector&quot;&amp;gt;
...
&amp;lt;dependencies&amp;gt;
  &amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jetty-sslengine&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;6.1.26&amp;lt;/version&amp;gt;
  &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;
&lt;/pre&gt;&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/implementing_extensionless_urls_with_tapestry</id>
        <title type="html">Implementing Extensionless URLs with Tapestry, Spring MVC, Struts 2 and JSF</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/implementing_extensionless_urls_with_tapestry"/>
        <published>2011-02-10T16:53:27-07:00</published>
        <updated>2011-02-11T00:04:52-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="tapestry5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="extensionlessurls" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">For the past couple of weeks, I&apos;ve spent several evening hours implementing extensionless URLs in &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. I&apos;ve been wanting to do this ever since I &lt;a href=&quot;http://raibledesigns.com/rd/entry/extensionless_urls_in_java_web&quot;&gt;wrote about how to do it&lt;/a&gt; a few years ago. This article details my experience and will hopefully help others implement this feature in their webapps.
&lt;/p&gt;
&lt;p&gt;First of all, I used the &lt;a href=&quot;http://www.tuckey.org/urlrewrite/&quot;&gt;UrlRewriteFilter&lt;/a&gt;, one of my favorite Java open source projects. Then I followed a pattern I found in Spring&apos;s &quot;mvc-basic&quot; sample app from &lt;a href=&quot;http://blog.springsource.com/2009/12/21/mvc-simplifications-in-spring-3-0/&quot;&gt;MVC Simplifications in Spring 3.0&lt;/a&gt;. The app has since changed (because SpringSource integrated UrlRewriteFilter-type functionality in Spring MVC), but the pattern was basically path-matching instead of extension-mapping. That is, the &quot;dispatcher&quot; for the web framework was mapped to /app/* instead of *.html. 
&lt;/p&gt;
&lt;p&gt;
Prior to the move to extensionless URLs, AppFuse used *.html for its mapping and this seemed to cause users problems when they wanted to serve up static HTML files. To begin with, I removed all extensions from URLs in tests (&lt;a href=&quot;http://webtest.canoo.com&quot;&gt;Canoo WebTest&lt;/a&gt; is used for testing the UI). I also did this for any links in the view pages and redirects in the Java code. This provided a decent foundation to verify my changes worked. Below are details about each framework I did this for, starting with the one that was easiest and moving to hardest.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tapestry 5&lt;/strong&gt;&lt;br/&gt;
Tapestry was by far the easiest to integrate extensionless URLs into. This is because it&apos;s a native feature of the framework and was already integrated as part of &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1116&quot;&gt;Serge Eby&apos;s Tapestry 5 implementation&lt;/a&gt;. In the end, the only things I had to do where 1) add a couple entries for CXF (mapped to /services/*) and DWR (/dwr/*) to my urlrewrite.xml and 2) change the UrlRewriteFilter so it was only mapped to REQUEST instead of both REQUEST and FORWARD. Below are the mappings I added for CXF and DWR.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;urlrewrite default-match-type=&quot;wildcard&quot;&amp;gt;
    ...
    &amp;lt;rule&amp;gt;
        &amp;lt;from&amp;gt;/dwr/**&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/dwr/$1&amp;lt;/to&amp;gt;
    &amp;lt;/rule&amp;gt;
    &amp;lt;rule&amp;gt;
        &amp;lt;from&amp;gt;/services/**&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/services/$1&amp;lt;/to&amp;gt;
    &amp;lt;/rule&amp;gt;
&amp;lt;/urlrewrite&amp;gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spring MVC&lt;/strong&gt;&lt;br/&gt;
I had a fair amount of experience with Spring MVC and extensionless URLs. Both the Spring MVC applications we developed last year at Time Warner Cable used them. To change from a *.html mapping to /app/* was pretty easy and involved removing more code than I added. Previously, I had a &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/common/src/main/java/org/appfuse/webapp/filter/StaticFilter.java?r=3250&quot;&gt;StaticFilter&lt;/a&gt; that looked for HTML files and if it didn&apos;t find them, it dispatched to Spring&apos;s DispatcherServlet. I was able to remove this class and make the web.xml file quite a bit cleaner. 
&lt;/p&gt;
&lt;p&gt;To make UrlRewriteFilter and Spring Security play well together, I had to move the securityFilter so it came &lt;em&gt;after&lt;/em&gt; the rewriteFilter and add an INCLUDE dispatcher so included JSPs would have a security context available to them. 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;rewriteFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;FORWARD&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;INCLUDE&amp;lt;/dispatcher&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The only other things I had to change were &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/spring/src/main/webapp/WEB-INF/security.xml?r2=3458&amp;r1=3379&quot;&gt;security.xml&lt;/a&gt; and &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/spring/src/main/webapp/WEB-INF/dispatcher-servlet.xml?r2=3458&amp;r1=3334&quot;&gt;dispatcher-servlet.xml&lt;/a&gt; to remove the .html extensions. The urlrewrite.xml file was fairly straightforward. I used the following at the bottom as a catch-all for dispatching to Spring MVC.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule&amp;gt;
    &amp;lt;from&amp;gt;/**&amp;lt;/from&amp;gt;
    &amp;lt;to&amp;gt;/app/$1&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&amp;lt;outbound-rule&amp;gt;
    &amp;lt;from&amp;gt;/app/**&amp;lt;/from&amp;gt;
    &amp;lt;to&amp;gt;/$1&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
Then I added a number of other rules for j_security_check, DWR, CXF and static assets (/images, /scripts, /styles, /favicon.ico). You can view the &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/spring/src/main/webapp/WEB-INF/urlrewrite.xml?r=HEAD&quot;&gt;current urlrewrite.xml in FishEye&lt;/a&gt;. The only major issue I ran into was that Spring Security recorded protected URLs as /app/URL so I had to add a rule to redirect when this happened after logging in.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule&amp;gt;
    &amp;lt;from&amp;gt;/app/**&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;true&quot; type=&quot;redirect&quot;&amp;gt;%{context-path}/$1&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Struts 2&lt;/strong&gt;&lt;br/&gt;
Using extensionless URLs with Struts 2 is likely pretty easy thanks to the &lt;a href=&quot;http://struts.apache.org/2.1.8/docs/convention-plugin.html&quot;&gt;Convention Plugin&lt;/a&gt;. Even though this plugin is included in AppFuse, it&apos;s not configured with the proper &lt;a href=&quot;http://struts.apache.org/2.1.8/docs/converting-application-from-codebehind-to-convention-plugin.html&quot;&gt;constants&lt;/a&gt; and I have struts.convention.action.disableScanning=true in struts.xml. It looks like I had to do this when I &lt;a href=&quot;http://appfuse.markmail.org/thread/ktbqtx2mslvrkjkq&quot;&gt;upgraded from Struts 2.0.x to Struts 2.1.6&lt;/a&gt;. It&apos;s true AppFuse&apos;s Struts 2 support could use a bit of love to be aligned with Struts 2&apos;s recommended practices, but I didn&apos;t want to spend the time doing it as part of this exercise. 
&lt;/p&gt;
&lt;p&gt;With Struts 2, I tried the path-mapping like I did with Spring MVC, but ran into issues. Instead, I opted to use an &quot;.action&quot; extension by changing &lt;code&gt;struts.action.extension&lt;/code&gt; from &quot;html&quot; to &quot;action,&quot; in struts.xml. Then I had to do a bunch of filter re-ordering and dispatcher changes. Before, with a .html extension, I had all filters mapped to /* and in the following order.&lt;/p&gt;
&lt;table class=&quot;comparison&quot; style=&quot;width: 250px&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Filter Name&lt;/th&gt;&lt;th&gt;Dispatchers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;securityFilter&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rewriteFilter&lt;/td&gt;
&lt;td&gt;request, forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts-prepare&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sitemesh&lt;/td&gt;
&lt;td&gt;request, forward, include&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;staticFilter&lt;/td&gt;
&lt;td&gt;request, forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Similar to Spring MVC, I had to remove the rewriteFilter in front of the securityFilter and I was able to remove the staticFilter. I also had to map the struts filter to *.action instead of /* to stop Struts from trying to catch static asset and DWR/CXF requests. Below is the order of filters and their dispatchers that seems to work best.
&lt;table class=&quot;comparison&quot; style=&quot;width: 250px&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Filter Name&lt;/th&gt;&lt;th&gt;Dispatchers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rewriteFilter&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;securityFilter&lt;/td&gt;
&lt;td&gt;request, forward, include&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts-prepare&lt;/td&gt;
&lt;td&gt;request, forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sitemesh&lt;/td&gt;
&lt;td&gt;request, forward, include&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts&lt;/td&gt;
&lt;td&gt;forward&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;From there, it was a matter of modifying &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/struts/src/main/webapp/WEB-INF/urlrewrite.xml?r=HEAD&quot;&gt;urlrewrite.xml&lt;/a&gt; to have the following catch-all and rules for static assets, j_security_check and DWR/CXF.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^(&amp;#91;^?&amp;#93;*)/(&amp;#91;^?/\.&amp;#93;+)(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;true&quot;&amp;gt;$1/$2.action$3&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&amp;lt;outbound-rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^(.*)\.action(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;false&quot;&amp;gt;$1$2&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;JSF&lt;/strong&gt;&lt;br/&gt;
JSF was by far the most difficult to get extensionless URLs working with. I&apos;m not convinced it&apos;s impossible, but I spent a several hours over a few days and was unsuccessful in completely removing them. I was able to make things work so I could request pages without an extension, but found when clicking buttons and links, the extension would often show up in the URL. I&apos;m also still using JSF 1.2, so it&apos;s possible that upgrading to 2.0 would solve many of the issues I encountered. &lt;/p&gt;
&lt;p&gt;For the time being, I&apos;ve changed my FacesServlet mapping from *.html to *.jsf. As with Struts, I had issues when I tried to map it to /app/*. Other changes include &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/WEB-INF/web.xml?r1=3384&amp;r2=3458#l188&quot;&gt;changing the order of dispatchers and filters&lt;/a&gt;, the good ol&apos; catch-all in &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/WEB-INF/urlrewrite.xml?r=HEAD&quot;&gt;urlrewrite.xml&lt;/a&gt; and &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/WEB-INF/security.xml?r1=3384&amp;r2=3458#l188&quot;&gt;modifying security.xml&lt;/a&gt;. For some reason, I wasn&apos;t able to get file upload working without adding an exception to the outbound-rule.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^(&amp;#91;^?&amp;#93;*)/(&amp;#91;^?/\.&amp;#93;+)(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;true&quot;&amp;gt;$1/$2.jsf&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&amp;lt;outbound-rule match-type=&quot;regex&quot;&amp;gt;
  &amp;lt;!-- TODO: Figure out how to make file upload work w/o using *.jsf --&amp;gt;
    &amp;lt;condition type=&quot;path-info&quot;&amp;gt;selectFile&amp;lt;/condition&amp;gt;
    &amp;lt;from&amp;gt;^(.*)\.jsf(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;false&quot;&amp;gt;$1$2&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I also spent a couple hours trying to get &lt;a href=&quot;http://ocpsoft.com/prettyfaces/&quot;&gt;Pretty Faces&lt;/a&gt; to work. I wrote about my issues &lt;a href=&quot;http://ocpsoft.com/support/topic/rewrite-every-jsf&quot;&gt;on the forums&lt;/a&gt;. I tried writing a custom Processor to strip the extension, but found that I&apos;d get into an infinite loop where the processor kept getting called. To workaround this, I tried using Spring&apos;s RequestContextHolder to ensure the processor only got invoked once, but that proved fruitless. Finally, I tried inbound &lt;em&gt;and&lt;/em&gt; outbound custom processors, but failed to get those working. The final thing I tried was url-mappings for each page in pretty-config.xml.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;url-mapping&amp;gt;
  &amp;lt;pattern value=&quot;/admin/users&quot;/&amp;gt;
  &amp;lt;view-id value=&quot;/admin/users.jsf&quot;/&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&amp;lt;url-mapping&amp;gt;
  &amp;lt;pattern value=&quot;/mainMenu&quot;/&amp;gt;
  &amp;lt;view-id value=&quot;/mainMenu.jsf&quot;/&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The issue with doing this was that some of the navigation rules in my faces-config.xml stopped working. I didn&apos;t spend much time trying to diagnose the problem because I didn&apos;t like having to add an entry for each page in the application. The one nice thing about Pretty Faces is it did allow me to do things like the following, which I formerly did with a form that auto-submitted when the page loaded.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;url-mapping&amp;gt;
  &amp;lt;pattern value=&quot;/passwordHint/#{username}&quot;/&amp;gt;
  &amp;lt;view-id value=&quot;/passwordHint.jsf&quot;/&amp;gt;
  &amp;lt;action&amp;gt;#{passwordHint.execute}&amp;lt;/action&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;
My journey implementing extensionless URLs was an interesting one, and I solidified my knowledge about ordering of filters, dispatchers and the UrlRewriteFilter. I still think I have more to learn about properly implementing extensionless URLs in Struts 2 and JSF and I hope to do that in the near future. I believe Struts&apos; Convention Plugin will help me and JSF 2 + Pretty Faces will hopefully work nicely too. Of course, it&apos;d be great if all Java Web Frameworks had an easy mechanism for producing and consuming extensionless URLs. In the meantime, thank goodness for the UrlRewriteFilter.
&lt;/p&gt;
&lt;p&gt;If you&apos;d like to try AppFuse and its shiny new URLs, see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; and choose the 2.1.0-SNAPSHOT version.

</content>
    </entry>
</feed>

