<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/xsl" href="https://raibledesigns.com/roller-ui/styles/rss.xsl" media="screen"?><rss version="2.0" 
  xmlns:dc="http://purl.org/dc/elements/1.1/"
  xmlns:atom="http://www.w3.org/2005/Atom" >
<channel>
  <title>Raible Designs</title>
  <link>https://raibledesigns.com/rd/</link>
      <atom:link rel="self" type="application/rss+xml" href="https://raibledesigns.com/rd/feed/entries/rss?tags=spring" />
    <description>Raible Designs is an Enterprise Open Source Consulting company. We specialize in UI and Full Stack Architectures using HTML5, CSS, JavaScript and Java. We love HTML5, Angular, Bootstrap, Spring Boot, and especially JHipster.</description>
  <language>en-us</language>
  <copyright>Copyright 2026</copyright>
  <lastBuildDate>Mon, 30 Mar 2026 03:31:45 -0600</lastBuildDate>
  <generator>Apache Roller (incubating) 5.0.3 (1388864191739:dave)</generator>
        <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/jhipsterconf_2018_summer_solstice_in</guid>
    <title>JHipster Conf 2018: Summer Solstice in Paris</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/jhipsterconf_2018_summer_solstice_in</link>
        <pubDate>Thu, 28 Jun 2018 10:13:27 -0600</pubDate>
    <category>Java</category>
    <category>angular</category>
    <category>jhipster</category>
    <category>jhipsterconf2018</category>
    <category>spring</category>
    <category>paris</category>
    <category>ippon</category>
    <category>react</category>
    <category>jhipsterconf</category>
    <category>spring-boot</category>
            <description>&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;
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/speaking_adventures_at_j_spring</guid>
    <title>Speaking Adventures at J-Spring, Devoxx UK, GeeCON, and Spring I/O</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/speaking_adventures_at_j_spring</link>
        <pubDate>Wed, 24 May 2017 09:50:55 -0600</pubDate>
    <category>Java</category>
    <category>geecon</category>
    <category>springio17</category>
    <category>okta</category>
    <category>microservices</category>
    <category>java</category>
    <category>angular</category>
    <category>jspring</category>
    <category>spring</category>
    <category>devoxxuk</category>
    <category>springboot</category>
    <atom:summary type="html">&lt;p&gt;As a Developer Advocate at &lt;a href=&quot;https://okta.com&quot;&gt;Okta&lt;/a&gt;, I&apos;m expected to travel up to 25% per month
    to speak at conferences and meetups. This May was more like 50%! I had opportunities to contribute to a
    number of cool conferences in exotic cities that I was eager to accept.
&lt;/p&gt;
&lt;p&gt;
    My adventure began on Monday, May 8 when I flew to Amsterdam to speak at the
    &lt;a href=&quot;http://jspring.nl/&quot;&gt;J-Spring conference&lt;/a&gt;.
    It was the first time the &lt;a href=&quot;http://www.nljug.org/&quot;&gt;NLJUG&lt;/a&gt; hosted this conference in several years.
    I marveled at the venue and especially liked the outdoor area it offered during breaks. The walk from/to
    the train station was pretty nice too.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4272/34023195124_ceb14fe282_c.jpg&quot;
       title=&quot;J-Spring Outdoor Area&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34023195124/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4272/34023195124_ceb14fe282_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;J-Spring Outdoor Area&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/4200/34735030581_65ab0797b0_c.jpg&quot;
       title=&quot;Amsterdam Bike Paths&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34735030581/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4200/34735030581_65ab0797b0_m.jpg&quot; width=&quot;240&quot; alt=&quot;Amsterdam Bike Paths&quot;
            style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    I spoke about Microservices for
    the Masses with Spring Boot, JHipster, and JWT. Feedback I received mentioned it was a bit too fast
    and I crammed too much into the 50-minute time slot. I do tend to mention everything I know about
    topics when I speak, so I apologize for trying to cram too much in.
&lt;/p&gt;</atom:summary>        <description>&lt;p&gt;As a Developer Advocate at &lt;a href=&quot;https://okta.com&quot;&gt;Okta&lt;/a&gt;, I&apos;m expected to travel up to 25% per month
    to speak at conferences and meetups. This May was more like 50%! I had opportunities to contribute to a
    number of cool conferences in exotic cities that I was eager to accept.
&lt;/p&gt;
&lt;p&gt;
    My adventure began on Monday, May 8 when I flew to Amsterdam to speak at the
    &lt;a href=&quot;http://jspring.nl/&quot;&gt;J-Spring conference&lt;/a&gt;.
    It was the first time the &lt;a href=&quot;http://www.nljug.org/&quot;&gt;NLJUG&lt;/a&gt; hosted this conference in several years.
    I marveled at the venue and especially liked the outdoor area it offered during breaks. The walk from/to
    the train station was pretty nice too.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4272/34023195124_ceb14fe282_c.jpg&quot;
       title=&quot;J-Spring Outdoor Area&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34023195124/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4272/34023195124_ceb14fe282_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;J-Spring Outdoor Area&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/4200/34735030581_65ab0797b0_c.jpg&quot;
       title=&quot;Amsterdam Bike Paths&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34735030581/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4200/34735030581_65ab0797b0_m.jpg&quot; width=&quot;240&quot; alt=&quot;Amsterdam Bike Paths&quot;
            style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    I spoke about Microservices for
    the Masses with Spring Boot, JHipster, and JWT. Feedback I received mentioned it was a bit too fast
    and I crammed too much into the 50-minute time slot. I do tend to mention everything I know about
    topics when I speak, so I apologize for trying to cram too much in.
&lt;/p&gt;
&lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;018d1c36fb8c468e91c93d178296f80e&quot; data-ratio=&quot;1.77469670710572&quot;
        src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;
    After J-Spring, I flew to London to speak at &lt;a href=&quot;https://www.devoxx.co.uk/&quot;&gt;Devoxx UK&lt;/a&gt;. I arrived just in
    time to catch the speaker&apos;s dinner and had
    fun seeing and catching up with old friends from the conference circuit.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4226/34023199904_d8764ea9f4_c.jpg&quot;
       title=&quot;View from Room 404 in London&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34023199904/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4226/34023199904_d8764ea9f4_m.jpg&quot; width=&quot;240&quot;
            alt=&quot;View from Room 404 in London&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/4270/34735034351_9bfe4be80c_c.jpg&quot;
       title=&quot;Devoxx UK Venue&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34735034351/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4270/34735034351_9bfe4be80c_m.jpg&quot; width=&quot;240&quot; alt=&quot;Devoxx UK Venue&quot;
            style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
    Thursday morning, I had an Angular workshop
    and did my microservices presentation in the afternoon. Friday, I had an early morning talk on Front End Development
    for Back End Developers. You can find all my presentations below.
&lt;/p&gt;
&lt;table style=&quot;width: 100%&quot;&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td width=&quot;50%&quot;&gt;
            &lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;dcd38052340b4f91b5d454d6da7bcb63&quot;
                    data-ratio=&quot;1.77777777777778&quot; src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
        &lt;/td&gt;
        &lt;td width=&quot;50%&quot;&gt;
            &lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;e013a60aaf2b495da36746feb28bc224&quot;
                    data-ratio=&quot;1.77469670710572&quot; src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;3ba7973631ef4603a4f4df5bd2a6b888&quot;
                    data-ratio=&quot;1.77777777777778&quot; src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;
    I rushed straight from my last talk on Friday to the airport to catch a flight to Boston for the weekend. In Boston,
    we celebrated Trish&apos;s brother&apos;s 50th birthday, Mother&apos;s Day, and had a blast with friends and family.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4220/34023204014_5600993dc0_c.jpg&quot;
       title=&quot;Happy Mother&apos;s Day!&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34023204014/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4220/34023204014_5600993dc0.jpg&quot; width=&quot;500&quot; alt=&quot;Happy Mother&apos;s Day!&quot;
            style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
    The following Monday, I hopped on a plane to return to Europe with Krakow (for &lt;a
        href=&quot;https://geecon.org/&quot;&gt;GeeCON&lt;/a&gt;) as my destination. Three
    flights later and I arrived in time to take a nice stroll around the city, enjoying the greenery.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4275/34056217043_a76d037fd7_c.jpg&quot; title=&quot;Krakow&quot;
       rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34056217043/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4275/34056217043_a76d037fd7_q.jpg&quot; width=&quot;150&quot; alt=&quot;Krakow&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/4201/34023205364_6bbac55966_c.jpg&quot; title=&quot;Krakow&quot;
       rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34023205364/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4201/34023205364_6bbac55966_q.jpg&quot; width=&quot;150&quot; alt=&quot;Krakow&quot;
            style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;

    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4202/34702783102_49973cd47f_c.jpg&quot; title=&quot;Krakow&quot;
       rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34702783102/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4202/34702783102_49973cd47f_q.jpg&quot; width=&quot;150&quot; alt=&quot;Krakow&quot;
            style=&quot;border: 1px solid black; margin-left: 15px;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;
    At GeeCON, I spoke about how to build a progressive web app with Ionic, Angular, and Spring Boot. Half of my talk
    was live coding and I
    &lt;em&gt;almost&lt;/em&gt; got all my demos working. Deploying to Cloud Foundry and my phone was the final step, and due to
    Xcode updating, that demo failed. I wrote a
    &lt;a href=&quot;http://developer.okta.com/blog/2017/05/17/develop-a-mobile-app-with-ionic-and-spring-boot&quot;&gt;tutorial about
        Ionic&lt;/a&gt; for the Okta developer blog that has everything (and more!) that I showed in my demo.
&lt;/p&gt;
&lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;8cf85e4d8acc4627b29a2ee42533fa74&quot; data-ratio=&quot;1.77777777777778&quot;
        src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
&lt;p&gt;
    I had to head straight to the airport after finishing my talk, this time heading for &lt;a
        href=&quot;http://2017.springio.net/&quot;&gt;Spring I/O&lt;/a&gt; in Barcelona.
    Barcelona has always been on Trish&apos;s bucket list, so I easily talked her into joining me. At Spring I/O, I did a
    workshop on developing with Spring Boot and Angular, followed by my Front End Development for Back End Developers
    talk. There weren&apos;t that many talks on front-end development, so I felt privileged to be one of the few talking
    about UI development.
&lt;/p&gt;
&lt;table width=&quot;100%&quot;&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td width=&quot;50%&quot;&gt;
            &lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;96b8761b8bcf430683e289c75c3cfc98&quot;
                    data-ratio=&quot;1.77777777777778&quot; src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
        &lt;/td&gt;
        &lt;td width=&quot;50%&quot;&gt;
            &lt;script async=&quot;&quot; class=&quot;speakerdeck-embed&quot; data-id=&quot;7f4814b375cb4e3c9e3d7d4467793dfc&quot;
                    data-ratio=&quot;1.77777777777778&quot; src=&quot;//speakerdeck.com/assets/embed.js&quot;&gt;&lt;/script&gt;
        &lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
    I also enjoyed &lt;a href=&quot;https://twitter.com/deepu105&quot;&gt;Deepu&apos;s&lt;/a&gt; talk on JHipster and &lt;a
        href=&quot;https://twitter.com/sebi2706&quot;&gt;Sebastien&apos;s&lt;/a&gt; talk on &lt;a href=&quot;http://www.keycloak.org/&quot;&gt;Keycloak&lt;/a&gt;.
    It was the first time I&apos;d met these great guys in person, so that was a lot of fun.
&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;At &lt;a href=&quot;https://twitter.com/spring_io&quot;&gt;@spring_io&lt;/a&gt;
        where &lt;a href=&quot;https://twitter.com/java_hipster&quot;&gt;@java_hipster&lt;/a&gt;&apos;s meet &lt;a href=&quot;https://t.co/I9OPErVWeF&quot;&gt;pic.twitter.com/I9OPErVWeF&lt;/a&gt;
    &lt;/p&gt;&#8212; Deepu K Sasidharan (@deepu105) &lt;a href=&quot;https://twitter.com/deepu105/status/865163186479263744&quot;&gt;May 18,
        2017&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;
    On Friday, Trish and I hit some of the sites in Barcelona and had a wonderful time. The weather was beautiful, the
    architecture was amazing, and the experience was awesome.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4204/34056220883_3b09f9692f_c.jpg&quot;
       title=&quot;Amazing Architecture in Barcelona&quot; rel=&quot;lightbox[may2017speakingtour]&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[may2017speakingtour]&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 style=&quot;text-align: center&quot;&gt;
    &lt;a data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4196/34826704476_40e475dce8_c.jpg&quot;
       title=&quot;Barcelona Fountains&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34826704476/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4196/34826704476_40e475dce8.jpg&quot; width=&quot;500&quot; alt=&quot;Barcelona Fountains&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-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4249/34056228583_138e7d92d8_c.jpg&quot; title=&quot;Happiness&quot;
       rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34056228583/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4249/34056228583_138e7d92d8_m.jpg&quot; width=&quot;240&quot; alt=&quot;Happiness&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/4275/34023214754_b9cab3fcd1_c.jpg&quot;
       title=&quot;Sagrada Familia&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34023214754/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4275/34023214754_b9cab3fcd1_m.jpg&quot; width=&quot;240&quot; alt=&quot;Sagrada Familia&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 data-flickr-embed=&quot;true&quot; href=&quot;https://c1.staticflickr.com/5/4223/34056230883_2889fc6891_c.jpg&quot;
       title=&quot;Sagrada Familia&quot; rel=&quot;lightbox[may2017speakingtour]&quot;
       data-href=&quot;https://www.flickr.com/photos/mraible/34056230883/in/album-72157682270620100/&quot;&gt;&lt;img
            src=&quot;https://c1.staticflickr.com/5/4223/34056230883_2889fc6891.jpg&quot; width=&quot;500&quot; alt=&quot;Sagrada Familia&quot;
            style=&quot;border: 1px solid black;&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;div style=&quot;margin: 0 auto; text-align: right; margin-top: -10px; max-width: 500px; font-size: .9em&quot;&gt;
    More photos on Flickr &amp;#8594; &lt;a href=&quot;https://www.flickr.com/photos/mraible/sets/72157682270620100/&quot;&gt;European Speaking Tour - May 2017&lt;/a&gt;
&lt;/div&gt;
&lt;!--Below are some of our favorite photos from the trip.--&gt;
&lt;p&gt;
    Thanks to the organizers of each conference for allowing me to speak and for covering my travel expenses. My company
    doesn&apos;t pay for overseas conferences (yet!), but they do pay me while I&apos;m there, so that&apos;s nice. To everyone that
    attended my sessions - thank you! I really appreciate the feedback and will do my best to improve future talks. If
    you have additional feedback, feel free to
    &lt;a href=&quot;//raibledesigns.com/contact.jsp&quot;&gt;contact me&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    In the meantime, keep an eye on the &lt;a href=&quot;http://developer.okta.com&quot;&gt;Okta developer
    blog&lt;/a&gt;. I&apos;ve been writing a lot of articles lately and there&apos;s more to come in the pipeline! Here&apos;s a few that&apos;ve
    been published in the last month.
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;http://developer.okta.com/blog/2017/04/17/angular-authentication-with-oidc&quot;&gt;Angular Authentication with
        OpenID Connect and Okta in 20 Minutes&lt;/a&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;http://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;http://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;http://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;/ul&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_3_5_released</guid>
    <title>AppFuse 3.5 Released!</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_3_5_released</link>
        <pubDate>Fri, 20 Feb 2015 09:08:53 -0700</pubDate>
    <category>Java</category>
    <category>wicket</category>
    <category>java</category>
    <category>gwt</category>
    <category>springmvc</category>
    <category>springsecurity</category>
    <category>maven</category>
    <category>tapestry5</category>
    <category>javaee</category>
    <category>jsf</category>
    <category>struts2</category>
    <category>spring</category>
            <description>&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;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/converting_an_application_to_jhipster</guid>
    <title>Converting an Application to JHipster</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/converting_an_application_to_jhipster</link>
        <pubDate>Thu, 12 Feb 2015 09:28:59 -0700</pubDate>
    <category>Java</category>
    <category>groovy</category>
    <category>jhipster</category>
    <category>jpa</category>
    <category>scala</category>
    <category>springboot</category>
    <category>spring</category>
    <category>angularjs</category>
    <category>java</category>
    <category>dosug</category>
            <description>&lt;p&gt;&lt;a href=&quot;http://jhipster.github.io/&quot;&gt;&lt;img src=&quot;http://jhipster.github.io/images/logo-jhipster.png&quot; class=&quot;picture&quot; width=&quot;94&quot;&gt;&lt;/a&gt;
I&apos;ve been intrigued by &lt;a href=&quot;http://jhipster.github.io/&quot;&gt;JHipster&lt;/a&gt; ever since I first tried it &lt;a href=&quot;http://raibledesigns.com/rd/entry/getting_started_with_jhipster_on&quot;&gt;last September&lt;/a&gt;. I&apos;d worked with AngularJS and Spring Boot quite a bit, and I liked the idea that someone had combined them, adding some nifty features along the way. When I &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_art_of_angularjs_in&quot;&gt;spoke about AngularJS&lt;/a&gt; earlier this month, I included &lt;a href=&quot;http://www.slideshare.net/mraible/the-art-of-angularjs-in-2015/67&quot;&gt;a few slides on JHipster&lt;/a&gt; near the end of the presentation.&lt;/p&gt;
&lt;p&gt;This week, I received an email from someone who attended that presentation. &lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
&lt;p style=&quot;margin-top: 0&quot;&gt;Hey Matt,&lt;br&gt;
We met a few weeks back when you presented at DOSUG. You were talking about JHipster which I had been eyeing for a few months and wanted your quick .02 cents.&lt;/p&gt;
&lt;p&gt;
I have built a pretty heavy application over the last 6 months that is using mostly the same tech as JHipster. 
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Java&lt;/li&gt;
&lt;li&gt;Spring&lt;/li&gt;
&lt;li&gt;JPA&lt;/li&gt;
&lt;li&gt;AngularJS&lt;/li&gt;
&lt;li&gt;Compass&lt;/li&gt;
&lt;li&gt;Grunt&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
It&apos;s ridiculously close for most of the tech stack. So, I was debating rolling it over into a JHipster app to make it a more familiar stack for folks. My concern is that it I will spend months trying to shoehorn it in for not much ROI. Any thoughts on going down this path?
What are the biggest issues you&apos;ve seen in using JHipster?
It seems pretty straightforward except for the entity generators. I&apos;m concerned they are totally different than what I am using. 
&lt;/p&gt;
&lt;p style=&quot;margin-bottom: 0&quot;&gt;
The main difference in what I&apos;m doing compared to JHipster is my almost complete use of groovy instead of old school Java in the app. I would have to be forced into going back to regular java beans...
Thoughts?&lt;/p&gt; 
&lt;/blockquote&gt;
&lt;p&gt;I replied with the following advice:&lt;/p&gt;
&lt;blockquote class=&quot;quote&quot;&gt;
&lt;p style=&quot;margin-top: 0&quot;&gt;
JHipster is great for starting a project, but I don&apos;t know that it buys you much value after the first few months. I would stick with your current setup and consider JHipster for your next project. I&apos;ve only prototyped with it, I haven&apos;t created any client apps or put anything in production. I have with Spring Boot and AngularJS though, so I like that JHipster combines them for me.
&lt;/p&gt;
&lt;p&gt;
JHipster doesn&apos;t generate Scala or Groovy code, but you could still use them in a project as long as you had Maven/Gradle configured properly. 
&lt;/p&gt;
&lt;p style=&quot;margin-bottom: 0&quot;&gt;
You might try generating a new app with JHipster and examine how they&apos;re doing this. At the very least, it can be a good learning tool, even if you&apos;re not using it directly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Java Hipsters: Do you agree with this advice? Have you tried migrating an existing app to JHipster? Are any of you using Scala or Groovy in your JHipster projects?&lt;/p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/integrating_node_js_ruby_and</guid>
    <title>Integrating Node.js, Ruby and Spring with Okta&apos;s SAML Support</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/integrating_node_js_ruby_and</link>
        <pubDate>Thu, 8 Jan 2015 11:43:47 -0700</pubDate>
    <category>Java</category>
    <category>node.js</category>
    <category>spring</category>
    <category>ruby</category>
    <category>okta</category>
    <category>security</category>
    <category>jruby</category>
    <category>saml</category>
    <atom: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;</atom:summary>        <description>&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;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_reduced</guid>
    <title>AppFuse, Reduced</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_reduced</link>
        <pubDate>Tue, 16 Dec 2014 06:03:31 -0700</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>maven</category>
    <category>maintenance</category>
    <category>lessxml</category>
    <category>appfuse</category>
    <category>spring</category>
    <atom: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;</atom:summary>        <description>&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;
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/building_a_rest_api_with</guid>
    <title>Building a REST API with JAXB, Spring Boot and Spring Data</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/building_a_rest_api_with</link>
        <pubDate>Wed, 29 Oct 2014 05:52:37 -0600</pubDate>
    <category>Java</category>
    <category>jaxb</category>
    <category>rest</category>
    <category>spring-boot</category>
    <category>spring</category>
    <category>api</category>
    <category>spring-data</category>
    <atom:summary type="html">&lt;p&gt;
&lt;a href=&quot;https://jaxb.java.net/&quot;&gt;&lt;img src=&quot;//raibledesigns.com/repository/images/javaxml-duke.gif&quot; alt=&quot;Project JAXB&quot; width=&quot;100&quot; class=&quot;picture&quot; style=&quot;margin-top: -20px&quot;&gt;&lt;/a&gt;
    If someone asked you to develop a REST API on the JVM, which frameworks would you use? I was recently tasked with such a project.
    My client asked me to implement a REST API to ingest requests from a 3rd party. The project entailed consuming XML
    requests, storing the data in a database, then exposing the data to internal application with a JSON endpoint.
    Finally, it would allow taking in a JSON request and turning it into an XML request back to the 3rd party.
&lt;/p&gt;
&lt;p&gt;
    With the recent &lt;a href=&quot;http://www.infoq.com/news/2014/10/apache-camel-2.14&quot;&gt;release of Apache Camel 2.14&lt;/a&gt; and
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel2&quot;&gt;my success using it&lt;/a&gt;, I started by
    copying my Apache Camel / CXF / Spring Boot project and trimming it down to the bare essentials. I whipped together
    a simple &lt;em&gt;Hello World&lt;/em&gt; service using Camel and Spring MVC. I also integrated Swagger into both. Both
    implementations were pretty easy to create (&lt;a href=&quot;http://camel.465427.n5.nabble.com/Camel-s-Swagger-vs-Spring-MVC-Swagger-td5757023.html&quot;&gt;sample code&lt;/a&gt;),
    but I decided to use Spring MVC. My reasons were simple: its REST support was more mature, I knew it well, and
    &lt;a href=&quot;http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/testing.html#spring-mvc-test-framework&quot;&gt;Spring MVC Test&lt;/a&gt; makes it easy to test APIs.
&lt;/p&gt;
&lt;p class=&quot;alert alert-info&quot;&gt;&lt;strong&gt;Camel&apos;s Swagger support without web.xml&lt;/strong&gt;&lt;br/&gt;
    As part of the aforementioned spike, I learned out how to configure Camel&apos;s REST and Swagger support using Spring&apos;s
    JavaConfig and no web.xml. I made this into a sample project and put it on GitHub as
    &lt;a href=&quot;https://github.com/mraible/camel-rest-swagger&quot;&gt;camel-rest-swagger&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    This article shows how I built a REST API with Java 8, Spring Boot/MVC, JAXB and Spring Data (JPA and REST
    components).
    I stumbled a few times while developing this project, but figured out how to get over all the hurdles. I hope this
    helps the team that&apos;s now maintaining this project (my last day was Friday) and those that are trying to do
    something similar.
&lt;/p&gt;</atom:summary>        <description>&lt;p&gt;
&lt;a href=&quot;https://jaxb.java.net/&quot;&gt;&lt;img src=&quot;//raibledesigns.com/repository/images/javaxml-duke.gif&quot; alt=&quot;Project JAXB&quot; width=&quot;100&quot; class=&quot;picture&quot; style=&quot;margin-top: -20px&quot;&gt;&lt;/a&gt;
    If someone asked you to develop a REST API on the JVM, which frameworks would you use? I was recently tasked with such a project.
    My client asked me to implement a REST API to ingest requests from a 3rd party. The project entailed consuming XML
    requests, storing the data in a database, then exposing the data to internal application with a JSON endpoint.
    Finally, it would allow taking in a JSON request and turning it into an XML request back to the 3rd party.
&lt;/p&gt;
&lt;p&gt;
    With the recent &lt;a href=&quot;http://www.infoq.com/news/2014/10/apache-camel-2.14&quot;&gt;release of Apache Camel 2.14&lt;/a&gt; and
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel2&quot;&gt;my success using it&lt;/a&gt;, I started by
    copying my Apache Camel / CXF / Spring Boot project and trimming it down to the bare essentials. I whipped together
    a simple &lt;em&gt;Hello World&lt;/em&gt; service using Camel and Spring MVC. I also integrated Swagger into both. Both
    implementations were pretty easy to create (&lt;a href=&quot;http://camel.465427.n5.nabble.com/Camel-s-Swagger-vs-Spring-MVC-Swagger-td5757023.html&quot;&gt;sample code&lt;/a&gt;),
    but I decided to use Spring MVC. My reasons were simple: its REST support was more mature, I knew it well, and
    &lt;a href=&quot;http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/testing.html#spring-mvc-test-framework&quot;&gt;Spring MVC Test&lt;/a&gt; makes it easy to test APIs.
&lt;/p&gt;
&lt;p class=&quot;alert alert-info&quot;&gt;&lt;strong&gt;Camel&apos;s Swagger support without web.xml&lt;/strong&gt;&lt;br/&gt;
    As part of the aforementioned spike, I learned out how to configure Camel&apos;s REST and Swagger support using Spring&apos;s
    JavaConfig and no web.xml. I made this into a sample project and put it on GitHub as
    &lt;a href=&quot;https://github.com/mraible/camel-rest-swagger&quot;&gt;camel-rest-swagger&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    This article shows how I built a REST API with Java 8, Spring Boot/MVC, JAXB and Spring Data (JPA and REST
    components).
    I stumbled a few times while developing this project, but figured out how to get over all the hurdles. I hope this
    helps the team that&apos;s now maintaining this project (my last day was Friday) and those that are trying to do
    something similar.
&lt;/p&gt;
&lt;h3 id=&quot;jaxb&quot;&gt;XML to Java with JAXB&lt;/h3&gt;
&lt;p&gt;
    The data we needed to ingest from a 3rd party was based on the &lt;a href=&quot;http://ncpdp.org/&quot;&gt;NCPDP&lt;/a&gt; Standards. As a member,
    we were able to download a number of XSD files, put them in our project and generate Java classes to handle the
    incoming/outgoing requests. I used the &lt;a href=&quot;https://java.net/projects/maven-jaxb2-plugin/pages/Home&quot;&gt;maven-jaxb2-plugin&lt;/a&gt;
    to generate the Java classes.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.jvnet.jaxb2.maven2&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;maven-jaxb2-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;0.8.3&amp;lt;/version&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;generate&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
            &amp;lt;configuration&amp;gt;
                &amp;lt;args&amp;gt;
                    &amp;lt;arg&amp;gt;-XtoString&amp;lt;/arg&amp;gt;
                    &amp;lt;arg&amp;gt;-Xequals&amp;lt;/arg&amp;gt;
                    &amp;lt;arg&amp;gt;-XhashCode&amp;lt;/arg&amp;gt;
                    &amp;lt;arg&amp;gt;-Xcopyable&amp;lt;/arg&amp;gt;
                &amp;lt;/args&amp;gt;
                &amp;lt;plugins&amp;gt;
                    &amp;lt;plugin&amp;gt;
                        &amp;lt;groupId&amp;gt;org.jvnet.jaxb2_commons&amp;lt;/groupId&amp;gt;
                        &amp;lt;artifactId&amp;gt;jaxb2-basics&amp;lt;/artifactId&amp;gt;
                        &amp;lt;version&amp;gt;0.6.4&amp;lt;/version&amp;gt;
                    &amp;lt;/plugin&amp;gt;
                &amp;lt;/plugins&amp;gt;
                &amp;lt;schemaDirectory&amp;gt;src/main/resources/schemas/ncpdp&amp;lt;/schemaDirectory&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;The first error I ran into was about a property already being defined.
&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
[INFO] --- maven-jaxb2-plugin:0.8.3:generate (default) @ spring-app ---
[ERROR] Error while parsing schema(s).Location [ file:/Users/mraible/dev/spring-app/src/main/resources/schemas/ncpdp/structures.xsd{1811,48}].
com.sun.istack.SAXParseException2; systemId: file:/Users/mraible/dev/spring-app/src/main/resources/schemas/ncpdp/structures.xsd;
    lineNumber: 1811; columnNumber: 48; Property &quot;MultipleTimingModifierAndTimingAndDuration&quot; is already defined.
    Use &amp;lt;jaxb:property&gt; to resolve this conflict.
at com.sun.tools.xjc.ErrorReceiver.error(ErrorReceiver.java:86)
&lt;/pre&gt;
&lt;p&gt;
    I was able to workaround this by upgrading to maven-jaxb2-plugin version 0.9.1. I created a controller and stubbed
    out a response with hard-coded data. I confirmed the incoming XML-to-Java marshalling worked by testing with a
    sample request provided by our 3rd party customer. I started with a &lt;code&gt;curl&lt;/code&gt;
    command, because it was easy to use and could be run by anyone with the file and curl installed.
&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
curl -X POST -H &apos;Accept: application/xml&apos; -H &apos;Content-type: application/xml&apos; \
--data-binary @sample-request.xml http://localhost:8080/api/message -v
&lt;/pre&gt;
&lt;p&gt;
    This is when I ran into another stumbling block: the response wasn&apos;t getting marshalled back to XML correctly.
    After some research, I found out this was caused by the lack of &lt;code&gt;@XmlRootElement&lt;/code&gt; annotations on my
    generated classes.
    I
    posted a question to Stack Overflow titled &lt;a
        href=&quot;http://stackoverflow.com/questions/26070566/returning-jaxb-generated-elements-from-spring-boot-controller&quot;&gt;
    Returning JAXB-generated elements from Spring Boot Controller&lt;/a&gt;. After banging my head against the wall for a
    couple days, I figured out &lt;a href=&quot;http://stackoverflow.com/a/26124104/65681&quot;&gt;the solution&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
    I created a bindings.xjb file in the same directory as my schemas. This causes JAXB to generate &lt;code&gt;@XmlRootElement&lt;/code&gt;
    on
    classes.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;
&amp;lt;jxb:bindings version=&quot;1.0&quot;
              xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot;
              xmlns:jxb=&quot;http://java.sun.com/xml/ns/jaxb&quot;
              xmlns:xjc=&quot;http://java.sun.com/xml/ns/jaxb/xjc&quot;
              xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
              xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd&quot;&amp;gt;

    &amp;lt;jxb:bindings schemaLocation=&quot;transport.xsd&quot; node=&quot;/xsd:schema&quot;&amp;gt;
        &amp;lt;jxb:globalBindings&amp;gt;
            &amp;lt;xjc:simple/&amp;gt;
        &amp;lt;/jxb:globalBindings&amp;gt;
    &amp;lt;/jxb:bindings&amp;gt;
&amp;lt;/jxb:bindings&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To add namespaces prefixes to the returned XML, I had to modify the maven-jaxb2-plugin to add a couple arguments.
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;arg&amp;gt;-extension&amp;lt;/arg&amp;gt;
&amp;lt;arg&amp;gt;-Xnamespace-prefix&amp;lt;/arg&amp;gt;
&lt;/pre&gt;
&lt;p&gt;And add a dependency:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependencies&amp;gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;org.jvnet.jaxb2_commons&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;jaxb2-namespace-prefix&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;1.1&amp;lt;/version&amp;gt;
    &amp;lt;/dependency&amp;gt;
&amp;lt;/dependencies&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Then I modified &lt;code&gt;bindings.xjb&lt;/code&gt; to include the package and prefix settings. I also moved
    &lt;code&gt;&amp;lt;xjc:simple/&amp;gt;&lt;/code&gt; into a global setting. I eventually had to add prefixes for all schemas and their
    packages. &lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot;?&amp;gt;
&amp;lt;bindings version=&quot;2.0&quot; xmlns:xsd=&quot;http://www.w3.org/2001/XMLSchema&quot; xmlns=&quot;http://java.sun.com/xml/ns/jaxb&quot;
          xmlns:xjc=&quot;http://java.sun.com/xml/ns/jaxb/xjc&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
          xmlns:namespace=&quot;http://jaxb2-commons.dev.java.net/namespace-prefix&quot;
          xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/jaxb http://java.sun.com/xml/ns/jaxb/bindingschema_2_0.xsd
              http://jaxb2-commons.dev.java.net/namespace-prefix http://java.net/projects/jaxb2-commons/sources/svn/content/namespace-prefix/trunk/src/main/resources/prefix-namespace-schema.xsd&quot;&amp;gt;

    &amp;lt;globalBindings&amp;gt;
        &amp;lt;xjc:simple/&amp;gt;
    &amp;lt;/globalBindings&amp;gt;

    &amp;lt;bindings schemaLocation=&quot;transport.xsd&quot; node=&quot;/xsd:schema&quot;&amp;gt;
        &amp;lt;schemaBindings&amp;gt;
            &amp;lt;package name=&quot;org.ncpdp.schema.transport&quot;/&amp;gt;
        &amp;lt;/schemaBindings&amp;gt;
        &amp;lt;bindings&amp;gt;
            &amp;lt;namespace:prefix name=&quot;transport&quot;/&amp;gt;
        &amp;lt;/bindings&amp;gt;
    &amp;lt;/bindings&amp;gt;
&amp;lt;/bindings&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
    I learned how to add prefixes from the &lt;a href=&quot;https://java.net/projects/jaxb2-commons/pages/Namespace-prefix&quot;&gt;namespace-prefix
    plugins page&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;Finally, I customized the code-generation process to generate Joda Time&apos;s
    &lt;a href=&quot;http://joda-time.sourceforge.net/apidocs/org/joda/time/DateTime.html&quot;&gt;DateTime&lt;/a&gt; instead of the
    default &lt;code&gt;XMLGregorianCalendar&lt;/code&gt;. This involved a couple custom XmlAdapters and a couple
    additional lines in &lt;code&gt;bindings.xjb&lt;/code&gt;. You can see the adapters and &lt;code&gt;bindings.xjb&lt;/code&gt; with all
    necessary prefixes
    in &lt;a href=&quot;https://gist.github.com/mraible/abad8d78c1f053ec686b&quot;&gt;this gist&lt;/a&gt;.
    Nicolas Fr&#228;nkel&apos;s &lt;a href=&quot;http://blog.frankel.ch/customize-your-jaxb-bindings&quot;&gt;Customize your JAXB bindings&lt;/a&gt;
    was a great resource for making all this work.
&lt;/p&gt;
&lt;p&gt;I wrote a test to prove that the ingest API worked as desired.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = Application.class)
@WebAppConfiguration
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
public class InitiateRequestControllerTest {

    @Inject
    private InitiateRequestController controller;

    private MockMvc mockMvc;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
        this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
    }

    @Test
    public void testGetNotAllowedOnMessagesAPI() throws Exception {
        mockMvc.perform(get(&quot;/api/initiate&quot;)
                .accept(MediaType.APPLICATION_XML))
                .andExpect(status().isMethodNotAllowed());
    }

    @Test
    public void testPostPaInitiationRequest() throws Exception {
        String request = new Scanner(new ClassPathResource(&quot;sample-request.xml&quot;).getFile()).useDelimiter(&quot;\\Z&quot;).next();

        mockMvc.perform(post(&quot;/api/initiate&quot;)
                .accept(MediaType.APPLICATION_XML)
                .contentType(MediaType.APPLICATION_XML)
                .content(request))
                .andExpect(status().isOk())
                .andExpect(content().contentType(MediaType.APPLICATION_XML))
                .andExpect(xpath(&quot;/Message/Header/To&quot;).string(&quot;3rdParty&quot;))
                .andExpect(xpath(&quot;/Message/Header/SenderSoftware/SenderSoftwareDeveloper&quot;).string(&quot;HID&quot;))
                .andExpect(xpath(&quot;/Message/Body/Status/Code&quot;).string(&quot;010&quot;));
    }
}
&lt;/pre&gt;
&lt;h3 id=&quot;spring-data&quot;&gt;Spring Data for JPA and REST&lt;/h3&gt;
&lt;p&gt;
    With JAXB out of the way, I turned to creating an internal API that could be used by another application. Spring
    Data was fresh in my mind after &lt;a href=&quot;http://shop.oreilly.com/product/0636920024767.do&quot;&gt;reading about it&lt;/a&gt; last
    summer. I created classes for entities I wanted to persist, using &lt;a href=&quot;http://projectlombok.org/&quot;&gt;Lombok&apos;s&lt;/a&gt;
    @Data to reduce boilerplate.
&lt;/p&gt;
&lt;p&gt;
    I read the &lt;a href=&quot;https://spring.io/guides/gs/accessing-data-jpa/&quot;&gt;Accessing Data with JPA&lt;/a&gt; guide, created
    a couple repositories and wrote some tests to prove they worked. I ran into an issue trying to persist
    Joda&apos;s DateTime and found &lt;a href=&quot;http://jadira.sourceforge.net/usertype-userguide.html&quot;&gt;Jadira&lt;/a&gt; provided a
    solution.
&lt;/p&gt;
&lt;p&gt;
    I added its usertype.core as a dependency to my pom.xml:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.jadira.usertype&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;usertype.core&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.2.0.GA&amp;lt;/version&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;... and annotated DateTime variables accordingly.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Column(name = &quot;last_modified&quot;, nullable = false)
@Type(type=&quot;org.jadira.usertype.dateandtime.joda.PersistentDateTime&quot;)
private DateTime lastModified;
&lt;/pre&gt;
&lt;p&gt;With JPA working, I turned to exposing REST endpoints. I used &lt;a
        href=&quot;https://spring.io/guides/gs/accessing-data-rest/&quot;&gt;Accessing JPA Data with REST&lt;/a&gt;
    as a guide and was looking at JSON in my browser in a matter of minutes. I was surprised to see a &quot;profile&quot; service
    listed next to mine, and posted &lt;a href=&quot;https://github.com/spring-projects/spring-boot/issues/1718&quot;&gt;a question&lt;/a&gt;
    to the Spring Boot team. Oliver Gierke &lt;a
            href=&quot;https://github.com/spring-projects/spring-boot/issues/1718#issuecomment-59329942&quot;&gt;provided an
        excellent answer&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;swagger&quot;&gt;Swagger&lt;/h3&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/martypitt/swagger-springmvc&quot;&gt;Spring MVC&apos;s integration for Swagger&lt;/a&gt; has greatly
    improved
    since I &lt;a href=&quot;http://raibledesigns.com/rd/entry/documenting_your_spring_api_with&quot;&gt;last wrote about it&lt;/a&gt;.
    Now you can enable it with a &lt;code&gt;@EnableSwagger&lt;/code&gt; annotation. Below
    is the &lt;code&gt;SwaggerConfig&lt;/code&gt; class I used to configure Swagger and read properties from
    &lt;code&gt;application.yml&lt;/code&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Configuration
@EnableSwagger
public class SwaggerConfig implements EnvironmentAware {
	public static final String DEFAULT_INCLUDE_PATTERN = &quot;/api/.*&quot;;

	private RelaxedPropertyResolver propertyResolver;

	@Override
	public void setEnvironment(Environment environment) {
		this.propertyResolver = new RelaxedPropertyResolver(environment, &quot;swagger.&quot;);
	}

	/**
	 * Swagger Spring MVC configuration
	 */
	@Bean
	public SwaggerSpringMvcPlugin swaggerSpringMvcPlugin(SpringSwaggerConfig springSwaggerConfig) {
		return new SwaggerSpringMvcPlugin(springSwaggerConfig)
				.apiInfo(apiInfo())
				.genericModelSubstitutes(ResponseEntity.class)
				.includePatterns(DEFAULT_INCLUDE_PATTERN);
	}

	/**
	 * API Info as it appears on the swagger-ui page
	 */
	private ApiInfo apiInfo() {
		return new ApiInfo(
				propertyResolver.getProperty(&quot;title&quot;),
				propertyResolver.getProperty(&quot;description&quot;),
				propertyResolver.getProperty(&quot;termsOfServiceUrl&quot;),
				propertyResolver.getProperty(&quot;contact&quot;),
				propertyResolver.getProperty(&quot;license&quot;),
				propertyResolver.getProperty(&quot;licenseUrl&quot;));
	}
}
&lt;/pre&gt;
&lt;p&gt;After getting Swagger to work, I discovered that endpoints published with &lt;code&gt;@RepositoryRestResource&lt;/code&gt; aren&apos;t
    picked up by Swagger. There is an &lt;a href=&quot;https://github.com/martypitt/swagger-springmvc/issues/238&quot;&gt;open issue&lt;/a&gt;
    for Spring Data support in the swagger-springmvc project.&lt;/p&gt;

&lt;h3 id=&quot;liquibase&quot;&gt;Liquibase Integration&lt;/h3&gt;
&lt;p&gt;
    I configured this project to use H2 in development and PostgreSQL in production. I used Spring profiles to do this
    and copied XML/YAML (for Maven and application*.yml files) from a previously created &lt;a href=&quot;https://jhipster.github.io&quot;&gt;JHipster&lt;/a&gt;
    project.
&lt;/p&gt;
&lt;p&gt;Next, I needed to create a database. I decided to use &lt;a href=&quot;http://www.liquibase.org/&quot;&gt;Liquibase&lt;/a&gt; to
    create tables, rather than Hibernate&apos;s schema-export. I chose Liquibase
    over &lt;a href=&quot;http://flywaydb.org/&quot;&gt;Flyway&lt;/a&gt; based of discussions in the &lt;a
            href=&quot;https://github.com/jhipster/generator-jhipster/issues/588&quot;&gt;JHipster project&lt;/a&gt;. To use Liquibase with
    Spring Boot is dead simple: add the following dependency to pom.xml, then place changelog files in
    &lt;code&gt;src/main/resources/db/changelog&lt;/code&gt;.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.liquibase&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;liquibase-core&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;&lt;p&gt;
    I started by using Hibernate&apos;s schema-export and changing &lt;code&gt;hibernate.ddl-auto&lt;/code&gt; to &quot;create-drop&quot; in
    &lt;code&gt;application-dev.yml&lt;/code&gt;. I also commented out the liquibase-core dependency.
    Then I setup a PostgreSQL database and started the app with &quot;mvn spring-boot:run -Pprod&quot;.
&lt;/p&gt;
&lt;p&gt;I generated the liquibase changelog from an existing schema using the following command (after
    &lt;a href=&quot;http://www.liquibase.org/download/&quot;&gt;downloading&lt;/a&gt; and installing Liquibase). &lt;/p&gt;
&lt;pre&gt;
liquibase --driver=org.postgresql.Driver --classpath=&quot;/Users/mraible/.m2/repository/org/postgresql/postgresql/9.3-1102-jdbc41/postgresql-9.3-1102-jdbc41.jar:/Users/mraible/snakeyaml-1.11.jar&quot; --changeLogFile=/Users/mraible/dev/spring-app/src/main/resources/db/changelog/db.changelog-02.yaml --url=&quot;jdbc:postgresql://localhost:5432/mydb&quot; --username=user --password=pass generateChangeLog
&lt;/pre&gt;

&lt;p&gt;I did find one bug - the generateChangeLog command &lt;a href=&quot;https://liquibase.jira.com/browse/CORE-2056&quot;&gt;generates
    too many constraints in version 3.2.2&lt;/a&gt;. I was able to fix this by manually editing the generated YAML file.
&lt;/p&gt;
&lt;div class=&quot;alert alert-success&quot;&gt;&lt;p style=&quot;margin-top: 5px&quot;&gt;&lt;strong&gt;Tip:&lt;/strong&gt; If you want to drop all tables in your database to verify
    Liquibase creation is working in PostgeSQL, run the following commands:&lt;/p&gt;
&lt;pre style=&quot;margin-bottom: 5px&quot;&gt;psql -d mydb
drop schema public cascade;
create schema public;
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;After writing minimal code for Spring Data and configuring Liquibase to create tables/relationships, I relaxed
    a bit, documented how everything worked and added a &lt;a href=&quot;https://github.com/isrsal/spring-mvc-logger&quot;&gt;LoggingFilter&lt;/a&gt;.
    The LoggingFilter was handy for viewing API requests and responses.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
@Bean
public FilterRegistrationBean loggingFilter() {
    LoggingFilter filter = new LoggingFilter();
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(filter);
    registrationBean.setUrlPatterns(Arrays.asList(&quot;/api/*&quot;));
    return registrationBean;
}
&lt;/pre&gt;
&lt;h3 id=&quot;resttemplate&quot;&gt;Accessing API with RestTemplate&lt;/h3&gt;
&lt;p&gt;The final step I needed to do was figure out how to access my new and fancy API with
    &lt;a href=&quot;http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/client/RestTemplate.html&quot;&gt;RestTemplate&lt;/a&gt;.
    At first, I thought it would be easy. Then I realized that Spring Data produces a
    &lt;a href=&quot;http://stateless.co/hal_specification.html&quot;&gt;HAL&lt;/a&gt;-compliant API, so its content is embedded inside an
    &quot;_embedded&quot; JSON key.
&lt;/p&gt;
&lt;p&gt;After much trial and error, I discovered I needed to create a &lt;code&gt;RestTemplate&lt;/code&gt; with HAL and Joda-Time
    awareness.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Bean
public RestTemplate restTemplate() {
	ObjectMapper mapper = new ObjectMapper();
	mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	mapper.registerModule(new Jackson2HalModule());
	mapper.registerModule(new JodaModule());

	MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
	converter.setSupportedMediaTypes(MediaType.parseMediaTypes(&quot;application/hal+json&quot;));
	converter.setObjectMapper(mapper);
	StringHttpMessageConverter stringConverter = new StringHttpMessageConverter();
	stringConverter.setSupportedMediaTypes(MediaType.parseMediaTypes(&quot;application/xml&quot;));

	List&amp;lt;HttpMessageConverter&amp;lt;?&amp;gt;&amp;gt; converters = new ArrayList&amp;lt;&amp;gt;();
	converters.add(converter);
	converters.add(stringConverter);

	return new RestTemplate(converters);
}
&lt;/pre&gt;
&lt;p&gt;
    The &lt;code&gt;JodaModule&lt;/code&gt; was provided by the following dependency:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;com.fasterxml.jackson.datatype&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jackson-datatype-joda&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;With the configuration complete, I was able to write a &lt;code&gt;MessagesApiITest&lt;/code&gt; integration test that posts a
    request
    and retrieves it using the API. The API was secured using basic authentication, so it took me a bit to figure out
    how
    to make that work with RestTemplate. Willie Wheeler&apos;s
    &lt;a href=&quot;http://springinpractice.com/2013/10/02/quick-tip-basic-authentication-with-spring-resttemplate&quot;&gt;Basic
        Authentication With Spring RestTemplate&lt;/a&gt; was a big help.&lt;/p&gt;

&lt;pre class=&quot;brush: java&quot;&gt;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = IntegrationTestConfig.class)
public class MessagesApiITest {
    private final static Log log = LogFactory.getLog(MessagesApiITest.class);
    @Value(&quot;http://${app.host}/api/initiate&quot;)
    private String initiateAPI;
    @Value(&quot;http://${app.host}/api/messages&quot;)
    private String messagesAPI;
    @Value(&quot;${app.host}&quot;)
    private String host;
    @Inject
    private RestTemplate restTemplate;

    @Before
    public void setup() throws Exception {
        String request = new Scanner(new ClassPathResource(&quot;sample-request.xml&quot;).getFile()).useDelimiter(&quot;\\Z&quot;).next();

        ResponseEntity&amp;lt;org.ncpdp.schema.transport.Message&amp;gt; response = restTemplate.exchange(getTestUrl(initiateAPI),
                HttpMethod.POST, getBasicAuthHeaders(request), org.ncpdp.schema.transport.Message.class,
                Collections.emptyMap());
        assertEquals(HttpStatus.OK, response.getStatusCode());
    }

    @Test
    public void testGetMessages() {
        HttpEntity&amp;lt;String&amp;gt; request = getBasicAuthHeaders(null);

        ResponseEntity&amp;lt;PagedResources&amp;lt;Message&amp;gt;&amp;gt; result = restTemplate.exchange(getTestUrl(messagesAPI), HttpMethod.GET,
                request, new ParameterizedTypeReference&amp;lt;PagedResources&amp;lt;Message&amp;gt;&amp;gt;() {});
        HttpStatus status = result.getStatusCode();
        Collection&amp;lt;Message&amp;gt; messages = result.getBody().getContent();

        log.debug(&quot;messages found: &quot; + messages.size());
        assertEquals(HttpStatus.OK, status);
        for (Message message : messages) {
            log.debug(&quot;message.id: &quot; + message.getId());
            log.debug(&quot;message.dateCreated: &quot; + message.getDateCreated());
        }
    }

    private HttpEntity&amp;lt;String&amp;gt; getBasicAuthHeaders(String body) {
        String plainCreds = &quot;user:pass&quot;;
        byte&amp;#91;&amp;#93; plainCredsBytes = plainCreds.getBytes();
        byte&amp;#91;&amp;#93; base64CredsBytes = Base64.encodeBase64(plainCredsBytes);
        String base64Creds = new String(base64CredsBytes);

        HttpHeaders headers = new HttpHeaders();
        headers.add(&quot;Authorization&quot;, &quot;Basic &quot; + base64Creds);
        headers.add(&quot;Content-type&quot;, &quot;application/xml&quot;);

        if (body == null) {
            return new HttpEntity&amp;lt;&amp;gt;(headers);
        } else {
            return new HttpEntity&amp;lt;&amp;gt;(body, headers);
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;To get Spring Data to populate the message id, I created a custom &lt;code&gt;RestConfig&lt;/code&gt; class to expose it. I learned how to do this from &lt;a href=&quot;http://tommyziegler.com/how-to-expose-the-resourceid-with-spring-data-rest/&quot;&gt;Tommy Ziegler&lt;/a&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
/**
 * Used to expose ids for resources.
 */
@Configuration
public class RestConfig extends RepositoryRestMvcConfiguration {

    @Override
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(Message.class);
        config.setBaseUri(&quot;/api&quot;);
    }
}

&lt;/pre&gt;
&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;
&lt;p&gt;
    This article explains how I built a REST API using JAXB, Spring Boot, Spring Data and Liquibase.
    It was relatively easy to build, but required some tricks to access it with Spring&apos;s RestTemplate. Figuring out
    how to customize JAXB&apos;s code generation was also essential to make things work.
&lt;/p&gt;&lt;p&gt;
    I started developing the project with Spring Boot 1.1.7, but upgraded to 1.2.0.M2 after I found it supported
    Log4j2 and configuring Spring Data REST&apos;s base URI in application.yml. When I handed the project off to my client
    last week, it was using 1.2.0.BUILD-SNAPSHOT because of a
    &lt;a href=&quot;https://github.com/spring-projects/spring-boot/issues/1719&quot;&gt;bug when running in Tomcat&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;This was an enjoyable project to work on. I especially liked how easy Spring Data makes it to expose JPA
    entities in an API. Spring Boot made things easy to configure once again and Liquibase seems like a nice
    tool for database migrations.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;If someone asked me to develop a REST API on the JVM, which frameworks would I use?&lt;/em&gt; Spring Boot, Spring Data, Jackson, Joda-Time, Lombok and Liquibase. These frameworks worked really well for me on this particular project.&lt;/p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/developing_services_with_apache_camel1</guid>
    <title>Developing Services with Apache Camel - Part II: Creating and Testing Routes</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/developing_services_with_apache_camel1</link>
        <pubDate>Tue, 30 Sep 2014 10:05:38 -0600</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>junit</category>
    <category>testing</category>
    <category>maven</category>
    <category>tomcat</category>
    <category>apachecamel</category>
    <category>spring</category>
    <category>microservices</category>
    <category>camel</category>
    <category>jenkins</category>
    <atom:summary type="html">&lt;p&gt;
    &lt;a href=&quot;http://camel.apache.org&quot;&gt;&lt;img src=&quot;http://camel.apache.org/images/camel-box-small.png&quot; height=&quot;150&quot;
                                           alt=&quot;Apache Camel&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
    This article is the second in a series on Apache Camel and how I used it to replace IBM Message Broker for a client.
    The first article, &lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel&quot;&gt;
    Developing Services with Apache Camel - Part I: The Inspiration&lt;/a&gt;, describes why I chose Camel for this project.
&lt;/p&gt;

&lt;p&gt;

&lt;p&gt;To make sure these new services correctly replaced existing services, a 3-step approach was used:&lt;/p&gt;
&lt;ol class=&quot;task-list&quot;&gt;
    &lt;li&gt;Write an integration test pointing to the old service.&lt;/li&gt;
    &lt;li&gt;Write the implementation and a unit test to prove it works.&lt;/li&gt;
    &lt;li&gt;Write an integration test pointing to the new service.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
    I chose to start by replacing the simplest service first. It was a SOAP Service that talked to a database to
    retrieve
    a value based on an input parameter. To learn more about Camel and how it works, I started by looking at the
    &lt;a href=&quot;http://camel.apache.org/cxf-tomcat-example.html&quot;&gt;CXF Tomcat Example&lt;/a&gt;. I learned that
    Camel is used to provide &lt;em&gt;routing&lt;/em&gt; of requests. Using its &lt;a href=&quot;http://camel.apache.org/cxf.html&quot;&gt;CXF
    component&lt;/a&gt;, it can easily produce SOAP web service
    endpoints. An end point is simply an interface, and Camel takes care of producing the implementation.
&lt;/p&gt;</atom:summary>        <description>&lt;p&gt;
    &lt;a href=&quot;http://camel.apache.org&quot;&gt;&lt;img src=&quot;http://camel.apache.org/images/camel-box-small.png&quot; height=&quot;150&quot;
                                           alt=&quot;Apache Camel&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
    This article is the second in a series on Apache Camel and how I used it to replace IBM Message Broker for a client.
    The first article, &lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel&quot;&gt;
    Developing Services with Apache Camel - Part I: The Inspiration&lt;/a&gt;, describes why I chose Camel for this project.
&lt;/p&gt;

&lt;p&gt;

&lt;p&gt;To make sure these new services correctly replaced existing services, a 3-step approach was used:&lt;/p&gt;
&lt;ol class=&quot;task-list&quot;&gt;
    &lt;li&gt;Write an integration test pointing to the old service.&lt;/li&gt;
    &lt;li&gt;Write the implementation and a unit test to prove it works.&lt;/li&gt;
    &lt;li&gt;Write an integration test pointing to the new service.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;
    I chose to start by replacing the simplest service first. It was a SOAP Service that talked to a database to
    retrieve
    a value based on an input parameter. To learn more about Camel and how it works, I started by looking at the
    &lt;a href=&quot;http://camel.apache.org/cxf-tomcat-example.html&quot;&gt;CXF Tomcat Example&lt;/a&gt;. I learned that
    Camel is used to provide &lt;em&gt;routing&lt;/em&gt; of requests. Using its &lt;a href=&quot;http://camel.apache.org/cxf.html&quot;&gt;CXF
    component&lt;/a&gt;, it can easily produce SOAP web service
    endpoints. An end point is simply an interface, and Camel takes care of producing the implementation.
&lt;/p&gt;

&lt;h3 id=&quot;legacy-integration-test&quot;&gt;Legacy Integration Test&lt;/h3&gt;

&lt;p&gt;I started by writing a &lt;code&gt;LegacyDrugServiceTests&lt;/code&gt; integration test for the old drug service.
    I tried two different ways of testing, using WSDL-generated Java classes, as well as using JAX-WS&apos;s SOAP API.
    Finding the WSDL for the legacy service was difficult because IBM Message Broker doesn&apos;t expose it when adding
    &quot;?wsdl&quot; to the service&apos;s URL. Instead, I had to dig through the project files until I found it. Then I
    used the &lt;a href=&quot;http://cxf.apache.org/docs/maven-cxf-codegen-plugin-wsdl-to-java.html&quot;&gt;cxf-codegen-plugin&lt;/a&gt;
    to generate the web service client. Below is what one of the tests looked like that uses the JAX-WS API.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Test
public void sendGPIRequestUsingSoapApi() throws Exception {
    SOAPElement bodyChildOne = getBody(message).addChildElement(&quot;gpiRequest&quot;, &quot;m&quot;);
    SOAPElement bodyChildTwo = bodyChildOne.addChildElement(&quot;args0&quot;, &quot;m&quot;);
    bodyChildTwo.addChildElement(&quot;NDC&quot;, &quot;ax22&quot;).addTextNode(&quot;54561237201&quot;);
    SOAPMessage reply = connection.call(message, getUrlWithTimeout(SERVICE_NAME));
    if (reply != null) {
        Iterator itr = reply.getSOAPBody().getChildElements();
        Map resultMap = TestUtils.getResults(itr);
        assertEquals(&quot;66100525123130&quot;, resultMap.get(&quot;GPI&quot;));
    }
}
&lt;/pre&gt;
&lt;h3 id=&quot;implementation&quot;&gt;Implementing the Drug Service&lt;/h3&gt;

&lt;p&gt;In the last article, I mentioned I wanted no XML in the project. To facilitate this, I used Camel&apos;s
    &lt;a href=&quot;http://camel.apache.org/java-dsl.html&quot;&gt;Java DSL&lt;/a&gt; to define routes and Spring&apos;s
    &lt;a href=&quot;http://docs.spring.io/spring/docs/4.0.6.RELEASE/spring-framework-reference/htmlsingle/#beans-java&quot;&gt;JavaConfig&lt;/a&gt;
    to configure dependencies.
&lt;/p&gt;

&lt;p&gt;The first route I wrote was one that looked up a GPI (Generic Product Identifier) by NDC (National Drug Code).&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@WebService
public interface DrugService {
    @WebMethod(operationName = &quot;gpiRequest&quot;)
    GpiResponse findGpiByNdc(GpiRequest request);
}
&lt;/pre&gt;
&lt;p&gt;
    To expose this as a web service endpoint with CXF, I needed to do two things:
&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Tell Spring how to configure CXF by importing &quot;classpath:META-INF/cxf/cxf.xml&quot; into a @Configuration class.&lt;/li&gt;
    &lt;li&gt;Configure CXF&apos;s Servlet so endpoints can be served up at a particular URL.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;To satisfy item #1, I created a &lt;code&gt;CamelConfig&lt;/code&gt; class that extends &lt;a
        href=&quot;http://camel.apache.org/maven/camel-2.14.0/camel-spring-javaconfig/apidocs/org/apache/camel/spring/javaconfig/CamelConfiguration.html&quot;&gt;CamelConfiguration&lt;/a&gt;.
    This class allows Camel to be configured by Spring&apos;s JavaConfig. In it, I imported the CXF configuration, allowed
    tracing to be
    configured dynamically, and exposed my &lt;code&gt;application.properties&lt;/code&gt; to Camel. I also set it up (with &lt;code&gt;@ComponentScan&lt;/code&gt;)
    to look
    for Camel routes annotated with &lt;code&gt;@Component&lt;/code&gt;.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Configuration
@ImportResource(&quot;classpath:META-INF/cxf/cxf.xml&quot;)
@ComponentScan(&quot;com.raibledesigns.camel&quot;)
public class CamelConfig extends CamelConfiguration {
    @Value(&quot;${logging.trace.enabled}&quot;)
    private Boolean tracingEnabled;

    @Override
    protected void setupCamelContext(CamelContext camelContext) throws Exception {
        PropertiesComponent pc = new PropertiesComponent();
        pc.setLocation(&quot;classpath:application.properties&quot;);
        camelContext.addComponent(&quot;properties&quot;, pc);
        // see if trace logging is turned on
        if (tracingEnabled) {
            camelContext.setTracing(true);
        }
        super.setupCamelContext(camelContext);
    }

    @Bean
    public Tracer camelTracer() {
        Tracer tracer = new Tracer();
        tracer.setTraceExceptions(false);
        tracer.setTraceInterceptors(true);
        tracer.setLogName(&quot;com.raibledesigns.camel.trace&quot;);
        return tracer;
    }
}
&lt;/pre&gt;
&lt;p&gt;CXF has a servlet that&apos;s responsible for serving up its services at common path. To map CXF&apos;s servlet, I leveraged
    Spring&apos;s
    &lt;a href=&quot;http://docs.spring.io/autorepo/docs/spring-framework/4.0.x/javadoc-api/org/springframework/web/WebApplicationInitializer.html&quot;&gt;
        WebApplicationInitializer&lt;/a&gt; in an &lt;code&gt;AppInitializer&lt;/code&gt; class. I decided to serve up everything from a
    &lt;code&gt;/api/*&lt;/code&gt; base URL.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package com.raibledesigns.camel.config;

import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

public class AppInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        servletContext.addListener(new ContextLoaderListener(getContext()));
        ServletRegistration.Dynamic servlet = servletContext.addServlet(&quot;CXFServlet&quot;, new CXFServlet());
        servlet.setLoadOnStartup(1);
        servlet.setAsyncSupported(true);
        servlet.addMapping(&quot;/api/*&quot;);
    }

    private AnnotationConfigWebApplicationContext getContext() {
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        context.setConfigLocation(&quot;com.raibledesigns.camel.config&quot;);
        return context;
    }
}
&lt;/pre&gt;
&lt;p&gt;
    To implement this web service with Camel, I created a &lt;code&gt;DrugRoute&lt;/code&gt; class that extends Camel&apos;s
    &lt;code&gt;RouteBuilder&lt;/code&gt;.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Component
public class DrugRoute extends RouteBuilder {
    private String uri = &quot;cxf:/drugs?serviceClass=&quot; + DrugService.class.getName();

    @Override
    public void configure() throws Exception {
        from(uri)
            .recipientList(simple(&quot;direct:${header.operationName}&quot;));
        from(&quot;direct:gpiRequest&quot;).routeId(&quot;gpiRequest&quot;)
            .process(new Processor() {
                public void process(Exchange exchange) throws Exception {
                    // get the ndc from the input
                    String ndc = exchange.getIn().getBody(GpiRequest.class).getNDC();
                    exchange.getOut().setBody(ndc);
                }
            })
            .to(&quot;sql:{{sql.selectGpi}}&quot;)
            .to(&quot;log:output&quot;)
            .process(new Processor() {
                public void process(Exchange exchange) throws Exception {
                    // get the gpi from the input
                    List&amp;lt;HashMap&amp;gt; data = (ArrayList&amp;lt;HashMap&amp;gt;) exchange.getIn().getBody();
                    DrugInfo drug = new DrugInfo();
                    if (data.size() &amp;gt; 0) {
                        drug = new DrugInfo(String.valueOf(data.get(0).get(&quot;GPI&quot;)));
                    }
                    GpiResponse response = new GpiResponse(drug);
                    exchange.getOut().setBody(response);
                }
            });
    }
}
&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;sql.selectGpi&lt;/code&gt; property is read from &lt;code&gt;src/main/resources/application.properties&lt;/code&gt; and looks
    as follows:&lt;/p&gt;
&lt;pre&gt;sql.selectGpi=select GPI from drugs where ndc = #?dataSource=ds.drugs&lt;/pre&gt;
&lt;p&gt;The &quot;ds.drugs&quot; reference is to a datasource that&apos;s created by Spring. From my
    &lt;code&gt;AppConfig&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Configuration
@PropertySource(&quot;classpath:application.properties&quot;)
public class AppConfig {

    @Value(&quot;${ds.driver.db2}&quot;)
    private String jdbcDriverDb2;

    @Value(&quot;${ds.password}&quot;)
    private String jdbcPassword;

    @Value(&quot;${ds.url}&quot;)
    private String jdbcUrl;

    @Value(&quot;${ds.username}&quot;)
    private String jdbcUsername;

    @Bean(name = &quot;ds.drugs&quot;)
    public DataSource drugsDataSource() {
        return createDataSource(jdbcDriverDb2, jdbcUsername, jdbcPassword, jdbcUrl);
    }

    private BasicDataSource createDataSource(String driver, String username, String password, String url) {
        BasicDataSource ds = new BasicDataSource();
        ds.setDriverClassName(driver);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setUrl(url);
        ds.setMaxActive(100);
        ds.setMaxWait(1000);
        ds.setPoolPreparedStatements(true);
        return ds;
    }
}
&lt;/pre&gt;

&lt;h3 id=&quot;unit-testing&quot;&gt;Unit Testing&lt;/h3&gt;

&lt;p&gt;
    The hardest part about unit testing this route was figuring out how to use Camel&apos;s
    &lt;a href=&quot;http://camel.apache.org/testing.html&quot;&gt;testing support&lt;/a&gt;. I posted
    &lt;a href=&quot;http://camel.465427.n5.nabble.com/Mocking-SQL-results-in-a-route-td5752169.html&quot;&gt;a question&lt;/a&gt; to the
    Camel users mailing list in early June. Based on advice received, I bought
    &lt;a href=&quot;http://www.manning.com/ibsen/&quot;&gt;Camel in Action&lt;/a&gt;, read chapter 6 on testing and went to work.
    I wanted to eliminate the dependency on a datasource, so I used Camel&apos;s
    &lt;a href=&quot;http://camel.apache.org/advicewith.html&quot;&gt;AdviceWith&lt;/a&gt; feature to modify my route and intercept the
    SQL call. This allowed me to return pre-defined results and verify everything worked.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@RunWith(CamelSpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = CamelSpringDelegatingTestContextLoader.class, classes = CamelConfig.class)
@DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_EACH_TEST_METHOD)
@UseAdviceWith
public class DrugRouteTests {

    @Autowired
    CamelContext camelContext;

    @Produce
    ProducerTemplate template;

    @EndpointInject(uri = &quot;mock:result&quot;)
    MockEndpoint result;

    static List&amp;lt;Map&amp;gt; results = new ArrayList&amp;lt;Map&amp;gt;() {{
        add(new HashMap&amp;lt;String, String&amp;gt;() {{
            put(&quot;GPI&quot;, &quot;123456789&quot;);
        }});
    }};

    @Before
    public void before() throws Exception {
        camelContext.setTracing(true);

        ModelCamelContext context = (ModelCamelContext) camelContext;
        RouteDefinition route = context.getRouteDefinition(&quot;gpiRequest&quot;);
        route.adviceWith(context, new RouteBuilder() {
            @Override
            public void configure() throws Exception {
                interceptSendToEndpoint(&quot;sql:*&quot;).skipSendToOriginalEndpoint().process(new Processor() {
                    @Override
                    public void process(Exchange exchange) throws Exception {
                        exchange.getOut().setBody(results);
                    }
                });
            }
        });
        route.to(result);
        camelContext.start();
    }

    @Test
    public void testMockSQLEndpoint() throws Exception {
        result.expectedMessageCount(1);
        GpiResponse expectedResult = new GpiResponse(new DrugInfo(&quot;123456789&quot;));
        result.allMessages().body().contains(expectedResult);

        GpiRequest request = new GpiRequest();
        request.setNDC(&quot;123&quot;);
        template.sendBody(&quot;direct:gpiRequest&quot;, request);

        MockEndpoint.assertIsSatisfied(camelContext);
    }
}
&lt;/pre&gt;
&lt;p&gt;
    I found AdviceWith to be extremely useful as I developed more routes and tests in this project. I used its
    &lt;a href=&quot;http://camel.apache.org/advicewith.html#AdviceWith-UsingweaveById&quot;&gt;weaveById&lt;/a&gt; feature to intercept
    calls to stored procedures, replace steps in my routes and remove steps I didn&apos;t want to test. For example,
    in one route, there was a complicated workflow to interact with a customer&apos;s data.
&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Call a stored procedure in a remote database, which then inserts a record into a temp table.&lt;/li&gt;
    &lt;li&gt;Lookup that data using the value returned from the stored procedure.&lt;/li&gt;
    &lt;li&gt;Delete the record from the temp table.&lt;/li&gt;
    &lt;li&gt;Parse the data (as CSV) since the returned value is ~ delimited.&lt;/li&gt;
    &lt;li&gt;Convert the parsed data into objects, then do database inserts in a local database (if data doesn&apos;t exist).&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To make matters worse, remote database access was restricted by IP address. This meant that, while developing, I
    couldn&apos;t
    even manually test from my local machine. To solve this, I used the following:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;interceptSendToEndpoint(&quot;bean:*&quot;)&lt;/code&gt; to intercept the call to my stored procedure bean.&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;weaveById(&quot;myJdbcProcessor&quot;).before()&lt;/code&gt; to replace the temp table lookup with a CSV file.&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://code.google.com/p/mockito/&quot;&gt;Mockito&lt;/a&gt; to mock a JdbcTemplate that does the inserts.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
    To figure out how to configure and execute stored procedures in a route, I used the &lt;a
        href=&quot;https://github.com/quephird/camel-stored-procedure&quot;&gt;
    camel-store-procedure project on GitHub&lt;/a&gt;. Mockito&apos;s
    &lt;a href=&quot;http://docs.mockito.googlecode.com/hg/org/mockito/ArgumentCaptor.html&quot;&gt;ArgumentCaptor&lt;/a&gt; also became very
    useful
    when developing a route that called a 3rd-party web service within a route. James Carr has
    &lt;a href=&quot;http://blog.james-carr.org/2009/09/28/mockito-verifying-details-of-an-object-passed-to-a-collaborator/&quot;&gt;more
        information&lt;/a&gt;
    on how you might use this to verify values on an argument.
&lt;/p&gt;

&lt;p&gt;
    To see if my tests were hitting all aspects of the code, I integrated the
    &lt;a href=&quot;http://mojo.codehaus.org/cobertura-maven-plugin/&quot;&gt;cobertura-maven-plugin&lt;/a&gt; for code coverage
    reports (generated by running &lt;code&gt;mvn site&lt;/code&gt;).
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&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;cobertura-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;configuration&amp;gt;
                &amp;lt;instrumentation&amp;gt;
                    &amp;lt;excludes&amp;gt;
                        &amp;lt;exclude&amp;gt;**/model/*.class&amp;lt;/exclude&amp;gt;
                        &amp;lt;exclude&amp;gt;**/AppInitializer.class&amp;lt;/exclude&amp;gt;
                        &amp;lt;exclude&amp;gt;**/StoredProcedureBean.class&amp;lt;/exclude&amp;gt;
                        &amp;lt;exclude&amp;gt;**/SoapActionInterceptor.class&amp;lt;/exclude&amp;gt;
                    &amp;lt;/excludes&amp;gt;
                &amp;lt;/instrumentation&amp;gt;
                &amp;lt;check/&amp;gt;
            &amp;lt;/configuration&amp;gt;
            &amp;lt;version&amp;gt;2.6&amp;lt;/version&amp;gt;
        &amp;lt;/plugin&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;cobertura-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;2.6&amp;lt;/version&amp;gt;
        &amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;h3 id=&quot;integration-testing&quot;&gt;Integration Testing&lt;/h3&gt;

&lt;p&gt;
    Writing an integration test was fairly straightforward. I created a &lt;code&gt;DrugRouteITest&lt;/code&gt; class, a
    client using CXF&apos;s &lt;a href=&quot;https://cxf.apache.org/javadoc/latest/org/apache/cxf/jaxws/JaxWsProxyFactoryBean.html&quot;&gt;JaxWsProxyFactoryBean&lt;/a&gt;
    and called the method on the service.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public class DrugRouteITest {

    private static final String URL = &quot;http://localhost:8080/api/drugs&quot;;

    protected static DrugService createCXFClient() {
        JaxWsProxyFactoryBean factory = new JaxWsProxyFactoryBean();
        factory.setBindingId(&quot;http://schemas.xmlsoap.org/wsdl/soap12/&quot;);
        factory.setServiceClass(DrugService.class);
        factory.setAddress(getTestUrl(URL));
        return (DrugService) factory.create();
    }

    @Test
    public void findGpiByNdc() throws Exception {
        // create input parameter
        GpiRequest input = new GpiRequest();
        input.setNDC(&quot;54561237201&quot;);

        // create the webservice client and send the request
        DrugService client = createCXFClient();
        GpiResponse response = client.findGpiByNdc(input);

        assertEquals(&quot;66100525123130&quot;, response.getDrugInfo().getGPI());
    }
}
&lt;/pre&gt;
&lt;p&gt;This integration test is only run after Tomcat has started and deployed the app. Unit tests are run by Maven&apos;s
    &lt;a href=&quot;http://maven.apache.org/surefire/maven-surefire-plugin/&quot;&gt;surefire-plugin&lt;/a&gt;, while integration tests are
    run by the &lt;a href=&quot;http://maven.apache.org/surefire/maven-failsafe-plugin/&quot;&gt;failsafe-plugin&lt;/a&gt;. An available
    Tomcat port is determined by the &lt;a href=&quot;http://mojo.codehaus.org/build-helper-maven-plugin/&quot;&gt;
        build-helper-maven-plugin&lt;/a&gt;. This port is set as a system property and read by the &lt;code&gt;getTestUrl()&lt;/code&gt;
    method call above.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public static String getTestUrl(String url) {
    if (System.getProperty(&quot;tomcat.http.port&quot;) != null) {
        url = url.replace(&quot;8080&quot;, System.getProperty(&quot;tomcat.http.port&quot;));
    }
    return url;
}
&lt;/pre&gt;
&lt;p&gt;Below are the relevant bits from
    &lt;code&gt;pom.xml&lt;/code&gt; that determines when to start/stop Tomcat, as well as which tests to run. &lt;/p&gt;

&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;/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&amp;lt;/goal&amp;gt;
            &amp;lt;/goals&amp;gt;
            &amp;lt;configuration&amp;gt;
                &amp;lt;fork&amp;gt;true&amp;lt;/fork&amp;gt;
                &amp;lt;port&amp;gt;${tomcat.http.port}&amp;lt;/port&amp;gt;
            &amp;lt;/configuration&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;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;maven-surefire-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.17&amp;lt;/version&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;excludes&amp;gt;
            &amp;lt;exclude&amp;gt;**/*IT*.java&amp;lt;/exclude&amp;gt;
            &amp;lt;exclude&amp;gt;**/Legacy**.java&amp;lt;/exclude&amp;gt;
        &amp;lt;/excludes&amp;gt;
        &amp;lt;includes&amp;gt;
            &amp;lt;include&amp;gt;**/*Tests.java&amp;lt;/include&amp;gt;
            &amp;lt;include&amp;gt;**/*Test.java&amp;lt;/include&amp;gt;
        &amp;lt;/includes&amp;gt;
    &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.apache.maven.plugins&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;maven-failsafe-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;2.17&amp;lt;/version&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;includes&amp;gt;
            &amp;lt;include&amp;gt;**/*IT*.java&amp;lt;/include&amp;gt;
        &amp;lt;/includes&amp;gt;
        &amp;lt;systemProperties&amp;gt;
            &amp;lt;tomcat.http.port&amp;gt;${tomcat.http.port}&amp;lt;/tomcat.http.port&amp;gt;
        &amp;lt;/systemProperties&amp;gt;
    &amp;lt;/configuration&amp;gt;
    &amp;lt;executions&amp;gt;
        &amp;lt;execution&amp;gt;
            &amp;lt;goals&amp;gt;
                &amp;lt;goal&amp;gt;integration-test&amp;lt;/goal&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;The most useful part of integration testing came when I copied one of my legacy tests into it and started verifying
    backwards compatibility. Since we wanted to replace existing services, and require no client changes, I had to make
    the XML request and response match. &lt;a href=&quot;http://www.charlesproxy.com&quot;&gt;Charles&lt;/a&gt; was very useful for this
    exercise,
    letting me inspect the request/response and tweak things to match. The following JAX-WS annotations allowed me to
    change the XML
    element names and achieve backward compatibility.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;code&gt;@BindingType(SOAPBinding.SOAP12HTTP_BINDING)&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;@WebResult(name = &quot;return&quot;, targetNamespace = &quot;...&quot;)&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;@ResponseWrapper(localName = &quot;gpiResponse&quot;)&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;@WebParam(name = &quot;args0&quot;, targetNamespace = &quot;...&quot;)&lt;/code&gt;&lt;/li&gt;
    &lt;li&gt;&lt;code&gt;@XmlElement(name = &quot;...&quot;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;jenkins-and-continuous-deployment&quot;&gt;Continuous Integration and Deployment&lt;/h3&gt;

&lt;p&gt;My next item of business was configuring a job in &lt;a href=&quot;http://jenkins-ci.org/&quot;&gt;Jenkins&lt;/a&gt; to continually test
    and deploy. Getting all the tests to pass was easy, and deploying to Tomcat was simple enough thanks to the
    &lt;a href=&quot;https://wiki.jenkins-ci.org/display/JENKINS/Deploy+Plugin&quot;&gt;Deploy Plugin&lt;/a&gt; and
    &lt;a href=&quot;http://paxcel.net/blog/automation-of-warear-deployment-using-jenkins/&quot;&gt;this article&lt;/a&gt;. However, after a
    few deploys, Tomcat would throw OutOfMemory exceptions. Therefore, I ended up creating a second &quot;deploy&quot; job that
    stops Tomcat, copies the successfully-built WAR to $CATALINA_HOME/webapps, removes $CATALINA_HOME/webapps/ROOT and
    restarts Tomcat. I used Jenkins &quot;Execute shell&quot; feature to configure these three steps.
    I was pleased to find my &lt;a
            href=&quot;http://raibledesigns.com/tomcat/boot-howto.html&quot;&gt;&lt;code&gt;/etc/init.d/tomcat&lt;/code&gt;&lt;/a&gt;
    script still worked for starting Tomcat at boot time and providing convenient start/stop commands.
&lt;/p&gt;

&lt;h3 id=&quot;summary&quot;&gt;Summary&lt;/h3&gt;

&lt;p&gt;
    This article shows you how I implemented and tested a simple Apache Camel route. The route described
    only does a simple database lookup, but you can see how Camel&apos;s testing support allows you to mock results and concentrate
    on developing your route logic. I found its testing framework very useful and not well documented, so hopefully this
    article helps to fix that. In the &lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_services_with_apache_camel2&quot;&gt;next article&lt;/a&gt;, I&apos;ll talk about upgrading to Spring 4, integrating Spring Boot and
    our team&apos;s microservice deployment discussions.
&lt;/p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_3_0_released</guid>
    <title>AppFuse 3.0 Released!</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_3_0_released</link>
        <pubDate>Mon, 23 Dec 2013 14:31:15 -0700</pubDate>
    <category>Java</category>
    <category>spring</category>
    <category>primefaces</category>
    <category>wicket</category>
    <category>java</category>
    <category>bootstrap3</category>
    <category>maven</category>
    <category>spring4</category>
    <category>appfuse</category>
            <description>&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;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/a_webapp_makeover_with_spring</guid>
    <title>A Webapp Makeover with Spring 4 and Spring Boot</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/a_webapp_makeover_with_spring</link>
        <pubDate>Wed, 11 Dec 2013 12:47:15 -0700</pubDate>
    <category>Java</category>
    <category>spring4</category>
    <category>maven</category>
    <category>jersey</category>
    <category>springboot</category>
    <category>spring</category>
    <atom:summary type="html">&lt;p&gt;A typical Maven and Spring web application has a fair amount of XML and 
verbosity to it. Add in Jersey and Spring Security and you can have hundreds of lines of 
XML before you even start to write your Java code. As part of a recent project,
I was tasked with upgrading a webapp like this to use Spring 4 and 
&lt;a href=&quot;http://projects.spring.io/spring-boot/&quot;&gt;Spring Boot&lt;/a&gt;. I also figured I&apos;d try to minimize the XML.&lt;/p&gt; 
&lt;p&gt;This is my story on how I upgraded to Spring 4, Jersey 2, Java 8 and Spring Boot 0.5.0 M6. 
&lt;/p&gt;
&lt;p&gt;When I started, the app was using Spring 3.2.5, Spring Security 3.1.4 and Jersey 1.18. The
pom.xml had four Jersey dependencies, three Spring dependencies and three Spring Security
dependencies, along with a number of exclusions for &quot;jersey-spring&quot;.&lt;/p&gt;
&lt;p id=&quot;spring4&quot;&gt;&lt;strong&gt;Upgrading to Spring 4&lt;/strong&gt;&lt;br/&gt;
Upgrading to Spring 4 was easy, I changed the version property to 4.0.0.RC2 and added the new 
Spring &lt;a href=&quot;http://spring.io/blog/2013/12/03/spring-framework-4-0-rc2-available&quot;&gt;bill of materials&lt;/a&gt;
to my pom.xml. I also add the Spring milestone repo since Spring 4 won&apos;t be released to Maven central
until tomorrow.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependencyManagement&amp;gt;
    &amp;lt;dependencies&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-framework-bom&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
            &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/dependencyManagement&amp;gt;

&amp;lt;repositories&amp;gt;
    &amp;lt;repository&amp;gt;
        &amp;lt;id&amp;gt;spring-milestones&amp;lt;/id&amp;gt;
        &amp;lt;url&amp;gt;http://repo.spring.io/milestone&amp;lt;/url&amp;gt;
        &amp;lt;snapshots&amp;gt;
            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;
        &amp;lt;/snapshots&amp;gt;
    &amp;lt;/repository&amp;gt;
&amp;lt;/repositories&amp;gt;
&lt;/pre&gt;</atom:summary>        <description>&lt;p&gt;A typical Maven and Spring web application has a fair amount of XML and 
verbosity to it. Add in Jersey and Spring Security and you can have hundreds of lines of 
XML before you even start to write your Java code. As part of a recent project,
I was tasked with upgrading a webapp like this to use Spring 4 and 
&lt;a href=&quot;http://projects.spring.io/spring-boot/&quot;&gt;Spring Boot&lt;/a&gt;. I also figured I&apos;d try to minimize the XML.&lt;/p&gt; 
&lt;p&gt;This is my story on how I upgraded to Spring 4, Jersey 2, Java 8 and Spring Boot 0.5.0 M6. 
&lt;/p&gt;
&lt;p&gt;When I started, the app was using Spring 3.2.5, Spring Security 3.1.4 and Jersey 1.18. The
pom.xml had four Jersey dependencies, three Spring dependencies and three Spring Security
dependencies, along with a number of exclusions for &quot;jersey-spring&quot;.&lt;/p&gt;
&lt;p id=&quot;spring4&quot;&gt;&lt;strong&gt;Upgrading to Spring 4&lt;/strong&gt;&lt;br/&gt;
Upgrading to Spring 4 was easy, I changed the version property to 4.0.0.RC2 and added the new 
Spring &lt;a href=&quot;http://spring.io/blog/2013/12/03/spring-framework-4-0-rc2-available&quot;&gt;bill of materials&lt;/a&gt;
to my pom.xml. I also add the Spring milestone repo since Spring 4 won&apos;t be released to Maven central
until tomorrow.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependencyManagement&amp;gt;
    &amp;lt;dependencies&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-framework-bom&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
            &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;
&amp;lt;/dependencyManagement&amp;gt;

&amp;lt;repositories&amp;gt;
    &amp;lt;repository&amp;gt;
        &amp;lt;id&amp;gt;spring-milestones&amp;lt;/id&amp;gt;
        &amp;lt;url&amp;gt;http://repo.spring.io/milestone&amp;lt;/url&amp;gt;
        &amp;lt;snapshots&amp;gt;
            &amp;lt;enabled&amp;gt;true&amp;lt;/enabled&amp;gt;
        &amp;lt;/snapshots&amp;gt;
    &amp;lt;/repository&amp;gt;
&amp;lt;/repositories&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Next, I removed all the references to ${spring.framework.version} in dependencies since it&apos;d 
be controlled by &lt;a href=&quot;http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html#Dependency_Management&quot;&gt;
Maven&apos;s dependency management feature&lt;/a&gt;. 
&lt;/p&gt;
&lt;pre class=&quot;brush: diff&quot;&gt;
     &amp;lt;dependency&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;version&amp;gt;${spring.framework.version}&amp;lt;/version&amp;gt;
     &amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
I also changed to use Maven 3&apos;s &lt;a href=&quot;http://maven.apache.org/pom.html#Exclusions&quot;&gt;wildcard syntax&lt;/a&gt; to exclude multiple 
dependencies.&lt;/p&gt;
&lt;pre class=&quot;brush: diff&quot;&gt;
    &amp;lt;dependency&amp;gt;
        &amp;lt;groupId&amp;gt;com.sun.jersey.contribs&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;jersey-spring&amp;lt;/artifactId&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&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;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-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;artifactId&amp;gt;*&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 confirmed the upgrade worked by running &quot;mvn dependency:tree | grep spring&quot;, followed by &quot;mvn jetty:run&quot; and viewing the app in my browser. &lt;/p&gt;
&lt;p id=&quot;jersey2&quot;&gt;&lt;strong&gt;Upgrading to Jersey 2&lt;/strong&gt;&lt;br/&gt;
The next item I tackled was upgrading to Jersey 2.4.1. I changed the version number in my pom.xml, then added the Jersey BOM.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.glassfish.jersey&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jersey-bom&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${jersey.version}&amp;lt;/version&amp;gt;
    &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
    &amp;lt;scope&amp;gt;import&amp;lt;/scope&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
You might ask &quot;why Jersey?&quot; if we already have Spring MVC and its REST support? You might also ask why not Play or Grails instead of a Java + Spring stack? For this particular project, I recommended technology options, and these were certainly among them. However, the team chose differently and I support their decision. The project is 
creating an iOS app, as well as a responsive HTML5 mobile/desktop app. We figured we had enough risk with new technologies on the front-end that we should play it a bit safer on the backend. To make the backend work a bit sexier, we&apos;ve decided to allow Spring 4, Java 8 and possibly some reactive principles.&lt;/p&gt;
&lt;p&gt;Next, I changed from the old &lt;i&gt;com.sun.jersey&lt;/i&gt; dependencies to &lt;i&gt;org.glassfish.jersey&lt;/i&gt; and removed jersey-spring. &lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.glassfish.jersey.containers&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jersey-container-servlet&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.glassfish.jersey.media&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;jersey-media-json-jackson&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
The last thing I needed to do was change the servlet-class and param-name in web.xml:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;servlet&amp;gt;
    &amp;lt;servlet-name&amp;gt;jersey-servlet&amp;lt;/servlet-name&amp;gt;
    &amp;lt;servlet-class&amp;gt;org.glassfish.jersey.servlet.ServletContainer&amp;lt;/servlet-class&amp;gt;
    &amp;lt;init-param&amp;gt;
        &amp;lt;param-name&amp;gt;jersey.config.server.provider.packages&amp;lt;/param-name&amp;gt;
        &amp;lt;param-value&amp;gt;com.raibledesigns.boot.service&amp;lt;/param-value&amp;gt;
    &amp;lt;/init-param&amp;gt;
    &amp;lt;load-on-startup&amp;gt;1&amp;lt;/load-on-startup&amp;gt;
&amp;lt;/servlet&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;java8&quot;&gt;&lt;strong&gt;Requiring Java 8&lt;/strong&gt;&lt;br/&gt;
Requiring Java 8 to compile was easy enough. I added the maven-compiler-plugin to enforce a minimum version.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;plugin&amp;gt;
    &amp;lt;artifactId&amp;gt;maven-compiler-plugin&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;3.1&amp;lt;/version&amp;gt;
    &amp;lt;configuration&amp;gt;
        &amp;lt;source&amp;gt;1.8&amp;lt;/source&amp;gt;
        &amp;lt;target&amp;gt;1.8&amp;lt;/target&amp;gt;
    &amp;lt;/configuration&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;&lt;p&gt;I &lt;a href=&quot;https://jdk8.java.net/download.html&quot;&gt;downloaded the latest Java 8 SDK&lt;/a&gt; and installed it. Then I set my JAVA_HOME to use it.&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
export JAVA_HOME=`/usr/libexec/java_home -v 1.8`
&lt;/pre&gt;
&lt;p id=&quot;boot&quot;&gt;&lt;strong&gt;Integrating Spring Boot&lt;/strong&gt;&lt;br/&gt;
I learned about Spring Boot a few weeks ago &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_2013_a_nordic_countries&quot;&gt;at Devoxx&lt;/a&gt;. &lt;a href=&quot;http://www.joshlong.com/&quot;&gt;Josh Long&lt;/a&gt; gave me a 3-minute demo at the speaker&apos;s dinner and showed me enough to pique my interest. To integrate it into my project, I started with the &lt;a href=&quot;http://projects.spring.io/spring-boot/#quick-start&quot;&gt;Quick Start&lt;/a&gt;. I added the boot-parent, dependencies for web, security and actuator (logging, metrics, etc.) and the Maven plugin. I removed all the Spring and Spring Security dependencies.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;parent&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-parent&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;0.5.0.M6&amp;lt;/version&amp;gt;
&amp;lt;/parent&amp;gt;
...
&amp;lt;pluginRepositories&amp;gt;
    &amp;lt;pluginRepository&amp;gt;
        &amp;lt;id&amp;gt;spring-milestones&amp;lt;/id&amp;gt;
        &amp;lt;url&amp;gt;http://repo.spring.io/milestone&amp;lt;/url&amp;gt;
    &amp;lt;/pluginRepository&amp;gt;
&amp;lt;/pluginRepositories&amp;gt;
...
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-web&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-security&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-starter-actuator&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
...
&amp;lt;plugin&amp;gt;
    &amp;lt;groupId&amp;gt;org.springframework.boot&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;spring-boot-maven-plugin&amp;lt;/artifactId&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Upon restarting my app, I got an error about spring-security.xml using a 3.1 XSD. I fixed it by changing to 3.2. Next, I wanted to eliminate web.xml. First of all, I created an &lt;code&gt;ApplicationInitializer&lt;/code&gt; so the WAR could be started from the command line.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package com.raibledesigns.boot.config;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.SpringBootServletInitializer;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class ApplicationInitializer extends SpringBootServletInitializer {

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
        return application.sources(ApplicationInitializer.class);
    }

    public static void main(String[] args) {
        SpringApplication.run(ApplicationInitializer.class, args);
    }
}
&lt;/pre&gt;
&lt;p&gt;However, after adding this, I received the following error on startup:&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
&apos;org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor&apos;: 
Invocation of init method failed; nested exception is 
java.lang.AbstractMethodError: org.hibernate.validator.internal.engine.ConfigurationImpl
.getDefaultParameterNameProvider()Ljavax/validation/ParameterNameProvider;
&lt;/pre&gt;
&lt;p&gt;Adding hibernate-validator as a dependency solved this problem:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.hibernate&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;hibernate-validator&amp;lt;/artifactId&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To configure Spring Security without web.xml and spring-security.xml, I created &lt;code&gt;WebSecurityConfig.java&lt;/code&gt;:
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package com.raibledesigns.boot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.annotation.Order;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;

@Configuration
@EnableWebSecurity
@Order(Ordered.LOWEST_PRECEDENCE - 6)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                .antMatchers(&quot;/&quot;, &quot;/home&quot;).permitAll()
                .antMatchers(&quot;/v1.0/**&quot;).hasRole(&quot;USER&quot;)
                .anyRequest().authenticated();
        http.httpBasic().realmName(&quot;My API&quot;);
    }

    @Override
    protected void configure(AuthenticationManagerBuilder authManagerBuilder) throws Exception {
        authManagerBuilder.inMemoryAuthentication()
                .withUser(&quot;test&quot;).password(&quot;test123&quot;).roles(&quot;USER&quot;);
    }
}
&lt;/pre&gt;
&lt;p&gt;To configure Jersey without web.xml, I created a &lt;code&gt;JerseyConfig&lt;/code&gt; class:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package com.raibledesigns.boot.config;

import org.glassfish.jersey.filter.LoggingFilter;
import org.glassfish.jersey.jackson.JacksonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.glassfish.jersey.server.ServerProperties;

import javax.ws.rs.ApplicationPath;

@ApplicationPath(&quot;/v1.0&quot;)
public class JerseyConfig extends ResourceConfig {

    public JerseyConfig() {
        packages(&quot;com.raibledesigns.boot.service&quot;);
        property(ServerProperties.BV_SEND_ERROR_IN_RESPONSE, true);
        property(ServerProperties.JSON_PROCESSING_FEATURE_DISABLE, false);
        property(ServerProperties.MOXY_JSON_FEATURE_DISABLE, true);
        property(ServerProperties.WADL_FEATURE_DISABLE, true);
        register(LoggingFilter.class);
        register(JacksonFeature.class);
    }
}
&lt;/pre&gt;
&lt;p&gt;Finally, I created &lt;code&gt;MvcConfig.java&lt;/code&gt; to set the welcome page.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
package com.raibledesigns.boot.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;

@Configuration
public class MvcConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController(&quot;/&quot;).setViewName(&quot;index&quot;);
    }
}
&lt;/pre&gt;
&lt;p&gt;To cleanup, I deleted &lt;code&gt;src/main/webapp/WEB-INF&lt;/code&gt; and created &lt;code&gt;src/main/resources/logback.xml&lt;/code&gt;:
&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;include resource=&quot;org/springframework/boot/logging/logback/base.xml&quot;/&amp;gt;
    &amp;lt;logger name=&quot;org.springframework.boot&quot; level=&quot;INFO&quot;/&amp;gt;
    &amp;lt;logger name=&quot;org.springframework.security&quot; level=&quot;ERROR&quot;/&amp;gt;
&amp;lt;/configuration&amp;gt;
&lt;/pre&gt;&lt;p&gt;Since Boot doesn&apos;t support JSP out-of-the-box, I renamed my index.jsp file to index.html and changed the URL in it to point to &quot;/v1.0/hello&quot;. I was pleased to see that everything worked nicely. I learned shortly after that I could remove the Spring BOM since Spring Boot &lt;a href=&quot;https://twitter.com/rob_winch/status/410609696639184896&quot;&gt;uses a &amp;lt;spring.version&amp;gt; property to control its Spring version&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;The only issue I found is when started the app with &quot;mvn package &amp;&amp; java -jar target/app.war&quot;, it failed to initialize Jersey. I tried adding a @Bean for the servlet:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Bean
public ServletRegistrationBean jerseyServlet() {
    ServletRegistrationBean registration = new ServletRegistrationBean(new ServletContainer(), &quot;/v1.0/*&quot;);
    registration.addInitParameter(ServletProperties.JAXRS_APPLICATION_CLASS, JerseyConfig.class.getName());
    return registration;
}
&lt;/pre&gt;
&lt;p&gt;Unfortunately, when running it using &quot;java -jar&quot;, I get the following error:
&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
org.glassfish.hk2.api.MultiException: A MultiException has 1 exceptions.  They are:
1. org.glassfish.jersey.server.internal.scanning.ResourceFinderException: 
java.io.FileNotFoundException: /.../target/app.war!/WEB-INF/classes (No such file or directory)
	at org.jvnet.hk2.internal.Utilities.justCreate(Utilities.java:869)
	at org.jvnet.hk2.internal.ServiceLocatorImpl.create(ServiceLocatorImpl.java:814)
	at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:906)
	at org.jvnet.hk2.internal.ServiceLocatorImpl.createAndInitialize(ServiceLocatorImpl.java:898)
	at org.glassfish.jersey.server.ApplicationHandler.createApplication(ApplicationHandler.java:300)
	at org.glassfish.jersey.server.ApplicationHandler.&amp;lt;init&amp;gt;(ApplicationHandler.java:279)
	at org.glassfish.jersey.servlet.WebComponent.&amp;lt;init&amp;gt;(WebComponent.java:302)
&lt;/pre&gt;
&lt;p&gt;
This seems strange since there is a WEB-INF/classes in my WAR. Regardless, this is not a Boot problem per se, but more of a Jersey issue. From one of the Boot developers:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
The whole idea with Boot is that servlets are just a transport - they are a means to an end, and hopefully not the only one - the &quot;container&quot; is Spring, not the servlet container. We probably could add some form of support for SCI but only by hacking the containers since the spec really doesn&apos;t allow for much control of their lifecycle. It hasn&apos;t been a priority so far.
&lt;/p&gt;
&lt;p id=&quot;summary&quot;&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
I hope this article is useful to see how you to upgrade your Java webapps to use Spring 4 and Spring Boot. I&apos;ve created a &lt;a href=&quot;https://github.com/mraible/boot-makeover&quot;&gt;boot-makeover project on GitHub&lt;/a&gt; with all the code mentioned. You can also &lt;a href=&quot;https://github.com/mraible/boot-makeover/commits/master&quot;&gt;view the commits&lt;/a&gt; for each step. &lt;/p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_light_2_2_1</guid>
    <title>AppFuse Light 2.2.1 Released!</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_light_2_2_1</link>
        <pubDate>Thu, 24 Jan 2013 19:43:20 -0700</pubDate>
    <category>Java</category>
    <category>hibernate</category>
    <category>spring</category>
    <category>java</category>
    <category>appfuse</category>
    <category>security</category>
    <category>appfuse-light</category>
    <category>maven</category>
            <description>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;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_2_1_released</guid>
    <title>AppFuse 2.2.1 Released!</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_2_1_released</link>
        <pubDate>Tue, 11 Dec 2012 15:21:44 -0700</pubDate>
    <category>Java</category>
    <category>maven</category>
    <category>security</category>
    <category>appfuse</category>
    <category>java</category>
    <category>hibernate</category>
    <category>spring</category>
            <description>&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;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/my_what_s_new_in</guid>
    <title>My What&apos;s New in Spring 3.1 Presentation</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/my_what_s_new_in</link>
        <pubDate>Sat, 4 Feb 2012 17:47:14 -0700</pubDate>
    <category>Java</category>
    <category>twitter</category>
    <category>java7</category>
    <category>hibernate</category>
    <category>servlet3</category>
    <category>spring</category>
    <category>springdata</category>
            <description>My first business trip of the year was to Dublin, CA this past week. &lt;a href=&quot;http://www.mcginityphoto.com&quot;&gt;Trish&lt;/a&gt; joined me because she wanted to take some pictures of San Francisco. She got some awesome shots as you can see below. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/6803885291/&quot; title=&quot;Lombard Ave in SF with Bay view by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7172/6803885291_dc21faf748_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;Lombard Ave in SF with Bay view&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/6803888629/&quot; title=&quot;Kissing Sea lions by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7167/6803888629_a5b5e3b8a6_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;Kissing Sea lions&quot; style=&quot;border: 1px solid black; margin-left: 20px&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/6803890133/&quot; title=&quot;Pier 38 San Fran by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7164/6803890133_a1ffb843c9_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;Pier 38 San Fran&quot; style=&quot;border: 1px solid black; margin-left: 20px&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/6803914983/&quot; title=&quot;San Francisco Bay Bridge at Night by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7027/6803914983_e97df823fb_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;San Francisco Bay Bridge at Night&quot; style=&quot;border: 1px solid black; margin-left: 20px&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/6803907077/&quot; title=&quot;Bay Bridge San Francisco at Night by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7035/6803907077_20e4589919_s.jpg&quot; width=&quot;75&quot; height=&quot;75&quot; alt=&quot;Bay Bridge San Francisco at Night&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;http://www.flickr.com/photos/mcginityphoto/6803887361/&quot; title=&quot;Balclutha Maritime Museum San Fran by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7016/6803887361_6ababa7e50.jpg&quot; width=&quot;500&quot; height=&quot;332&quot; alt=&quot;Balclutha Maritime Museum San Fran&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;On Tuesday night, I attended &lt;a href=&quot;http://raibledesigns.com/rd/entry/twitter_s_open_source_summit&quot;&gt;Twitter&apos;s Open Source Summit&lt;/a&gt; with a co-worker and had a great time. 
&lt;/p&gt;
&lt;p&gt;
On Wednesday, I talked about What&apos;s New in Spring 3.1 at the &lt;a href=&quot;http://www.meetup.com/SV-SUG/events/43376082/&quot;&gt;Silicon Valley Spring User Group&lt;/a&gt;. I discussed the support for Java 7, Servlet 3, Hibernate 4 (and JPA 2 with &lt;a href=&quot;http://www.springsource.org/spring-data&quot;&gt;Spring Data&lt;/a&gt;) and the new Cache Abstraction. I mentioned how &lt;a href=&quot;https://github.com/SpringSource/spring-data-jpa-examples&quot;&gt;spring-data-jpa-examples&lt;/a&gt; is a great sample project and showed a bunch of code from my &lt;a href=&quot;https://github.com/mraible/spring-kickstart&quot;&gt;Spring Kickstart&lt;/a&gt; project. I was surprised to find that no one in the audience (all Spring users) was using Java Config. Below are the slides from my presentation and you can also &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Whats_New_in_Spring_3.1.pdf&quot;&gt;download the PDF&lt;/a&gt;.
  &lt;div style=&quot;text-align: center&quot;&gt;&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/11376683?rel=0&quot; width=&quot;510&quot; height=&quot;426&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;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_security</guid>
    <title>Upgrading AppFuse to Spring Security 3.1 and Spring 3.1</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_security</link>
        <pubDate>Thu, 5 Jan 2012 08:58:21 -0700</pubDate>
    <category>Java</category>
    <category>appfuse</category>
    <category>springsecurity</category>
    <category>spring</category>
            <description>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;.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_1_released</guid>
    <title>AppFuse 2.1 Released!</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_1_released</link>
        <pubDate>Mon, 4 Apr 2011 09:38:05 -0600</pubDate>
    <category>Java</category>
    <category>myfaces</category>
    <category>javaee</category>
    <category>ibatis</category>
    <category>appfuse</category>
    <category>springmvc</category>
    <category>tapestry5</category>
    <category>appfuse-light</category>
    <category>jsf2</category>
    <category>hibernate</category>
    <category>jpa</category>
    <category>spring</category>
    <category>struts2</category>
    <category>java</category>
    <category>maven</category>
            <description>&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;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery</guid>
    <title>Implementing Ajax Authentication using jQuery, Spring Security and HTTPS</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/implementing_ajax_authentication_using_jquery</link>
        <pubDate>Wed, 23 Feb 2011 16:55:55 -0700</pubDate>
    <category>Java</category>
    <category>springsecurity</category>
    <category>jquery</category>
    <category>spring</category>
    <category>owasp</category>
    <category>authentication</category>
    <category>overstock.com</category>
    <category>springmvc</category>
    <category>ajax</category>
    <category>appfuse-light</category>
    <category>https</category>
            <description>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.
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/how_i_calculated_ratings_for</guid>
    <title>How I Calculated Ratings for My JVM Web Frameworks Comparison</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/how_i_calculated_ratings_for</link>
        <pubDate>Mon, 6 Dec 2010 11:55:18 -0700</pubDate>
    <category>Java</category>
    <category>devoxx2010</category>
    <category>webframeworks</category>
    <category>jvm</category>
    <category>lift</category>
    <category>comparingwebframeworks</category>
    <category>webframeworksmatrix</category>
    <category>spring</category>
    <category>rails</category>
    <category>vaadin</category>
    <category>jsf</category>
    <category>flex</category>
    <category>gwt</category>
    <category>wicket</category>
    <category>springmvc</category>
    <category>stripes</category>
    <category>java</category>
    <category>rubyonrails</category>
    <category>devoxx</category>
    <category>grails</category>
    <category>struts2</category>
    <category>playframework</category>
            <description>When I re-wrote my &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks&quot;&gt;Comparing JVM Web Frameworks presentation&lt;/a&gt; from scratch, I decided to add a &lt;a href=&quot;http://bit.ly/jvm-frameworks-matrix&quot;&gt;matrix&lt;/a&gt; that allows you to rate a framework based on &lt;a href=&quot;https://docs.google.com/document/pub?id=1jAGPWwlEcYikqOPg8faYgRV7cQNS_iCCoJ1VNc_99M4&quot;&gt;20 different criteria&lt;/a&gt;. The reason I did this was because I&apos;d used this method when &lt;a href=&quot;http://raibledesigns.com/rd/entry/ajax_framework_analysis_results&quot;&gt;choosing an Ajax framework for Evite&lt;/a&gt; last year. The matrix seemed to work well for selecting the top 5 frameworks, but it also inspired a lot of discussion in the community that my &lt;a href=&quot;http://ptrthomas.wordpress.com/2010/12/04/comparing-jvm-web-frameworks-a-response-to-matt-raible/&quot;&gt;ratings&lt;/a&gt; &lt;a href=&quot;http://blog.frankel.ch/critical-analysis-of-frameworks-comparison&quot;&gt;were&lt;/a&gt; &lt;a href=&quot;http://basementcoders.com/2010/12/episode-27-hudson-oracle-raible-and-astycrapper/&quot;&gt;wrong&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;I expected this, as I certainly don&apos;t know every framework as well as I&apos;d like. The mistake I made was asking for the community to provide feedback on my ratings without describing how I arrived at them. From &lt;a href=&quot;http://ptrthomas.wordpress.com/2010/12/04/comparing-jvm-web-frameworks-a-response-to-matt-raible/&quot;&gt;Peter Thomas&apos;s blog&lt;/a&gt;:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
What you are doing is adjusting ratings based on who in the community shouts the loudest. I can&apos;t help saying that this approach comes across as highly arrogant and condescending, you seem to expect framework developers and proponents to rush over and fawn over you to get better ratings, like waiters in a restaurant trying to impress a food-critic for Michelin stars.
&lt;/p&gt;
&lt;p&gt;
I apologize for giving this impression. It certainly wasn&apos;t my intent. By having simple numbers (1.0 == framework does well, 0.5 == framework is OK and 0 == framework not good at criteria) with no rationalization, I can see how the matrix can be interpreted as useless (or to put it bluntly, as &lt;a href=&quot;http://basementcoders.com/2010/12/episode-27-hudson-oracle-raible-and-astycrapper/&quot;&gt;something you should wipe your ass with&lt;/a&gt;). I don&apos;t blame folks for getting angry.&lt;/p&gt;
&lt;p&gt;For my Rich Web Experience presentation, I documented why I gave each framework the rating I did. Hopefully this will allow folks to critique my ratings more constructively and I can make the numbers more accurate. You can view this document below or &lt;a href=&quot;http://bit.ly/jvm-webfwk-ratings-logic&quot;&gt;on Google Docs&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;&lt;iframe src=&quot;//docs.google.com/document/pub?id=1X_XvpJd6TgEAMe4a6xxzJ38yzmthvrA6wD7zGy2Igog&amp;amp;embedded=true&quot; style=&quot;width: 100%; border: 1px solid silver; height: 400px&quot;&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;In the end, what I was hoping to do with this matrix was to simply highlight a &lt;em&gt;technique&lt;/em&gt; for choosing a web framework. Furthermore, I think adding a &quot;weight&quot; to each criteria is important because things like books often aren&apos;t as important as REST support. To show how this might be done, I added a second sheet to the matrix and made up some weighting numbers. I&apos;d expect anyone that wants to use this to &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/JVM_Web_Framework_Matrix_20101206.xls&quot;&gt;downloaded the matrix&lt;/a&gt;, verify the ratings are accurate for your beliefs and weight the criteria accordingly.
&lt;/p&gt;
&lt;p&gt;
Of course, as I and many others have said, the best way to choose a web framework is to try them yourself. I emphasized this at the end of my presentation with the following two slides.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/5238846712/&quot; title=&quot;Slide #77 from Comparing JVM Web Frameworks Talk at RWX2010&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5281/5238846712_375a63e4c6.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Slide #77 from Comparing JVM Web Frameworks Talk at RWX2010&quot; /&gt;&lt;/a&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/5238846740/&quot; title=&quot;Slide #76 from Comparing JVM Web Frameworks Talk at RWX2010&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5129/5238846740_29b06ee0eb.jpg&quot; width=&quot;500&quot; height=&quot;375&quot; alt=&quot;Slide #76 from Comparing JVM Web Frameworks Talk at RWX2010&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks</guid>
    <title>My Comparing JVM Web Frameworks Presentation from Devoxx 2010</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks</link>
        <pubDate>Thu, 18 Nov 2010 05:23:10 -0700</pubDate>
    <category>Java</category>
    <category>spring</category>
    <category>stripes</category>
    <category>rubyonrails</category>
    <category>java</category>
    <category>jvm</category>
    <category>struts2</category>
    <category>devoxx2010</category>
    <category>playframework</category>
    <category>lift</category>
    <category>devoxx</category>
    <category>grails</category>
    <category>webframeworks</category>
    <category>rails</category>
    <category>wicket</category>
    <category>gwt</category>
    <category>springmvc</category>
    <category>vaadin</category>
    <category>jsf</category>
    <category>flex</category>
            <description>This week, I&apos;ve been having a great time in Antwerp, Belgium at the &lt;a href=&quot;http://www.devoxx.com/display/Devoxx2K10/Home&quot;&gt;Devoxx&lt;/a&gt; Conference. This morning, I had the pleasure of delivering my &lt;a href=&quot;http://www.devoxx.com/display/Devoxx2K10/Comparing+JVM+Web+Frameworks&quot;&gt;Comparing JVM Web Frameworks&lt;/a&gt; talk. I thoroughly enjoyed giving this presentation, especially to such a large audience. You can view the presentation below (if you have Flash installed) or &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Comparing_JVM_Web_Frameworks_Devoxx2010.pdf&quot;&gt;download it here&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/key/uBZoC22SGdjpFy&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;/p&gt;
&lt;p&gt;
Unlike previous years, I chose to come up with a &lt;a href=&quot;http://bit.ly/jvm-frameworks-matrix&quot;&gt;spreadsheet matrix&lt;/a&gt; that shows why I chose the 5 I did. This spreadsheet and rankings given to each framework are likely to be debated, as I don&apos;t know all the frameworks as well as I&apos;d like to. Also, the missing column on this spreadsheet is a &quot;weighting&quot; column where you can prioritize certain criteria like I&apos;ve done in the past when &lt;a href=&quot;http://raibledesigns.com/rd/entry/ajax_framework_analysis_results&quot;&gt;Comparing Ajax Frameworks&lt;/a&gt;. If you believe there are incorrect numbers, please let me know and I&apos;ll try to get those fixed before I do this talk again at &lt;a href=&quot;http://www.therichwebexperience.com/conference/fort_lauderdale/2010/11/home&quot;&gt;The Rich Web Experience&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
One thing that doesn&apos;t come across in this presentation is that I believe &lt;em&gt;anyone&lt;/em&gt; can use this matrix, and weightings, to make &lt;em&gt;any&lt;/em&gt; of these frameworks come out on top. I also believe web frameworks are like spaghetti sauce in &lt;a href=&quot;http://www.gladwell.com/2004/2004_09_06_a_ketchup.html&quot;&gt;The Ketchup Conundrum&lt;/a&gt;. That is, the only way to make more happy spaghetti sauce lovers was to make more &lt;em&gt;types&lt;/em&gt; of spaghetti sauce. You can read more about this in my &lt;a href=&quot;http://raibledesigns.com/rd/entry/there_is_no_best_web&quot;&gt;There is no &quot;best&quot; web framework&lt;/a&gt; article.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; If you disagree with the various ratings I gave to web frameworks in this presentation, please provide your opinions by &lt;a href=&quot;http://bit.ly/webmatrixsurvey&quot;&gt;filling out this survey&lt;/a&gt;. Thanks to &lt;a href=&quot;http://twitter.com/sarbogast&quot;&gt;Sebastien Arbogast&lt;/a&gt; for setting this up.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Sebastien has posted his survey results at &lt;a href=&quot;http://sebastien-arbogast.com/2010/11/19/jvm-web-framework-survey-first-results/&quot;&gt;JVM Web Framework Survey, First Results&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 12/6:&lt;/strong&gt; A video of this presentation is &lt;a href=&quot;http://parleys.com/d/2118&quot;&gt;now available on Parleys.com&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;
P.S. My current gig is ending in mid-December. If you&apos;re looking for a UI Architect with a passion for open source frameworks, please &lt;a href=&quot;http://raibledesigns.com/contact.jsp&quot;&gt;let me know&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_2</guid>
    <title>AppFuse 2.1 Milestone 2 Released</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_2</link>
        <pubDate>Mon, 15 Nov 2010 15:28:57 -0700</pubDate>
    <category>Java</category>
    <category>myfaces</category>
    <category>appfuse-light</category>
    <category>webframeworks</category>
    <category>java</category>
    <category>appfuse</category>
    <category>jsf</category>
    <category>springmvc</category>
    <category>freemarker</category>
    <category>wicket</category>
    <category>maven2</category>
    <category>spring</category>
    <category>maven</category>
    <category>stripes</category>
    <category>hibernate</category>
    <category>java5</category>
    <category>ibatis</category>
    <category>archetypes</category>
    <category>jpa</category>
    <category>tapestry</category>
    <category>maven3</category>
    <category>struts2</category>
            <description>I&apos;m pleased to announce the 2nd milestone 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 Spring 3 and Struts 2.1. This release fixes many issues with archetypes and contains many improvements to support Maven 3. For more details on specific changes see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.1.0+M2&quot;&gt;2.1.0 M2 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 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://raibledesigns.com/rd/entry/using_jrebel_with_intellij_idea&quot;&gt;JRebel with AppFuse&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;strong&gt;
Release Details&lt;/strong&gt;&lt;br/&gt;
Archetypes 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. In the final 2.1.0 release, the light archetypes will allow code generation like the basic and modular archetypes. 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 &lt;a href=&quot;http://static.appfuse.org/archetype.html&quot;&gt;archetypes&lt;/a&gt; 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.
&lt;/p&gt;
&lt;p&gt;
Please note that this release does not contain updates to the documentation. Code generation will work, but it&apos;s likely that some content in the &lt;a href=&quot;http://appfuse.org/display/APF/Tutorials&quot;&gt;tutorials&lt;/a&gt; won&apos;t match. For example, you can use annotations (vs. XML) for Spring MVC and Tapestry is a whole new framework. I&apos;ll be working on documentation over the next several weeks in preparation for the 2.1 final release.
&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 bugs, please &lt;a href=&quot;http://issues.appfuse.org/browse/APF&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.
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/re_moving_from_spring_to</guid>
    <title>RE: Moving from Spring to Java EE 6: The Age of Frameworks is Over</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/re_moving_from_spring_to</link>
        <pubDate>Sat, 16 Oct 2010 15:19:07 -0600</pubDate>
    <category>Java</category>
    <category>javaee</category>
    <category>spring</category>
    <category>java</category>
    <category>frameworks</category>
    <category>webframeworks</category>
            <description>Last Tuesday, Cameron McKenzie wrote an interesting article on TheServerSide titled &lt;a href=&quot;http://www.theserverside.com/discussions/thread.tss?thread_id=61023&quot;&gt;Moving from Spring to Java EE 6: The Age of Frameworks is Over&lt;/a&gt;. In this article, Cameron says the following:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
J2EE represents the past, and Java EE 6 represents the future. Java EE 6 promises us the ability to go beyond frameworks. Frameworks like Spring are really just a bridge between the mistakes of the J2EE past and the success of the Java EE 6 future. Frameworks are out, and extensions to the Java EE 6 platform are in. Now is the time to start looking past Spring, and looking forward to Seam and Weld and CDI technologies.
&lt;/p&gt;
&lt;p&gt;He then links to an article titled &lt;a href=&quot;http://ocpsoft.com/java/spring-to-java-ee-a-migration-guide-cdi-jsf-jpa-jta-ejb/&quot;&gt;Spring to Java EE - A Migration Experience&lt;/a&gt;, an article written by JBoss&apos;s Lincoln Baxter. In this article, Lincoln talks about many of the technologies in Java EE 6, namely JPA, EJB, JSF, CDI and JAX-RS. He highlights all the various XML files you&apos;ll need to know about and the wide variety of Java EE 6 application servers: JBoss AS 6 and GlassFish v3.&lt;/p&gt;
&lt;p&gt;I don&apos;t have a problem with Lincoln&apos;s article, in fact I think it&apos;s very informative and some of the best documentation I&apos;ve seen for Java EE 6. 
&lt;/p&gt;
&lt;p&gt;
I do have some issues with Cameron&apos;s statements that frameworks are mistakes of the J2EE past and that Java EE 6 represents the future. Open source frameworks made J2EE successful. Struts and Hibernate came out in the early days of J2EE and still exist today. Spring came out shortly after and has turned into the do-everything J2EE implementation it was trying to fix. Java EE 6 &lt;em&gt;might be&lt;/em&gt; a better foundation to build upon, but it&apos;s certainly not going to replace frameworks.
&lt;/p&gt;
&lt;p&gt;
To prove my point, let&apos;s start by looking at the persistence layer. We used to have Hibernate based on JDBC, now we have JPA implementations built on top of the JPA API. Is JPA a replacement for all persistence frameworks? I&apos;ve worked with it and think it&apos;s a good API, but the 2.0 version &lt;a href=&quot;https://repository.sonatype.org/index.html#nexus-search;quick~javax.persistence&quot;&gt;isn&apos;t available in a Maven repo&lt;/a&gt; and &lt;a href=&quot;http://wiki.alfresco.com/wiki/Alfresco_Community_3.4.a#Hibernate_Removal&quot;&gt;Alfresco recently moved away from Hibernate&lt;/a&gt; (which == JPA IMO) to iBATIS for greater data access layer control and scalability. Looks like the age of frameworks isn&apos;t over for persistence frameworks.&lt;/p&gt;
&lt;p&gt;The other areas that Java EE 6 covers that I believe frameworks will continue to excel in: EJB, CDI, JSF and JAX-RS. Personally, I don&apos;t have a problem with EJB 3 and think it&apos;s a vast improvement on EJB 2.x. I don&apos;t have an issue with CDI either, and as long as it resembles Guice for dependency injection, it works for me. However, when you get into the space I&apos;ve been living in for the last couple years (high-traffic public internet sites), EJB and things like the &quot;conversation-scope&quot; feature of CDI don&apos;t buy you much. The way to make web application scale is to eliminate state and cache as much as possible, both of which Java EE doesn&apos;t provide much help for. In fact, to disable sessions in a servlet-container, you have to write a Filter like the following:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public class DisabledSessionFilter extends OncePerRequestFilter {

    /**
     * Filters requests to disable URL-based session identifiers.
     */
    @Override
    protected void doFilterInternal(final HttpServletRequest request,
                                    final HttpServletResponse response,
                                    final FilterChain chain)
            throws IOException, ServletException {

        HttpServletRequestWrapper wrappedRequest = new HttpServletRequestWrapper(request) {

            @Override
            public HttpSession getSession(final boolean create) {
                if (create) {
                    throw new UnsupportedOperationException(&quot;Session support disabled&quot;);
                }
                return null;
            }

            @Override
            public HttpSession getSession() {
                throw new UnsupportedOperationException(&quot;Session support disabled&quot;);
            }
        };

        // process next request in chain
        chain.doFilter(wrappedRequest, response);
    }
}
&lt;/pre&gt;
&lt;p&gt;What about JAX-RS? Does it replace the need for frameworks? I like the idea of having a REST API in Java. However, its reference implementation is &lt;a href=&quot;https://jersey.dev.java.net/&quot;&gt;Jersey&lt;/a&gt;, which seems more like a framework than just Java EE. If you choose to use JAX-RS in your application, you still have to choose between CXF, Jersey, RESTEasy and Restlet. &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_experience_with_java_rest&quot;&gt;I compared these frameworks last year&lt;/a&gt; and found the Java EE implementation lacking in the features I needed. 
&lt;/p&gt;
&lt;p&gt;Finally, let&apos;s talk about my-least-framework-web-framework: JSF. The main reason I don&apos;t like JSF is because of its 1.x version. JSF 1.0 was released a year before the Ajax term was coined (see timeline below). Not only did it take forever to develop as a spec, but it tried to be a client-component framework that was very stateful by default. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm5.static.flickr.com/4067/4378559350_aef7d39d06_o.png&quot; title=&quot;History of Web Frameworks&quot; rel=&quot;lightbox&quot;&gt;
&lt;img src=&quot;//farm5.static.flickr.com/4067/4378559350_13f0755403.jpg&quot; width=&quot;500&quot; height=&quot;234&quot; alt=&quot;History of Web Frameworks&quot;/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;Now that JSF 2.0 is out, it has Ajax integrated and allows you to use GET instead of POST-for-everything. However, the only people that like Ajax integrated into their web frameworks are programmers scared of JavaScript (who probably shouldn&apos;t be developing your UI). Also, the best component development platform for the web &lt;em&gt;is&lt;/em&gt; JavaScript. I recommend using an Ajax framework for your components if you really want a rich UI. 
&lt;/p&gt;
&lt;p&gt;
Sure you can use the likes of Tapestry and Wicket if you like POJO-based web development, but if you&apos;re looking to develop a webapp that&apos;s easy to maintain and understand, chances are that you&apos;ll do much better with traditional MVC frameworks like Spring MVC and Struts 2. The simplicity and popularity of Rails and Grails further emphasize that developers prefer these types of web frameworks.&lt;/p&gt;
&lt;p&gt;Another reason I don&apos;t like JSF: there&apos;s very few developers in the wild happy with it. The major promoters of JSF are book authors, trainers, Java EE Vendors and MyFaces developers. Whenever I speak at conferences, I ask folks to raise their hands for the various web frameworks they&apos;re using. I always ask the JSF users to keep their hands up if they like it. Rarely do they stay up.
&lt;/p&gt;
&lt;p&gt;
So it looks like we still need web frameworks. 
&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://jandiandme.blogspot.com/2010/10/spring-vs-java-ee-and-why-i-dont-care.html&quot;&gt;Eberhard Wolff has an interesting post&lt;/a&gt; where he defends Spring and talks about the productivity comparisons between Spring and Java EE. He recommends using Grails or Spring Roo if you want the level of productivity that Ruby on Rails provides. That&apos;s a valid recommendation if you&apos;re building CRUD-based webapps, but I haven&apos;t developed those in quite some time. Nowadays, the apps I develop are true SOFEA apps, where the backend serves up XML or JSON and the frontend client is HTML/JavaScript/CSS, Android, iPad or Sony Blu-Ray players. On my current project, our services don&apos;t even talk to a database, they talk to a CMS via RESTful APIs. We use Spring&apos;s RestTemplate for this and HttpClient when it doesn&apos;t have the features we need. Not much in Java EE 6 for this type of communication. Sure, &lt;a href=&quot;http://blogs.sun.com/enterprisetechtips/entry/consuming_restful_web_services_with&quot;&gt;Jersey has a client&lt;/a&gt;, but it&apos;s certainly not part of the Java EE spec.
&lt;/p&gt;
&lt;p&gt;As far as getting Ruby on Rails&apos; zero-turnaround productivity, I don&apos;t need Grails or Spring Roo, I simply use &lt;a href=&quot;http://www.jetbrains.com/idea/&quot;&gt;IDEA&lt;/a&gt; and &lt;a href=&quot;http://www.zeroturnaround.com/jrebel/&quot;&gt;JRebel&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;
I don&apos;t see how new features in Java EE 6 can mean the age of frameworks is over. Java SE and J2EE have always been foundations for frameworks. The Java EE 6 features are often frameworks in themselves that can be used outside of a Java EE container. Furthermore, Java EE 6 doesn&apos;t provide all the features you need to build a high-scale web app today. There&apos;s no caching, no stateless web framework that can serve up JSON and HTML and no hot-reload productivity enhancements like JRebel. Furthermore, there&apos;s real excitement in Javaland for languages like Scala, Groovy and JRuby. All of these languages have web frameworks that&apos;ve made many developers happy. 
&lt;/p&gt;
&lt;p&gt;
Here&apos;s to the Age of Frameworks - may it live as long as the JVM!
&lt;/p&gt;
&lt;p style=&quot;padding-top: 5px; border-top: 1px dotted silver; color: #666&quot;&gt;
P.S. If you&apos;d like to hear me talk about web frameworks on the JVM, I&apos;ll be speaking at &lt;a href=&quot;http://www.meetup.com/csopensource/calendar/15088624/&quot; style=&quot;color: #666&quot;&gt;The Colorado Springs Open Source Meetup&lt;/a&gt; and &lt;a href=&quot;http://www.devoxx.com/display/Devoxx2K10/Comparing+JVM+Web+Frameworks&quot; style=&quot;color: #666&quot;&gt;Devoxx 2010&lt;/a&gt; in the near future.&lt;/p&gt;
&lt;p&gt;
&lt;!--p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; I am an independent consultant and don&apos;t have any affiliations with Java EE vendors. I do have an affection for open source frameworks, particularly Spring and web frameworks. This is because I&apos;ve seen them successfully implemented at high scale web sites such as LinkedIn, Evite and Time Warner Cable.&lt;/p--&gt; </description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/tssjs_2010_presentations_and_summary</guid>
    <title>My TSSJS 2010 Presentations and Summary</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/tssjs_2010_presentations_and_summary</link>
        <pubDate>Fri, 19 Mar 2010 17:29:08 -0600</pubDate>
    <category>Java</category>
    <category>future</category>
    <category>webframeworks</category>
    <category>vegas</category>
    <category>tssjs</category>
    <category>gwt</category>
    <category>spring</category>
    <category>java</category>
    <category>flex</category>
            <description>This afternoon, I delivered my last talk at &lt;a href=&quot;http://javasymposium.techtarget.com/&quot;&gt;TSSJS 2010&lt;/a&gt; on &lt;a href=&quot;http://javasymposium.techtarget.com/html/frameworks.html#MRaibleFrameworks&quot;&gt;The Future of Web Frameworks&lt;/a&gt;. It&apos;s true that I made some &lt;a href=&quot;http://twitter.com/xgerman/status/10741037460&quot; title=&quot;JSF and Wicket are dead! Bold statement but GWT is a better alternative to begin with anyway #tssjs&quot;&gt;bold statements&lt;/a&gt;, but please remember that this is my personal opinion, based on my experience. For the most part, I&apos;ve been involved in super high-traffic websites for the last few years and this has influenced my opinion on web frameworks. Just because I don&apos;t recommend your favorite framework doesn&apos;t mean it won&apos;t work for you. In fact, many of the best web applications today were built without an open source (or commercial) web framework. In the end, it&apos;s not as much about the web framework you&apos;re using as it is about hiring smart people. Below is my slide deck from this talk.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;&lt;object width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=thefutureofwebframeworks-100225012146-phpapp02&amp;stripped_title=the-future-of-web-frameworks&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 src=&quot;//static.slidesharecdn.com/swf/ssplayer2.swf?doc=thefutureofwebframeworks-100225012146-phpapp02&amp;stripped_title=the-future-of-web-frameworks&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;

&lt;p&gt;Yesterday, I did a &lt;a href=&quot;http://javasymposium.techtarget.com/html/theclientside.html#MRaibleSmack&quot;&gt;GWT vs. Flex Smackdown&lt;/a&gt; with &lt;a href=&quot;http://jamesward.com&quot;&gt;James Ward&lt;/a&gt;. While there wasn&apos;t as much trash talking as I&apos;d hoped, I enjoyed delivering it and disputing the greatness of Flex. Below is the presentation that James and I delivered.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;object width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=flexvsgwtsmackdown-100311234937-phpapp01&amp;stripped_title=flex-vs-gwt-smackdown&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 src=&quot;//static.slidesharecdn.com/swf/ssplayer2.swf?doc=flexvsgwtsmackdown-100311234937-phpapp01&amp;stripped_title=flex-vs-gwt-smackdown&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;
&lt;/p&gt;
&lt;p&gt;The show itself was great this year. It had more attendees than I&apos;ve seen in a long time. There were a lot of really interesting sessions and and an often humorous &lt;a href=&quot;http://twitter.com/search?q=%23tssjs&quot;&gt;Twitter back-channel&lt;/a&gt;. I attended quite a few talks and jotted down my notes from several of them. Please see the links below if you&apos;re interested in the sessions I attended. You can view all of the presentations from TSSJS 2010 on &lt;a href=&quot;http://slideshare.net/javasymposium&quot;&gt;SlideShare&lt;/a&gt;.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/what_s_happening_in_the&quot;&gt;What&apos;s Happening in the Java World?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/software_quality_the_quest_for&quot;&gt;Software Quality: The Quest for the Holy Grail?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/the_cloud_computing_continuum_with&quot;&gt;The Cloud Computing Continuum with Bob McWhirter&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/highly_interactive_software_with_java&quot;&gt;Highly Interactive Software with Java and Flex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/c_java_and_net_lessons&quot;&gt;C++, Java and .NET: Lessons Learned from the Internet Age&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/developing_rich_web_service_apis&quot;&gt;Developing Rich Web Service APIs with Java&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/what_s_new_in_spring&quot;&gt;What&apos;s New in Spring 3.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to everyone who came to Vegas and to &lt;a href=&quot;http://theserverside.com&quot;&gt;TheServerSide&lt;/a&gt; for an excellent conference.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/what_s_new_in_spring</guid>
    <title>What&apos;s New in Spring 3.0</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/what_s_new_in_spring</link>
        <pubDate>Fri, 19 Mar 2010 11:46:25 -0600</pubDate>
    <category>Java</category>
    <category>vmware</category>
    <category>javaconfig</category>
    <category>spring</category>
    <category>java</category>
    <category>tomcat</category>
    <category>roo</category>
    <category>springsource</category>
    <category>twitter</category>
            <description>This morning, I attended Rod Johnson&apos;s &lt;a href=&quot;http://javasymposium.techtarget.com/html/sessions.html#RJohnsonKeynote&quot;&gt;What&apos;s New in Spring 3.0&lt;/a&gt; keynote at TSSJS. Rod ditched his slides for the talk and mentioned that this might be risky. Especially since he was pretty jetlagged (flew in from Paris at 11pm last night). Below are my notes from his talk.
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 10px&quot;&gt;
The most important thing for the future of Java is productivity and cloud computing. The focus at SpringSource is heavily on productivity and not just on improving the Spring codebase. If you look at the comparisons out there between Rails and Spring, it&apos;s not an apples-to-apples comparison. The philosophy with Spring has always been the developer is always right. However, if you look at something like Rails, you&apos;ll see it&apos;s far more prescriptive. That layer of opinionated frameworks is important in that it improves your productivity greatly.
&lt;/p&gt;
&lt;p&gt;
SpringSource is putting a lot of emphasis on improving developer productivity with two opinionated frameworks: Grails and Spring Roo. To show how productive developers can be, Rod started to build a web app with Spring Roo. As part of this demo, he mentioned we&apos;d see many of the new features of Spring 3: RestTemplate, @Value and Spring EL. 
&lt;/p&gt;
&lt;p&gt;
Rod used STS to write the application and built a Twitter client. After creating a new project using File -&gt; New Roo Project, a Roo Shell tab shows up at the bottom. Typing &quot;hint&quot; tells you what you should do write away. The initial message is &quot;Roo requires the installation of a JPA provider and associated database.&quot; The initial command is &quot;persistence setup --provider HIBERNATE --database HYPERSONIC_IN_MEMORY&quot;. After running this, a bunch of log messages are shown on the console, most of them indicating that pom.xml has been modified.
&lt;/p&gt;
&lt;p&gt;
The first file that Rod shows is src/main/resources/META-INF/spring/applicationContext.xml. It&apos;s the only XML file you&apos;ll need in your application and includes a PropertyPlaceHolderConfigurer, a context:component-scan for finding annotations and a transaction manager.
&lt;/p&gt;
&lt;p&gt;
After typing &quot;hint&quot; again, Roo indicates that Rod should create entities. He does this by running &quot;ent --class ~.domain.Term --testAutomatically&quot;.  A Term class (with a bunch of annotations) is created, as well as a number of *.aj files and an integration test. Most of the files don&apos;t have anything in them but annotations. The integration test uses @RooIntegrationTest(entity=Term.class) on its class to fire up a Spring container in the test and do dependency injection (if necessary). From there, Rod demonstrated that he could easily modify the test to verify the database existed.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
private SimpleJdbcTemplate jt;

@Autowired
public void init(DataSource ds) {
    this.jt = new SimpleJdbcTemplate(ds);
}

@Test 
public void testDb() {
    jt.queryForInt(&quot;SELECT COUNT(0) FROM TERM&quot;);
}
&lt;/pre&gt;
&lt;p&gt;
Interestingly, after running the test, you could see a whole bunch of tests being run, not just the one that was in the class itself. From there, he modified the Term class to add two new properties: name and searchTerms. He also used JSR 303&apos;s @NotNull annotation to make the fields required.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Entity
@RooJavaBean
@RooToString
@RooEntity
public class Term {

    @NotNull
    private String name;

    @NotNull
    private String searchTerms;
}
&lt;/pre&gt;
&lt;p&gt;
Next, Rod added a new test and showed that the setters for these properties were automatically created and he never had to write getters and setters. This is done by aspects that are generated beside your Java files. Roo is smart enough that if you write toString() methods in your Java code, it will delete the aspect that normally generates the toString() method.
&lt;/p&gt;
&lt;p&gt;
To add fields to an entity from the command lie, you can run commands like &quot;field string --fieldName text --notNull&quot; and &quot;field number --type java.lang.Long --fieldName twitterId --notNull&quot;. The Roo Shell is also capable of establishing relationships between entities. 
&lt;/p&gt;
&lt;p&gt;
After successfully modifying his Entities, Rod started creating code to talk to Twitter&apos;s API. He used RestTemplate to do this and spent a good 5 minutes trying to get Eclipse to import the class properly. The best part of this demo was watching him do what most developers do: searching Google for RestTemplate to get the package name to import.
&lt;/p&gt;
&lt;p&gt;
After awkward silence and some fumbling, he opened an existing project (that had the dependencies properly configured) and used Java Config to configure beans for the project. This was done with a @Configuration annotation on the class, @Value annotations on properties (that read from a properties file) and @Bean annotations for the beans to expose. The first time Rod tried to run the test it failed because a twitter.properties file didn&apos;t exist.  After creating it, he successfully ran the test and successfully searched Twitter&apos;s API. 
&lt;/p&gt;
&lt;p&gt;
The nice thing about @Configuration is the classes are automatically picked up and you don&apos;t need to configure any XML to recognize them. Also, in your Java classes, you don&apos;t have to use @Autowired to get @Bean references injected. 
&lt;/p&gt;
&lt;p&gt;
After this, Rod attempted to show a web interface of the application. He started the built-in SpringSource tc Server and proceeded to show us Tomcat&apos;s 404 page. Unfortunately, Tomcat seemed to startup OK (no errors in the logs), but obviously something didn&apos;t work well. For the next few silent moments, we watched him try to delete web.xml from Eclipse. Unfortunately, this didn&apos;t work and we weren&apos;t able to see the scaffolding the entities that Rod created. 
&lt;/p&gt;
&lt;p&gt;
At this point, Rod opened a completed version of the app and was able to show it to us in a browser. You could hear the murmur of the crowd as everyone realized he was about to show the the &lt;a href=&quot;http://twitter.com/search?q=%23tssjs&quot;&gt;Twitter search results for #tssjs&lt;/a&gt;. Most of the tweets displayed were from folks commenting about how some things didn&apos;t work in the demo. 
&lt;/p&gt;
&lt;p&gt;
In summary, there&apos;s some really cool things in Spring 3: @Configuration, @Value, task scheduling with @Scheduled and one-way methods with @Async. 
&lt;/p&gt;
&lt;p&gt;
Final points of SpringSource and VMWare: they&apos;re committed to Java and middleware. Their big focus is providing an integrated experience from productivity to cloud. There&apos;s other languages that are further along than Java and SpringSource is trying to fix that. One thing they&apos;re working on is a private Java cloud that companies can use and leverage as a VMWare appliance.
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 10px&quot;&gt;
I think there&apos;s a lot of great things in Spring 3 and most users of Roo seem to be happy with it. It&apos;s unfortunate that the Demo Gods frowned upon Rod, but it was cool to see him do the &quot;no presentation&quot; approach. 
&lt;/p&gt;
&lt;p&gt;

</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/highly_interactive_software_with_java</guid>
    <title>Highly Interactive Software with Java and Flex</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/highly_interactive_software_with_java</link>
        <pubDate>Thu, 18 Mar 2010 12:29:26 -0600</pubDate>
    <category>Java</category>
    <category>mxml</category>
    <category>spring</category>
    <category>ria</category>
    <category>jamesward</category>
    <category>adobe</category>
    <category>java</category>
    <category>soap</category>
    <category>flex</category>
    <category>blazeds</category>
    <category>actionscript</category>
    <category>amf</category>
            <description>This morning at TSSJS, I attended &lt;a href=&quot;http://jamesward.com&quot;&gt;James Ward&apos;s&lt;/a&gt; talk about &lt;a href=&quot;http://javasymposium.techtarget.com/html/theclientside.html%23JWardFlex&quot;&gt;Highly Interactive Software with Java and Flex&lt;/a&gt;. Below are my notes from his talk.
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 10px&quot;&gt;
Application have moved from mainframes (hard to deploy, limited clients) to client/server (hard to deploy, full client capabilities) to web applications (easy to deploy, limited clients) to rich internet applications (easy to deploy, full client capabilities). 
&lt;/p&gt;
&lt;p&gt;
Shortly after showing a diagram of how applications have changed, James showed a demo of a sample Flex app for an automobile insurance company. It was very visually appealing, kinda like using an iPhone app. It was a multi-form application that slides right-to-left as you progress through the wizard. It also allowed you to interact with a picture of your car (to indicate where the damage happened) and a map (to indicate how the accident happened). Both of these interactive dialogs still performed data entry, they just did it in more of a visual way.
&lt;/p&gt;
&lt;p&gt;
Adobe&apos;s developer technology for building RIAs is Flex. There&apos;s two different languages in Flex: ActionScript and MXML. ActionScript was originally based on JavaScript, but now (in ActionScript 3) uses features from Java and C#. On top of ActionScript is MXML. It&apos;s a declarative language, but unlike JSP taglibs. All you can do with MXML is instantiate objects and set properties. It&apos;s merely a convenience language, but also allows tooling. The open source SDK compiler takes Flex files and compiles it into a *.swf file. This file can then be executed using the Flash Player (in browser) or Air (desktop).
&lt;/p&gt;
&lt;p&gt;
The reason Adobe developed two different runtimes was because they didn&apos;t want to bloat the Flash Player. Once the applications are running client-side, the application talks to the web server. Protocols that can be used for communication: SOAP, HTTP/S, AMF/S and RTMP/S. The web server can be composed of REST or SOAP Web Services, as well as BlazeDS or LC Data Services to talk directly to Java classes.
&lt;/p&gt;
&lt;p&gt;
To see all the possible Flex components, see &lt;a href=&quot;http://flex.org/tour&quot;&gt;Tour de Flex&lt;/a&gt;. It contains a number of components: core components, data access controls, AIR capabilities, cloud APIs, data visualization. The &lt;a href=&quot;http://www.adobe.com/devnet/flex/tourdeflex/web/%23sampleId=14050;illustIndex=0;docIndex=-1&quot;&gt;IBM ILOG Elixir real-time dashboard&lt;/a&gt; is particularly interesting, as is Doug McCune&apos;s &lt;a href=&quot;http://www.adobe.com/devnet/flex/tourdeflex/web/#sampleId=16300;illustIndex=0;docIndex=0&quot;&gt;Physics Form&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;Next James showed us some code. He used Flex Builder to create a new Flex project with BlazeDS. The backend for this application was a JSP page that talks to a database and displays the results in XML. In the main .mxml file, he used &amp;lt;s:HTTPService&gt; with a URL pointing to the URI of the JSP. Then he added an &amp;lt;mx:DataGrid&gt; and the data binding feature of Flex. To do this, he added dataProvider=&quot;{srv.lastResult.items.item}&quot; to the DataGrid tag, where &quot;srv&quot; is the id of the HTTPService. Then he added a Button with click=&quot;srv.send()&quot; and set the layout to VerticalLayout. This was a simple demo to show how to hook in a backend with XML. 
&lt;/p&gt;
&lt;p&gt;To show that Flex can interact with more than XML over HTTP, James wrote a SOAP service and changed &amp;lt;s:HTTPService&gt; to &amp;lt;s:WebService&gt; and changed the &quot;url&quot; attribute to &quot;wsdl&quot; (and adjusted the value as appropriate). Then rather than using {srv.lastResult.*}, he had to bind to a particular method and change it to {srv.getElements.lastResults}. The Button&apos;s click value also had to change to &quot;srv.getElements(0, 2000)&quot; (since the method takes 2 parameters). 
&lt;/p&gt;
&lt;p&gt;After doing coding in Flex Builder, James switched to his &lt;a href=&quot;http://www.jamesward.com/census&quot;&gt;Census&lt;/a&gt; to compare server-execution times. In the first example (Flash XML AS), most of the time was spent gzipping the 1MB XML file, but the transfer time is reduced because of this. The server execution time is around 800ms. Compare this to the Flex AMF3 example where the server execution time is 49ms. This is because the AMF (binary) protocol streamlines the data and doesn&apos;t include repeated metadata. 
&lt;/p&gt;
&lt;p&gt;
To integrate BlazeDS in your project, you add the dependencies and then map the MessageBrokerServlet in your web.xml. Then you use a services-config.xml to define the protocol and remoting-config.xml to define what Java classes to export as services. To use this in the Flex aplication, James changed &amp;lt;s:WebService&gt; to &amp;lt;s:RemoteObject&gt;. He changed the &quot;wsdl&quot; attribute to &quot;endpoint&quot; and added a &quot;destination&quot; attribute to specify the name of the aliased Java class to talk to. Next, James ran the demo and showed that he could change the number of rows from 2,000 to 20,000 and the load time was still much, much faster than the XML and SOAP versions.
&lt;/p&gt;
&lt;p&gt;
There&apos;s also a &lt;a href=&quot;http://www.springsource.org/spring-flex&quot;&gt;Spring BlazeDS Integration project&lt;/a&gt; that allows you to simply annotate beans to expose them as AMF services. 
&lt;/p&gt;
&lt;p&gt;
BlazeDS also includes a messaging service that you can use to create publishers and subscribers. The default channels in BlazeDS uses HTTP Streaming and HTTP Long Polling (comet), but it can be configurable (e.g. to use JMS). There&apos;s also an Adobe commercial product that keeps a connection open using NIO on the server and has a binary protocol. This is useful for folks that need more real-time data in their applications (e.g. trading floors). 
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 10px&quot;&gt;
I thought this was a really good talk by James. It had some really cool visual demos and the demo was interesting in showing how easy it was to switch between different web services and protocols. This afternoon, I&apos;ll be duking it out with James at the &lt;a href=&quot;http://javasymposium.techtarget.com/html/theclientside.html#MRaibleSmack&quot;&gt;Flex vs. GWT Smackdown&lt;/a&gt;. If you have deficiencies of Flex you&apos;d like me to share during that talk, please let me know.
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_1</guid>
    <title>AppFuse 2.1 Milestone 1 Released</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_1</link>
        <pubDate>Thu, 19 Nov 2009 07:16:36 -0700</pubDate>
    <category>Java</category>
    <category>webframeworks</category>
    <category>tapestry</category>
    <category>archetypes</category>
    <category>appfuse-light</category>
    <category>appfuse</category>
    <category>freemarker</category>
    <category>java</category>
    <category>wicket</category>
    <category>maven2</category>
    <category>spring</category>
    <category>springmvc</category>
    <category>jsf</category>
    <category>stripes</category>
    <category>maven</category>
    <category>struts2</category>
    <category>hibernate</category>
    <category>java5</category>
    <category>myfaces</category>
    <category>ibatis</category>
    <category>jpa</category>
            <description>&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//appfuse.dev.java.net/images/icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the first milestone 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 &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_hibernate_to_3_4&quot;&gt;Hibernate&lt;/a&gt;, &lt;a href=&quot;http://raibledesigns.com/rd/entry/moving_from_spring_s_xml&quot;&gt;Spring&lt;/a&gt; and Tapestry 5. 
&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 tools built on the Java platform to help you develop Web applications quickly and efficiently. It was originally developed to eliminate the ramp-up time found when building new web applications for customers. 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.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Release Details&lt;/strong&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 &lt;em&gt;jetty:run&lt;/em&gt; and your IDE will work much smoother now. The backend is still embedded in JARs, enabling you to choose which 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 &lt;em&gt;appfuse:full-source&lt;/em&gt;. 
&lt;/p&gt;
&lt;p&gt;
In addition, AppFuse Light has been &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven&quot;&gt;converted to Maven&lt;/a&gt; and has archetypes available. AppFuse provides archetypes for JSF, Spring MVC, Struts 2 and Tapestry 5. The &lt;em&gt;light&lt;/em&gt; archetypes are available for these frameworks, as well as for Spring MVC + FreeMarker, Stripes and Wicket.
&lt;/p&gt;
&lt;p&gt;Other notable improvements:&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Added &lt;a href=&quot;http://issues.appfuse.org/browse/APF-267&quot;&gt;Compass support&lt;/a&gt; thanks to a patch from &lt;a href=&quot;http://www.kimchy.org/&quot;&gt;Shay Banon&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Upgraded from &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1125&quot;&gt;XFire to CXF&lt;/a&gt; for Web Services.&lt;/li&gt;
&lt;li&gt;Moved Maven repository to &lt;a href=&quot;https://docs.sonatype.com/display/NX/OSS+Repository+Hosting&quot;&gt;Sonatype&apos;s OSS Repository Hosting&lt;/a&gt; for snapshots and releasing to Maven Central. There are no longer any AppFuse-specific artifacts, all are available in central. Thanks to &lt;a href=&quot;http://sonatype.com&quot;&gt;Sonatype&lt;/a&gt; for this great service and its &lt;a href=&quot;http://raibledesigns.com/rd/entry/nexus_is_a_kick_ass&quot;&gt;excellent repository manager&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Upgraded to Canoo WebTest 3.0. &lt;em&gt;Now if we could just get its &lt;a href=&quot;http://people.apache.org/~sgoeschl/download/maven-plugins/webtest-maven-plugin/site/index.html&quot;&gt;Maven Plugin&lt;/a&gt; moved to Codehaus.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Added &lt;a href=&quot;http://raibledesigns.com/rd/entry/ajaxified_body&quot;&gt;Ajaxified Body&lt;/a&gt; to AppFuse Light archetypes.&lt;/li&gt;
&lt;li&gt;Infrastructure upgrades, including &lt;a href=&quot;http://issues.appfuse.org/&quot;&gt;JIRA 4&lt;/a&gt;, &lt;a href=&quot;http://appfuse.org/&quot;&gt;Confluence 3&lt;/a&gt;, &lt;a href=&quot;http://source.appfuse.org&quot;&gt;FishEye 2&lt;/a&gt;, &lt;a href=&quot;http://builds.appfuse.org&quot;&gt;Bamboo 2&lt;/a&gt; and &lt;a href=&quot;http://login.appfuse.org&quot;&gt;Crowd 1.6&lt;/a&gt;. Many thanks to &lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot;&gt;Atlassian&lt;/a&gt; and &lt;a href=&quot;http://contegix.com&quot;&gt;Contegix&lt;/a&gt; for their excellent products and services.&lt;/li&gt;
&lt;li&gt;For more details on specific changes see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.1.0+M1&quot; title=&quot;Release Notes 2.1.0 M1&quot;&gt;release notes&lt;/a&gt;.
&lt;/ul&gt;
&lt;p&gt;Please note that this release does not contain updates to the documentation. Code generation will work, but it&apos;s likely that some content in the &lt;a href=&quot;http://appfuse.org/display/APF/Tutorials&quot;&gt;tutorials&lt;/a&gt; won&apos;t match. For example, you can use annotations (vs. XML) for dependency injection and Tapestry is a whole new framework. I&apos;ll be working on documentation over the next several weeks in preparation for Milestone 2.
&lt;/p&gt;
&lt;p&gt;AppFuse is available as several Maven archetypes. For information on creating a new project, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; title=&quot;AppFuse QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt;.
&lt;/p&gt;
&lt;p class=&quot;smokey&quot;&gt;
To learn more about AppFuse, please read Ryan Withers&apos; &lt;a href=&quot;http://www.ociweb.com/jnb/jnbMay2008.html&quot;&gt;Igniting your applications with AppFuse&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;The 2.x series of AppFuse has a minimum requirement of the following specification versions:&lt;/p&gt;

&lt;ul class=&quot;glassList&quot;&gt;
	&lt;li&gt;Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)&lt;/li&gt;
	&lt;li&gt;Java 5+&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; title=&quot;FAQ&quot;&gt;FAQ&lt;/a&gt; or join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot; title=&quot;Mailing Lists&quot;&gt;user mailing list&lt;/a&gt;. If you find bugs, please &lt;a href=&quot;http://issues.appfuse.org/secure/CreateIssue!default.jspa&quot;&gt;create an issue in JIRA&lt;/a&gt;.&lt;/p&gt; 

&lt;p&gt;Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues. </description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/a_letter_to_the_appfuse</guid>
    <title>A Letter to the AppFuse Community</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/a_letter_to_the_appfuse</link>
        <pubDate>Wed, 4 Nov 2009 00:17:17 -0700</pubDate>
    <category>Java</category>
    <category>spring</category>
    <category>seam</category>
    <category>rubyonrails</category>
    <category>letter</category>
    <category>springroo</category>
    <category>appfuse</category>
    <category>grails</category>
    <category>play</category>
    <category>community</category>
            <description>The last &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; release was way back in &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_0_2_released&quot;&gt;May 2008&lt;/a&gt;. Many folks have asked when the next release would be ever since. Often, I&apos;ve said &quot;sometimes this quarter&quot;, but obviously, that&apos;s never happened. For that, I apologize.
&lt;/p&gt;
&lt;p&gt;There are many reasons I haven&apos;t worked on AppFuse for the past 18 months, but it mostly comes down to the fact that I didn&apos;t make time for it. The good news is I&apos;m working on it again and &lt;em&gt;will&lt;/em&gt; have a release out sometime this month. Unfortunately, it probably won&apos;t be a 2.1 final release, but there&apos;s so many things that&apos;ve changed, I feel like a milestone release is a good idea. Here&apos;s a brief summary of changes so far:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Changed archetypes to include all source and tests for the &quot;webapp&quot; portion of the application. No more warpath plugin, merging wars and IDE issues. Using &quot;mvn jetty:run&quot; should work as expected.&lt;/li&gt;
&lt;li&gt;Moved from &lt;a href=&quot;http://raibledesigns.com/rd/entry/moving_from_spring_s_xml&quot;&gt;Spring XML to Annotations&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;AppFuse Light &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven&quot;&gt;converted to Maven modules&lt;/a&gt; and now depends on AppFuse&apos;s backend.&lt;/li&gt;
&lt;li&gt;Published easier to use archetype selection form in the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Published &lt;a href=&quot;http://static.appfuse.org/light/archetypes.html&quot;&gt;archetype selection form for AppFuse Light&lt;/a&gt;. I do plan on combining these forms as soon as I figure out the best UI and instructions for users to choose AppFuse or AppFuse Light.&lt;/li&gt;
&lt;li&gt;Upgraded all libraries to latest released versions (Spring 3 hasn&apos;t had a final release yet).&lt;/li&gt;
&lt;li&gt;Upgraded to Tapestry 5 thanks to &lt;a href=&quot;http://code.google.com/p/tapestry5-appfuse/&quot;&gt;Serge Eby&lt;/a&gt;. I still need to complete tests and code generation for tests.&lt;/li&gt;
&lt;li&gt;Added &lt;a href=&quot;http://issues.appfuse.org/browse/APF-267&quot;&gt;Compass support&lt;/a&gt; thanks to a patch from &lt;a href=&quot;http://www.kimchy.org/&quot;&gt;Shay Banon&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Upgraded from &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1125&quot;&gt;XFire to CXF&lt;/a&gt; for Web Services.&lt;/li&gt;
&lt;li&gt;Moved Maven repository to &lt;a href=&quot;https://docs.sonatype.com/display/NX/OSS+Repository+Hosting&quot;&gt;Sonatype&apos;s OSS Repository Hosting&lt;/a&gt; for snapshots and releasing to Maven Central. There are no longer any AppFuse-specific artifacts, all are available in central.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I realize there&apos;s many full-stack frameworks that do the same thing as AppFuse with less code. Examples include &lt;a href=&quot;http://rubyonrails.org&quot;&gt;Ruby on Rails&lt;/a&gt;, &lt;a href=&quot;http://grails.org&quot;&gt;Grails&lt;/a&gt;, &lt;a href=&quot;http://seamframework.org&quot;&gt;Seam&lt;/a&gt;, &lt;a href=&quot;http://www.springsource.org/roo&quot;&gt;Spring Roo&lt;/a&gt; and the &lt;a href=&quot;http://www.playframework.org/&quot;&gt;Play framework&lt;/a&gt;. However, there seems to be quite a few folks that continue to use AppFuse and it stills serves the community as a nice example of how to integrate frameworks. Furthermore, it helps me keep up with the latest framework releases, their quirks and issues that happen when you try to integrate them. In short, working on it helps me stay up to speed with Java open source frameworks.
&lt;/p&gt;
&lt;p&gt;
For those folks that like the 1.x, Ant-based version of AppFuse, there will &lt;em&gt;not&lt;/em&gt; be a 1.9.5 release. I know I promised it for years, but it&apos;s simply something I will not use, so I&apos;d rather not invest my time in it. I&apos;m sorry for lying to those that expected it.&lt;/p&gt;
&lt;p&gt;So what&apos;s the future of AppFuse? Will it continue to integrate web frameworks with Spring and popular persistence frameworks? Possibly, but it seems more logical to align it with the types of Ajax + REST applications I&apos;m creating these days. I&apos;m currently thinking AppFuse 3.0 would be nice as a RESTful backend with GWT and Flex UIs. I might create the backend with &lt;a href=&quot;http://cxf.apache.org/&quot;&gt;CXF&lt;/a&gt;, but it&apos;s possible I&apos;d use one of the frameworks mentioned above and simply leverage it to create the default features AppFuse users have come to expect.&lt;/p&gt;
&lt;p&gt;More than anything, I&apos;m writing this letter to let you know that the AppFuse project is not dead and you can expect a release in the near future.&lt;/p&gt;
&lt;p&gt;Thanks for your support,&lt;/p&gt;
&lt;p&gt;Matt</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/integrating_gwt_with_spring_security</guid>
    <title>Integrating GWT with Spring Security</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/integrating_gwt_with_spring_security</link>
        <pubDate>Thu, 6 Aug 2009 08:50:15 -0600</pubDate>
    <category>Java</category>
    <category>authentication</category>
    <category>security</category>
    <category>spring</category>
    <category>gwt</category>
    <category>springsecurity</category>
            <description>Yesterday, I wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_to_do_cross_domain&quot;&gt;How to do cross-domain GWT RPC with a ProxyServlet&lt;/a&gt;. Today I&apos;ll be discussing
    how to modify the ProxyServlet to authenticate with Spring Security. For the application I&apos;m working on, the ProxyServlet
    is only used in development (when running GWT&apos;s hosted mode) and isn&apos;t necessary when deploying the client and
    server on the same server. Using the ProxyServlet allows cross-domain requests so you can run GWT in hosted mode and
    talk to your backend running on another server. This setup can be especially handy in that you
    can easily point your hosted client at different backends (for example, if you have testing and staging environments).
&lt;/p&gt;
&lt;p&gt;
    In this example, the backend application is a JSF/Spring application that has Spring Security wired in to protect
    services with both Basic and Form-based authentication. Basic authentication will kick in if a &quot;Authorization&quot; header
    is sent, otherwise Form-based authentication is used. Here&apos;s the Spring Security context file that makes this happen:
&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;beans:beans xmlns=&quot;http://www.springframework.org/schema/security&quot;
             xmlns:beans=&quot;http://www.springframework.org/schema/beans&quot;
             xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
             xsi:schemaLocation=&quot;...&quot;&amp;gt;

    &amp;lt;http auto-config=&quot;true&quot; realm=&quot;My Web Application&quot;&amp;gt;
        &amp;lt;intercept-url pattern=&quot;/faces/welcome.jspx&quot; access=&quot;ROLE_USER&quot;/&amp;gt;
        &amp;lt;intercept-url pattern=&quot;/*.rpc&quot; access=&quot;ROLE_USER&quot;/&amp;gt;
        &amp;lt;http-basic/&amp;gt;
        &amp;lt;form-login login-page=&quot;/faces/login.jspx&quot; authentication-failure-url=&quot;/faces/accessDenied.jspx&quot;
                    login-processing-url=&quot;/j_spring_security_check&quot; default-target-url=&quot;/redirect.jsp&quot;
                    always-use-default-target=&quot;true&quot;/&amp;gt;
    &amp;lt;/http&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&quot;/&amp;gt;
        &amp;lt;/user-service&amp;gt;
    &amp;lt;/authentication-provider&amp;gt;
&amp;lt;/beans:beans&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
The easiest way to configure your GWT application to talk to a Spring Security protected resource is to
&lt;a href=&quot;http://www.dotnetguru2.org/bmarchesson/index.php?p=678&amp;amp;more=1&amp;amp;c=1&amp;amp;tb=1&amp;amp;pb=1&quot;&gt;protect your HTML page that GWT is embedded in&lt;/a&gt;. This is the documented way to integrate GWT with Spring Security (ref: 
&lt;a href=&quot;http://code.google.com/p/google-web-toolkit-incubator/wiki/LoginSecurityFAQ&quot;&gt;GWT&apos;s LoginSecurityFAQ&lt;/a&gt;, search for &quot;Acegi&quot;).
This works well for production, but not for hosted-mode development.&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Basic Authentication&lt;/strong&gt;&lt;br/&gt;
To authenticate with Basic Authentication, you can use GWT&apos;s RequestBuilder and set an &quot;Authentication&quot; header that
contains the user&apos;s (base64-encoded) credentials.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
private class LoginRequest {
    public LoginRequest(RequestCallback callback) {
        String url = &quot;/services/faces/welcome.jspx&quot;;

        RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, url);
        rb.setHeader(&quot;Authorization&quot;, createBasicAuthToken());
        rb.setCallback(callback);
        try {
            rb.send();
        } catch (RequestException e) {
            Window.alert(e.getMessage());
        }
    }
}

protected String createBasicAuthToken() {
    byte[] bytes = stringToBytes(username.getValue() + &quot;:&quot; + password.getValue());
    String token = Base64.encode(bytes);
    return &quot;Basic &quot; + token;
}

protected byte[] stringToBytes(String msg) {
    int len = msg.length();
    byte[] bytes = new byte[len];
    for (int i = 0; i &amp;lt; len; i++)
        bytes[i] = (byte) (msg.charAt(i) &amp;amp; 0xff);
    return bytes;
}
&lt;/pre&gt;
&lt;p&gt;
To use this LoginRequest class, create it with a callback and look for a 401 response code to determine if
authentication failed.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
new LoginRequest(new RequestCallback() {
    public void onResponseReceived(Request request, Response response) {
        if (response.getStatusCode() != Response.SC_UNAUTHORIZED &amp;amp;&amp;amp;
                response.getStatusCode() != Response.SC_OK) {
            onError(request, new RequestException(response.getStatusText() + &quot;:\n&quot; + response.getText()));
            return;
        }

        if (response.getStatusCode() == Response.SC_UNAUTHORIZED) {
            Window.alert(&quot;You have entered an incorrect username or password. Please try again.&quot;);
        } else {
            // authentication worked, show a fancy dashboard screen
        }
    }

    public void onError(Request request, Throwable throwable) {
        Window.alert(throwable.getMessage());
    }
});
&lt;/pre&gt;
&lt;p&gt;If your GWT application is included in the &quot;services&quot; war, everything should work at this point. However, if you try to login
with invalid credentials, your browser&apos;s login dialog will appear. To suppress this in the aforementioned
ProxyServlet, you&apos;ll need to make a change in its &lt;em&gt;executeProxyRequest()&lt;/em&gt; method so the &quot;WWW-Authenticate&quot; header
is not copied.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
// Pass the response code back to the client
httpServletResponse.setStatus(intProxyResponseCode);

// Pass response headers back to the client
Header[] headerArrayResponse = httpMethodProxyRequest.getResponseHeaders();
for (Header header : headerArrayResponse) {
    if (header.getName().equals(&quot;Transfer-Encoding&quot;) &amp;amp;&amp;amp; header.getValue().equals(&quot;chunked&quot;) ||
            header.getName().equals(&quot;Content-Encoding&quot;) &amp;amp;&amp;amp; header.getValue().equals(&quot;gzip&quot;) ||
            header.getName().equals(&quot;WWW-Authenticate&quot;)) { // don&apos;t copy WWW-Authenticate header
    } else {
        httpServletResponse.setHeader(header.getName(), header.getValue());
    }
}
&lt;/pre&gt;
&lt;p&gt;I&apos;m not sure how to suppress the browser prompt when not using the ProxyServlet. If you have a solution, please
&lt;a href=&quot;http://raibledesigns.com/rd/entry/integrating_gwt_with_spring_security#comments&quot;&gt;let me know&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Basic Authentication works well for GWT applications because you don&apos;t need additional logic to retain the
authenticated state after the initial login. While Basic Authentication over SSL might offer a decent solution,
the downside is you can&apos;t logout. Form-based Authentication allows you to logout.&lt;/p&gt;
&lt;strong&gt;Form-based Authentication&lt;/strong&gt;&lt;br/&gt;
&lt;p&gt;Before I show you how to implement form-based authentication, you should be aware that Google does not recommend this.
Below is a warning from their LoginSecurityFAQ.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Do &lt;i&gt;NOT&lt;/i&gt; attempt to use the &lt;code&gt;Cookie&lt;/code&gt; header to transfer the sessionID from GWT to the server; it is
fraught with security issues that will become clear in the rest of this article. You &lt;strong&gt;MUST&lt;/strong&gt; transfer
the sessionID in the payload of the request. For an example of why this can fail, see CrossSiteRequestForgery.
&lt;/p&gt;
&lt;p&gt;In my experiment, I didn&apos;t want to change the server-side Spring Security configuration, so I ignored this
warning. If you know how to configure Spring Security so it looks for the sessionID in the payload of the request
(rather than in a cookie), I&apos;d love to hear about it. The upside of the example below is it should work with 
container-managed authentication as well.&lt;/p&gt;
&lt;p&gt;
The LoginRequest class for form-based authentication is similar to the previous one, except it has a different URL and
sends the user&apos;s credentials in the request body.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
private class LoginRequest {
    public LoginRequest(RequestCallback callback) {
        String url = &quot;/services/j_spring_security_check&quot;;

        RequestBuilder rb = new RequestBuilder(RequestBuilder.POST, url);
        rb.setHeader(&quot;Content-Type&quot;, &quot;application/x-www-form-urlencoded&quot;);
        rb.setRequestData(&quot;j_username=&quot; + URL.encode(username.getValue()) +
                    &quot;&amp;amp;j_password=&quot; + URL.encode(password.getValue()));

        rb.setCallback(callback);
        try {
            rb.send();
        } catch (RequestException e) {
            Window.alert(e.getMessage());
        }
    }
}
&lt;/pre&gt;
&lt;p&gt;If you deploy your GWT application in the same WAR your services are hosted in, this is all you&apos;ll need to do. If
you&apos;re using the ProxyServlet, there&apos;s a couple of changes you&apos;ll need to make in order to set/send cookies when
running in hosted mode.
&lt;/p&gt;
&lt;p&gt;
First of all, you&apos;ll need to make sure you&apos;ve configured the servlet to follow redirects (by subclassing or simply modifying its default).
After that, add the following logic on line 358 (or just look for &quot;&lt;code&gt;if (followRedirects)&lt;/code&gt;&quot;) to expose the sessionID to the client. The most important part is setting the cookie&apos;s path to &quot;/&quot; so the client (running at localhost:8888) can see it.&lt;/p&gt;
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
if (followRedirects) {
    // happens on first login attempt
    if (stringLocation.contains(&quot;jsessionid&quot;)) { 
        Cookie cookie = new Cookie(&quot;JSESSIONID&quot;,
                stringLocation.substring(stringLocation.indexOf(&quot;jsessionid=&quot;) + 11));
        cookie.setPath(&quot;/&quot;);
        httpServletResponse.addCookie(cookie);
    // the following happens if you refresh your GWT app after already logging in once
    } else if (httpMethodProxyRequest.getResponseHeader(&quot;Set-Cookie&quot;) != null) {
        Header header = httpMethodProxyRequest.getResponseHeader(&quot;Set-Cookie&quot;);
        String[] cookieDetails = header.getValue().split(&quot;;&quot;);
        String[] nameValue = cookieDetails[0].split(&quot;=&quot;);

        Cookie cookie = new Cookie(nameValue[0], nameValue[1]);
        cookie.setPath(&quot;/&quot;);
        httpServletResponse.addCookie(cookie);
    }
    httpServletResponse.sendRedirect(stringLocation.replace(getProxyHostAndPort() +
            this.getProxyPath(), stringMyHostName));
    return;
}
&lt;/pre&gt;
&lt;p style=&quot;font-style: italic&quot;&gt;Click &lt;a href=&quot;http://www.flickr.com/photos/mraible/3794558459/sizes/l/&quot;&gt;here&lt;/a&gt; to see a screenshot of the diff of the ProxyServlet after this code has been added.&lt;/p&gt;
&lt;p&gt;Figuring out that headers needed to be parsed &lt;strong&gt;after&lt;/strong&gt; authenticating successfully and &lt;strong&gt;before&lt;/strong&gt; redirecting was the hardest part for me. If you grab the JSESSIONID from
the &quot;Set-Cookie&quot; header anywhere else, the JSESSIONID is one that hasn&apos;t been authenticated. While the login will work,
subsequent calls to services will fail.&lt;/p&gt;
&lt;p&gt;To make subsequent calls with the cookie in the header, you&apos;ll need to make an additional modification to ProxyServlet to 
send cookies as headers. First of all, add a &lt;em&gt;setProxyRequestCookies()&lt;/em&gt; method:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
/**
 * Retrieves all of the cookies from the servlet request and sets them on
 * the proxy request
 *
 * @param httpServletRequest The request object representing the client&apos;s
 *                            request to the servlet engine
 * @param httpMethodProxyRequest The request that we are about to send to
 *                                the proxy host
 */
@SuppressWarnings(&quot;unchecked&quot;)
private void setProxyRequestCookies(HttpServletRequest httpServletRequest, 
                                    HttpMethod httpMethodProxyRequest) {
    // Get an array of all of all the cookies sent by the client
    Cookie[] cookies = httpServletRequest.getCookies();
    if (cookies == null) {
        return;
    }
    
    for (Cookie cookie : cookies) {
        cookie.setDomain(stringProxyHost);
        cookie.setPath(httpServletRequest.getServletPath());
        httpMethodProxyRequest.setRequestHeader(&quot;Cookie&quot;, cookie.getName() +  
                &quot;=&quot; + cookie.getValue() + &quot;; Path=&quot; + cookie.getPath());
    }
}
&lt;/pre&gt;
&lt;p&gt;Next, in the &lt;em&gt;doGet()&lt;/em&gt; and &lt;em&gt;doPost()&lt;/em&gt; methods, add the following line just after the call to &lt;em&gt;setProxyRequestHeaders()&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
setProxyRequestCookies(httpServletRequest, getMethodProxyRequest);
&amp;nbsp;
&lt;/pre&gt;
&lt;p&gt;After making these modifications to ProxyServlet, you can create LoginRequest and attempt to authenticate. To detect a failed attempt, I&apos;m looking for text in Spring Security&apos;s &quot;authentication-failure-url&quot; page.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
new LoginRequest(new RequestCallback() {

    public void onResponseReceived(Request request, Response response) {
        if (response.getStatusCode() != Response.SC_OK) {
            onError(request, new RequestException(response.getStatusText() + &quot;:\n&quot; + response.getText()));
            return;
        }
        
        if (response.getText().contains(&quot;Access Denied&quot;)) {
            Window.alert(&quot;You have entered an incorrect username or password. Please try again.&quot;);
        } else {
            // authentication worked, show a fancy dashboard screen
        }
    }

    public void onError(Request request, Throwable throwable) {
        Window.alert(throwable.getMessage());
    }
});
&lt;/pre&gt;
&lt;p&gt;After making these changes, you should be able to authenticate with Spring Security&apos;s form-based configuration. While this example doesn&apos;t show how to logout, it should be easy enough to do by 1) deleting the JSESSIONID cookie or 2) calling the Logout URL you have configured in your services WAR.&lt;/p&gt;
&lt;p&gt;Hopefully this howto gives you enough information to configure your GWT application to talk to Spring Security
without modifying your existing backend application. It&apos;s entirely possible that Spring Security offers a more GWT-friendly
authentication mechanism. If you know of a better way to integrate GWT with Spring Security, I&apos;d love to hear about it.&lt;/p&gt;
&lt;p id=&quot;update&quot;&gt;&lt;strong&gt;Update on October 7, 2009&lt;/strong&gt;: I did some additional work on this and got Remember Me working when using form-based authentication. I found I didn&apos;t need as much fancy logic in my ProxyServlet and was able to reduce the &quot;followRequests&quot; logic to the following:
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
if (followRedirects) {
    if (httpMethodProxyRequest.getResponseHeader(&quot;Set-Cookie&quot;) != null) {
        Header[] headers = httpMethodProxyRequest.getResponseHeaders(&quot;Set-Cookie&quot;);
        if (headers.length == 1) {
            extractCookieFromHeader(httpServletResponse, headers[0]);
        } else {
            // ignore the first header since there always seems two jsessionid headers
            // and the 2nd is the valid one
            for (int i = 1; i &lt; headers.length; i++) {
                extractCookieFromHeader(httpServletResponse, headers[i]);
            }
        }
    }
    httpServletResponse.sendRedirect(
            stringLocation.replace(getProxyHostAndPort() + getProxyPath(), stringMyHostName));
    return;
}
&lt;/pre&gt;
&lt;p&gt;I was also able to remove the &lt;em&gt;setProxyRequestCookies()&lt;/em&gt; method completely as it no longer seems necessary.&lt;/p&gt;
&lt;p&gt;Next, I&apos;d like to figure out how to make Spring Security more Ajax-friendly where it can read an authentication token in the request body or header (instead of from a cookie). Also, it&apos;d be sweet if I could convince it to return error codes instead of the login page (for example, when a certain header is present). </description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/moving_from_spring_s_xml</guid>
    <title>Moving from Spring&apos;s XML to Annotations in AppFuse</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/moving_from_spring_s_xml</link>
        <pubDate>Tue, 4 Nov 2008 11:39:54 -0700</pubDate>
    <category>Java</category>
    <category>appfuse</category>
    <category>junit4</category>
    <category>spring</category>
    <category>abstracttransactionaldatasourcespringcontexttests</category>
    <category>annotations</category>
    <category>xml</category>
            <description>Last night, I did a spike on AppFuse to &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1105&quot;&gt;change XML to Spring annotations (@Repository, @Service and @Autowired)&lt;/a&gt; in its service and data modules. While I was able to accomplish everything in a few hours (including converting tests), I did run into a couple issues.
&lt;/p&gt;
&lt;p style=&quot;text-align: left&quot;&gt;
&lt;strong&gt;AbstractTransactionalJUnit4..Tests vs. AbstractTransactionalDataSource..Tests&lt;/strong&gt;&lt;br/&gt;
I&apos;ve switched from &lt;a href=&quot;http://www.jroller.com/raible/entry/ditch_dbunit_use_abstracttransactionaldatasourcespringcontexttests&quot;&gt;my favorite Spring class&lt;/a&gt; to the annotation-happy &lt;a href=&quot;http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/test/context/junit4/AbstractTransactionalJUnit4SpringContextTests.html&quot;&gt;AbstractTransactionalJUnit4SpringContextTests&lt;/a&gt;. However, this has presented an issue: when using ATDSSCT, I was able to call &lt;code&gt;endTransaction()&lt;/code&gt; and &lt;code&gt;startNewTransaction()&lt;/code&gt;. With ATJ4SCT, this doesn&apos;t seem possible. Below is a screenshot of the diff on a test method in the JPA implementation of UserDaoTest:
&lt;/p&gt;
&lt;a href=&quot;http://farm4.static.flickr.com/3166/3003374654_31fff24bd1_o.png&quot; title=&quot;AbstractTransactionalJUnit4SpringContextTests vs. AbstractTransactionalDataSourceSpringContextTests&quot; rel=&quot;lightbox[appfuse-annotations]&quot;&gt;&lt;img src=&quot;//farm4.static.flickr.com/3166/3003374654_a3f2ca2ebd.jpg&quot; width=&quot;500&quot; height=&quot;188&quot; alt=&quot;AbstractTransactionalJUnit4SpringContextTests vs. AbstractTransactionalDataSourceSpringContextTests&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;text-align: left&quot;&gt;On the right, you&apos;ll notice that I had to comment out &lt;code&gt;@ExpectedException&lt;/code&gt; to get the test to pass. This concerns me since this exception should be thrown. Is there a way to call &lt;code&gt;endTransaction()&lt;/code&gt; and &lt;code&gt;startNewTransaction()&lt;/code&gt; when subclassing AbstractTransactionalJUnit4SpringContextTests?
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Instantiating GenericDao Implementations Programmatically&lt;/strong&gt;&lt;br/&gt;
The second feature I tried to add is the ability to instantiate a GenericDao programatically rather than requiring a XML bean definition. In current versions of AppFuse, you can use the following bean definition to create a GenericDao for a model object.&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&quot;personDao&quot; class=&quot;org.appfuse.dao.hibernate.GenericDaoHibernate&quot;&amp;gt;
    &amp;lt;constructor-arg value=&quot;org.appfuse.tutorial.model.Person&quot;/&amp;gt; 
    &amp;lt;property name=&quot;sessionFactory&quot; ref=&quot;sessionFactory&quot;/&amp;gt;
&amp;lt;/bean&amp;gt; 
&lt;/pre&gt;
&lt;p&gt;When moving to a &lt;em&gt;no-XML required&lt;/em&gt; architecture, it&apos;d be nice to allow users to create GenericDao&apos;s programmatically. Below is the easiest way I&apos;ve found to do this in a test:
&lt;/p&gt;
&lt;pre&gt;
GenericDao&amp;lt;User, Long&gt; genericDao;
@Autowired
SessionFactory sessionFactory;

@Before
public void setUp() {
    genericDao = new GenericDaoHibernate&amp;lt;User, Long&gt;(User.class);
    genericDao.setSessionFactory(sessionFactory);
}
&lt;/pre&gt;
&lt;p&gt;However, there&apos;s a couple problems with this. First of all, mixing constructor injection and setter injection probably isn&apos;t a good idea. Changing the constructor to take a SessionFactory solves this problem, but now all subclasses need to have a more verbose constructor:
&lt;/p&gt;
&lt;pre&gt;
@Autowired
public UserDaoHibernate(SessionFactory sessionFactory) {
    super(User.class, sessionFactory);
}
&lt;/pre&gt;
&lt;p&gt;Whereas before they had:&lt;/p&gt;
&lt;pre&gt;
public UserDaoHibernate() {
    super(User.class);
}
&lt;/pre&gt;
&lt;p style=&quot;text-align: left&quot;&gt;In an ideal world, I could call &lt;code&gt;new GenericDaoHibernate&amp;lt;User, Long&gt;(User.class)&lt;/code&gt; and the SessionFactory would be wired in auto-magically. Is this possible with Spring 2.5?
&lt;p&gt;The 2nd problem this presents is your client code will now be dependent on an implementation rather than the interface. I don&apos;t know how to solve that one, but I&apos;d love to figure out a way to create GenericDaos with no XML and no implementation details in the client. Any ideas are most welcome.&lt;/p&gt;
&lt;p&gt;If you&apos;d like to see all the changes I made in converting from XML to Annotations, please &lt;a href=&quot;http://issues.appfuse.org/secure/attachment/10512/XMLToAnnotations.patch&quot;&gt;see this patch&lt;/a&gt;.
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/colorado_software_summit_2008_wrapup</guid>
    <title>Colorado Software Summit 2008 Wrapup</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/colorado_software_summit_2008_wrapup</link>
        <pubDate>Tue, 28 Oct 2008 23:03:23 -0600</pubDate>
    <category>Java</category>
    <category>ajax</category>
    <category>maven</category>
    <category>softwaresummit</category>
    <category>spring</category>
    <category>rest</category>
    <category>java</category>
    <category>appcelerator</category>
    <category>camel</category>
            <description>&lt;a title=&quot;Snowman in Keystone&quot; href=&quot;http://blog.linkedin.com/blog/2008/10/colorado-softwa.html&quot;&gt;&lt;img alt=&quot;Snowman in Keystone&quot; src=&quot;//farm4.static.flickr.com/3057/2980923121_f44dd0dc42_t.jpg&quot; class=&quot;picture&quot; height=&quot;75&quot; width=&quot;100&quot;&gt;&lt;/a&gt;

Last week, I attended the Colorado Software Summit in Keystone and had a great time. Not only was the weather beautiful and the food delicious, the sessions I attended were awesome. If you ever get a chance to go to this conference, I highly recommend it. It&apos;s like being on vacation and learning with a bunch of old friends.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;http://www.linkedin.com/in/yan&quot;&gt;Yan Pujante&lt;/a&gt; also attended this conference and documents his experience, photography and presentations in &lt;a href=&quot;http://blog.linkedin.com/blog/2008/10/colorado-softwa.html&quot;&gt;Colorado Software Summit 2008&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;Below is a list of my entries for all the sessions I attended.&lt;/p&gt;
&lt;ul class=&quot;glassList&quot;&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/building_linkedin_s_next_generation&quot;&gt;Building LinkedIn&apos;s Next Generation Architecture with OSGi by Yan Pujante&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/comprehensive_project_intelligence_with_jason&quot;&gt;Comprehensive Project Intelligence with Jason van Zyl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/what_s_coming_in_spring&quot;&gt;What&apos;s Coming in Spring 3.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/applying_flash_to_java_flex&quot;&gt;Applying Flash to Java: Flex and OpenLaszlo with Dustin Marx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/building_rich_applications_with_appcelerator&quot;&gt;Building Rich Applications with Appcelerator&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/taking_apache_camel_for_a&quot;&gt;Taking Apache Camel for a Ride with Bruce Snyder&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/core_animation_with_bill_dudney&quot;&gt;Core Animation with Bill Dudney&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/restful_web_applications_with_subbu&quot;&gt;RESTful Web Applications with Subbu Allamaraju&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;p&gt;For next year, I think the conference should shorten its sessions (from 90 to 60 minutes), invite more speakers and cut the price in half (to $999 per person). How do you think the Software Summit could be improved?</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/taking_apache_camel_for_a</guid>
    <title>Taking Apache Camel for a Ride with Bruce Snyder</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/taking_apache_camel_for_a</link>
        <pubDate>Thu, 23 Oct 2008 14:25:30 -0600</pubDate>
    <category>Java</category>
    <category>eip</category>
    <category>camel</category>
    <category>apache</category>
    <category>java</category>
    <category>servicemix</category>
    <category>spring</category>
    <category>softwaresummit</category>
    <category>opensource</category>
    <category>brucesnyder</category>
            <description>&lt;a href=&quot;http://activemq.apache.org/camel/&quot;&gt;Camel&lt;/a&gt; is a Java API that allows you to do message routing very easily. It implements many of the patterns found in &lt;a href=&quot;http://activemq.apache.org/camel/enterprise-integration-patterns.html&quot;&gt;Enterprise Integration Patterns&lt;/a&gt;. It doesn&apos;t require a container and can be run in any Java-based environment. Camel has a whole bunch of components - Bruce is showing a 6 x 10 grid with a component name in each grid. In other words, there&apos;s 60 components that Camel can use. Examples include: ActiveMQ, SQL, Velocity, File and iBATIS. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;http://www.chrisrichardson.net/&quot;&gt;Chris Richardson&lt;/a&gt; asks &quot;What&apos;s left inside of ServiceMix&quot;. Why use ServiceMix if you have Camel? ServiceMix is a container that can run standalone or inside an app server. You can run distributed ServiceMix as a federated ESB. Camel is much smaller and lightweight and is really just a Java API. ServiceMix 4 changed from a JBI-based architecture to OSGi (based on Apache Felix). They also expect to create your routes for ServiceMix 4 with Camel instead of XML. To process messages, you can use many different languages: BeanShell, JavaScript, Groovy, Python, PHP, Ruby, JSP EL, OGNL, SQL, XPath and XQuery. 
&lt;/p&gt;
&lt;p&gt;
Camel has a &lt;code&gt;CamelContext&lt;/code&gt; that&apos;s similar to Spring&apos;s &lt;code&gt;ApplicationContext&lt;/code&gt;. You can initialize it in Java and add your routes to it:&lt;/p&gt;
&lt;pre&gt;
CamelContext context = new DefaultCamelContext();
context.addRoutes(new MyRouterBuilder());
context.start();
&lt;/pre&gt;
&lt;p&gt;Or you can initialize it using XML:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;camelContext xmlns=&quot;http://activemq.apache.org/camel/schema/spring&quot;&amp;gt;
    &amp;lt;package&amp;gt;com.acme.routes&amp;lt;/package&amp;gt;
&amp;lt;/camelContext&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Camel&apos;s &lt;code&gt;&lt;a href=&quot;http://activemq.apache.org/camel/routebuilder.html&quot;&gt;RouteBuilder&lt;/a&gt;&lt;/code&gt; contains a &lt;a href=&quot;http://activemq.apache.org/camel/dsl.html&quot;&gt;fluid API&lt;/a&gt; that allows you to define to/from and other criteria. At this point, Bruce is showing a number of examples using the Java API. He&apos;s showing a Content Based Router, a Message Filter, a Splitter, an Aggregator, a Message Translator, a Resequencer, a Throttler and a Delayer.&lt;/p&gt;
&lt;p&gt;Bruce spent the last 10 minutes doing a demo using Eclipse, m2eclipse, the camel-maven-plugin and ActiveMQ. It&apos;s funny to see a command-line guy like Bruce say he can&apos;t live w/o m2eclipse. I guess Maven&apos;s XML isn&apos;t so great after all. &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;Camel is built on top of Spring and has good integration. Apparently, the Camel developers tried to get it added to Spring, but the SpringSource guys didn&apos;t want it. Coincidentally, &lt;a href=&quot;http://www.springframework.org/spring-integration&quot;&gt;Spring Integration&lt;/a&gt; was &lt;a href=&quot;http://blog.springsource.com/2007/12/14/spring-integration-a-new-addition-to-the-spring-portfolio/&quot;&gt;released&lt;/a&gt; about a year later.&lt;/p&gt;
&lt;p&gt;Camel also allows you to use &quot;beans&quot; and bind them to Camel Endpoints with annotations. For example:

&lt;pre&gt;
public class Foo {

    @MessageDriven (uri=&quot;activemq:cheese&quot;)
    public void onCheese(String name) {
        ...
    }
}
&lt;/pre&gt;
&lt;p&gt;Other annotations include @XPath, @Header and @EndpointInject. 
&lt;/p&gt;
&lt;p&gt;Camel can also be used for BAM (Business Activity Monitoring). Rather than using RouteBuilder, you can use ActivityBuilder to listen for activities and create event notifications.&lt;/p&gt;
&lt;p&gt;Bruce had quite a few folks show up for this presentation. I had trouble finding a seat because I was late. I think he did a good job of showing what Camel is and how you might use it.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/what_s_coming_in_spring</guid>
    <title>What&apos;s Coming in Spring 3.0</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/what_s_coming_in_spring</link>
        <pubDate>Wed, 22 Oct 2008 11:51:12 -0600</pubDate>
    <category>Java</category>
    <category>spring</category>
    <category>springframework</category>
    <category>rest</category>
    <category>presentation</category>
    <category>annotations</category>
    <category>webframeworks</category>
    <category>softwaresummit</category>
    <category>springexpressionlanguage</category>
            <description>This morning, I delivered my &lt;a href=&quot;http://softwaresummit.com/2008/speakers/raible.htm&quot;&gt;What&apos;s Coming in Spring 3.0&lt;/a&gt; talk for the 2nd time at Colorado Software Summit. Since there is no Spring 3.0 source code to speak of, I was unable to do the &quot;Choose Your Own Adventure&quot; demo at the end. &lt;img src=&quot;https://raibledesigns.com/images/smileys/sad.gif&quot; class=&quot;smiley&quot; alt=&quot;:(&quot; title=&quot;:(&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
The good news is I was able to easily upgrade the &lt;a href=&quot;http://spring-kickstart.googlecode.com&quot;&gt;Spring Kickstart&lt;/a&gt; application from Spring 2.0 to Spring 2.5.5 (using annotations). When 3.0 is released, I hope to update this project to use 3.0 as well as show what I needed to change. If I get ambitious, I might even change the UI to use Flex or Ext JS to show a RESTful client. Below is my presentation - hope you enjoy.
&lt;/p&gt;
&lt;div style=&quot;text-align:center&quot;&gt;&lt;object style=&quot;margin:0px&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://static.slideshare.net/swf/ssplayer2.swf?doc=whats-coming-in-spring-30-18636&amp;stripped_title=whats-coming-in-spring-30&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 src=&quot;//static.slideshare.net/swf/ssplayer2.swf?doc=whats-coming-in-spring-30-18636&amp;stripped_title=whats-coming-in-spring-30&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;355&quot;&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div style=&quot;font-size:11px;font-family:tahoma,arial;height:26px;padding-top:2px;&quot;&gt;&lt;a style=&quot;text-decoration:underline;&quot; href=&quot;http://www.slideshare.net/mraible/whats-coming-in-spring-30?type=powerpoint&quot; title=&quot;View What&amp;#39;s Coming in Spring 3.0 on SlideShare&quot;&gt;View on Slideshare&lt;/a&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/building_linkedin_s_next_generation</guid>
    <title>Building LinkedIn&apos;s Next Generation Architecture with OSGi by Yan Pujante</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/building_linkedin_s_next_generation</link>
        <pubDate>Mon, 20 Oct 2008 11:20:09 -0600</pubDate>
    <category>Java</category>
    <category>rpc</category>
    <category>eclipse</category>
    <category>glassfish</category>
    <category>yanpujante</category>
    <category>linkedin</category>
    <category>infiniflow</category>
    <category>tomcat</category>
    <category>apache</category>
    <category>osgi</category>
    <category>spring</category>
    <category>architecture</category>
    <category>softwaresummit</category>
            <description>This week, I&apos;m attending the &lt;a href=&quot;http://softwaresummit.com&quot;&gt;Colorado Software Summit&lt;/a&gt; in Keystone, Colorado. Below are my notes from an &lt;strong&gt;OSGi at LinkedIn&lt;/strong&gt; presentation I attended by &lt;a href=&quot;http://www.linkedin.com/in/yan&quot;&gt;Yan Pujante&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
LinkedIn was created in March of 2003. Today there&apos;s close to 30M members. In the first 6 months, there was 60,000 members that signed up. Now, 1 million sign up every 2-3 weeks. LinkedIn is profitable with 5 revenue lines and there&apos;s 400 employees in Mountain View.
&lt;/p&gt;
&lt;p&gt;
Technologies: 2 datacenters (~600 machines). SOA with Java, Tomcat, Spring Framework, Oracle, MySQL, Servlets, JSP, Cloud/Graph, OSGi. Development is done on Mac OS X, production is on Solaris.
&lt;/p&gt;
&lt;p&gt;
The biggest challenges for LinkedIn are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Growing Engineering Team on a monolithic code base (it&apos;s modular, but only one source tree)&lt;/li&gt;
&lt;li&gt;Growing Product Team wanting more and more features faster&lt;/li&gt;
&lt;li&gt;Growing Operations Team deploying more and more servers&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Front-end has many BL services in one webapp (in Tomcat). The backend is many wars in 5 containers (in Jetty) with 1 service per WAR. Production and Development environments are very different. Total services in backend is close to 100, front-end has 30-40.
&lt;p&gt;
&lt;strong&gt;Container Challenges&lt;/strong&gt;&lt;br/&gt;
1 WAR with N services does not scale for developers (conflicts, monolithic). N wars with 1 service does not scale for containers (no shared JARs). You can add containers, but there&apos;s only 12GB of RAM available.
&lt;/p&gt;
&lt;p&gt;
Upgrading back-end service to new version requires downtime (hardware load-balancer does not account for version). Upgrading front-end service to new version requires redeploy. Adding new backend services is also painful because there&apos;s lots of configuration (load-balancer, IPs, etc.).
&lt;/p&gt;
&lt;p&gt;
Is there a solution to all these issues? Yan believes that OSGi is a good solution.  OSGi stands for &lt;strong&gt;Open Services Gateway initiative&lt;/strong&gt;. Today that term doesn&apos;t really mean anything. Today it&apos;s a spec with several implementations: Equinox (Eclipse), Knoplerfish and Felix (Apache). 
&lt;/p&gt;
&lt;p&gt;
OSGi has some really, really good features. These include smart class loading (multiple versions of JARs is OK), it&apos;s highly dynamic (deploy/undeploy built-in), it has a service registry and is highly extensible/configurable. An OSGi bundle is simply a JAR file with an OSGi manifest.
&lt;/p&gt;
&lt;p&gt;
In LinkedIn&apos;s current architecture, services are exported with Spring/RPC and services in same WAR can see each other. The problem with this architecture comes to light when you want to move services to a 2nd web container. You cannot share JARs and can&apos;t talk directly to the other web app. With OSGi, the bundles (JARs) are shared, services are shared and bundles can be dynamically replaced. OSGi solves the container challenge.
&lt;/p&gt;
&lt;p&gt;
One thing missing from OSGi is allowing services to live on multiple containers. To solve this, LinkedIn has developed a way to have &lt;strong&gt;Distributed OSGi&lt;/strong&gt;. Multicast is used to see what&apos;s going on in other containers. Remote servers use the OSGi lifecycle and create dynamic proxies to export services using Spring RPC over HTTP. Then this service is registered in the service registry on the local server. 
&lt;/p&gt;
&lt;p&gt;
With Distributed OSGi, there&apos;s no more N-1 / 1-N problem. Libraries and services can be shared in one container (memory footprint is much smaller). Services can be shared across containers. The location of the services is transparent to the clients. There&apos;s no more configuration to change when adding/removing/moving services. This architecture allows the software to be the load balancer instead of using a hardware load balancer.
&lt;/p&gt;
&lt;p&gt;
Unfortunately, everything is not perfect. OSGi has quite a few problems. OSGi is great, but the tooling is not quite there yet. Not every library is a bundle and many JARs doesn&apos;t have OSGi manifests. OSGi was designed for embedded devices and using it for the server-side is very recent (but very active).
&lt;/p&gt;
&lt;p&gt;
OSGi is pretty low-level, but there is some work being done to hide the complexity. Spring DM helps, as do vendor containers. SpringSource has Spring dm Server, Sun has GlassFish, and Paremus has Infiniflow. OSGi is container centric, but next version will add distributed OSGi, but will have no support for load-balancing.
&lt;/p&gt;
&lt;p&gt;
Another big OSGi issue is version management. If you specify &lt;code&gt;version=1.0.0&lt;/code&gt;, it means &lt;code&gt;[1.0.0, &amp;#8734;]&lt;/code&gt;. You should at least use &lt;code&gt;version=[1.0.0,2.0.0]&lt;/code&gt;. When using OSGi, you have to be careful and follow something similar to &lt;a href=&quot;http://apr.apache.org/versioning.html&quot;&gt;Apache&apos;s APR Project Versioning Guidelines&lt;/a&gt; so that you can easily identify release compatibility.
&lt;/p&gt;
&lt;p&gt;At LinkedIn, the OSGi implementation is progressing, but there&apos;s still a lot of work to do. First of all, a bundle repository needs to be created. Ivy and bnd is used to generate bundles. Containers are being evaluated and Infiniflow is most likely the one that will be used. LinkedIn Spring (an enhanced version of Spring) and SCA will be used to deploy composites. Work on load-balancing and distribution is in progress as is work on tooling and build integration (Sigil from Paremus). 
&lt;/p&gt;
&lt;p&gt;In conclusion, LinkedIn will definitely use OSGi but they&apos;ll do their best to hide the complexity from the build system and from developers. For more information on OSGi at LinkedIn, stay tuned to the &lt;a href=&quot;http://blog.linkedin.com/blog/engineering/&quot;&gt;LinkedIn Engineering Blog&lt;/a&gt;. Yan has promised to blog about some of the challenges LinkedIn has faced and how he&apos;s fixed them.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Yan has posted his presentation on the &lt;a href=&quot;http://blog.linkedin.com/blog/2008/10/colorado-softwa.html&quot;&gt;LinkedIn Engineering Blog&lt;/a&gt;.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/the_colorado_software_summit_and</guid>
    <title>The Colorado Software Summit and Spring 3.0&apos;s SVN</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/the_colorado_software_summit_and</link>
        <pubDate>Thu, 9 Oct 2008 08:23:21 -0600</pubDate>
    <category>Java</category>
    <category>softwaresummit</category>
    <category>appcelerator</category>
    <category>coloradosoftwaresummit</category>
    <category>keystone</category>
    <category>spring</category>
    <category>colorado</category>
            <description>&lt;a href=&quot;http://www.softwaresummit.com&quot;&gt;&lt;img src=&quot;//static.raibledesigns.com/repository/images/css-logo.gif&quot; width=&quot;300&quot; height=&quot;135&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;/&gt;&lt;/a&gt;

In a little over two weeks, my &lt;a href=&quot;http://www.softwaresummit.com&quot;&gt;favorite conference&lt;/a&gt; begins in Keystone, Colorado. The reason I like it so much is because it&apos;s an annual gathering (this will be my 4th year) with friends and it&apos;s somewhat like a vacation, except you get to learn a lot. This year I&apos;ll be speaking about &lt;a href=&quot;http://www.softwaresummit.com/2008/speakers/raible.htm&quot;&gt;Appcelerator and Spring 3.0&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;A few weeks ago, I wondered &lt;a href=&quot;http://raibledesigns.com/rd/entry/re_how_open_source_is&quot;&gt;How open source is Spring&lt;/a&gt; and expressed my frustration in not being able to find the source code. At almost the same time, SpringSource&apos;s &lt;a href=&quot;http://www.theserverside.com/news/thread.tss?thread_id=50727&quot;&gt;controversial maintenance policy was announced&lt;/a&gt;. Developers booed, &lt;a href=&quot;http://freespring.org/&quot;&gt;Free Spring&lt;/a&gt; was founded and &lt;a href=&quot;http://blog.springsource.com/2008/10/07/a-question-of-balance-tuning-the-maintenance-policy/&quot;&gt;SpringSource changed their tune&lt;/a&gt;. In addition, someone sent me the &lt;a href=&quot;https://fisheye.springframework.org/browse/spring-framework&quot;&gt;FishEye URL&lt;/a&gt; for Spring 3.0&apos;s SVN. From that, I was able to figure out how to get Spring 3.0&apos;s source code.&lt;/p&gt;
&lt;pre&gt;
svn co https://src.springframework.org/svn/spring-framework/trunk spring-3.0
&lt;/pre&gt;
&lt;p&gt;The only bad news is FishEye shows the last change as &quot;17 September 2008 ... (21 days ago)&quot;. If Spring 3.0 M1 is supposed to be released &lt;em&gt;any day now&lt;/em&gt;, you&apos;d think there would be more SVN commits. Anyone from SpringSource care to comment?</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/re_how_open_source_is</guid>
    <title>RE: How Open Source is Spring?</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/re_how_open_source_is</link>
        <pubDate>Fri, 19 Sep 2008 09:54:48 -0600</pubDate>
    <category>Java</category>
    <category>opensource</category>
    <category>springsource</category>
    <category>spring</category>
            <description>Peter Mularien has a very well written post titled &lt;a href=&quot;http://www.mularien.com/blog/2008/09/19/how-open-source-is-spring-an-analytical-investigation/&quot;&gt;How Open Source is Spring?: An Analytical Investigation&lt;/a&gt;:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
This post is to expand on some of the &lt;a href=&quot;http://blog.springsource.com/main/2008/05/27/open-source-open-strategy-the-springsource-manifesto/#comment-107907&quot;&gt;thoughts I posted&lt;/a&gt; on the SpringSource Blog in response to &lt;a href=&quot;http://blog.springsource.com/main/2008/05/27/open-source-open-strategy-the-springsource-manifesto&quot;&gt;Rod Johnson&apos;s excellent description of the SpringSource business model&lt;/a&gt; and its commitment to development of open source software.

&lt;br/&gt;&lt;br/&gt;
Now that SpringSource has shown an ability to crank out new product releases on a seemingly weekly basis, I wanted to reflect on where Spring is positioned in the Java open source community, and how open the Spring Core project is to work done by the public.

&lt;br/&gt;&lt;br/&gt;
The hypothesis of my experiment occurred to me when I happened to be reviewing &lt;a href=&quot;http://jira.springframework.org/secure/Dashboard.jspa&quot;&gt;Spring JIRA&lt;/a&gt; assignments one day. I was curious whether, following the bug assignments, the majority of development on the &quot;&lt;a href=&quot;http://jira.springframework.org/browse/SPR&quot;&gt;Spring Core&lt;/a&gt;&quot; projects (including Spring MVC and what we would consider &quot;classic Spring&quot;) is performed solely by SpringSource employees. &lt;/p&gt;
&lt;p&gt;Peter&apos;s post is near and dear to me because I&apos;m doing a &lt;strong&gt;What&apos;s coming in Spring 3.0&lt;/strong&gt; talk at the &lt;a href=&quot;http://www.softwaresummit.com/2008/speakers/raible.htm&quot;&gt;Colorado Software Summit&lt;/a&gt; in October. The only information I was able to find on Spring 3.0 is from random blog posts and &lt;a href=&quot;http://twitter.com/devylon/statuses/910473775&quot;&gt;Juergen&apos;s presentation&lt;/a&gt;. When I give talks about technologies, I prefer to dig in and try them before talking about it. With Spring 3.0&apos;s source code nowhere to be found, this is very difficult to do.&lt;/p&gt;
&lt;p&gt;I really hope Spring 3.0 becomes available in early October. If it does, I hope to upgrade &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;, &lt;a href=&quot;http://appfuse-light.dev.java.net&quot;&gt;AppFuse Light&lt;/a&gt; and &lt;a href=&quot;http://spring-kickstart.googlecode.com&quot;&gt;Spring Kickstart&lt;/a&gt;. If it doesn&apos;t, my talk will most likely be a regurgitation of what Juergen&apos;s slides have and that&apos;s just not right.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/spring_mvc_vs_jsf_and</guid>
    <title>Spring MVC vs. JSF and The State of Spring Web</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/spring_mvc_vs_jsf_and</link>
        <pubDate>Fri, 16 May 2008 18:17:52 -0600</pubDate>
    <category>Java</category>
    <category>springmvc</category>
    <category>spring</category>
    <category>webframeworks</category>
            <description>&lt;a href=&quot;http://altadult.blogspot.com&quot;&gt;Alternative Adult&lt;/a&gt; has only posted a couple times in 2008, but his entries have peaked my interest.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
&lt;a href=&quot;http://altadult.blogspot.com/2008/05/spring-mvc-or-jsf.html&quot;&gt;Spring MVC or JSF+?&lt;/a&gt;&lt;br/&gt;My business unit is trying to standardize if we can on a single Java-based Web framework going forward to simplify the Web development process, especially as individual developers move from one division to another, or centralized support groups need to maintain multiple applications from multiple divisions.
&lt;br/&gt;&lt;br/&gt;
At the enterprise level within my company, the architecture group says that they will provide support for either Spring MVC or JSF+ (where the + represents the accompanying technologies you would use to provide a more maintainable application and a more rich user experience, e.g. Facelets, Richfaces, etc.).
&lt;br/&gt;&lt;br/&gt;
Now my business unit is trying to decide which of these two frameworks, Spring MVC or JSF+, is the most appropriate to standardize upon for our development community. [&lt;a href=&quot;http://altadult.blogspot.com/2008/05/spring-mvc-or-jsf.html&quot;&gt;Read More&lt;/a&gt;]&lt;br/&gt;
&lt;br/&gt;...and...&lt;br/&gt;&lt;br/&gt;
&lt;a href=&quot;http://altadult.blogspot.com/2008/05/state-of-spring-web.html&quot;&gt;State of Spring Web&lt;/a&gt;&lt;br/&gt;
For those that are interested, the following is a summary of the notes I captured from a conversation with SpringSource on the state of Spring Web. [&lt;a href=&quot;http://altadult.blogspot.com/2008/05/state-of-spring-web.html&quot;&gt;Read More&lt;/a&gt;]
&lt;/p&gt;
&lt;p&gt;Good stuff Michael - keep it coming.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_0_2_released</guid>
    <title>AppFuse 2.0.2 Released</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_0_2_released</link>
        <pubDate>Sun, 11 May 2008 23:25:40 -0600</pubDate>
    <category>Java</category>
    <category>myfaces</category>
    <category>jpa</category>
    <category>java</category>
    <category>tapestry</category>
    <category>jsf</category>
    <category>springmvc</category>
    <category>struts2</category>
    <category>java5</category>
    <category>ibatis</category>
    <category>maven2</category>
    <category>spring</category>
    <category>hibernate</category>
    <category>appfuse</category>
            <description>&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//appfuse.dev.java.net/images/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.0.2. This release includes upgrades to Spring Security 2.0, jMock 2.4, the ability to customize code generation templates and many bug fixes.&lt;/p&gt;

&lt;p&gt;For information on upgrading from 2.0.1, see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0.2&quot; title=&quot;Release Notes 2.0.2&quot;&gt;Release Notes&lt;/a&gt; or &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0.2#ReleaseNotes2.0.2-changelog&quot;&gt;changelog&lt;/a&gt;. AppFuse 2.0.2 is available as a Maven archetype. For information on creating a new project using AppFuse, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; title=&quot;AppFuse QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; or the &lt;a href=&quot;http://appfuse.org/display/APF/Demos+and+Videos&quot; title=&quot;Demos and Videos&quot;&gt;demos and videos&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;smokey&quot;&gt;
To learn more about AppFuse, please read Ryan Withers&apos; &lt;a href=&quot;http://www.ociweb.com/jnb/jnbMay2008.html&quot;&gt;Igniting your applications with AppFuse&lt;/a&gt;.
&lt;/p&gt;

&lt;p&gt;The 2.0 series of AppFuse has a minimum requirement of the following specification versions:&lt;/p&gt;

&lt;ul class=&quot;glassList&quot;&gt;
	&lt;li&gt;Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)&lt;/li&gt;
	&lt;li&gt;Java 5+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&apos;ve used AppFuse 1.x, but not 2.x, you&apos;ll want to read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot; title=&quot;FAQ&quot;&gt;FAQ&lt;/a&gt;.  Join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot; title=&quot;Mailing Lists&quot;&gt;user mailing list&lt;/a&gt; if you have any questions. 

&lt;p&gt;Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues. &lt;/p&gt;

&lt;p class=&quot;smokey&quot;&gt;
Please post any issues you have with this release to the &lt;a href=&quot;http://www.nabble.com/-ANN--AppFuse-2.0.2-Released-td17181660s2369.html&quot;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/running_spring_mvc_web_applications</guid>
    <title>Running Spring MVC Web Applications in OSGi</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/running_spring_mvc_web_applications</link>
        <pubDate>Wed, 30 Apr 2008 00:42:34 -0600</pubDate>
    <category>Java</category>
    <category>maven</category>
    <category>springmvc</category>
    <category>osgi</category>
    <category>equinox</category>
    <category>spring</category>
            <description>For the past couple of weeks, I&apos;ve been developing a web application that deploys into an OSGi container (Equinox) and uses Spring DM&apos;s &lt;a href=&quot;http://static.springframework.org/osgi/docs/1.1.0-m2/reference/html/web.html#web:spring-mvc&quot;&gt;Spring MVC support&lt;/a&gt;. The first thing I discovered was that Spring MVC&apos;s annotations weren&apos;t supported in the M1 release. This was apparently caused by a &lt;a href=&quot;http://groups.google.com/group/spring-osgi/browse_thread/thread/cf1fa802f846feac/b0f7483ea63b8f8e?lnk=gst#b0f7483ea63b8f8e&quot;&gt;bug &lt;/a&gt; in Spring 2.5.3 and not Spring DM. Since Spring DM 1.1.0 M2 was released with Spring 2.5.4 &lt;a href=&quot;http://www.springframework.org/node/646&quot;&gt;today&lt;/a&gt;, I believe this is fixed now.
&lt;/p&gt;
&lt;p&gt;The story below is about my experience getting a Spring MVC application up and running in Equinox 3.2.2, Jetty 6.1.9 and Spring DM 1.1.0 M2 SNAPSHOT (from last week). If you want to read more about why Spring MVC + OSGi is cool, see Costin Leau&apos;s &lt;a href=&quot;http://blog.springsource.com/main/2008/04/29/web-applications-and-osgi/&quot;&gt;Web Applications and OSGi&lt;/a&gt; article.&lt;/p&gt;
&lt;p&gt;To get a simple &quot;Hello World&quot; Spring MVC application working in OSGi is pretty easy. The hard part is setting up a container with all the Spring and Jetty bundles installed and started. I imagine &lt;a href=&quot;http://www.infoq.com/news/2008/04/springsource-app-platform&quot;&gt;SSAP&lt;/a&gt; might solve this. Luckily for me, this was done by another member of my team.&lt;/p&gt;
&lt;p&gt;After you&apos;ve done this, it&apos;s simply a matter of creating a MANIFEST.MF for your WAR that contains the proper information for OSGi to recognize. Below is the one that I used when I first tried to get my application working. 
&lt;/p&gt;
&lt;pre&gt;
Manifest-Version: 1
Bundle-ManifestVersion: 2
Spring-DM-Version: 1.1.0-m2-SNAPSHOT
Spring-Version: 2.5.2
Bundle-Name: Simple OSGi War
Bundle-SymbolicName: myapp
Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar,
 WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar,
 WEB-INF/lib/spring-beans-2.5.2.jar,WEB-INF/lib/spring-context-2.5.2.jar,
 WEB-INF/lib/spring-context-support-2.5.2.jar,WEB-INF/lib/spring-core-2.5.2.jar,
 WEB-INF/lib/spring-web-2.5.2.jar,WEB-INF/lib/spring-webmvc-2.5.2.jar 
Import-Package: javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
 javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
 org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional
&lt;/pre&gt;
&lt;p class=&quot;smokey&quot;&gt;Ideally, you could generate this MANIFEST.MF using the &lt;a href=&quot;http://felix.apache.org/site/maven-bundle-plugin-bnd.html&quot;&gt;maven-bundle-plugin&lt;/a&gt;. However, it &lt;a href=&quot;http://www.nabble.com/Is-it-possible-to-use-the-maven-bundle-plugin-on-a-WAR-project--ts16763483.html&quot;&gt;doesn&apos;t support WARs&lt;/a&gt; in its 1.4.0 release.&lt;/p&gt;

&lt;p&gt;You can see this is an application that uses Spring MVC, FreeMarker, SiteMesh and the URLRewriteFilter. You should be able to &lt;a href=&quot;http://static.raibledesigns.com/downloads/myapp-noosgi.zip&quot;&gt;download it&lt;/a&gt;, unzip it, run &quot;mvn package&quot; and install it into Equinox using &quot;install file://&amp;lt;path to war&gt;&quot;.&lt;/p&gt;
&lt;p&gt;That&apos;s all fine and dandy, but doesn&apos;t give you any benefits of OSGi. This setup works great until you try to import OSGi services using a context file with an &lt;strong&gt;&amp;lt;osgi:reference&gt;&lt;/strong&gt; element. After adding such a reference, it&apos;s likely you&apos;ll get the following error:
&lt;/p&gt;
&lt;pre&gt;
SEVERE: Context initialization failed
org.springframework.beans.factory.parsing.BeanDefinitionParsingException:
Configuration problem: Unable to locate Spring NamespaceHandler for
XML schema namespace [http://www.springframework.org/schema/osgi]
&lt;/pre&gt;
&lt;p&gt;To fix this, add the following to your web.xml (if you&apos;re using ContextLoaderListener, as an &amp;lt;init-parameter&amp;gt; on DispatcherServlet if you&apos;re not):&lt;/p&gt;
&lt;pre&gt;
  &amp;lt;context-param&amp;gt;
    &amp;lt;param-name&amp;gt;contextClass&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext&amp;lt;/param-value&amp;gt;
  &amp;lt;/context-param&amp;gt;
&lt;/pre&gt;
&lt;p&gt;After doing this, you might get the following error on startup:&lt;/p&gt;
&lt;pre&gt;
SEVERE: Context initialization failed
org.springframework.context.ApplicationContextException: Custom
context class [org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext]
is not of type [org.springframework.web.context.ConfigurableWebApplicationContext] 
&lt;/pre&gt;
&lt;p&gt;To fix this, I change from referencing the Spring JARs in WEB-INF/lib
to importing the packages for Spring (which were already installed in my
Equinox container).
&lt;/p&gt;
&lt;pre&gt;
Bundle-Classpath: .,WEB-INF/classes,WEB-INF/lib/freemarker-2.3.12.jar,
 WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar
Import-Package:
javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
 javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
 org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,
 org.springframework.osgi.web.context.support,
 org.springframework.context.support,
 org.springframework.web.context,
 org.springframework.web.context.support,
 org.springframework.web.servlet,
 org.springframework.web.servlet.mvc,
 org.springframework.web.servlet.mvc.support,
 org.springframework.web.servlet.view,
 org.springframework.ui,
 org.springframework.web.servlet.view.freemarker 
&lt;/pre&gt;
&lt;p&gt;After rebuilding my WAR and reloading the bundle in Equinox, I was confronted with the following error message:&lt;/p&gt;
&lt;pre&gt;
SEVERE: Context initialization failed
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name &apos;freemarkerConfig&apos; defined in ServletContext
resource [/WEB-INF/myapp-servlet.xml]: Instantiation of bean failed;
nested exception is java.lang.NoClassDefFoundError:
freemarker/cache/TemplateLoader
        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:851) 
&lt;/pre&gt;
&lt;p&gt;As far as I can tell, this is because the version of Spring MVC installed in Equinox
cannot resolve the FreeMarker JAR in my WEB-INF/lib directory.
&lt;/p&gt;
&lt;p&gt;To prove I wasn&apos;t going insane, I commented out my &quot;freemarkerConfig&quot; and &quot;viewResolver&quot; beans in myapp-servlet.xml and changed to a regular ol&apos; InternalResourceViewResolver:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&quot;viewResolver&quot; class=&quot;org.springframework.web.servlet.view.InternalResourceViewResolver&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;
&lt;/pre&gt;
&lt;p&gt;This worked and I was able to successfully see &quot;Hello World&quot; from a JSP in my browser. FreeMarker/SiteMesh worked too, but FreeMarker didn&apos;t work as a View for Spring MVC.
&lt;/p&gt;
&lt;p&gt;
To attempt to solve this, I create a &lt;a href=&quot;http://static.raibledesigns.com/downloads/freemarker-2.3.12-bundle.jar&quot;&gt;bundle for FreeMarker&lt;/a&gt; using &quot;java -jar
bnd-0.0.249.jar wrap freemarker-2.3.12.jar&quot; and installed it in Equinox.
I then change my MANIFEST.MF to use FreeMarker imports instead of
referencing the JAR in WEB-INF/lib.
&lt;/p&gt;
&lt;pre&gt;
Bundle-Classpath:
.,WEB-INF/classes,WEB-INF/lib/sitemesh-2.3.jar,WEB-INF/lib/urlrewritefilter-3.0.4.jar
Import-Package:
javax.servlet,javax.servlet.http,javax.servlet.resources,javax.swing.tree,
 javax.naming,org.w3c.dom,org.apache.commons.logging,javax.xml.parsers;resolution:=optional,
 org.xml.sax;resolution:=optional,org.xml.sax.helpers;resolution:=optional,
 org.springframework.osgi.web.context.support,
 org.springframework.context.support,
 org.springframework.web.context,
 org.springframework.web.context.support,
 org.springframework.web.servlet,
 org.springframework.web.servlet.mvc,
 org.springframework.web.servlet.mvc.support,
 org.springframework.web.servlet.view,
 org.springframework.ui,
 org.springframework.web.servlet.view.freemarker,
 freemarker.cache,freemarker.core,freemarker.template,freemarker.ext.servlet 
&lt;/pre&gt;
&lt;p&gt;Unfortunately, this still doesn&apos;t work and I still haven&apos;t been able to get FreeMarker to work with Spring MVC in OSGi. The crazy thing is I actually solved this at one point a week ago. Shortly after, I rebuilt Equinox from scratch and I&apos;m been banging my head against the wall over this issue ever since. Last week, I entered an &lt;a href=&quot;http://jira.springframework.org/browse/OSGI-461&quot;&gt;issue in Spring&apos;s JIRA&lt;/a&gt;, but thought I&apos;d fixed it a few hours later.
&lt;/p&gt;
&lt;p&gt;
I&apos;ve uploaded the final project that&apos;s not working to the following URL:&lt;/p&gt;
&lt;p style=&quot;padding-left: 15px&quot;&gt;&lt;a href=&quot;http://static.raibledesigns.com/downloads/myapp-osgi.zip&quot;&gt;http://static.raibledesigns.com/downloads/myapp-osgi.zip&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;If you&apos;d like to see this project work with Spring MVC + JSP, simply modify myapp-servlet.xml to remove the FreeMarker references and use the InternalResourceViewResolver instead.&lt;/p&gt;
&lt;p&gt;I hope Spring DM + Spring MVC supports more than just JSP as a view technology. I hope I can&apos;t get FreeMarker working because of some oversight on my part. 
If you have a Spring DM + Spring MVC application working with Velocity or FreeMarker, I&apos;d love to hear about it.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/spring_mvc_s_conventions_get</guid>
    <title>Spring MVC&apos;s Conventions get even better</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/spring_mvc_s_conventions_get</link>
        <pubDate>Mon, 7 Apr 2008 09:43:42 -0600</pubDate>
    <category>Java</category>
    <category>springmvc</category>
    <category>spring</category>
            <description>Spring 2.5.3 was &lt;a href=&quot;http://www.springframework.org/node/622&quot;&gt;released this morning&lt;/a&gt; and contains a &lt;a href=&quot;http://jira.springframework.org/browse/SPR-4129&quot;&gt;new feature&lt;/a&gt; I really like. When I first started working with Spring MVC&apos;s annotations (way back in November of last year), I found it awkward that I had to hard-code the URLs for my controllers into @RequestMappings on methods. Previous to annotations, I was using Spring&apos;s &lt;a href=&quot;http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/web/servlet/mvc/support/ControllerClassNameHandlerMapping.html&quot;&gt;ControllerClassNameHandlerMapping&lt;/a&gt; which allows for more conventions-based URL-mappings. 
&lt;/p&gt;
&lt;p&gt;
With 2.5.3, @Controller and ControllerClassNameHandlerMapping have been synced up so you don&apos;t have to specify URLs in your annotations anymore. &lt;em&gt;Thanks guys!&lt;/em&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/david_sachdev_on_web_framework</guid>
    <title>David Sachdev on Web Framework Proliferation</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/david_sachdev_on_web_framework</link>
        <pubDate>Fri, 22 Feb 2008 14:47:44 -0700</pubDate>
    <category>Java</category>
    <category>jsf</category>
    <category>webframeworks</category>
    <category>springmvc</category>
    <category>spring</category>
    <category>grails</category>
    <category>rails</category>
    <category>jruby</category>
            <description>David Sachdev left the following &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_framework_smackdown_at#comment-1203718076000&quot;&gt;comment&lt;/a&gt; in my post about the &lt;a href=&quot;http://raibledesigns.com/rd/entry/java_web_framework_smackdown_at&quot;&gt;Java Web Framework Smackdown at TSSJS in Vegas&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;smokey&quot; style=&quot;padding: 10px; margin-bottom: 10px&quot;&gt;
&lt;p&gt;The number of web frameworks out there is just astonishing, and in alot of ways I think that there is need for some consolidation in some way, shape or form. If you work in the Java world there is a sense of consolidation in the ORM space these days with JPA (the Java Persistence API). Sure if you are working strictly with JPA it is a bit more limiting then working directly with Hibernate, iBatis, or TopLink - but you no longer worry that you have made a critical misstep in your architecture by tying yourself do a particular ORM implementation. Similarly Spring gives you that similar &quot;loosely coupled&quot; feel that if Google&apos;s Guice because appealing to you, you don&apos;t feel like you&apos;ve wasted all your framework foo on Spring. But web frameworks....that&apos;s another story.
&lt;/p&gt;
&lt;p&gt;
I think if you had asked me a few months ago, I would have told you that the industry is promoting JSF (Java Server Faces). Everything from support in the IDEs to the availability of AJAX frameworks...and of course a flexible life cycle that allows for alternate implementations and various code to plug or be weaved in to the life cycle. And that while JSF on its own left quite a bit to be desired, the JBoss Seam project really has filled in the gaps in JSF, and in fact brought Java web development closer in agility to the Rails and Grails of the world that tout quickly built and deployed web applications.
&lt;/p&gt;
&lt;p&gt;
But the thing that you continue to hear is that programming in JSF is painful. And you hear that EVERYONE used to use Struts. And that it is time to move past Struts. And given that, you have to consider Webwork and the merger of Struts2 into that framework - and their claims of rapid development. But you also have to consider Spring WebFlow and how that may help solve your JSF ills given that everyone is building off of the Spring Framework and they have been so good about keeping the framework updated and integrating the best of what is out there while innovating themselves. And then if you are looking at Spring WebFlow, you kinda have to go &quot;Wait, but what about Spring MVC?&quot;
&lt;/p&gt;

&lt;p&gt;
Given its age, you might quickly dismiss Spring MVC until you realize that Grails is build upon it. Grails, that web platform that every java developer is either working with, or intends to work with soon. (Come on, you all have made the Ruby/Rails, Groovy/Grails, JRuby decision in favor of G2, right? I mean all the flexibility of what is out there in the Java world on top of the JVM, with a language that doesn&apos;t suck the life outta you....) And then you have to wonder that if you build upon Spring MVC as well as using Groovy and Grails where appropriate, might you be able to make that killer app in half the time.
&lt;/p&gt;
&lt;p&gt;
But wait, you didn&apos;t think your choices were nearly that simple did you? There is this wonderful software company out in Mountain View that we need to pay attention too. In Google We Trust, right? And even if you don&apos;t worship at the Temple of the G (TOTG) like Sprout, you don&apos;t want to ignore them. And, if you&apos;ve looked at the Google Web Toolkit (GWT) and weren&apos;t at least slightly impressed, I would be surprised. And if you are looking at the GWT, you can&apos;t totally ignore Yahoo&apos;s YUI - maybe with some of the what Prototype, Scriptaculous, or DoJo offer you. And then someone will come over and point out Echo2 to you, and well you have to admit, their demo looks nice. And well, there is Adobe Flex, and OpenLaszlo - I mean after all isn&apos;t Web 2.0 all about Rich Internet Applications. And surely you&apos;ve heard that the performance of Swing is so much better these days and the &quot;power of the modern Java applet&quot;
&lt;/p&gt;
&lt;p style=&quot;margin-bottom: 5px&quot;&gt;
So at the end of it all, you&apos;ve got yourself alot of R&amp;amp;D to do, and just as you thing you&apos;ve got a good grasp for the offerings out there, new and improved versions are out. And don&apos;t worry, someone else is also busy working on a new and greater web framework that you have to consider.
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Wow - that&apos;s quite a mouthful David. &lt;em&gt;Well written!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;P.S. The &lt;a href=&quot;http://www.theserverside.com/news/thread.tss?thread_id=48454&quot;&gt;Early Bird Deadline for TSSJS is today&lt;/a&gt;.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/spring_security_2</guid>
    <title>Spring Security 2</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/spring_security_2</link>
        <pubDate>Thu, 6 Dec 2007 15:52:34 -0700</pubDate>
    <category>Java</category>
    <category>security</category>
    <category>acegi</category>
    <category>spring</category>
            <description>It looks like we&apos;ll have to wait until next week to get our hands on Spring Security 2 (the next release of Acegi Security). The good news is it &lt;a href=&quot;http://blog.interface21.com/main/2007/12/06/whats-new-in-spring-security-2/&quot;&gt;looks much simpler&lt;/a&gt;. From what I can tell, this new code is available in Acegi&apos;s &lt;a href=&quot;http://sourceforge.net/svn/?group_id=104215&quot;&gt;SVN repository&lt;/a&gt;. Here&apos;s to hoping the Acegi Team writes some sort of migration guide.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/spring_mvc_jstlview_and_exposecontextbeansasattributes</guid>
    <title>Spring MVC, JstlView and exposeContextBeansAsAttributes</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/spring_mvc_jstlview_and_exposecontextbeansasattributes</link>
        <pubDate>Wed, 5 Dec 2007 18:34:41 -0700</pubDate>
    <category>Java</category>
    <category>jstl</category>
    <category>spring</category>
            <description>Did you know that Spring MVC&apos;s &lt;a href=&quot;http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/web/servlet/view/JstlView.html&quot;&gt;JstlView &lt;/a&gt; has a &lt;strong&gt;exposeContextBeansAsAttributes&lt;/strong&gt; property you can use to expose all your Spring beans to JSTL? I didn&apos;t. To configure it, you configure your viewResolver as follows:
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;bean id=&quot;viewResolver&quot; 
    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;exposeContextBeansAsAttributes&quot; value=&quot;true&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;
&lt;/pre&gt;
&lt;p&gt;After doing this, any Spring bean can get referenced in JSTL with:
&lt;/p&gt;
&lt;pre&gt;
${beanId.getterMethodWithoutTheGetPrefix}
&lt;/pre&gt;
&lt;p&gt;If you&apos;re using Spring 2.5a annotations and &amp;lt;context:component-scan&amp;gt;, you&apos;ll need to specify a &quot;value&quot; attribute on your annotations in order to reference them in JSTL. For example:
&lt;/p&gt;
&lt;pre&gt;
@Controller(value = &quot;beanId&quot;)
@RequestMapping(&quot;/foo.html&quot;)
public class MyController extends SimpleFormController

...

@Component(value=&quot;testClass&quot;)
public class TestClass {
&lt;/pre&gt;
&lt;p&gt;Pretty cool stuff. It&apos;d be a lot more useful if you could call methods with parameters. Hopefully &lt;a href=&quot;http://juel.sourceforge.net/&quot;&gt;JUEL&lt;/a&gt; will solve that problem. &lt;a href=&quot;http://www.javaworld.com/javaworld/jw-05-2003/jw-0523-calltag.html&quot;&gt;JSTL&apos;s functions&lt;/a&gt; work, but I&apos;d rather write ${foo.method(&apos;arg&apos;)} rather than ${taglib:callMethod(foo, &apos;method&apos;, &apos;arg&apos;)}.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_0_1_released</guid>
    <title>AppFuse 2.0.1 Released</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_0_1_released</link>
        <pubDate>Mon, 26 Nov 2007 09:29:43 -0700</pubDate>
    <category>Java</category>
    <category>appfuse</category>
    <category>tapestry</category>
    <category>java</category>
    <category>spring</category>
    <category>jsf</category>
    <category>maven2</category>
    <category>springmvc</category>
    <category>jpa</category>
    <category>java5</category>
    <category>struts2</category>
    <category>hibernate</category>
    <category>myfaces</category>
    <category>ibatis</category>
            <description>The AppFuse Team is pleased to announce the release of AppFuse 2.0.1. This release squashes a number of bugs and includes an upgrade to Spring 2.5. To learn more about Spring 2.5&apos;s features, see InfoQ&apos;s &lt;span class=&quot;nobr&quot;&gt;&lt;a href=&quot;http://www.infoq.com/articles/spring-2.5-part-1&quot; rel=&quot;nofollow&quot;&gt;What&apos;s New in Spring 2.5: Part 1&lt;/a&gt;&lt;/span&gt; article.&lt;/p&gt;

&lt;p&gt;For information on upgrading from 2.0, see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0.1&quot; title=&quot;Release Notes 2.0.1&quot;&gt;2.0.1 Release Notes&lt;/a&gt; or &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0.1#ReleaseNotes2.0.1-changelog&quot;&gt;changelog&lt;/a&gt;. AppFuse 2.0.1 is available as a Maven archetype. For information on creating a new project using AppFuse, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; title=&quot;AppFuse QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; or the &lt;a href=&quot;http://appfuse.org/display/APF/Demos+and+Videos&quot; title=&quot;Demos and Videos&quot;&gt;demos and videos&lt;/a&gt;. &lt;/p&gt;
&lt;p class=&quot;smokey&quot;&gt;
What is AppFuse? &lt;a href=&quot;?&quot; onclick=&quot;Effect.toggle(&apos;whatisappfuse&apos;, &apos;blind&apos;); return false&quot;&gt;Click here&lt;/a&gt; to find out.
&lt;/p&gt;
&lt;p style=&quot;display: none; border: 1px solid #F0C000;
 background-color: #FFFFCE;
 text-align:left;
 margin-top: 5px;
 margin-bottom: 5px; padding: 10px&quot; id=&quot;whatisappfuse&quot;&gt;
&lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; is an open source project and application that uses open source tools built on the Java platform to help you develop Web applications quickly and efficiently. It was originally developed to eliminate the ramp-up time found when building new web applications for customers. 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.
&lt;br/&gt;&lt;br/&gt;
AppFuse 1.x uses Ant to create your project, as well as build/test/deploy it. AppFuse 2.0 uses Maven 2 to create your project as well as build/test/deploy it. IDE support is much better in 2.0 because you can generate the IDE project files with Maven plugins. AppFuse 1.x uses XDoclet and JDK 1.4+.&lt;br/&gt;&lt;br/&gt;
This project was started in &lt;a href=&quot;http://raibledesigns.com/rd/entry/announce_struts_resume_and_appfuse&quot;&gt;April 2003&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;The 2.0 series of AppFuse has a minimum requirement of the following specification versions:&lt;/p&gt;

&lt;ul class=&quot;glassList&quot;&gt;
	&lt;li&gt;Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)&lt;/li&gt;
	&lt;li&gt;Java 5+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you&apos;ve used AppFuse 1.x, but not 2.x, you&apos;ll want to read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot; title=&quot;FAQ&quot;&gt;FAQ&lt;/a&gt;.  Join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot; title=&quot;Mailing Lists&quot;&gt;user mailing list&lt;/a&gt; if you have any questions. 

&lt;p&gt;Thanks to everyone for their help contributing code, writing documentation, posting to the mailing lists, and logging issues. &lt;/p&gt;

&lt;p&gt;We greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot; title=&quot;Sponsors&quot;&gt;our sponsors&lt;/a&gt;, particularly &lt;span class=&quot;nobr&quot;&gt;&lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot; rel=&quot;nofollow&quot;&gt;Atlassian&lt;/a&gt;&lt;/span&gt;, &lt;span class=&quot;nobr&quot;&gt;&lt;a href=&quot;http://contegix.com&quot; rel=&quot;nofollow&quot;&gt;Contegix&lt;/a&gt;&lt;/span&gt;, &lt;span class=&quot;nobr&quot;&gt;&lt;a href=&quot;http://www.jetbrains.com&quot; rel=&quot;nofollow&quot;&gt;JetBrains&lt;/a&gt;&lt;/span&gt;, and &lt;span class=&quot;nobr&quot;&gt;&lt;a href=&quot;http://www.java.net&quot; rel=&quot;nofollow&quot;&gt;Java.net&lt;/a&gt;&lt;/span&gt;. Atlassian and Contegix are especially awesome: &lt;span class=&quot;nobr&quot;&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_now_powered_by_contegix&quot; rel=&quot;nofollow&quot;&gt;Atlassian has donated licenses to all its products and Contegix has donated an entire server&lt;/a&gt;&lt;/span&gt; to the AppFuse project. Thanks guys - &lt;em&gt;you rock!&lt;/em&gt;&lt;/p&gt;

&lt;p class=&quot;smokey&quot;&gt;
Please post any issues you have with this release to the &lt;a href=&quot;http://www.nabble.com/-ANN--AppFuse-2.0.1-Released-tf4876194s2369.html&quot;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;
</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_2</guid>
    <title>Upgrading AppFuse to Spring 2.5</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/upgrading_appfuse_to_spring_2</link>
        <pubDate>Wed, 7 Nov 2007 08:27:20 -0700</pubDate>
    <category>Java</category>
    <category>maven</category>
    <category>appfuse</category>
    <category>spring</category>
            <description>Last night, I spent a few minutes upgrading AppFuse to &lt;a href=&quot;http://www.springframework.org/node/548&quot;&gt;Spring 2.5 RC1&lt;/a&gt;. According to InfoQ, &lt;a href=&quot;http://www.infoq.com/news/2007/11/spring25rc&quot;&gt;Spring 2.5 is a drop-in upgrade for Spring 2.0&lt;/a&gt;. However, if you&apos;re using Maven, it&apos;s not quite that easy. The good news is it is easy, you just need to change your pom.xml a bit. The steps I used to upgrade AppFuse are listed below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a repository for Spring&apos;s milestone releases:
&lt;pre style=&quot;margin-top: 5px&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;
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Change artifactId of &quot;spring-mock&quot; to be &quot;spring-test&quot;.&lt;/li&gt;
&lt;li&gt;Change version to be 2.5-rc1.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point, if you&apos;re using &quot;spring&quot; as your artifactId (instead of the smaller fine-grained dependencies), you&apos;ll likely get the following error in a Spring MVC application:&lt;/p&gt;
&lt;pre&gt;
java.lang.NoClassDefFoundError: 
org/springframework/web/servlet/handler/AbstractUrlHandlerMapping
&lt;/pre&gt;
&lt;p&gt;This happens because Spring MVC is no longer included in the uber spring.jar. You&apos;ll need to add a dependency on &quot;spring-webmvc&quot; to solve this problem. Unfortunately, this JAR is dependent on the fine-grained modules, so you may have to modify your pom.xml to depend on the fine-grained modules - or exclude them all from spring-webmvc.
&lt;/p&gt;
&lt;p&gt;The good news is Spring has excluded all the &lt;a href=&quot;http://raibledesigns.com/rd/entry/maven_2_hates_commons_logging&quot;&gt;invalid commons-logging dependencies&lt;/a&gt; for you so you don&apos;t have to anymore.
&lt;/p&gt;
&lt;p&gt;After getting all the dependencies straightened out - I ran the integration tests:
&lt;/p&gt;
&lt;pre&gt;
org.springframework.beans.NotReadablePropertyException: Invalid property 
&apos;fileUpload&apos; of bean class [org.appfuse.webapp.controller.FileUpload]: Bean 
property &apos;fileUpload&apos; is not readable or has an invalid getter method: Does the 
return type of the getter match the parameter type of the setter?
&lt;/pre&gt;
&lt;p&gt;
Looking at uploadForm.jsp, I&apos;m guessing the problem happens because of the following code:
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;spring:bind path=&quot;fileUpload.file&quot;&amp;gt;
&amp;lt;input type=&quot;file&quot; name=&quot;file&quot; id=&quot;file&quot; class=&quot;file medium&quot; value=&quot;&amp;lt;c:out value=&quot;${status.value}&quot;/&amp;gt;&quot;/&amp;gt;
&amp;lt;/spring:bind&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;a href=&quot;http://opensource.atlassian.com/projects/spring/browse/SPR-4022&quot;&gt;Confirmed&lt;/a&gt; - changing the &quot;path&quot; attribute to &quot;file&quot; fixes the problem. I also found out that setting the &quot;value&quot; on an &amp;lt;input type=&quot;file&quot;&amp;gt; doesn&apos;t work, so wrapping the field with &amp;lt;spring:bind&amp;gt; doesn&apos;t make a whole lot of sense anyway.&lt;/p&gt;
&lt;p&gt;To conclude, it doesn&apos;t look like the first release candidate of Spring 2.5 is &lt;em&gt;exactly&lt;/em&gt; a drop-in upgrade for Spring 2.0, but it&apos;s pretty darn close. I&apos;m sure by the time it&apos;s released, it will be. I&apos;d encourage you to try 2.5 in your Spring-dependent projects to see if you find any issues.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I was successfully able to migrate AppFuse from using the uber JAR to fine-grained JARs. However, I ran into a couple issues in the process. The first is that even though I&apos;m including spring-aop in the &lt;em&gt;appfuse-service&lt;/em&gt; module, it&apos;s not pulled in for the web frameworks (which depend on appfuse-service). Explicitly declaring spring-aop as a dependency for the appfuse-web module fixes this. Secondly, I had to modify my Acegi Security exclusions  so it wouldn&apos;t include dependencies that no longer exist in 2.5.
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;dependency&amp;gt;
    &amp;lt;groupId&amp;gt;org.acegisecurity&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;acegi-security-tiger&amp;lt;/artifactId&amp;gt;
    &amp;lt;version&amp;gt;${acegi.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-dao&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-jdbc&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-remoting&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;
&lt;/pre&gt;
&lt;p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/google_goods_at_the_colorado</guid>
    <title>Google Goods at the Colorado Software Summit</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/google_goods_at_the_colorado</link>
        <pubDate>Tue, 23 Oct 2007 17:46:56 -0600</pubDate>
    <category>Java</category>
    <category>guice</category>
    <category>spring</category>
    <category>google</category>
    <category>gears</category>
            <description>This morning, I woke up early and attended &lt;a href=&quot;http://almaer.com/blog/&quot;&gt;Dion Almaer&lt;/a&gt;&apos;s talk on &lt;a href=&quot;http://gears.google.com&quot;&gt;Google Gears&lt;/a&gt;.
Dion works at Google in the Developer API group and is a member of the Google Gears development team. This presentation is called How to take your Web Application offline with Google Gears.
&lt;/p&gt;
&lt;p&gt;
Dion starts with a video that Google Developers made. It&apos;s a parody of &lt;a href=&quot;http://www.nbc.com/Saturday_Night_Live/uncensored.shtml&quot;&gt;Dick in a Box&lt;/a&gt;, but it&apos;s called &lt;strong&gt;API in a Box&lt;/strong&gt;. This was by far my favorite part of the presentation and it all went downhill from there. &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;Gears is a browser plugin that adds a database and a JavaScript API that allows applications to &quot;go offline&quot; and use these resources to store data. It does not do anything to handle synchronization of data back to the online database.&lt;/p&gt;
&lt;p&gt;Gears has three modules as part of its &lt;a href=&quot;http://code.google.com/apis/gears/&quot;&gt;API&lt;/a&gt;: &lt;a href=&quot;http://code.google.com/apis/gears/api_localserver.html&quot;&gt;LocalServer&lt;/a&gt;, &lt;a href=&quot;http://code.google.com/apis/gears/api_database.html&quot;&gt;Database&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/apis/gears/api_workerpool.html&quot;&gt;Workerpool&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The Database is embedded using SQLite. Google contributed Full Text Search to it and the entire database is 250K. Below is an example of how you might use the API:
&lt;/p&gt;
&lt;pre&gt;
var db = google.gears.factory.create(&quot;beta.database&quot;, &quot;1.0&quot;);
db.open(&quot;database-demo&quot;);
db.execute(&quot;create table if not exists ...&quot;);
...
var rs = db.execute(&quot;select * from Demo order by Timestamp desc&quot;);
while (rs.isValidRolw()) {
    var name = fs.field(|);
    ...
}
&lt;/pre&gt;
&lt;p&gt;During the rest of the talk, I tuned in and out, but caught a number of interesting tidbits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://m.ac.nz/gearshift/&quot;&gt;GearShift&lt;/a&gt; - DB Migrations for Gears.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/apis/gears/tools.html&quot;&gt;Database Query Tool&lt;/a&gt; - one-page browser-based application that can be added to existing applications to add a query browser.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/gearsinmotion/&quot;&gt;Gears in Motion&lt;/a&gt; - full database tool for creating databases, modifying tables, inline-editing, etc. After building your database, you can export the SQL for use in a Gears application.
&lt;li&gt;Syncing is not a part of Gears because it&apos;s a very difficult problem to solve - especially when you have huge data.&lt;/li&gt;
&lt;li&gt;The best way to implement synching is to start simple, like &lt;a href=&quot;http://writer.zoho.com&quot;&gt;Zoho Writer&lt;/a&gt;. It&apos;s like Google Docs, but allows you to read your documents off-line. The next version they&apos;re planning on allowing offline editing.
&lt;/li&gt;
&lt;li&gt;You should plan on allowing your application to run - possibly by using cookies to store the data and create a &quot;CookieBaseContent&quot; implementation that gets chosen instead of &quot;GearsBaseContent&quot;. In other words:
&lt;pre&gt;
content = hasGears() ? new GearsBaseContent() : new CookieBaseContent();
&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Debugging is a pain - you can simplify by using helper functions that allow you to clear the database.&lt;/li&gt;
&lt;li&gt;Google&apos;s &lt;a href=&quot;http://ajaxian.com/archives/google-launches-javascript-api-that-allows-you-to-write-back&quot;&gt;Read/Write JavaScript API&lt;/a&gt; looks like some really cool stuff. It solves the cross-domain problem and is (at its core) a clever bundling of browser hacks. It&apos;s not specific to Google&apos;s APIs and can be used in any Ajax application.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/gears-monkey/&quot;&gt;Gearsmonkey&lt;/a&gt; - uses Google Gears with the Firefox &lt;a href=&quot;https://addons.mozilla.org/en-US/firefox/addon/748&quot;&gt;Greasemonkey&lt;/a&gt; plug-in to take other&apos;s applications offline.&lt;/li&gt;
&lt;li&gt;Dion uses Greasemonkey to add keystrokes to GMail and remove ads from Facebook.&lt;/li&gt;
&lt;li&gt;Wikipedia has an offline version that&apos;s powered by Gears. It uses iframes to cache pages with Gears and was developed by Google. It&apos;s unannounced by Dion didn&apos;t say I couldn&apos;t blog about it. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;&lt;/li&gt;
&lt;li&gt;Dojo offline has a &lt;a href=&quot;http://ajaxian.com/archives/dojo-offline-09-and-gears&quot;&gt;sync framework&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://ajaxian.com/archives/vortex-a-new-offline-abstraction-on-top-of-google-gears&quot;&gt;Vortex&lt;/a&gt; is an offline toolkit that builds on Gears.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://googlewebtoolkit.blogspot.com/2007/05/gwt-gears-up.html&quot;&gt;GWT has Gears support&lt;/a&gt; - all you have to do is drop a JAR in your classpath. If you don&apos;t like using Gear&apos;s JDBC-esque API - maybe you can use &lt;a href=&quot;http://blog.robjsoftware.org/2007/06/why-blogger-needs-offline-editing.html&quot;&gt;Hibernate with Gears&lt;/a&gt;?
&lt;/ul&gt;
&lt;p&gt;Dion ended by talking about how Adobe Air is great for desktop-like applications that you can easily build with Ajax technologies. Silverlight is impressive, but only for media applications - you have to draw components yourself. Java Applets may make a comeback. The browser plugin has been rewritten to be fast as well as have &lt;em&gt;full support&lt;/em&gt; for Java Web Start. It&apos;s possible that Gears + the Java Plugin can make it possible to use Java technologies (i.e. Hibernate or JPA) to talk to the browser&apos;s database. Firefox and WebKit are adding database components to their next major releases - so offline applications should become even easier to develop in the future.
&lt;/ul&gt;
&lt;p&gt;Overall, this was a great talk - largely because Dion is a great speaker and made it fun and interesting.
&lt;/p&gt;
&lt;p&gt;After Dion&apos;s talk, I delivered my &lt;a href=&quot;http://raibledesigns.com/rd/entry/choosing_a_jvm_web_framework2&quot;&gt;Web Framework&lt;/a&gt; talk and had some lunch while trying to get Rockies tickets (no luck). After lunch, I attended Bill Dudney&apos;s &lt;a href=&quot;http://softwaresummit.com/2007/speakers/dudney.htm&quot;&gt;Comparing Spring &amp;amp; Guice&lt;/a&gt; talk. I learned some things about Guice I didn&apos;t know and enjoyed his comparison of the two Dependency Injection frameworks. 
&lt;/p&gt;
&lt;p&gt;
One question that Bill couldn&apos;t answer is how Spring 2.5&apos;s annotation support stacks up against Guice. Is it as full-featured as Guice? Does it add additional features and keep up with Guice for performance? What about wiring up objects without annotations - does it allow you to autowire your classes based on naming patterns without annotations in your code? What I&apos;m hoping for is a DI framework that allows me to autowire classes using rules/conventions rather than annotations. I&apos;m fine with using annotations for edge-cases, but it seems like a lot of the DI I do these days could be configured up-front and used for the entire application (rather than having to wire up each class).
&lt;/p&gt;
&lt;p&gt;Overall, it was a great day at the Colorado Software Summit.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm3.static.flickr.com/2016/1717632027_973441a24a_o.jpg&quot; title=&quot;View from our condo at CSS&quot; rel=&quot;lightbox&quot;&gt;&lt;img src=&quot;//farm3.static.flickr.com/2016/1717632027_25bb4ac042_m.jpg&quot; width=&quot;240&quot; height=&quot;180&quot; alt=&quot;View from our condo at CSS&quot; style=&quot;border: 1px solid black&quot;/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/interface21_on_open_source</guid>
    <title>Interface21 on Open Source</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/interface21_on_open_source</link>
        <pubDate>Fri, 21 Sep 2007 11:10:47 -0600</pubDate>
    <category>Java</category>
    <category>spring</category>
    <category>opensource</category>
            <description>Rod Johnson in &lt;a href=&quot;http://blog.interface21.com/main/2007/09/20/replies-to-nonsense-about-open-source/&quot;&gt;Replies to Nonsense about Open Source&lt;/a&gt; says that Interface21 is the only legitimate company that can offer support for Spring. 
&lt;/p&gt;
&lt;p&gt;...at least that&apos;s my interpretation...&lt;/p&gt;
&lt;p&gt;Ben Speakmon (of SourceLabs) responds with &lt;a href=&quot;http://taose.blogspot.com/2007/09/nonsense-about-interface21.html&quot;&gt;Nonsense about Interface21&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Both articles are good reads. However, I think Ben has a good point:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
One final point for Rod: why did you open source Spring at all? If you&apos;re so convinced that no one else can offer credible support for it, why not just make it proprietary?
&lt;/p&gt;
&lt;p&gt;Is Interface21 becoming the JBoss from two years ago? Will they one day make it difficult for companies to provide services around Spring like &lt;a href=&quot;http://bill.dudney.net/roller/bill/entry/1&quot;&gt;JBoss has&lt;/a&gt;? Fleury and Johnson will say that &quot;professional open source&quot; is the only way to have a truly successful project. While it may be working well for them, I tend to like &lt;a href=&quot;http://www.loudthinking.com/posts/6-why-theres-no-rails-inc&quot;&gt;DHH&apos;s stance on Rails&lt;/a&gt; a bit more:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
I believe a Rails Inc consisting of a large group of core committers would have an unfair advantage in the training and consulting space - easily siphoning off all the best juice and leaving little for anything else. There are plenty of examples in our industry of that happening around open source tools.
&lt;br/&gt;&lt;br/&gt;
&lt;strong&gt;It&apos;s much more satisfying to see a broader pool of companies all competing on a level playing field.&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Disclaimer:&lt;/strong&gt; In &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_adventure_is_over&quot;&gt;the past&lt;/a&gt;, I&apos;ve provided training and consulting around Spring - in addition to writing a &lt;a href=&quot;http://springlive.com&quot;&gt;book&lt;/a&gt; about it. Interface21 has never done anything to discourage people from using my services. At least they haven&apos;t done anything that I know of. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_0_released</guid>
    <title>AppFuse 2.0 Released!</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_0_released</link>
        <pubDate>Tue, 18 Sep 2007 15:22:20 -0600</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>struts2</category>
    <category>java5</category>
    <category>myfaces</category>
    <category>ibatis</category>
    <category>jpa</category>
    <category>hibernate</category>
    <category>tapestry</category>
    <category>appfuse</category>
    <category>springmvc</category>
    <category>jsf</category>
    <category>maven2</category>
    <category>spring</category>
            <description>&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//appfuse.dev.java.net/images/icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
I&apos;m extremely happy to announce we&apos;ve finally finished developing AppFuse 2.0. The road to AppFuse 2.0 has been a long journey through Mavenland, annotations and generics. Thanks to all the developers, contributors and users for helping test, polish and prove that AppFuse 2 is an excellent solution for developing Java-based applications. Your time, patience and usage of AppFuse has made it the strong foundation it is today. Last but certainly not least, thanks to all the great Java developers who wrote the frameworks that AppFuse uses - we&apos;re truly standing on the shoulders of giants.
&lt;/p&gt;
&lt;p class=&quot;smokey&quot;&gt;
What is AppFuse? &lt;a href=&quot;?&quot; onclick=&quot;Effect.toggle(&apos;whatisappfuse&apos;, &apos;blind&apos;); return false&quot;&gt;Click here&lt;/a&gt; to find out.
&lt;/p&gt;
&lt;p style=&quot;display: none; border: 1px solid #F0C000;
 background-color: #FFFFCE;
 text-align:left;
 margin-top: 5px;
 margin-bottom: 5px; padding: 10px&quot; id=&quot;whatisappfuse&quot;&gt;
&lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; is an open source project and application that uses open source tools built on the Java platform to help you develop Web applications quickly and efficiently. It was originally developed to eliminate the ramp-up time found when building new web applications for customers. 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.
&lt;br/&gt;&lt;br/&gt;
AppFuse 1.x uses Ant to create your project, as well as build/test/deploy it. AppFuse 2.0 uses Maven 2 to create your project as well as build/test/deploy it. IDE support is much better in 2.0 because you can generate the IDE project files with Maven plugins. AppFuse 1.x uses XDoclet and JDK 1.4+.&lt;br/&gt;&lt;br/&gt;
This project was started in &lt;a href=&quot;http://raibledesigns.com/rd/entry/announce_struts_resume_and_appfuse&quot;&gt;April 2003&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;AppFuse 2.0 is available as a Maven archetype. For information on creating a new project using this release, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; title=&quot;AppFuse QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; or the &lt;a href=&quot;http://appfuse.org/display/APF/Demos+and+Videos&quot;&gt;demos and videos&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you&apos;ve used AppFuse 1.x, but not 2.x, you&apos;ll might want to read our &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot; title=&quot;FAQ&quot;&gt;Frequently Asked Questions&lt;/a&gt;.  If you have any questions or issues, please post them to the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot; title=&quot;Mailing Lists&quot;&gt;user mailing list&lt;/a&gt;. The &lt;a href=&quot;http://appfuse.org/display/APF/Maven+2&quot; title=&quot;Maven 2&quot;&gt;Maven Reference Guide&lt;/a&gt; has a map of Ant &amp;raquo; Maven commands. &lt;a href=&quot;http://appfuse.org/display/APF/Maven+for+Newbies&quot; title=&quot;Maven for Newbies&quot;&gt;Maven for Newbies&lt;/a&gt; might also be useful if you&apos;ve never used Maven before. There is &lt;a href=&quot;http://appfuse.org/display/APF/FAQ#FAQ-usingant&quot;&gt;some support for Ant&lt;/a&gt; in this release.&lt;/p&gt;

&lt;p&gt;AppFuse 2.0 contains over 200 pages of &lt;a href=&quot;http://appfuse.org&quot;&gt;documentation&lt;/a&gt;, downloadable as a &lt;a href=&quot;https://appfuse.dev.java.net/files/documents/1397/68818/appfuse-documentation-2.0.pdf&quot;&gt;PDF&lt;/a&gt; (3 MB). You can also download all its &lt;a href=&quot;https://appfuse.dev.java.net/files/documents/1397/68819/appfuse-dependencies-2.0.zip&quot;&gt;dependencies&lt;/a&gt; and install them in your local repository if you want to work offline.&lt;/p&gt;

&lt;p&gt;For more information, please see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0&quot; title=&quot;Release Notes 2.0&quot;&gt;2.0 Release Notes&lt;/a&gt;. The 2.0 series of AppFuse has a minimum requirement of the following specification versions:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)&lt;/li&gt;
	&lt;li&gt;Java 5+&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;New features in AppFuse 2.0 include:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Maven 2 Integration&lt;/li&gt;
	&lt;li&gt;Upgraded WebWork to Struts 2&lt;/li&gt;
	&lt;li&gt;JDK 5, Annotations, JSP 2.0, Servlet 2.4&lt;/li&gt;
	&lt;li&gt;JPA Support&lt;/li&gt;
	&lt;li&gt;Generic CRUD backend&lt;/li&gt;

	&lt;li&gt;Full Eclipse, IDEA and NetBeans support&lt;/li&gt;
	&lt;li&gt;Fast startup and no deploy with Maven Jetty Plugin&lt;/li&gt;
	&lt;li&gt;Testable on multiple appservers and databases with Cargo and profiles&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We appreciate the time and effort everyone has put toward contributing code and documentation, posting to the mailing lists, and logging issues. &lt;/p&gt;

&lt;p&gt;We&apos;re also grateful for the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot; title=&quot;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;, &lt;a href=&quot;http://www.jetbrains.com&quot;&gt;JetBrains&lt;/a&gt;, and &lt;a href=&quot;http://www.java.net&quot;&gt;Java.net&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. Thanks guys - &lt;em&gt;you rock!&lt;/em&gt;&lt;/p&gt;
&lt;p class=&quot;smokey&quot;&gt;
Comments and issues should be posted to the &lt;a href=&quot;http://www.nabble.com/-ANN--AppFuse-2.0-Released%21-tf4477191s2369.html&quot;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_0_rc1_released</guid>
    <title>AppFuse 2.0 RC1 Released</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_0_rc1_released</link>
        <pubDate>Tue, 4 Sep 2007 01:42:15 -0600</pubDate>
    <category>Java</category>
    <category>struts</category>
    <category>maven2</category>
    <category>hibernate</category>
    <category>spring</category>
    <category>struts2</category>
    <category>jsf</category>
    <category>tapestry</category>
    <category>springmvc</category>
    <category>appfuse</category>
            <description>&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//appfuse.dev.java.net/images/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.0 RC1! This release marks a huge step in the march to releasing AppFuse 2.0. This release puts the finishing touches on the &lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin&quot;&gt;AppFuse Maven Plugin&lt;/a&gt; (AMP), which offers CRUD generation, as well as the ability to change AppFuse from &quot;embedded mode&quot; to &quot;full source&quot; (like 1.x). In addition, we&apos;ve addressed over 100 issues in preparation for the final 2.0 release. We hope to fix any bugs related to this release and release 2.0 Final in the next week or two.&lt;/p&gt;

&lt;p&gt;The &lt;a href=&quot;http://appfuse.org/display/APF/Demos+and+Videos&quot; title=&quot;Demos and Videos&quot;&gt;videos&lt;/a&gt; still represent how M5 works, but things have been simplified (now you don&apos;t need to run &lt;em&gt;appfuse:install&lt;/em&gt; after &lt;em&gt;appfuse:gen&lt;/em&gt;).&lt;/p&gt;

&lt;p&gt;AppFuse 2.0 is available as a Maven archetype. For information on creating a new project using this release, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; title=&quot;AppFuse QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; or the &lt;a href=&quot;http://static.appfuse.org/movies/2.0/helloworld.mov&quot;&gt;Hello World video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you&apos;ve used AppFuse 1.x, but not 2.x, you&apos;ll want to read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot; title=&quot;FAQ&quot;&gt;FAQ&lt;/a&gt;.  Join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot; title=&quot;Mailing Lists&quot;&gt;user mailing list&lt;/a&gt; if you have any questions. The &lt;a href=&quot;http://appfuse.org/display/APF/Maven+2&quot; title=&quot;Maven 2&quot;&gt;Maven Reference Guide&lt;/a&gt; has a map of Ant &amp;raquo; Maven commands. &lt;a href=&quot;http://appfuse.org/display/APF/Maven+for+Newbies&quot; title=&quot;Maven for Newbies&quot;&gt;Maven for Newbies&lt;/a&gt; might also be useful if you&apos;ve never used Maven before. There is &lt;a href=&quot;http://appfuse.org/display/APF/FAQ#FAQ-usingant&quot;&gt;some support for Ant&lt;/a&gt; in this release.&lt;/p&gt;

&lt;p&gt;For more information, please see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0+RC1&quot; title=&quot;Release Notes 2.0 RC1&quot;&gt;2.0 RC1 Release Notes&lt;/a&gt;. The 2.0 series of AppFuse has a minimum requirement of the following specification versions:&lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;Java Servlet 2.4 and JSP 2.0 (2.1 for JSF)&lt;/li&gt;
	&lt;li&gt;Java 5+&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;We appreciate the time and effort everyone has put toward contributing code and documentation, posting to the mailing lists, and logging issues. &lt;/p&gt;

&lt;p&gt;We also greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot; title=&quot;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;, &lt;a href=&quot;http://www.jetbrains.com&quot;&gt;JetBrains&lt;/a&gt;, and &lt;a href=&quot;http://www.java.net&quot;&gt;Java.net&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. Thanks guys - &lt;em&gt;you rock!&lt;/em&gt;
&lt;/p&gt;
&lt;p class=&quot;smokey&quot;&gt;
Comments and issues should be posted to the &lt;a href=&quot;http://www.nabble.com/-ANN--AppFuse-2.0-RC1-Released%21-tf4376078s2369.html&quot;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I&apos;ve uploaded a &lt;a href=&quot;http://tinyurl.com/2qlst4&quot;&gt;247-page PDF version of the RC1 documentation&lt;/a&gt; to java.net. This PDF contains the relevant pages from the wiki that help you develop with AppFuse 2.0. Who knew I&apos;d end up writing another book? &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/spring_web_flow_2_0</guid>
    <title>Spring Web Flow 2.0</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/spring_web_flow_2_0</link>
        <pubDate>Wed, 29 Aug 2007 15:49:15 -0600</pubDate>
    <category>Java</category>
    <category>springwebflow</category>
    <category>jsf</category>
    <category>spring</category>
            <description>The first milestone release of Spring Web Flow 2.0 &lt;a href=&quot;http://www.springframework.org/node/510&quot;&gt;has been released&lt;/a&gt;.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
We are pleased to announce that the first milestone of the next generation version of Spring Web Flow is now available. Spring Web Flow 2.0 M1 introduces several major new features, including support for flow-managed persistence contexts, improved support for Java Server Faces, full unified expression language (EL) support, and a more comprehensive &lt;a href=&quot;http://spring.ervacon.com/swf-booking-jsf&quot;&gt;sample web application&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;I think the most interesting part of this release is &lt;strong&gt;Spring Faces&lt;/strong&gt;:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Spring Web Flow 2.0 M1 introduces the &lt;em&gt;Spring Faces&lt;/em&gt; module (spring-faces-2.0-m1.jar), a component shipped with the Web Flow distribution that contains first-class support for organizations developing web applications with Java Server Faces. The pre-existing Web Flow + JSF integration has been factored out to this project, and this project will be the home of all future JSF integration work.
&lt;br/&gt;&lt;br/&gt;
The Spring Faces module provides the Spring community a dedicated project for exploring additional JSF integration opportunities. The initial work in 2.0 M1 on this front introduces integration with &lt;a href=&quot;http://www.extjs.com&quot;&gt;Ext&lt;/a&gt;, a popular Javascript GUI widget framework.&lt;/p&gt;
&lt;p&gt;Of course, I also like how the &lt;a href=&quot;http://spring.ervacon.com/swf-booking-jsf&quot;&gt;new sample app&lt;/a&gt; looks a lot like one of &lt;a href=&quot;http://seam.demo.jboss.com/home.seam&quot;&gt;Seam&apos;s demos&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;JSF has needed a good client-side validation framework for quite some time. I also like the Ext integration as most JSF date pickers are hideous. Well done gents.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/how_popular_is_your_web</guid>
    <title>How popular is your web framework?</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/how_popular_is_your_web</link>
        <pubDate>Fri, 13 Jul 2007 11:43:29 -0600</pubDate>
    <category>Java</category>
    <category>struts</category>
    <category>webframeworks</category>
    <category>hibernate</category>
    <category>myfaces</category>
    <category>spring</category>
    <category>tapestry</category>
    <category>wicket</category>
    <category>jsf</category>
            <description>From the &lt;a href=&quot;http://www.nabble.com/-ANN--Struts-Downloads-Skyrocket-in-2007-tf4044764.html&quot;&gt;Struts user mailing list&lt;/a&gt;:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Since its release in June 2001, &lt;a href=&quot;http://struts.apache.org&quot;&gt;Apache Struts&lt;/a&gt; has become the most popular web framework for
Java. Six years later, by any objective measure, Struts is still Java&apos;s most popular web framework.
&lt;br/&gt;&lt;br/&gt;
In February and March 2007, the group released both Struts 1.3.8 and
Struts 2.0.6 to the general public, and Struts downloads zoomed to
over &lt;a href=&quot;http://people.apache.org/~vgritsenko/stats/projects/struts#Downloads-N1008F&quot;&gt;340,000 a month&lt;/a&gt; from the Apache site alone. And this is just
the tip of the iceberg. Most copies of Struts are downloaded from an
network of mirrors or obtained from Maven repositories.
&lt;/p&gt;
&lt;p&gt;So how popular is Struts compared to the other heavy hitters like Spring and Hibernate? Spring has about 1/2 as many (80K) &lt;a href=&quot;http://tinyurl.com/2gz7ql&quot;&gt;downloads in the same period&lt;/a&gt; and &lt;a href=&quot;http://tinyurl.com/28n988&quot;&gt;so does Hibernate&lt;/a&gt;. How do MyFaces, Wicket and Tapestry stack up? Here&apos;s their best download numbers in the past few months:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://people.apache.org/~vgritsenko/stats/projects/myfaces#Downloads-N1008F&quot;&gt;MyFaces&lt;/a&gt;: ~12K (and that&apos;s only because of a rate 3-times-normal spike)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://people.apache.org/~vgritsenko/stats/projects/tapestry#Downloads-N1008F&quot;&gt;Tapestry&lt;/a&gt;: ~12K&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tinyurl.com/yte94y&quot;&gt;Wicket&lt;/a&gt;: ~10K&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;span style=&quot;text-decoration: line-through&quot;&gt;Sorry JSF, you appear to be losing. Badly.&lt;/span&gt; This is an incorrect statement as pointed out by commentors. Thanks for keeping me honest guys. &lt;br/&gt;&lt;br/&gt;
Disclaimer: Yes, I realize that these statistics are not very accurate, especially considering Maven. Unfortunately, until Maven has repository download stats, this information is the best we&apos;ve got.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/live_coding_for_4_days</guid>
    <title>Live Coding for 4 Days Straight</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/live_coding_for_4_days</link>
        <pubDate>Thu, 24 May 2007 13:50:30 -0600</pubDate>
    <category>Java</category>
    <category>java</category>
    <category>spring</category>
    <category>selenium</category>
    <category>maven</category>
    <category>dbunit</category>
    <category>ant</category>
            <description>Last week I had an interesting 4-day consulting gig for a client in Boulder.  I was supposed to fly out to Connecticut to deliver a training course, but it got rescheduled due to the 45-day Vendor Approval Process I need to go through. The client in Boulder wanted me to come out and do an architectural assessment and provide recommendations. Topics they were interested in: web tier (specifically Spring MVC), Security, Ajax integration, build process, web services and localization. I&apos;ve done this kind of before with Virtuas, but this time was different. With Virtuas, I&apos;d do 5-days worth of presentations on just about anything the customer wanted. For example, checkout &lt;a href=&quot;http://static.raibledesigns.com/repository/text/JavaWebTechnologiesAgenda.pdf&quot;&gt;this agenda&lt;/a&gt; for a client in NY last year.
&lt;br/&gt;&lt;br/&gt;
With the company in Boulder, I delivered zero presentations. Instead, everything we talked about and coded was hands-on. On Tuesday, we started out by discussing their application and some issues they were having. They&apos;d done a lot of customization to Spring MVC and had managed to eliminate all the XML needed when adding new controllers and views. I spent 3-4 hours that day with 2 of their engineers finalizing and implementing their convention-over-configuration rules. On Wednesday, I helped them implement Acegi Security into their application.  This was interesting because they didn&apos;t have any security mechanism and we had to implement Acegi from scratch and then tie it into their backend (using a custom AuthenticationProvider).  We also integrated i18n so all messages were retrieved from their database.
&lt;br/&gt;&lt;br/&gt;
On Thursday, we configured Ant to run their tests and wrote some tests for their controllers. As part of this process, I showed them how to use jMock and EasyMock and tried to explain the benefits of using Spring IoC (which they still aren&apos;t sold on). On Friday, we integrated Selenium into their build process and wrote a few tests using Selenium&apos;s Java support. In the afternoon, I showed them how they might use Scriptaculous and Prototype to Ajax-enable some features in their application.
&lt;br/&gt;&lt;br/&gt;
Doing all the &quot;live coding&quot; on someone else&apos;s machine (with 5 developer&apos;s watching) was a bit nerve wracking. However, thanks to Cenqua&apos;s &lt;a href=&quot;http://www.cenqua.com/fisheye/&quot;&gt;FishEye&lt;/a&gt; tool, I was able to search &lt;a href=&quot;http://fisheye4.cenqua.com/browse/appfuse&quot;&gt;AppFuse&lt;/a&gt; and &lt;a href=&quot;http://fisheye4.cenqua.com/browse/appfuse-light&quot;&gt;AppFuse Light&apos;s&lt;/a&gt; SVN repositories for code snippets and examples. While I knew how to do much of the stuff we covered, FishEye and Google bailed me out when I didn&apos;t. About halfway through, I realized that I don&apos;t keep a lot of my knowledge in my head. Instead, it&apos;s on this blog, or spread out on the web. I don&apos;t remember URLs anymore, all I remember are keywords. If I&apos;ve read a blog post or article on the web, chances are I can find it again pretty easily with Google. Even though I store a lot of bookmarks in del.icio.us, I didn&apos;t use it all week. Remembering keywords is the new bookmark for me.
&lt;br/&gt;&lt;br/&gt;
The whole week was an interesting exercise in &quot;live coding.&quot; The whole team (6 or so) sat in a conference room all week and VNC&apos;ed into the architect&apos;s box to do the work. We worked in Eclipse and used WTP to deploy/test things on Tomcat. The keyboard was passed around between developers at random and everyone got a chance to implement new features. I think the reason that everything worked so well was because the team was full of Senior Java Developers. Everyone learned from each other as they saw new shortcuts, keystrokes and ways or writing code. I don&apos;t know if this kind of thing will work in all development teams, but I&apos;d encourage you to try it. It&apos;s a great way to share knowledge and educate the entire team on how a new module works.
&lt;br/&gt;&lt;br/&gt;
Over the weekend, I received the following e-mail from one of the developers on the team:&lt;/p&gt;
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Very nice to meet you this past week and get a chance to see firsthand the breadth and depth of your experience in web app frameworks and such. I believe due to your visit, we will be cranking happily along here very shortly. Everyone was quite happy with the results at the end of the day yesterday.
&lt;/p&gt;
&lt;p&gt;
On a related note, if you&apos;re looking to hire an enthusiastic Web + Java Developer, please take a look at &lt;a href=&quot;http://raibledesigns.com/resume.jsp&quot;&gt;my resume&lt;/a&gt; or &lt;a href=&quot;http://raibledesigns.com/contact.jsp&quot;&gt;send me an e-mail&lt;/a&gt;. My current contract ends this month and I&apos;m hoping to find something new to get me through the summer.</description>          </item>
    <item>
    <guid isPermaLink="true">https://raibledesigns.com/rd/entry/appfuse_2_0_m5_released</guid>
    <title>AppFuse 2.0 M5 Released - now with CRUD generation and XFire support</title>
    <dc:creator>Matt Raible</dc:creator>
    <link>https://raibledesigns.com/rd/entry/appfuse_2_0_m5_released</link>
        <pubDate>Wed, 23 May 2007 17:49:10 -0600</pubDate>
    <category>Java</category>
    <category>jsf</category>
    <category>struts2</category>
    <category>maven2</category>
    <category>spring</category>
    <category>hibernate</category>
    <category>appfuse</category>
    <category>struts</category>
    <category>springmvc</category>
    <category>tapestry</category>
            <description>&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//appfuse.dev.java.net/images/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.0 M5! 
This release marks a milestone in the features of AppFuse 2.x. This release adds CRUD code generation, full source support (just like 1.x) and XFire integration. In addition, we&apos;ve fixed all the issues related to switching persistence frameworks, and you should now be able to easily switch from using Hibernate to to iBATIS or JPA. The &lt;a href=&quot;http://appfuse.org/display/APF/Demos+and+Videos&quot; title=&quot;Demos and Videos&quot;&gt;videos&lt;/a&gt; have been updated for M5. The &lt;a href=&quot;http://static.appfuse.org/movies/2.0/struts2-crud.mov&quot; title=&quot;14.2 MB, 6 minutes 6 seconds&quot;&gt;Easy CRUD with Struts 2 video&lt;/a&gt; shows how code generation currently works.&lt;/p&gt;

&lt;p&gt;AppFuse 2.0 is available as a Maven archetype. For information on creating a new project using this release, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; title=&quot;AppFuse QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; or the &lt;a href=&quot;http://static.appfuse.org/movies/2.0/helloworld.mov&quot; title=&quot;13.2 MB, 6 minutes 14 seconds&quot;&gt;Hello World video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you&apos;ve used AppFuse 1.x, but not 2.x, you&apos;ll want to read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot; title=&quot;FAQ&quot;&gt;FAQ&lt;/a&gt; and join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot; title=&quot;Mailing Lists&quot;&gt;user mailing list&lt;/a&gt; if you have any questions. The &lt;a href=&quot;http://appfuse.org/display/APF/Maven+2&quot; title=&quot;Maven 2&quot;&gt;Maven Reference Guide&lt;/a&gt; has a map of &lt;a href=&quot;http://appfuse.org/display/APF/Maven+2#Maven2-Antvs.Maven&quot;&gt;Ant &amp;raquo; Maven commands&lt;/a&gt;. &lt;a href=&quot;http://appfuse.org/display/APF/Maven+for+Newbies&quot; title=&quot;Maven for Newbies&quot;&gt;Maven for Newbies&lt;/a&gt; might also be useful if you&apos;ve never used Maven before. There is &lt;a href=&quot;http://appfuse.org/display/APF/FAQ#FAQ-usingant&quot;&gt;some support for Ant&lt;/a&gt; in this release.&lt;/p&gt;

&lt;p&gt;For more information, please see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.0+M5&quot; title=&quot;Release Notes 2.0 M5&quot;&gt;2.0 M5 Release Notes&lt;/a&gt;. If you&apos;d like to use AppFuse offline (or download everything at once), you may want to &lt;a href=&quot;https://appfuse.dev.java.net/servlets/ProjectDocumentList?folderID=7516&quot;&gt;grab the dependencies&lt;/a&gt; and extract them into your ~/.m2/repository directory.&lt;/p&gt;

&lt;p&gt;The 2.0 series of AppFuse has a minumum requirement of the following specification versions:&lt;/p&gt;

&lt;ul class=&quot;glassList&quot;&gt;
	&lt;li&gt;Java Servlet 2.4 and JavaServer Pages (JSP) 2.0&lt;/li&gt;
	&lt;li&gt;Java 5 for Development (Java 1.4 for deployment using the &lt;a href=&quot;http://mojo.codehaus.org/retrotranslator-maven-plugin/examples/project-translation.html&quot;&gt;Retrotranslator Plugin&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p class=&quot;smokey&quot;&gt;
Comments and issues should be posted to the &lt;a href=&quot;http://www.nabble.com/-ANN--AppFuse-2.0-M5-Released%21-tf3807216s2369.html&quot;&gt;mailing list&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We appreciate the time and effort everyone has put toward contributing code and documentation, posting to the mailing lists, and logging issues. We also 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://cenqua.com/&quot;&gt;Cenqua&lt;/a&gt;, &lt;a href=&quot;http://contegix.com/&quot;&gt;Contegix&lt;/a&gt;, &lt;a href=&quot;http://www.jetbrains.com/&quot;&gt;JetBrains&lt;/a&gt;, &lt;a href=&quot;http://www.java.net&quot;&gt;Java.net&lt;/a&gt; and &lt;a href=&quot;http://kgbinternet.com/&quot;&gt;KGBInternet&lt;/a&gt;.  Without them, working on this project wouldn&apos;t be nearly as much fun.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; The videos are much lower quality than the ones I originally recorded (13 MB vs. 70 MB). If you want to view the high quality videos (they&apos;re much clearer), you can &lt;a href=&quot;https://appfuse.dev.java.net/files/documents/1397/58384/appfuse-2.0-videos.zip&quot;&gt;download them from java.net&lt;/a&gt;. If someone has a better way to compress these (I just used QuickTime&apos;s Export feature), please let me know.&lt;/p&gt;
&lt;p&gt;Also, this release contains the first release of the &lt;a href=&quot;http://static.appfuse.org/plugins/appfuse-maven-plugin&quot;&gt;AppFuse Maven Plugin&lt;/a&gt;. This plugin is largely based on &lt;a href=&quot;http://tools.hibernate.org&quot;&gt;Hibernate Tools&lt;/a&gt;. We modified many of the FreeMarker templates from Hibernate Tools to default to certain annotations, as well as clean up the formatting. These templates are currently available in &lt;a href=&quot;http://fisheye4.cenqua.com/browse/appfuse/trunk/plugins/appfuse-maven-plugin/src/main/resources/appfuse/model&quot;&gt;AppFuse&apos;s SVN&lt;/a&gt;. Hopefully making them available is enough to satisfy Hibernate&apos;s LGPL license.</description>          </item>
  </channel>
</rss>