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

    <title type="html">Search for [jsf] in weblog rd</title>
    <subtitle type="html">Search results for [jsf] within weblog Raible Designs</subtitle>
    <id>https://raibledesigns.com/rd/feed/entries/atom?q=jsf&amp;cat=%2FJava</id>

    <link rel="self" type="application/atom+xml" 
        href="https://raibledesigns.com/rd/feed/entries/atom?q=jsf&amp;cat=%2FJava" />

    <link rel="alternate" type="text/html" 
        href="https://raibledesigns.com/rd/search?q=jsf&amp;cat=%2FJava" />

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

    <link rel="first" type="application/atom+xml" href="https://raibledesigns.com/rd/feed/entries/atom?q=jsf&amp;cat=%2FJava" />
    <link rel="next" type="application/atom+xml" href="https://raibledesigns.com/rd/feed/entries/atom?q=jsf&amp;cat=%2FJava&amp;page=1" />
    <updated>2026-05-19T22:36:52-06:00</updated>
    <generator uri="http://roller.apache.org" version="5.0.3 (1388864191739:dave)">Apache Roller</generator>

        <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_reduced</id>
        <title type="html">AppFuse, Reduced</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_reduced"/>
        <published>2014-12-16T06:03:31-07:00</published>
        <updated>2014-12-17T16:39:14-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maintenance" scheme="http://roller.apache.org/ns/tags/" />
        <category term="lessxml" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
In November, I had some time off between clients. To occupy my time, I exercised my body and brain a bit. I spent a couple hours a day exercising and a few hours a day working on
&lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. AppFuse isn&apos;t used to start projects nearly as much as it once was. This makes sense since there&apos;s been a ton of innovation on the JVM and there&apos;s lots of
&lt;em&gt;get-started-quickly&lt;/em&gt; frameworks now. Among my favorites are Spring Boot, JHipster, Grails and Play.
&lt;p&gt;
    You can see that AppFuse&apos;s community activity has decreased quite a bit over the years by looking at its mailing list
    traffic.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://appfuse.markmail.org/&quot;
       title=&quot;AppFuse Mailing List Traffic, December 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7525/15825430580_0531875e59.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Mailing List Traffic, December 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Even though there&apos;s not a lot of users talking on the mailing list, it still seems to get quite a few downloads from
    Maven Central.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://www.flickr.com/photos/mraible/16011987392&quot;
       title=&quot;AppFuse Maven Central Stats, November 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7534/16011987392_442236433b.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Maven Central Stats, November 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    I think the biggest value that AppFuse provides now is a learning tool for those who work on it. Also, it&apos;s a good place to
    show other developers how they can evolve with open source frameworks (e.g. Spring, Hibernate, JSF, Tapestry, Struts) over several years. Showing how
    we migrated to Spring MVC Test, for example, might be useful. The upcoming move to Spring Data instead of our
    Generic DAO solution might be interesting as well. 
&lt;/p&gt;
&lt;p&gt;
    Regardless of whether AppFuse is used a lot or not, it should be easy to maintain. Over the several weeks, I made some
    opinionated changes and achieved some pretty good progress on simplifying things and making the project easier to
    maintain. The previous structure has a lot of duplicate versions, properties and plugin configurations between
    different projects. I was able to leverage Maven&apos;s inheritance model to make a number of improvements:
&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;
In November, I had some time off between clients. To occupy my time, I exercised my body and brain a bit. I spent a couple hours a day exercising and a few hours a day working on
&lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. AppFuse isn&apos;t used to start projects nearly as much as it once was. This makes sense since there&apos;s been a ton of innovation on the JVM and there&apos;s lots of
&lt;em&gt;get-started-quickly&lt;/em&gt; frameworks now. Among my favorites are Spring Boot, JHipster, Grails and Play.
&lt;p&gt;
    You can see that AppFuse&apos;s community activity has decreased quite a bit over the years by looking at its mailing list
    traffic.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;http://appfuse.markmail.org/&quot;
       title=&quot;AppFuse Mailing List Traffic, December 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7525/15825430580_0531875e59.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Mailing List Traffic, December 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    Even though there&apos;s not a lot of users talking on the mailing list, it still seems to get quite a few downloads from
    Maven Central.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
    &lt;a href=&quot;https://www.flickr.com/photos/mraible/16011987392&quot;
       title=&quot;AppFuse Maven Central Stats, November 2014 by Matt Raible, on Flickr&quot;&gt;&lt;img
        src=&quot;https://farm8.staticflickr.com/7534/16011987392_442236433b.jpg&quot; width=&quot;500&quot; 
        alt=&quot;AppFuse Maven Central Stats, November 2014&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
    I think the biggest value that AppFuse provides now is a learning tool for those who work on it. Also, it&apos;s a good place to
    show other developers how they can evolve with open source frameworks (e.g. Spring, Hibernate, JSF, Tapestry, Struts) over several years. Showing how
    we migrated to Spring MVC Test, for example, might be useful. The upcoming move to Spring Data instead of our
    Generic DAO solution might be interesting as well. 
&lt;/p&gt;
&lt;p&gt;
    Regardless of whether AppFuse is used a lot or not, it should be easy to maintain. Over the several weeks, I made some
    opinionated changes and achieved some pretty good progress on simplifying things and making the project easier to
    maintain. The previous structure has a lot of duplicate versions, properties and plugin configurations between
    different projects. I was able to leverage Maven&apos;s inheritance model to make a number of improvements:
&lt;/p&gt;
&lt;ol&gt;
    &lt;li&gt;Changed AppFuse&apos;s parent to be based on the &lt;a
        href=&quot;http://www.infoq.com/news/2014/07/springio-platform&quot;&gt;Spring IO Platform&lt;/a&gt;. This project
        is a dependency manager that defines version numbers for open source projects that work well with Spring.
    &lt;/li&gt;
    &lt;li&gt;Defined plugins, their versions and configurations in &lt;code&gt;&amp;lt;pluginManagement&gt;&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Defined dependencies, their versions and exclusions in &lt;code&gt;&amp;lt;dependencyManagement&gt;&lt;/code&gt;.&lt;/li&gt;
    &lt;li&gt;Simplified archetypes so new projects have minimal dependencies. For example, here&apos;s a basic project&apos;s &lt;code&gt;pom.xml&lt;/code&gt;:
    &lt;/li&gt;
&lt;/ol&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;
&amp;lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
         xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&amp;gt;

    &amp;lt;modelVersion&amp;gt;4.0.0&amp;lt;/modelVersion&amp;gt;
    &amp;lt;groupId&amp;gt;com.company&amp;lt;/groupId&amp;gt;
    &amp;lt;artifactId&amp;gt;springmvc-project&amp;lt;/artifactId&amp;gt;
    &amp;lt;packaging&amp;gt;war&amp;lt;/packaging&amp;gt;
    &amp;lt;version&amp;gt;1.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;name&amp;gt;AppFuse Spring MVC Application&amp;lt;/name&amp;gt;

    &amp;lt;parent&amp;gt;
        &amp;lt;groupId&amp;gt;org.appfuse&amp;lt;/groupId&amp;gt;
        &amp;lt;artifactId&amp;gt;appfuse-web&amp;lt;/artifactId&amp;gt;
        &amp;lt;version&amp;gt;3.5.0-SNAPSHOT&amp;lt;/version&amp;gt;
    &amp;lt;/parent&amp;gt;

    &amp;lt;build&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;de.juplo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;hibernate4-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;dbunit-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;build-helper-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/build&amp;gt;

    &amp;lt;dependencies&amp;gt;
        &amp;lt;dependency&amp;gt;
            &amp;lt;groupId&amp;gt;org.appfuse&amp;lt;/groupId&amp;gt;
            &amp;lt;artifactId&amp;gt;appfuse-${web.framework}&amp;lt;/artifactId&amp;gt;
            &amp;lt;version&amp;gt;${appfuse.version}&amp;lt;/version&amp;gt;
            &amp;lt;type&amp;gt;pom&amp;lt;/type&amp;gt;
        &amp;lt;/dependency&amp;gt;
    &amp;lt;/dependencies&amp;gt;

    &amp;lt;properties&amp;gt;
        &amp;lt;amp.genericCore&amp;gt;true&amp;lt;/amp.genericCore&amp;gt;
        &amp;lt;amp.fullSource&amp;gt;false&amp;lt;/amp.fullSource&amp;gt;
        &amp;lt;dao.framework&amp;gt;hibernate&amp;lt;/dao.framework&amp;gt;
        &amp;lt;db.name&amp;gt;mydatabase&amp;lt;/db.name&amp;gt;
        &amp;lt;web.framework&amp;gt;spring&amp;lt;/web.framework&amp;gt;

        &amp;lt;!-- Framework/Plugin versions --&amp;gt;
        &amp;lt;appfuse.version&amp;gt;3.5.0-SNAPSHOT&amp;lt;/appfuse.version&amp;gt;
        &amp;lt;java.version&amp;gt;1.7&amp;lt;/java.version&amp;gt;
    &amp;lt;/properties&amp;gt;

    &amp;lt;profiles&amp;gt;
        &amp;lt;profile&amp;gt;
            &amp;lt;id&amp;gt;itest&amp;lt;/id&amp;gt;
            &amp;lt;build&amp;gt;
                &amp;lt;plugins&amp;gt;
                    &amp;lt;plugin&amp;gt;
                        &amp;lt;groupId&amp;gt;org.codehaus.cargo&amp;lt;/groupId&amp;gt;
                        &amp;lt;artifactId&amp;gt;cargo-maven2-plugin&amp;lt;/artifactId&amp;gt;
                    &amp;lt;/plugin&amp;gt;
                    &amp;lt;plugin&amp;gt;
                        &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                        &amp;lt;artifactId&amp;gt;webtest-maven-plugin&amp;lt;/artifactId&amp;gt;
                    &amp;lt;/plugin&amp;gt;
                &amp;lt;/plugins&amp;gt;
            &amp;lt;/build&amp;gt;
        &amp;lt;/profile&amp;gt;
    &amp;lt;/profiles&amp;gt;

    &amp;lt;reporting&amp;gt;
        &amp;lt;plugins&amp;gt;
            &amp;lt;plugin&amp;gt;
                &amp;lt;groupId&amp;gt;org.codehaus.mojo&amp;lt;/groupId&amp;gt;
                &amp;lt;artifactId&amp;gt;webtest-maven-plugin&amp;lt;/artifactId&amp;gt;
            &amp;lt;/plugin&amp;gt;
        &amp;lt;/plugins&amp;gt;
    &amp;lt;/reporting&amp;gt;
&amp;lt;/project&amp;gt;
&lt;/pre&gt;
&lt;style type=&quot;text/css&quot;&gt;
    span.diffstat {
        white-space: nowrap;
        text-align: right;
        font-family: Helvetica, arial, freesans, clean, sans-serif, &quot;Segoe UI Emoji&quot;, &quot;Segoe UI Symbol&quot;;
        color: #666;
        font-weight: bold;
        font-size: 12px;
        cursor: default;
    }

    span.diffstat .lines-added, span.diffstat .lines-deleted {
        display: inline-block;
        margin-left: 3px;
        font-weight: bold;
    }
&lt;/style&gt;
&lt;p&gt;
    The pull request for these changes says it all:
&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/appfuse/appfuse/pull/20&quot;&gt;AppFuse&lt;/a&gt; &lt;span class=&quot;diffstat&quot;&gt;
          &lt;span class=&quot;lines-added&quot; style=&quot;color: #55a532&quot;&gt;
            &lt;span class=&quot;diffstat-icon&quot;&gt;+&lt;/span&gt;4,822
          &lt;/span&gt;
          &lt;span class=&quot;lines-deleted&quot; style=&quot;color: #bd2c00&quot;&gt;
            &lt;span class=&quot;diffstat-icon&quot;&gt;-&lt;/span&gt;14,369
          &lt;/span&gt;
        &lt;/span&gt;&lt;/li&gt;
    &lt;li&gt;&lt;a href=&quot;https://github.com/appfuse/appfuse-light/pull/1&quot;&gt;AppFuse Light&lt;/a&gt; &lt;span class=&quot;diffstat&quot;&gt;
              &lt;span class=&quot;lines-added&quot; style=&quot;color: #55a532&quot;&gt;
                &lt;span class=&quot;diffstat-icon&quot;&gt;+&lt;/span&gt;776
              &lt;/span&gt;
              &lt;span class=&quot;lines-deleted&quot; style=&quot;color: #bd2c00&quot;&gt;
                &lt;span class=&quot;diffstat-icon&quot;&gt;-&lt;/span&gt;4,687
              &lt;/span&gt;

            &lt;/span&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That&apos;s right, I was able to eliminate a good chunk of code without affecting any of AppFuse&apos;s functionality&lt;sup&gt;&lt;a
    href=&quot;http://raibledesigns.com/rd/entry/appfuse_reduced#footnote1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.
    I think we can all agree that less code == easier maintenance. This theme will continue as we work on future
    releases.
&lt;/p&gt;

&lt;p&gt;Other improvements include migrating all tests to use JUnit4, integrating Spring MVC Test, and configuring the
    surefire plugin to run tests in parallel. I also The &lt;a href=&quot;http://mojo.codehaus.org/build-helper-maven-plugin/&quot;&gt;build-helper-maven-plugin&lt;/a&gt;
    is now used to find open ports for Cargo to run and a lot of testing was done to ensure you can build/test multiple
    AppFuse-derived projects at the same time. Finally, I migrated to the &lt;a href=&quot;http://juplo.de/hibernate4-maven-plugin/&quot;&gt;hibernate4-maven-plugin&lt;/a&gt; and upgraded to Tapestry 5.4.&lt;/p&gt;

&lt;p&gt;In the next version of AppFuse, I plan to remove as
    much XML as possible - moving all of the configuration to Spring&apos;s JavaConfig. We&apos;ll also be moving to Java 8 as a
    minimum. I&apos;m even considering getting rid of all the pom.xml files in favor of another build language that requires
    less code. &lt;/p&gt;
&lt;p&gt;In other words, the upcoming 3.5 release will be the last release that supports Java 7 and uses Spring&apos;s XML for configuration. AppFuse 4.0 will strive for #NoXML.
   &lt;a href=&quot;http://appfuse.org/display/APF/Roadmap&quot;&gt;The project&apos;s roadmap&lt;/a&gt; has more details on additional
    hopes and dreams.&lt;/p&gt;

&lt;p&gt;We&apos;d love to hear your feedback on these change. Do you like the simplification theme? Are you OK with having AppFuse
    as a parent in your projects?
&lt;/p&gt;
&lt;p class=&quot;footnotes&quot; style=&quot;border-top: 1px dotted silver; padding-top: 5px; font-size: .9em&quot;&gt;
    &lt;a name=&quot;footnote1&quot;&gt;&lt;/a&gt;1. For project
    and code stats, see &lt;a href=&quot;https://www.openhub.net/p/appfuse/analyses/latest/languages_summary&quot;&gt;AppFuse on Open
    Hub&lt;/a&gt;.
&lt;/p&gt;
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/comparing_jvm_web_frameworks_at</id>
        <title type="html">Comparing JVM Web Frameworks at vJUG</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/comparing_jvm_web_frameworks_at"/>
        <published>2014-02-06T10:54:17-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="grails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="playframework" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vaadin" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="angularjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;A couple months ago, I was invited to &lt;a href=&quot;http://www.meetup.com/virtualJUG/events/153096902/&quot;&gt;speak at Virtual JUG&lt;/a&gt; - an online-only Java User Group organized by the &lt;a href=&quot;http://zeroturnaround.com/&quot;&gt;ZeroTurnaround&lt;/a&gt; folks. They chose my Comparing JVM Web Frameworks presentation and we agreed I&apos;d speak yesterday morning. They used a combination of Google Hangouts, live streaming on YouTube and IRC to facilitate the meeting. It all went pretty smoothly and produced a comfortable speaking environment. To practice for vJUG, I delivered the same talk on Tuesday night at the &lt;a href=&quot;http://www.meetup.com/DOSUG1/events/155080452/&quot;&gt;Denver Open Source Users Group&lt;/a&gt;.
&lt;p&gt;
The last time I delivered this talk was at &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_france_a_great_conference&quot;&gt;Devoxx France&lt;/a&gt; in March 2013. I didn&apos;t change any of the format this time, keeping with referencing the Paradox of Choice and encouraging people to define constraints to help them make their decision. I did add a few new slides regarding RebelLabs&apos; &lt;a href=&quot;http://zeroturnaround.com/rebellabs/the-curious-coders-java-web-frameworks-comparison-spring-mvc-grails-vaadin-gwt-wicket-play-struts-and-jsf/&quot;&gt;Curious Coder&#8217;s Java Web Frameworks Comparison: Spring MVC, Grails, Vaadin, GWT, Wicket, Play, Struts and JSF&lt;/a&gt; and &lt;a href=&quot;http://zeroturnaround.com/rebellabs/the-2014-decision-makers-guide-to-java-web-frameworks/&quot;&gt;The 2014 Decision Maker&#8217;s Guide to Java Web Frameworks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also updated all the pretty graphs (which may or may not have any significance) with the latest stats from Dice.com, LinkedIn, StackOverflow and respective mailing lists. Significant changes I found compared to one year ago:&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;A couple months ago, I was invited to &lt;a href=&quot;http://www.meetup.com/virtualJUG/events/153096902/&quot;&gt;speak at Virtual JUG&lt;/a&gt; - an online-only Java User Group organized by the &lt;a href=&quot;http://zeroturnaround.com/&quot;&gt;ZeroTurnaround&lt;/a&gt; folks. They chose my Comparing JVM Web Frameworks presentation and we agreed I&apos;d speak yesterday morning. They used a combination of Google Hangouts, live streaming on YouTube and IRC to facilitate the meeting. It all went pretty smoothly and produced a comfortable speaking environment. To practice for vJUG, I delivered the same talk on Tuesday night at the &lt;a href=&quot;http://www.meetup.com/DOSUG1/events/155080452/&quot;&gt;Denver Open Source Users Group&lt;/a&gt;.
&lt;p&gt;
The last time I delivered this talk was at &lt;a href=&quot;http://raibledesigns.com/rd/entry/devoxx_france_a_great_conference&quot;&gt;Devoxx France&lt;/a&gt; in March 2013. I didn&apos;t change any of the format this time, keeping with referencing the Paradox of Choice and encouraging people to define constraints to help them make their decision. I did add a few new slides regarding RebelLabs&apos; &lt;a href=&quot;http://zeroturnaround.com/rebellabs/the-curious-coders-java-web-frameworks-comparison-spring-mvc-grails-vaadin-gwt-wicket-play-struts-and-jsf/&quot;&gt;Curious Coder&#8217;s Java Web Frameworks Comparison: Spring MVC, Grails, Vaadin, GWT, Wicket, Play, Struts and JSF&lt;/a&gt; and &lt;a href=&quot;http://zeroturnaround.com/rebellabs/the-2014-decision-makers-guide-to-java-web-frameworks/&quot;&gt;The 2014 Decision Maker&#8217;s Guide to Java Web Frameworks&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I also updated all the pretty graphs (which may or may not have any significance) with the latest stats from Dice.com, LinkedIn, StackOverflow and respective mailing lists. Significant changes I found compared to one year ago:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Job Listings on Dice.com
&lt;ul&gt;
&lt;li&gt;Play Framework job listings increased almost 4x&lt;/li&gt;
&lt;li&gt;Tapestry jobs are 1/3 of what they were a year ago&lt;/li&gt;
&lt;li&gt;Wicket jobs are 1/2 of what they were a year ago&lt;/li&gt;
&lt;li&gt;JavaScript framework jobs are up quite a bit: Ember.js up ~300%, AngularJS up 900%, Backbone up 160%&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;LinkedIn Skills
&lt;ul&gt;
&lt;li&gt;Rails down ~30%&lt;/li&gt;
&lt;li&gt;Grails up 25%&lt;/li&gt;
&lt;li&gt;Play Framework up 200%&lt;/li&gt;
&lt;li&gt;Spring Roo up 40%&lt;/li&gt;
&lt;li&gt;Ember.js up 300%&lt;/li&gt;
&lt;li&gt;AngularJS up 840%&lt;/li&gt;
&lt;li&gt;Backbone up 200%&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As you can tell from these findings, AngularJS has gained quite a bit of mindshare in the last year. There&apos;s a lot of companies looking for JavaScript skills and quite a few folks have added JavaScript frameworks to their LinkedIn profiles.&lt;/p&gt;
&lt;p&gt;You can &lt;a href=&quot;https://www.youtube.com/watch?v=ygW8fJVlDxQ&quot;&gt;watch the recording on YouTube&lt;/a&gt; or click play in the embedded video below.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;//www.youtube.com/embed/ygW8fJVlDxQ&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;You can also quickly browse the slide deck below, &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Comparing_JVM_Web_Frameworks_February2014.pdf&quot;&gt;download the PDF&lt;/a&gt; or &lt;a href=&quot;http://www.slideshare.net/mraible/comparing-jvm-web-frameworks-february-2014&quot;&gt;view it on SlideShare&lt;/a&gt;.&lt;/li&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//www.slideshare.net/slideshow/embed_code/30861557?rel=0&quot; width=&quot;512&quot; height=&quot;325&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px&quot; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;Thanks to all the folks who attended these talks. And thanks to &lt;a href=&quot;http://twitter.com/dosug&quot;&gt;@dosug&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/virtualjug&quot;&gt;@virtualjug&lt;/a&gt; for giving me the opportunity to speak.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_3_0_released</id>
        <title type="html">AppFuse 3.0 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_3_0_released"/>
        <published>2013-12-23T14:31:15-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="primefaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="bootstrap3" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring4" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;
&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//static.appfuse.org/images/appfuse-icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the release of AppFuse 3.0. This release is AppFuse&apos;s first release as a &lt;a href=&quot;http://raibledesigns.com/rd/entry/happy_10_year_appfuse&quot;&gt;10-year old&lt;/a&gt; and includes a whole slew of improvements.&lt;/p&gt;
&lt;ul&gt;
    &lt;li&gt;Java 7 and Maven 3 are now minimal requirements&lt;/li&gt;
    &lt;li&gt;Replaced MyFaces and Tomahawk with PrimeFaces for JSF&lt;br&gt;
        &lt;ul&gt;
            &lt;li&gt;Removed SiteMesh in favor of JSF&apos;s built-in layout support&lt;/li&gt;
        &lt;/ul&gt;
    &lt;/li&gt;
    &lt;li&gt;Added Wicket support&lt;/li&gt;
    &lt;li&gt;Migrated from jMock to Mockito for tests&lt;/li&gt;
    &lt;li&gt;Integrated wro4j and WebJars&lt;/li&gt;
    &lt;li&gt;Migrated to Bootstrap 3 and defaulted to Bootswatch&apos;s &lt;a href=&quot;http://bootswatch.com/spacelab/&quot;&gt;Spacelab
        theme&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;In addition, this release includes upgrades to all dependencies to bring them up-to-date with their latest
    releases. Most notable are Spring 4, Spring Security 3.2 and Bootstrap 3. For more details on specific changes
    see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+3.0.0&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;

&lt;p class=&quot;quote&quot;&gt;&lt;strong&gt;What is AppFuse?&lt;/strong&gt;&lt;br&gt;

    AppFuse is a full-stack framework for building web applications on the JVM. It was
    originally developed to eliminate the ramp-up time when building new web applications. Over
    the years, it has matured into a very testable and secure system for creating Java-based
    webapps.
&lt;/p&gt;
&lt;p&gt;Demos for this release can be viewed at &lt;a href=&quot;http://demo.appfuse.org/&quot;&gt;http://demo.appfuse.org&lt;/a&gt;. Please see
    the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot; style=&quot;font-weight: bold&quot;&gt;QuickStart Guide&lt;/a&gt; to
    get started with this release. &lt;/p&gt;

&lt;p&gt;If you have questions about AppFuse, please read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot;&gt;FAQ&lt;/a&gt; or join the
    &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;user mailing list&lt;/a&gt;. If you find any
    issues, please report them on the users mailing list. You can also post them to &lt;a href=&quot;http://stackoverflow.com/questions/tagged/appfuse&quot;&gt;Stack Overflow&lt;/a&gt; with the &quot;appfuse&quot; tag.&lt;/p&gt;

&lt;p&gt;Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing
    lists.&lt;/p&gt;

&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;We greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot;&gt;our
    sponsors&lt;/a&gt;, particularly &lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot;&gt;Atlassian&lt;/a&gt;,
    &lt;a href=&quot;http://contegix.com/&quot;&gt;Contegix&lt;/a&gt;, and &lt;a href=&quot;http://www.jetbrains.com/&quot;&gt;JetBrains&lt;/a&gt;.
    Atlassian and Contegix are especially awesome:
    &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_now_powered_by_contegix&quot;&gt;Atlassian has donated licenses to all
        its products and Contegix has donated an entire server&lt;/a&gt; to the AppFuse project. &lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/happy_10_year_appfuse</id>
        <title type="html">Happy 10 Year AppFuse!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/happy_10_year_appfuse"/>
        <published>2013-04-05T08:56:45-06:00</published>
        <updated>2014-05-08T19:47:26-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="anniversary" scheme="http://roller.apache.org/ns/tags/" />
        <category term="10years" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//raw.github.com/appfuse/appfuse/master/www/logo/appfuse_72_transparent.gif&quot; width=&quot;72&quot; height=&quot;72&quot; class=&quot;picture&quot; /&gt;&lt;/a&gt;
10 years ago yesterday, I released the &lt;a href=&quot;http://raibledesigns.com/rd/entry/announce_struts_resume_and_appfuse&quot;&gt;first version of AppFuse&lt;/a&gt;. It started with XDoclet generating ActionForms from POJOs and became very popular for Struts developers that wanted to use Hibernate. The project&apos;s popularity peaked in 2006, as you can see from the mailing list traffic below.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://appfuse.markmail.org&quot; title=&quot;AppFuse Mailing List Traffic&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8251/8621164287_0acb4af5de.jpg&quot; width=&quot;500&quot; height=&quot;162&quot; alt=&quot;AppFuse Mailing List Traffic&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;It&apos;s possible the decrease in traffic is because we re-wrote everything to be based on Maven. It&apos;s also possible it was because of more attractive full-stack frameworks like &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_vs_grails_vs_rails&quot;&gt;Grails and Rails&lt;/a&gt;. However, the real reason is likely that I stopped working on it all the time due to &lt;span style=&quot;text-decoration: line-through&quot;&gt;getting a divorce&lt;/span&gt; &lt;a href=&quot;http://raibledesigns.com/rd/entry/5_years&quot;&gt;becoming an awesome dad&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Below is a timeline of how the project evolved over its first 4 years.&lt;/p&gt;
&lt;p style=&quot;text-align: center; background: white&quot;&gt;
&lt;a href=&quot;http://static.raibledesigns.com/repository/images/appfuse-history.png&quot; rel=&quot;lightbox[appfuse-10yr]&quot; title=&quot;AppFuse History: 2003 - 2007&quot;&gt;&lt;img src=&quot;//static.raibledesigns.com/repository/images/appfuse-history.png&quot; alt=&quot;AppFuse History: 2003 - 2007&quot; width=&quot;500&quot;/&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;AppFuse has been a great project for me to work on and it&apos;s been a large source of my knowledge about Java, Web Frameworks, Spring, Hibernate - as well as build systems like Ant and Maven. We started with CVS, moved to SVN and now we&apos;re &lt;a href=&quot;http://github.com/appfuse&quot;&gt;on GitHub&lt;/a&gt;. We&apos;ve experienced &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven&quot;&gt;migrating from Tapestry 4 to Tapestry 5&lt;/a&gt; (thanks Serge Eby!), upgrading to &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_to_jsf_2&quot;&gt;JSF 2&lt;/a&gt; and enjoyed the backwards compatibility of Spring and Struts 2 throughout the years. We&apos;ve also added REST support, a Web Services archetype and kept up with the latest Spring and Hibernate releases.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://appfuse.org/download/attachments/84/appfuse-history2.png?version=1&amp;amp;modificationDate=1356633078000&quot; rel=&quot;lightbox[appfuse-10yr]&quot; title=&quot;AppFuse History: 2007 - 2013&quot;&gt;&lt;img src=&quot;//appfuse.org/download/attachments/84/appfuse-history2.png?version=1&amp;amp;modificationDate=1356633078000&quot; width=&quot;500&quot; alt=&quot;AppFuse History: 2007 - 2013&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Last year, we &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_2_1_released&quot;&gt;added Bootstrap and jQuery&lt;/a&gt; as foundational front-end frameworks. For our next release, we&apos;re &lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to&quot;&gt;switching to PrimeFaces&lt;/a&gt;, adding Wicket and changing from jMock to Mockito. Most of these changes are already in source control, we just need to polish them up a bit and add &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+Maven+Plugin&quot; title=&quot;AppFuse Maven Plugin&quot;&gt;AMP&lt;/a&gt; support. I hope to release 3.0 &lt;a href=&quot;http://www.flickr.com/photos/mraible/sets/72157633155884796/&quot;&gt;before the bus is done&lt;/a&gt;. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;Thanks to all the enthusiastic users of and contributors to AppFuse over the years. It&apos;s been a great ride! </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/devoxx_france_a_great_conference</id>
        <title type="html">Devoxx France: A Great Conference in a Magnificent City</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/devoxx_france_a_great_conference"/>
        <published>2013-03-29T13:14:30-06:00</published>
        <updated>2014-05-08T19:47:26-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="travel" scheme="http://roller.apache.org/ns/tags/" />
        <category term="paradoxofchoice" scheme="http://roller.apache.org/ns/tags/" />
        <category term="trish" scheme="http://roller.apache.org/ns/tags/" />
        <category term="france" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxxfr" scheme="http://roller.apache.org/ns/tags/" />
        <category term="grails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="play" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxx" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/8614997207/&quot; title=&quot;Red Eiffel flowers by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8386/8614997207_7320dec749_t.jpg&quot; width=&quot;66&quot; height=&quot;100&quot; alt=&quot;Red Eiffel flowers&quot; class=&quot;picture&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

This week, my &lt;a href=&quot;http://mcginityphoto.com&quot;&gt;lovely fianc&#233;&lt;/a&gt; and I traveled to the &lt;a href=&quot;http://en.wikipedia.org/wiki/Paris&quot;&gt;City of Light&lt;/a&gt;. Our journey was designed around some speaking engagements at Devoxx France. Devoxx is one of my favorite conference franchises and Devoxx France has been special to me ever since the Devoxx (Belgium) I spoke at in 2011. 
&lt;/p&gt;
&lt;p&gt;
2011 was the year I spoke about &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_html5_with_play_scala&quot;&gt;my experience with Play, Scala, CoffeeScript and Jade&lt;/a&gt;. I wrote the presentation on my flight over, composed the demo video the night before and made it all happen in the nick of time. Of course, this was after 120 hours of research and preparation, so the presentation composition process had all the data I needed. You can imagine my sense of relief after pulling off that talk and getting an enthusiastic applause from the audience for my efforts. 
&lt;/p&gt;
&lt;p&gt;
One of the first audience questions I received was from &lt;a href=&quot;https://twitter.com/nmartignole&quot;&gt;Nicolas Martignole&lt;/a&gt;, asking if I&apos;d speak at Devoxx France the following year. I whole-heartedly agreed to do it and was excited for the opportunity. It was with great disappointment that I later found out I couldn&apos;t attend Devoxx France in 2012. My client didn&apos;t like me taking so much time off and I agreed to scale my two week vacation back to &lt;a href=&quot;http://raibledesigns.com/rd/entry/cruising_around_the_western_caribbean&quot;&gt;1 week&lt;/a&gt;. This year, I was determined to go, so I submitted some of my favorite talks: Comparing JVM Web Frameworks and The Play vs. Grails Smackdown with &lt;a href=&quot;http://www.jamesward.com/&quot;&gt;James Ward&lt;/a&gt;. I was extremely pleased when they both got accepted.
&lt;/p&gt;
&lt;p&gt;
Side Story: I met Martin Odersky shortly when he sat down next to me for the Java Posse presentation in Belgium in 2011. After shaking his hand and introducing myself, I had to politely ask him to leave because it was Trish&apos;s seat. Talk about awkward; but Martin was very gracious and promptly found a new seat close by.
&lt;/p&gt;
&lt;p id=&quot;comparing-jvm-web-frameworks&quot;&gt;
&lt;a href=&quot;http://en.wikipedia.org/wiki/The_Paradox_of_Choice:_Why_More_Is_Less&quot; title=&quot;The Paradox of Choice&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8102/8600235023_dc4753c0aa_t.jpg&quot; width=&quot;65&quot; height=&quot;100&quot; alt=&quot;The Paradox of Choice&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
&lt;strong&gt;Comparing JVM Web Frameworks&lt;/strong&gt;&lt;br/&gt;
Both talks required a bit of updating. For Comparing JVM Web Frameworks, I started reading &lt;a href=&quot;http://en.wikipedia.org/wiki/The_Paradox_of_Choice:_Why_More_Is_Less&quot;&gt;The Paradox of Choice&lt;/a&gt; and found many parallels to the agony that developers experience with choosing a web framework. I described how I didn&apos;t think good framework decisions were based on the many, many features that frameworks have, but often on pre-defined constraints. There&apos;s those lucky developers that get to choose a Full Stack Framework because they&apos;re doing greenfield development. Then there&apos;s those that want a better &lt;em&gt;Pure&lt;/em&gt; Web Framework that replaces something (e.g. Struts) that&apos;s not satisfying their needs. And lastly, there&apos;s those that&apos;ve found it possible to leverage a &lt;abbr title=&quot;Service Oriented Front End Architecture&quot;&gt;SOFEA&lt;/abbr&gt; and use a JavaScript MVC framework with an API Framework on the backend. I don&apos;t think it makes sense to compare &lt;em&gt;all&lt;/em&gt; web frameworks and I tried to use these pre-defined constraints (language, platform and application type) argument to separate into categories and help make choosing easier. 
&lt;/p&gt;
&lt;p&gt;
I took out the parts of the presentation that&apos;ve pissed people off in the past - particular the JSF bashing by James Gosling, the Rails gushing from Craig McClanahan and the Pros and Cons sections of each framework. I added the &lt;a href=&quot;https://www.flickr.com/photos/mraible/8588701778&quot;&gt;history of web frameworks&lt;/a&gt; and research from &lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;InfoQ&lt;/a&gt; and &lt;a href=&quot;http://devrates.com/project/list?query=%5Bweb+framework%5D&quot;&gt;devrates.com&lt;/a&gt;.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a data-url=&quot;http://www.flickr.com/photos/mraible/8588701778/&quot; href=&quot;https://farm9.staticflickr.com/8529/8588701778_91aeb65377_o.png&quot; title=&quot;History of Web Frameworks 2013&quot; rel=&quot;lightbox[devoxxfr-2013]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8529/8588701778_0fb17b5612.jpg&quot; width=&quot;500&quot; height=&quot;223&quot; alt=&quot;History of Web Frameworks 2013&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The best part of the JVM Web Frameworks talk was the audience&apos;s reaction and enthusiasm. Devoxx always seems to attract passionate developers and Devoxx France was no different. Developers packing the room, clapping after your intro, laughing at your jokes, signifying that they agree with you about JSF. As a speaker, it&apos;s an unbelievable experience.
&lt;/p&gt;
&lt;p&gt;
You can view my Comparing JVM Web Frameworks presentation below or &lt;a href=&quot;http://www.slideshare.net/mraible/comparing-jvm-web-frameworks-devoxx-france-2013&quot;&gt;on Slideshare.net&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/17868398?rel=0&quot; width=&quot;512&quot; height=&quot;325&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; style=&quot;border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px&quot; allowfullscreen webkitallowfullscreen mozallowfullscreen&gt; &lt;/iframe&gt;
&lt;/p&gt;
&lt;p id=&quot;play-vs-grails-smackdown&quot;&gt;&lt;strong&gt;Play Frameworks vs. Grails Smackdown&lt;/strong&gt;&lt;br/&gt;
To prepare for James Ward and my Play vs. Grails Smackdown, we had a number of goals. First of all, we wanted to update our apps to use the latest versions of each framework. I &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_grails_from_2_0&quot;&gt;documented what it took for Grails&lt;/a&gt;, James just &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/6b674e6b8998b0996869cf510dae71a199deec07&quot;&gt;checked in his code&lt;/a&gt; to GitHub. It was interesting to see that Grails 2.0.3 -&gt; 2.2.1 caused a number of issues with testing, while Play 2.0.3 -&gt; Play 2.1.0 required API changes, but nothing for tests. Secondly, we &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/43795059fcd3d321ab93ea14dc149a3c762daf47&quot;&gt;updated all the stats&lt;/a&gt; for our pretty graphs and &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/9654e74e61c03ccd916ee839885503e206339c81&quot;&gt;ran load tests again&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
This is where the fun started. On Tuesday evening, I decided to challenge the notion that Play was twice as fast as Grails. James had proven this with &lt;a href=&quot;http://httpd.apache.org/docs/2.2/programs/ab.html&quot;&gt;Apache Bench&lt;/a&gt; tests. With Play 2.0 and Grails 2.0 (last summer), we clocked Play at 251/requests per second and 198 for Grails. After upgrading each app to the latest releases, we found the numbers to be 233/second for Play and 118 for Grails. 
&lt;/p&gt;
&lt;p&gt;
However, Apache Bench only tests until the first byte is received. Since I&apos;ve done a lot of browser optimizations recently, I fired up &lt;a href=&quot;http://whichloadsfaster.com&quot;&gt;whichloadsfaster.com&lt;/a&gt;, captured a screenshot and &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/5e867a85279d4be0736c4843704646d55e7eacd7&quot;&gt;added it to our presentation&lt;/a&gt;. The next day, James &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/1f15b8c06a5b7b298b111f263f3c26197fbee096&quot;&gt;added a CDN&lt;/a&gt; and a &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/ab532444258f494d40a7126716c6ac7190b80a98&quot;&gt;bunch of caching&lt;/a&gt; to his app and re-ran his AB tests. 
&lt;/p&gt;
&lt;p&gt;
Now he was &lt;em&gt;smoking&lt;/em&gt; Grails, so I &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/ea911b60e17837a6d6b5359e1e616bec43013ddd&quot;&gt;added a CDN&lt;/a&gt; and &lt;a href=&quot;https://github.com/jamesward/happytrails/commit/da776a16ce6ac17eb65d66cb8a206b18a44a6536&quot;&gt;caching&lt;/a&gt; as well. However, the best I could do was just over 1000/requests per second, while he was around 2200/second. When he ran live tests during our talk, Play was around 2800/sec and Grails was around 900.
&lt;/p&gt;
&lt;p&gt;
It was great to see how much better performance we could get with caching and a CDN. The best part is this should be available to most applications, not just these frameworks. By adding a CDN (we used Amazon CloudFront) and caching, we were both able to 10x the performance of our apps. You can find our presentation &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Play_vs_Grails_Smackdown_DevoxxFrance2013/&quot;&gt;here&lt;/a&gt; or view it below.
&lt;/p&gt;

&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//static.raibledesigns.com/repository/presentations/Play_vs_Grails_Smackdown_DevoxxFrance2013/&quot; width=&quot;500&quot; height=&quot;375&quot; frameborder=&quot;0&quot; marginwidth=&quot;0&quot; marginheight=&quot;0&quot; scrolling=&quot;no&quot; allowfullscreen webkitallowfullscreen mozallowfullscreen style=&quot;border:1px solid #CCC;margin-bottom:5px&quot;&gt; &lt;/iframe&gt;
&lt;/p&gt;

&lt;p id=&quot;summary&quot;&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
This was a very enjoyable conference to attend as a speaker. First of all, it was in one of the most beautiful cities in the world, but it&apos;s also a very special place for Trish and I. &lt;a href=&quot;http://raibledesigns.com/rd/entry/our_engaging_trip_to_paris&quot;&gt;We got engaged just outside of Paris in Versailles&lt;/a&gt; after the &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_html5_with_play_scala&quot;&gt;last Devoxx conference&lt;/a&gt; I spoke at. Trish has some &lt;a href=&quot;http://www.mcginityphoto.com/Other/MattandTrishengagementPhotos&quot;&gt;amazing photos&lt;/a&gt; from that trip. Secondly, the Devoxx conference attracts a special kind of developer - one that is passionate about and eager for knowledge. Lastly, speaking with my good friend James, in an exotic city about something we love - that was special. Asking for beers and having them brought to us at the start of our Smackdown. That was magical (thanks Nicolas!). 
&lt;/p&gt;
&lt;p&gt;
To all the Devoxx organizers and crew - well done on a great show!&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/integrating_gwt_into_appfuse</id>
        <title type="html">Integrating GWT into AppFuse</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/integrating_gwt_into_appfuse"/>
        <published>2013-03-07T18:49:28-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;https://developers.google.com/web-toolkit/images/gwt-logo.png&quot;&gt;&lt;img src=&quot;//developers.google.com/web-toolkit/images/gwt-logo.png&quot; class=&quot;picture&quot;  height=&quot;100&quot; width=&quot;100&quot;&gt;&lt;/a&gt;
I&apos;ve been interested in integrating &lt;a href=&quot;https://developers.google.com/web-toolkit/&quot;&gt;GWT&lt;/a&gt; into &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; ever since &lt;a href=&quot;http://raibledesigns.com/rd/entry/gwt_and_appfuse&quot;&gt;I blogged about it 4 years ago&lt;/a&gt;. A few months after that post, I wrote about &lt;a href=&quot;http://raibledesigns.com/rd/entry/enhancing_evite_com_with_gwt&quot;&gt;Enhancing Evite.com with GWT and Grails&lt;/a&gt;. After Evite, I had a gig near Boston where I developed with GXT for the remainder of the year. When all was said and done, I ended up spending a year with GWT and really enjoyed my experience. I haven&apos;t used it much since.&lt;/p&gt;
&lt;p&gt;GWT is &lt;a href=&quot;http://appfuse.org/display/APF/Roadmap&quot;&gt;scheduled to be integrated into AppFuse&lt;/a&gt; in version 4.0. That&apos;s quite a ways off. The good news is you might not have to wait that long, thanks to &lt;a href=&quot;https://github.com/ivangsa&quot;&gt;Iv&#225;n Garc&#237;a Sainz-Aja&lt;/a&gt;. Iv&#225;n let us know about his work a couple weeks ago in an &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Creating-a-new-archetype-td4656359.html&quot;&gt;email to the appfuse-dev&lt;/a&gt; mailing list.&lt;/p&gt;
&lt;div class=&quot;quote&quot;&gt;
&lt;p&gt;
It&apos;s still work in progress but it has already most of AppFuse functionality.. 
&lt;/p&gt;&lt;p&gt;
If you want to give it a try 
&lt;/p&gt;&lt;p&gt;
&lt;a href=&quot;https://github.com/ivangsa/appfuse.git&quot;&gt;https://github.com/ivangsa/appfuse.git&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
the quickest way to have a go would be&lt;/p&gt;
&lt;pre&gt;
web/gwt&gt; mvn -P gwtDebug -Dgwt.inplace=true gwt:compile jetty:run  
&lt;/pre&gt;
&lt;p&gt;
at the moment it still requires this fork of gwt-bootstrap to be compiled first 
&lt;/p&gt;&lt;p&gt;
&lt;a href=&quot;https://github.com/ivangsa/gwt-bootstrap.git&quot;&gt;https://github.com/ivangsa/gwt-bootstrap.git&lt;/a&gt;
&lt;/p&gt;&lt;p&gt;
It needs a lot of testing yet but it&apos;s getting quite there 
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;As you can imagine, I was very excited to hear about Iv&#225;n&apos;s work. So I cloned his repo, built gwt-bootstrap locally and checked it out. Functionality wise, it was great! However, when I dug into the source code, I found a whole lotta code. 
&lt;/p&gt;
&lt;p&gt;
To see how the GWT flavor compared to the other implementations in AppFuse, I &lt;a href=&quot;https://gist.github.com/mraible/5033218&quot;&gt;created a cloc report&lt;/a&gt; on the various web frameworks in AppFuse. I&apos;m sure these reports could be adjusted to be more accurate, but I believe they give a good general overview. I posted some graphs that displays my findings in visual form.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;

&lt;a href=&quot;http://farm9.staticflickr.com/8090/8538497066_be60cb73da_o.png&quot; title=&quot;Lines of Java&quot; rel=&quot;lightbox[appfuse-loc]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8090/8538497066_4f2a6ff71e_m.jpg&quot; width=&quot;240&quot; height=&quot;189&quot; alt=&quot;Lines of Java&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm9.staticflickr.com/8235/8537391497_deaa49c22d_o.png&quot; title=&quot;Number of Files by mraible, on Flickr&quot; rel=&quot;lightbox[appfuse-loc]&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8235/8537391497_3bbafe2383_m.jpg&quot; width=&quot;240&quot; height=&quot;189&quot; alt=&quot;Number of Files&quot; style=&quot;border: 1px solid black; margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;/p&gt;
&lt;p&gt;When I sent this to the mailing list, Ivan &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Creating-a-new-archetype-tt4656359.html#a4656374&quot;&gt;responded that it was a lot of code&lt;/a&gt; and estimated &lt;em&gt;12 new files&lt;/em&gt; would be needed to &lt;abbr title=&quot;Create, Retrieve, Update, Delete&quot;&gt;CRUD&lt;/a&gt; an entity. This sure seems like a lot to me, but he &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/GWT-RESTFull-backend-tt4656418.html&quot;&gt;defended this yesterday&lt;/a&gt; and noted that his implementation follows many of GWT&apos;s latest best 
practices: MVP pattern, Activities and Places, EventBus, Gin and Guice. He also shared a &lt;a href=&quot;https://github.com/ivangsa/appfuse/wiki&quot;&gt;wiki page&lt;/a&gt; with explanations and diagrams of how things work.&lt;/p&gt;
&lt;p&gt;The reason I&apos;m writing this post is to get more feedback on this implementation. First of all, &lt;em&gt;does GWT really require this much code&lt;/em&gt;? Secondly, are there other GWT implementations that reduce a lot of the boilerplate? &lt;a href=&quot;https://code.google.com/p/smartgwt/&quot;&gt;SmartGWT&lt;/a&gt;, &lt;a href=&quot;https://vaadin.com/home&quot;&gt;Vaadin&lt;/a&gt;* and &lt;a href=&quot;http://www.jboss.org/errai&quot;&gt;Errai&lt;/a&gt; come to mind. 
&lt;/p&gt;
&lt;p&gt;If you were starting a new GWT project and using AppFuse, how would &lt;em&gt;you&lt;/em&gt; want it implemented?&lt;/p&gt;
&lt;p style=&quot;font-size: .9em; border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;* Vaadin 7 claims it &lt;a href=&quot;http://www.infoq.com/news/2013/02/vaadin-7&quot;&gt;can be used as a drop-in replacement for GWT&lt;/a&gt;. I tried &lt;a href=&quot;https://gist.github.com/mraible/5113636&quot;&gt;replacing the gwt-servlet and gwt-user dependencies&lt;/a&gt; with Vaadin&apos;s, but it &lt;a href=&quot;https://gist.github.com/mraible/5113607&quot;&gt;didn&apos;t work&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to</id>
        <title type="html">Switching AppFuse from MyFaces to PrimeFaces</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to"/>
        <published>2013-02-06T12:19:34-07:00</published>
        <updated>2013-02-06T18:19:34-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="primefaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">When describing &lt;a href=&quot;http://raibledesigns.com/rd/entry/why_the_bias_against_jsf&quot;&gt;my bias against JSF&lt;/a&gt; back in November, I wrote:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
... there&apos;s a lot of folks praising JSF 2 (and &lt;a href=&quot;http://primefaces.org/&quot;&gt;PrimeFaces&lt;/a&gt; moreso). That&apos;s why I&apos;ll be integrating it (or merging your pull request) into the 2.3 release of AppFuse. Since PrimeFaces contains a Bootstrap theme, I hope this is a pleasant experience and my overall opinion of JSF improves.
&lt;/p&gt;
&lt;p&gt;Shortly after the &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_2_1_released&quot;&gt;AppFuse 2.2.1 release&lt;/a&gt; in December, Gilberto Andrade &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1351&quot;&gt;contributed a sample project&lt;/a&gt; that used &lt;a href=&quot;http://javaserverfaces.java.net/&quot;&gt;Mojarra&lt;/a&gt; (the JSF RI) and &lt;a href=&quot;http://primefaces.org&quot;&gt;PrimeFaces&lt;/a&gt; instead of &lt;a href=&quot;http://myfaces.apache.org/&quot;&gt;MyFaces&lt;/a&gt; and its  &lt;a href=&quot;http://myfaces.apache.org/tomahawk/index.html&quot;&gt;Tomahawk&lt;/a&gt; components. Last week, I spent a few hours integrating Gilberto&apos;s changes into AppFuse&apos;s master branch. You can see all the changes I made (which include a Jetty plugin upgrade and some cleanup) in &lt;a href=&quot;http://source.appfuse.org/cru/CR-3&quot;&gt;this Crucible review&lt;/a&gt;. Feel free to leave comments on ask questions in the review itself.&lt;/p&gt;
&lt;p&gt;
The first thing I noticed when integrating PrimeFaces is you have to add a custom repository in order to get its artifacts via Maven.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;repositories&amp;gt;
    &amp;lt;repository&amp;gt;
        &amp;lt;id&amp;gt;prime-repo&amp;lt;/id&amp;gt;
        &amp;lt;name&amp;gt;Prime Repo&amp;lt;/name&amp;gt;
        &amp;lt;url&amp;gt;http://repository.primefaces.org&amp;lt;/url&amp;gt;
    &amp;lt;/repository&amp;gt;
&amp;lt;/repositories&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This is unfortunate since all of AppFuse&apos;s other dependencies can be found in Maven Central. It means that if you&apos;re using a JSF archetype, the PrimeFaces repo will be checked for artifacts first, causing an unnecessary slowdown in artifact resolution. I hope the PrimeFaces developers fix this soon.&lt;/p&gt;
&lt;p&gt;While integrating these two frameworks, I ran into a number of issues.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#listener&quot;&gt;An IllegalStateException on startup when using &quot;mvn jetty:run&quot;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#button&quot;&gt;Conditionally rendering a button disables its click-ability&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#bootstrap&quot;&gt;The PrimeFaces Bootstrap theme 404s on some images&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#webtest&quot;&gt;Canoo WebTest doesn&apos;t work with fileUpload nor to set checkbox values&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/switching_appfuse_from_myfaces_to#javax.faces.resource&quot;&gt;PrimeFaces resources served up at /javax.faces.resource/* not found&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p id=&quot;listener&quot;&gt;&lt;strong&gt;An IllegalStateException on startup when using &quot;mvn jetty:run&quot;&lt;/strong&gt;&lt;br/&gt;The first issue I encountered was that I was unable to run the app in Jetty. It worked fine in Tomcat but I got the following error in Jetty:
&lt;/p&gt;
&lt;pre&gt;
2013-01-31 22:28:07.683:WARN:/:unavailable
java.lang.IllegalStateException: Application was not properly initialized at startup, could not find Factory: javax.faces.context.FacesContextFactory
at javax.faces.FactoryFinder$FactoryManager.getFactory(FactoryFinder.java:951)
at javax.faces.FactoryFinder.getFactory(FactoryFinder.java:316)
at javax.faces.webapp.FacesServlet.init(FacesServlet.java:302)
at org.eclipse.jetty.servlet.ServletHolder.initServlet(ServletHolder.java:492)
at org.eclipse.jetty.servlet.ServletHolder.doStart(ServletHolder.java:312)
&lt;/pre&gt;
&lt;p&gt;I &lt;a href=&quot;http://stackoverflow.com/questions/7886035/could-not-find-factory-javax-faces-context-facescontextfactory/7889899&quot;&gt;found the fix for this on  Stack Overflow&lt;/a&gt; and added the following listener to my web.xml to solve it.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;listener&amp;gt;
    &amp;lt;listener-class&amp;gt;com.sun.faces.config.ConfigureListener&amp;lt;/listener-class&amp;gt;
&amp;lt;/listener&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;button&quot;&gt;&lt;strong&gt;Conditionally rendering a button disables its click-ability&lt;/strong&gt;&lt;br/&gt;
The next thing I noticed was the Delete button didn&apos;t work when editing a user. It was hidden correctly when adding a user, but clicking on it to delete a user simply refreshes the page. Below is the code I used successfully with MyFaces. For some reason, this doesn&apos;t work with PrimeFaces.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;c:if test=&quot;${not empty userForm.user.id}&quot;&amp;gt;
&amp;lt;h:commandButton value=&quot;#{text&amp;#91;&apos;button.delete&apos;&amp;#93;}&quot; action=&quot;#{userForm.delete}&quot;
    styleClass=&quot;btn&quot; onclick=&quot;return confirmMessage(msgDelConfirm)&quot;/&amp;gt;
&amp;lt;/c:if&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I also tried the following, but no dice. This is currently an &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1366&quot;&gt;open issue&lt;/a&gt;.
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;h:commandButton rendered=&quot;${not empty userForm.user.id}&quot; value=&quot;#{text&amp;#91;&apos;button.delete&apos;&amp;#93;}&quot; 
    action=&quot;#{userForm.delete}&quot; styleClass=&quot;btn&quot; onclick=&quot;return confirmMessage(msgDelConfirm)&quot;/&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;bootstrap&quot;&gt;
&lt;strong&gt;The PrimeFaces Bootstrap theme 404s on some images&lt;/strong&gt;&lt;br/&gt;
After integrating PrimeFaces&apos; Bootstrap theme, the following error shows up in server logs.
&lt;/p&gt;
&lt;pre&gt;
[INFO] [talledLocalContainer] Feb 02, 2013 10:40:25 PM com.sun.faces.application.resource.ResourceHandlerImpl logMissingResource
[WARNING] [talledLocalContainer] WARNING: JSF1064: Unable to find or serve resource, images/ui-bg_highlight-hard_70_000000_1x100.png, from library, primefaces-bootstrap.
&lt;/pre&gt;
&lt;p&gt;This seems to have &lt;a href=&quot;http://forum.primefaces.org/viewtopic.php?f=9&amp;t=19250&amp;start=10&quot;&gt;happened before in previous releases&lt;/a&gt; and is currently an &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1367&quot;&gt;open issue&lt;/a&gt;. 
&lt;/p&gt;
&lt;p id=&quot;webtest&quot;&gt;&lt;strong&gt;Canoo WebTest doesn&apos;t work with fileUpload nor to set checkbox values&lt;/strong&gt;&lt;br/&gt;
We use &lt;a href=&quot;http://webtest.canoo.com/webtest/manual/WebTestHome.html&quot;&gt;Canoo WebTest&lt;/a&gt; to run integration tests on the UI in AppFuse. For some reason, performing file uploads and setting checkbox values works fine with MyFaces/Tomahawk, but not with Mojarra/PrimeFaces. I&apos;m not sure if this is caused by the JSF core or the component library, but it &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1368&quot;&gt;remains an open issue&lt;/a&gt;. For now, I&apos;ve just commented out the parts of tests that used to do this.
&lt;/p&gt;
&lt;p&gt;On a related note, getting the real path of a resource from the ServletContext worked fine before the switch, but results in a null value now.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
String uploadDir = getServletContext().getRealPath(&quot;/resources&quot;) + &quot;/&quot; + request.getRemoteUser() + &quot;/&quot;;
&lt;/pre&gt;
&lt;p id=&quot;javax.faces.resource&quot;&gt;&lt;strong&gt;PrimeFaces resources served up at /javax.faces.resource/* not found&lt;/strong&gt;&lt;br/&gt;While I didn&apos;t have problems with this in AppFuse, I did encounter it in AppFuse Light. I don&apos;t know why there was a difference between the two, but it turned out to be caused by the UrlRewriteFilter and my desire for &lt;a href=&quot;http://raibledesigns.com/rd/entry/extensionless_urls_in_java_web&quot;&gt;extensionless URLs&lt;/a&gt;. The outbound-rule to strip .xhtml from URLs was the culprit. Adding a condition to it solved the problem. Yeah, the condition seems backwards, but it works.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;outbound-rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;condition type=&quot;query-string&quot; operator=&quot;equal&quot;&amp;gt;ln=primefaces&amp;lt;/condition&amp;gt;
    &amp;lt;from&amp;gt;^(.*)\.xhtml(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;false&quot;&amp;gt;$1$2&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p id=&quot;summary&quot;&gt;&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;
The initial switch to Mojarra/PrimeFaces was pretty easy thanks to Gilberto&apos;s sample project. However, the small issues encountered after that turned out to be quite frustrating and you can see that several are still not fixed. I guess it just goes to show that not all web frameworks are perfect. Hopefully we&apos;ll get these minor issues fixed before the next release. In the meantime, you can checkout the updated demos for &lt;a href=&quot;http://demo.appfuse.org/appfuse-jsf&quot;&gt;AppFuse JSF&lt;/a&gt; and &lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-jsf&quot;&gt;AppFuse Light JSF&lt;/a&gt;.
 </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_light_2_2_1</id>
        <title type="html">AppFuse Light 2.2.1 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_light_2_2_1"/>
        <published>2013-01-24T19:43:20-07:00</published>
        <updated>2013-01-25T01:47:18-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse-light" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">In December, the &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; Team &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_2_2_1_released&quot;&gt;released 2.2.1&lt;/a&gt;. Right before that release, I decided to wait on enhancing its &quot;light&quot; modules, a.k.a. &lt;a href=&quot;https://github.com/appfuse/appfuse-light&quot;&gt;AppFuse Light&lt;/a&gt;. I&apos;m glad I did, because it took some effort to get jQuery and Bootstrap integrated, as well as to make it more secure. 
&lt;/p&gt;
&lt;p&gt;
The good news is AppFuse Light 2.2.1 is released and it&apos;s sitting out on the &lt;a href=&quot;http://search.maven.org/#search%7Cga%7C1%7Cappfuse-light&quot;&gt;Central Repository&lt;/a&gt;. This release is a refactoring of all  archetypes to be up-to-date with the AppFuse 2.2.1 release. This means Java 7 compatibility, Servlet 3, Bootstrap/jQuery integration, Tapestry 5.3.6 upgrade and security improvements. I integrated Bootstrap and jQuery using &lt;a href=&quot;http://www.webjars.org/documentation&quot;&gt;WebJars Servlet 3 support&lt;/a&gt; since it was simple and straightforward. 
&lt;/p&gt;
&lt;p&gt;
You can create projects using AppFuse&apos;s light archetypes using a command such as the following:
&lt;/p&gt;
&lt;pre class=&quot;brush: shell&quot;&gt;
mvn archetype:generate -B -DarchetypeGroupId=org.appfuse.archetypes 
  -DarchetypeArtifactId=appfuse-light-spring-freemarker-archetype -DarchetypeVersion=2.2.1 
  -DgroupId=com.mycompany -DartifactId=myproject 
&lt;/pre&gt;
&lt;p&gt;
The list of archetypes is as follows:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;appfuse-light-jsf-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-spring-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-spring-freemarker-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-spring-security-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-stripes-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-struts-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-tapestry-archetype&lt;/li&gt;
&lt;li&gt;appfuse-light-wicket-archetype&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; will help you get setup and demos are available at the following links:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-jsf&quot;&gt;JSF 2 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-spring&quot;&gt;Spring MVC 3 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-spring-freemarker&quot;&gt;Spring MVC 3 + FreeMarker + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-spring-security&quot;&gt;Spring MVC 3 + Spring Security + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-stripes&quot;&gt;Stripes + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-struts&quot;&gt;Struts 2 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-tapestry&quot;&gt;Tapestry 5 + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://demo2.appfuse.org/appfuse-light-wicket&quot;&gt;Wicket + Hibernate&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you have questions about AppFuse, we invite you to ask them on the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;users mailing list&lt;/a&gt; or tweet using #appfuse. &lt;/p&gt;
&lt;p&gt;
For those enjoying &lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Bootstrap&lt;/a&gt; in your apps, I encourage you to check out &lt;a href=&quot;https://wrapbootstrap.com/&quot;&gt;{wrap}bootstrap&lt;/a&gt; and &lt;a href=&quot;http://bootswatch.com/&quot;&gt;Bootswatch&lt;/a&gt;.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/what_s_the_best_way4</id>
        <title type="html">What&apos;s the best way to compare JVM Web Frameworks?</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/what_s_the_best_way4"/>
        <published>2013-01-09T08:29:17-07:00</published>
        <updated>2013-01-14T15:03:01-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="dzone" scheme="http://roller.apache.org/ns/tags/" />
        <category term="infoq" scheme="http://roller.apache.org/ns/tags/" />
        <summary type="html">&lt;p&gt;
I&apos;ve been comparing web frameworks ever since 2004. It was the first time I&apos;d ever proposed a talk for a conference. ApacheCon was in Vegas that year and my buddy Bruce suggested I speak at it. I submitted the talk, &lt;a href=&quot;http://raibledesigns.com/rd/entry/going_to_apachecon&quot;&gt;got accepted&lt;/a&gt; and went to work learning the frameworks I was talking about. At the time, I had a lot of Struts experience and I&apos;d made a good living learning it, consulting on it and blogging about it. However, there was a new kid on the block (Spring MVC) that was garnishing attention and some other frameworks (WebWork and Tapestry) that had a lot of high praise from developers. I was inspired to learn why so many people hated Struts. 
&lt;/p&gt;
&lt;p&gt;
Fast forward 8 years and I&apos;m still comparing web frameworks. Why? Because there still seems to be a large audience that&apos;s interested in the topic. Witness InfoQ&apos;s &lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;Top 20 JVM Web Frameworks&lt;/a&gt;, which was one of their most-read articles for two months in a row. One of the beauties of the Java Community is that it&apos;s very diverse. There&apos;s &lt;em&gt;tons&lt;/em&gt; of folks that are part of this community and, like it or not, several folks that are &lt;em&gt;former&lt;/em&gt; Java Developers. However, these developers still seem to maintain an interest in the community and it&apos;s still one of the largest pools of talent out there. Java is still &lt;a href=&quot;http://redmonk.com/sogrady/2012/02/08/language-rankings-2-2012/&quot;&gt;quite viable&lt;/a&gt; and only seems to be &lt;a href=&quot;http://frankhinkel.blogspot.de/2012/11/java-8-closures-lambda-expressions.html&quot;&gt;getting better with age&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
So the topic of web frameworks on the JVM is still hot, and I still &lt;a href=&quot;http://raibledesigns.com/rd/entry/why_the_bias_against_jsf&quot;&gt;like to write about it&lt;/a&gt;. For those of you still enthusiastic about the topic, you&apos;re in luck. The two best websites for the Java Community, &lt;a href=&quot;http://infoq.com&quot;&gt;InfoQ&lt;/a&gt; and &lt;a href=&quot;http://java.dzone.com&quot;&gt;DZone&lt;/a&gt; (formerly Javalobby) are still very interested in the topic too!&lt;/p&gt;</summary>
        <content type="html">&lt;p&gt;
I&apos;ve been comparing web frameworks ever since 2004. It was the first time I&apos;d ever proposed a talk for a conference. ApacheCon was in Vegas that year and my buddy Bruce suggested I speak at it. I submitted the talk, &lt;a href=&quot;http://raibledesigns.com/rd/entry/going_to_apachecon&quot;&gt;got accepted&lt;/a&gt; and went to work learning the frameworks I was talking about. At the time, I had a lot of Struts experience and I&apos;d made a good living learning it, consulting on it and blogging about it. However, there was a new kid on the block (Spring MVC) that was garnishing attention and some other frameworks (WebWork and Tapestry) that had a lot of high praise from developers. I was inspired to learn why so many people hated Struts.
&lt;/p&gt;
&lt;p&gt;
Fast forward 8 years and I&apos;m still comparing web frameworks. Why? Because there still seems to be a large audience that&apos;s interested in the topic. Witness InfoQ&apos;s &lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;Top 20 JVM Web Frameworks&lt;/a&gt;, which was one of their most-read articles for two months in a row. One of the beauties of the Java Community is that it&apos;s very diverse. There&apos;s &lt;em&gt;tons&lt;/em&gt; of folks that are part of this community and, like it or not, several folks that are &lt;em&gt;former&lt;/em&gt; Java Developers. However, these developers still seem to maintain an interest in the community and it&apos;s still one of the largest pools of talent out there. Java is still &lt;a href=&quot;http://redmonk.com/sogrady/2012/02/08/language-rankings-2-2012/&quot;&gt;quite viable&lt;/a&gt; and only seems to be &lt;a href=&quot;http://frankhinkel.blogspot.de/2012/11/java-8-closures-lambda-expressions.html&quot;&gt;getting better with age&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
So the topic of web frameworks on the JVM is still hot, and I still &lt;a href=&quot;http://raibledesigns.com/rd/entry/why_the_bias_against_jsf&quot;&gt;like to write about it&lt;/a&gt;. For those of you still enthusiastic about the topic, you&apos;re in luck. The two best websites for the Java Community, &lt;a href=&quot;http://infoq.com&quot;&gt;InfoQ&lt;/a&gt; and &lt;a href=&quot;http://java.dzone.com&quot;&gt;DZone&lt;/a&gt; (formerly Javalobby) are still very interested in the topic too!&lt;/p&gt;
&lt;!--p style=&quot;font-style: italic&quot;&gt;Sorry &lt;a href=&quot;http://theserverside.com&quot;&gt;TheServerSide.com&lt;/a&gt;, you were awesome at one time. Remember when Dion was pumping out the good content and there weren&apos;t ads in your face? Those where the days...&lt;/p--&gt; 
&lt;p&gt;
Both sites emailed me in November to get my advice for their research on the subject. InfoQ (specifically Dio Synodinos) was mostly interested in 1) having me analyze &lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;their recently-gathered data&lt;/a&gt;, or 2) helping them create a new version. DZone (specifically Mitch Pronschinske) emailed about doing a similar survey to InfoQ&apos;s, but with more relevant data points (include GWT, specifying Struts 2 vs. Struts 1, etc.).
&lt;/p&gt;
&lt;p&gt;
My response to Mitch at DZone:
&lt;/p&gt;
&lt;div class=&quot;quote&quot;&gt;
&lt;p&gt;
Interestingly enough, the folks at InfoQ contacted me as well as they&apos;re thinking of doing a new survey. One of the things I mentioned to them is it&apos;d be interesting to see what folks are using AND which frameworks they admire. Often, devs don&apos;t get to choose their web framework at work. I wonder if it&apos;d be possible to collaborate with InfoQ to gather data from developers so it&apos;s not being done on two different sites?
&lt;/p&gt;
&lt;p&gt;
I submitted a talk for ApacheCon NA (in February) called Comparing Apache Web Frameworks. When choosing Web Frameworks, I&apos;ve often found it helps to eliminate frameworks and narrow the scope. Obviously, this makes sense for an Apache Conference, but not for all developers. However, I do plan on analyzing each framework based on a limited set of criteria. Here&apos;s what I have so far:
&lt;/p&gt;
&lt;p&gt;
Community, HTML5, REST, Mobile, Performance, Web Performance Optimization
&lt;/p&gt;
&lt;p&gt;
Obviously, community is important for Apache projects, but might not be for the wider audience. It might be good to limit to these 5 criteria, or expand it to 10, but not more. I think it&apos;d be interesting to get the community to rank the various frameworks on these criteria, and also try to find developer&apos;s biases while doing it. For example, I wonder if people would be willing to admit they&apos;re biased for/against certain frameworks and then take that into account as part of gathering the data?&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Unfortunately, ApacheCon denied my submission. This make sense since their &lt;a href=&quot;http://na.apachecon.com/schedule/&quot;&gt;schedule&lt;/a&gt; seems to be concentrating on &lt;a href=&quot;http://httpd.apache.org/&quot;&gt;HTTPD&lt;/a&gt;, &lt;a href=&quot;http://incubator.apache.org/cloudstack/&quot;&gt;Cloud&lt;/a&gt; and &lt;a href=&quot;http://hadoop.apache.org/&quot;&gt;Big Data&lt;/a&gt;.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;
For InfoQ, Dio asked for a list of web frameworks to include. Below is a list we started with, followed by my response.
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Spring MVC&lt;/li&gt;
&lt;li&gt;Play&lt;/li&gt;
&lt;li&gt;Grails&lt;/li&gt;
&lt;li&gt;JSF&lt;/li&gt;
&lt;li&gt;Struts 2&lt;/li&gt;
&lt;li&gt;Wicket&lt;/li&gt;
&lt;li&gt;Lift&lt;/li&gt;
&lt;li&gt;Tapestry 5&lt;/li&gt;
&lt;li&gt;Seam&lt;/li&gt;
&lt;li&gt;JRuby on Rails&lt;/li&gt;
&lt;li&gt;Wicket&lt;/li&gt;
&lt;li&gt;GWT&lt;/li&gt;
&lt;li&gt;Vaadin&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&quot;quote&quot;&gt;
&lt;p&gt;
I would add Stripes, vert.x and maybe something like Apache Click. VRaptor is probably a good one to add too. There&apos;s always a few less-used frameworks that get a lot of complainers if you don&apos;t include them. 
&lt;/p&gt;
&lt;p&gt;
Comparing to your previous list, I don&apos;t think Seam should be in here since they&apos;ve &lt;a href=&quot;http://www.infoq.com/news/2012/04/seam-deltaspike&quot;&gt;split the project into separate bundles&lt;/a&gt; and are no longer developing Seam as a whole. JRuby on Rails is a tough one because if you say Ruby on Rails, you&apos;ll get a ton of responses, but probably not from the Java community. The Ruby community might chime it quite a bit if you can get in touch with them though.
&lt;/p&gt;
&lt;p&gt;
I believe you should include Clojure web frameworks, but I&apos;ve only heard of one of them: Compojure.
&lt;/p&gt;
&lt;p&gt;
SiteMesh, Netty, etc. - remove them.
&lt;/div&gt;
&lt;p&gt;
I also offered my advice on instructions:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
I actually like the two coordinates you used before, importance and adoptability. However, I don&apos;t know that everyone read the instructions this way. Most people didn&apos;t rank all frameworks and I believe that&apos;s part of the point. I only ranked the ones I&apos;d used, but I think it&apos;d be better if people ranked all of them. I also think having these two criteria opens it up to more than just developers. Project/Product Managers and stakeholders that&apos;ve been successful with certain frameworks should be able to vote too.
&lt;/p&gt;
&lt;p&gt;
For DZone, they wanted to include a set of criteria for ranking:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Project maturity, community support, and documentation quality (one criteria)&lt;/li&gt;
&lt;li&gt;UI Features Capability (maybe some are more graphics driven or form driven?)&lt;/li&gt;
&lt;li&gt;Code readability&lt;/li&gt;
&lt;li&gt;Flexibility (maybe this could be broken down into what types of projects the framework can handle) or several criteria that ask if it is &quot;Good for &apos;x&apos; type of project&quot;&lt;/li&gt;
&lt;li&gt;Performance/Speed&lt;/li&gt;
&lt;li&gt;Cross platform support&lt;/li&gt;
&lt;li&gt;Extensibility, Plugins, Community Libraries&lt;/li&gt;
&lt;li&gt;Architecture (this may just be information for later, not an opinion question)&lt;/li&gt;
&lt;li&gt;Web standards support&lt;/li&gt;
&lt;li&gt;REST support (is this something you would just rate a yes or no?  In that case it wouldn&apos;t need to be an opinion question)&lt;/li&gt;
&lt;li&gt;Mobile support&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
My response:&lt;/p&gt;

&lt;div class=&quot;quote&quot;&gt;
    &lt;p&gt;
For web frameworks, I believe the 5 I mentioned (Community, HTML5, REST, Mobile, Performance, Web Performance Optimization) are most important, with Security become more and more of a concern. For web standards support, I&apos;d almost change it to &quot;HTML5&quot; and to see how the various frameworks stack up. I think REST is very important, and I think it&apos;s cool that Struts 2, Spring MVC and Grails all have great support for it. It&apos;d be interesting to see how the component-based frameworks think of having REST support in the framework (vs. external like Jersey, CXF, etc.).
&lt;/p&gt;&lt;p&gt;
Of the list you provided, I don&apos;t know about Code readability or Flexibility. Code readability is kinda like Learnability. One of the nice things about Spring MVC and Grails is that you can learn how they work very quickly. Then you can use that knowledge and don&apos;t have to look things up much. Tapestry and Wicket might be similar for those writing large apps, but I haven&apos;t found that to be as true. The more traditional MVC Frameworks just make more sense to me.
&lt;/p&gt;
&lt;p&gt;
UI Feature Capability is a good one because frameworks with widgets are often popular with developers. Flex, GWT, jQuery UI, Sencha all do this very well.
&lt;/p&gt;
&lt;/div&gt;
&lt;p id=&quot;summary&quot;&gt;
&lt;strong&gt;Summary&lt;/strong&gt;&lt;br/&gt;The reason for this post is to add some transparency to the process of Comparing JVM Web Frameworks. I like to think that I&apos;ve tried to do this in the past (especially with my &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_i_calculated_ratings_for&quot;&gt;reasons for rankings&lt;/a&gt;). Now, we&apos;d like to hear from you, the community that uses these web frameworks. 
&lt;/p&gt;
&lt;p&gt;&lt;em&gt;What&apos;s the best way to compare JVM Web Frameworks?&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;While it&apos;s nice to hear from the generous folks that create and maintain JVM Web Frameworks, we&apos;re mostly interested in hearing from the developers that are using these things on a day-to-day basis. The Blue Collar Developers, if you will. If you could design a JVM Web Framework comparison that answered your questions, how would it look? What questions would it ask? What conclusions would make you happy? Should commercial frameworks like ZK be included?
    &lt;/p&gt;
    &lt;p&gt;Your responses are very greatly appreciated.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_news_liquibase_and_wro4j</id>
        <title type="html">AppFuse News: Liquibase and wro4j Tutorials from J. Garc&#237;a</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_news_liquibase_and_wro4j"/>
        <published>2012-11-30T14:32:47-07:00</published>
        <updated>2012-11-30T20:35:01-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="liquibase" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wro4j" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;p&gt;New committer &lt;a href=&quot;http://www.operatornew.com/&quot;&gt;J. Garc&#237;a&lt;/a&gt; has been doing a lot of work to improve i18n in AppFuse 2.2, as well as our Struts 2 support. In addition, he&apos;s written a couple articles that show
you how to integrate &lt;a href=&quot;http://www.liquibase.org/&quot;&gt;Liquibase&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/p/wro4j/&quot;&gt;wro4j&lt;/a&gt; in your AppFuse applications. Thanks for the
great documentation J!&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://www.operatornew.com/2012/10/adding-web-resource-fingerprinting-to.html&quot;&gt;Adding web resource fingerprinting to AppFuse with
wro4j&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://www.operatornew.com/2012/11/automatic-db-migration-for-java-web.html&quot;&gt;Automatic DB migration for Java web apps with
Liquibase&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The 2.2 release is coming along, and we&apos;re down to &lt;a href=&quot;http://issues.appfuse.org/secure/IssueNavigator.jspa?mode=hide&amp;amp;requestId=10190&quot;&gt;16
open issues&lt;/a&gt;. I&apos;ve updated the &lt;a href=&quot;http://appfuse.org/display/APF/Using+Hibernate&quot;&gt;Hibernate&lt;/a&gt;, &lt;a href=&quot;http://appfuse.org/display/APF/Using+JPA&quot;&gt;JPA&lt;/a&gt;, &lt;a
href=&quot;http://appfuse.org/display/APF/Services&quot;&gt;Services&lt;/a&gt; and &lt;a href=&quot;http://appfuse.org/display/APF/Web+Services&quot;&gt;Web Services&lt;/a&gt; tutorials and hope to finish the web
tutorials in the next week. You can try the latest code using the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; or check it out on the demo
site:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://demo.appfuse.org/appfuse-jsf&quot;&gt;http://demo.appfuse.org/appfuse-jsf&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a
href=&quot;http://demo.appfuse.org/appfuse-spring&quot;&gt;http://demo.appfuse.org/appfuse-spring&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://demo.appfuse.org/appfuse-struts&quot;
class=&quot;external-link&quot;&gt;http://demo.appfuse.org/appfuse-struts&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href=&quot;http://demo.appfuse.org/appfuse-tapestry&quot;
class=&quot;external-link&quot;&gt;http://demo.appfuse.org/appfuse-tapestry&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Please see &lt;a
href=&quot;http://appfuse.547863.n4.nabble.com/AppFuse-2-2-Ready-for-Testing-td4655722.html&quot;&gt;this thread&lt;/a&gt; on the mailing list if you have any questions or suggestions.&lt;/p&gt;&lt;p&gt;In
related news, &lt;a href=&quot;http://www.captaindebug.com/&quot;&gt;Roger Hughes&lt;/a&gt; has a good article titled &lt;a
href=&quot;http://www.captaindebug.com/2012/11/a-list-of-things-you-can-do-with-spring.html&quot;&gt;Ten Things You Can Do With Spring Security&lt;/a&gt;. Since AppFuse uses Spring Security
extensively, hopefully you can use some of Roger&apos;s tips to improve the security of your app.&lt;/p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/why_the_bias_against_jsf</id>
        <title type="html">Why the bias against JSF?</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/why_the_bias_against_jsf"/>
        <published>2012-11-08T09:24:27-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">In my last post about &lt;a href=&quot;http://raibledesigns.com/rd/entry/infoq_s_top_20_web&quot;&gt;InfoQ&apos;s Top 20 Web Frameworks for the JVM&lt;/a&gt;, I received a thought-provoking &lt;a href=&quot;http://raibledesigns.com/rd/entry/infoq_s_top_20_web#comment-1352305197000&quot;&gt;comment&lt;/a&gt; from &lt;a href=&quot;http://henk53.wordpress.com/&quot;&gt;henk53&lt;/a&gt;:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
There is one little thing that does bother me in those presentations, and that&apos;s your fairly obvious bias against JSF. &lt;br/&gt;...&lt;br/&gt;
If you are presenting yourself as, more or less, an authority on comparing web frameworks, then having a fairly obvious biased against one of them is just peculiar. I, all of my team, and various clients distrust your ranking of JSF. We do look at your data if the choice is between other frameworks, but as soon as JSF comes into the picture we just look elsewhere.
&lt;br/&gt;&lt;br/&gt;
I&apos;m not really sure where this bias comes from. Yes, JSF 1.0 sucked and 1.2 was only marginally better, but 2.0 is really cool and productive and there are SUPERB component and utility libraries now like PrimeFaces and OmniFaces. As a researcher of this topic I think you should keep up the date and not stick to some old grudge.
&lt;/p&gt;
&lt;p&gt;This is true, I am biased against JSF. It all started with my &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_jsf_experience&quot;&gt;first JSF experience&lt;/a&gt; back in August 2004. If you remember correctly, 2004 was a big year: JSF 1.0, Spring 1.0 and Flex 1.0 were all released. The &quot;AJAX&quot; term was coined in &lt;a href=&quot;http://www.adaptivepath.com/ideas/ajax-new-approach-web-applications&quot;&gt;early 2005&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/4378559350/&quot; title=&quot;History of Web Frameworks by mraible, on Flickr&quot;&gt;&lt;img src=&quot;//farm5.staticflickr.com/4067/4378559350_13f0755403.jpg&quot; width=&quot;500&quot; height=&quot;234&quot; alt=&quot;History of Web Frameworks&quot; style=&quot;border: 1px solid black&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;By &lt;a href=&quot;http://raibledesigns.com/rd/entry/jsf_still_sucks&quot;&gt;2007&lt;/a&gt; and &lt;a href=&quot;http://raibledesigns.com/rd/entry/what_s_wrong_with_jsf&quot;&gt;2008&lt;/a&gt;, JSF still hadn&apos;t gotten any better. In late 2009, JSF 2.0 was released and &lt;a href=&quot;http://raibledesigns.com/rd/entry/upgrading_to_jsf_2&quot;&gt;I upgraded in March 2011&lt;/a&gt;. As you can see from the aforementioned post, I ran into quite a few issues upgrading. JSF was also the &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_extensionless_urls_with_tapestry&quot;&gt;hardest one to get working with extension-less URLs&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;Most of my issues with JSF come from having maintained an application built with it since 2004. If I were to start a new application without any legacy migration issues, I imagine it wouldn&apos;t be as difficult. However, if you compare it to Struts 2 and Spring MVC, I&apos;ve had little-to-no issues upgrading those applications over the years. &lt;/p&gt;
&lt;p&gt;Also, I&apos;m not just biased against JSF, but most component-based web frameworks. Just ask the Tapestry and Wicket folks. They&apos;ve felt my criticisms over the years. My reason for preferring request-based frameworks like Struts 2/Spring MVC and Grails/Play has been because I&apos;ve never seen the appeal in component-based frameworks. Often I&apos;ve found that their components are just widgets that you can get from any decent JavaScript framework. And chances are that JavaScript framework can work with &lt;em&gt;any&lt;/em&gt; web framework. Also, I&apos;ve worked on a lot of high-traffic web applications that require statelessness for scalability.&lt;/p&gt;
&lt;p&gt;I see the value in component-based frameworks, I just don&apos;t think components should be authored on the server-side. Most of the Java-based component frameworks require 2+ files for components (one for the component, one for the view, possibly one for the config). I love GWT&apos;s component concept in that you can just extract a class and re-use it. With JS frameworks, you can often just include a script. These days, when I think of good component-based frameworks, I think of jQuery UI and Twitter Bootstrap.&lt;/p&gt;
&lt;p&gt;All that being said, there&apos;s a lot of folks praising JSF 2 (and &lt;a href=&quot;http://primefaces.org/&quot;&gt;PrimeFaces&lt;/a&gt; moreso). That&apos;s why I&apos;ll be integrating it (or merging your pull request) into the 2.3 release of AppFuse. Since PrimeFaces contains a Bootstrap theme, I hope this is a pleasant experience and my overall opinion of JSF improves.&lt;/p&gt;
&lt;p&gt;In other component-based frameworks in AppFuse news, Tapestry 5 has gotten &lt;em&gt;really fast&lt;/em&gt; in the last year. I imagine this is because we have a Tapestry expert, &lt;a href=&quot;http://www.linkedin.com/in/sergeeby&quot;&gt;Serge Eby&lt;/a&gt;, working on it. And we&apos;re planning on adding Wicket in the 2.3 release. &lt;/p&gt;
&lt;p&gt;So even though I &lt;em&gt;prefer&lt;/em&gt; request-based frameworks with REST support and Bootstrap, that doesn&apos;t mean everyone does. I&apos;ll do my best to be less-biased in the future. However, please remember that my view on web frameworks is as a developer, not an analyst. And aren&apos;t developers &lt;em&gt;supposed&lt;/em&gt; to be opinionated? &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;)&quot; title=&quot;;)&quot; /&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/infoq_s_top_20_web</id>
        <title type="html">InfoQ&apos;s Top 20 Web Frameworks for the JVM</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/infoq_s_top_20_web"/>
        <published>2012-11-06T12:04:28-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="infoq" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Back in early October, InfoQ.com published a community research article titled &lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;Top 20 Web Frameworks for the JVM&lt;/a&gt;. Their goal seemed to be fairly simple:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Using the new community research tool, we at InfoQ want to get YOUR opinions on the relative importance and maturity of a variety of web frameworks that are targeted for the JVM. Please vote by dragging each practice across two dimensions &#8211; how important is the framework relative to the other frameworks, and how much is it actually used in real teams and projects.
&lt;/p&gt;
&lt;p&gt;When I first saw this article, I noticed some strange web frameworks listed. Namely, Netty, SiteMesh and Spark. I haven&apos;t heard of many folks using &lt;a href=&quot;https://netty.io/&quot;&gt;Netty&lt;/a&gt; for a web framework, but I&apos;m sure it&apos;s possible. SiteMesh is certainly not a web framework and I&apos;ve never even heard of Spark. And where is GWT and Vaadin? Regardless of the choices, I went ahead and voted.&lt;/p&gt;
&lt;p&gt;Last week, InfoQ posted their top content for October on Facebook. &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/research/jvm-web-frameworks&quot;&gt;Top 20 Web Frameworks for the JVM&lt;/a&gt; 25,992 PV&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/news/2012/10/Ruby-on-Rails-Node-js-LinkedIn&quot;&gt;Ruby on Rails vs. Node.js at LinkedIn&lt;/a&gt; 11,904 PV&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/presentations/Mobile-Web-Development&quot;&gt;Mobile Webdev: The Horror&lt;/a&gt; 11,150 PV&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/articles/rest-introduction&quot;&gt;A Brief Introduction to REST&lt;/a&gt; 8,872 PV
&lt;li&gt;&lt;a href=&quot;http://www.infoq.com/minibooks/kanban-scrum-minibook&quot;&gt;Kanban and Scrum - making the most of both&lt;/a&gt; 7,665 PV&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;First of all, it&apos;s interesting to see that JVM Web Frameworks is still a hot topic for developers. Whenever I do my Comparing JVM Web Frameworks talk at conferences, I always see a few jabs about &quot;he&apos;s &lt;em&gt;still&lt;/em&gt; doing that talk!?&quot; Yes, it seems strange that a talk I first did in 2004 is still in high demand. &lt;/p&gt;
&lt;p&gt;Secondly, I think InfoQ does good in showing how the frameworks ranked and showing their &lt;em&gt;heatmaps&lt;/em&gt;. Below are their rankings from 1109 participants. &lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/8161758257/&quot; title=&quot;InfoQ&apos;s Top 20 Web Frameworks for the JVM&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8197/8161758257_ef6d919f5d.jpg&quot; width=&quot;500&quot; height=&quot;395&quot; alt=&quot;InfoQ&apos;s Top 20 Web Frameworks for the JVM&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;According to this research, the top 5 web frameworks for the JVM are Spring MVC, Play, Grails, JSF and Struts (I hope those surveyed meant Struts 2, not Struts 1).&lt;/p&gt;
&lt;p&gt;In &lt;a href=&quot;http://www.slideshare.net/mraible/comparing-jvm-web-frameworks-jfokus-2012&quot;&gt;my research from last February&lt;/a&gt; (slide 21), I ranked them (with no particular weightings) as Grails, GWT, JRuby on Rails, Spring MVC and Vaadin. So I guess you could say I got 2 out of 5 right (Grails and Spring MVC). Not bad considering InfoQ didn&apos;t even consider GWT and Vaadin.&lt;/p&gt;
&lt;p&gt;Another intriguing data point in this study is each frameworks&apos; heatmap. For example, below are heatmaps for the top 4 frameworks. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161758501/&quot; href=&quot;http://farm8.staticflickr.com/7247/8161758501_151b1a839c.jpg&quot; title=&quot;Spring MVC Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7247/8161758501_151b1a839c_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;Spring MVC Heatmap&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161762845/&quot; href=&quot;http://farm8.staticflickr.com/7125/8161762845_12cfdc076c.jpg&quot; title=&quot;Grails Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7125/8161762845_12cfdc076c_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;Grails Heatmap&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161758399/&quot; href=&quot;http://farm8.staticflickr.com/7255/8161758399_505e8cf4db.jpg&quot; title=&quot;Play Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7255/8161758399_505e8cf4db_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;Play Heatmap&quot;&gt;&lt;/a&gt;

&lt;a rev=&quot;http://www.flickr.com/photos/mraible/8161758341/&quot; href=&quot;http://farm8.staticflickr.com/7256/8161758341_7e1d37e1ea.jpg&quot; title=&quot;JSF Heatmap&quot; rel=&quot;lightbox[infotop20webframeworks]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7256/8161758341_7e1d37e1ea_m.jpg&quot; width=&quot;240&quot; height=&quot;215&quot; alt=&quot;JSF Heatmap&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Notice how Grails and Spring MVC are both &lt;em&gt;hotter&lt;/em&gt; in the bottom right corner? It seems the community&apos;s overall opinions of these two frameworks are more aligned than JSF and Play, which a fair amount of folks rank as hyped and unimportant. &lt;/p&gt;
&lt;p&gt;What I really like about this research is it&apos;s the community&apos;s opinions, visualized. It also confirms that some of my favorite frameworks are still on top. I don&apos;t know if JSF belongs as a top framework, however it seems a lot of folks do. I recently &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Drop-JSF-Support-td4655648.html&quot;&gt;thought about removing it from AppFuse&lt;/a&gt;, but decided to keep it (at least for the next release). I hope InfoQ does more research projects like this, especially if they get their list of web frameworks right. </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/comparing_web_frameworks_and_html5</id>
        <title type="html">Comparing Web Frameworks and HTML5 with Play Scala at Jfokus 2012</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/comparing_web_frameworks_and_html5"/>
        <published>2012-02-16T00:01:05-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jfokus" scheme="http://roller.apache.org/ns/tags/" />
        <category term="html5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="scala" scheme="http://roller.apache.org/ns/tags/" />
        <category term="playframework" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/8355301175/&quot; title=&quot;Riddenholm Church by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8330/8355301175_36050ce11c_t.jpg&quot; width=&quot;66&quot; height=&quot;100&quot; alt=&quot;Riddenholm Church&quot; class=&quot;picture&quot;&gt;&lt;/a&gt;
Stockholm seems a lot like Denver this time of year. Cold, snowy and beautiful. &lt;a href=&quot;http://www.mcginityphoto.com/&quot;&gt;Trish&lt;/a&gt; and I arrived in Stockholm (Sweden) on Monday for the &lt;a href=&quot;http://jfokus.se&quot;&gt;Jfokus&lt;/a&gt; conference and we&apos;re traveling to Madrid today for the &lt;a href=&quot;http://springio.net/&quot;&gt;Spring I/O&lt;/a&gt; conference. I was invited to Jfokus within minutes of delivering my &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_html5_with_play_scala&quot;&gt;HTML5 with Play Scala talk at Devoxx&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Both the Jfokus and Spring I/O Organizers were interested in my Comparing JVM Web Frameworks talk, so I updated it to reflect my latest thoughts. First of all, I mentioned that there&apos;s a lot of great frameworks out there and I think the reason people are so apprehensive to choose one is because they&apos;ve chosen badly at one point. This might&apos;ve been Struts back in the day (even thought it was one of the best frameworks at the time) or it might be because a vendor talked them into it. However, if you look at the modern JVM frameworks today, you should be able to see that they&apos;re all pretty awesome.
&lt;/p&gt;
&lt;p&gt;
I mentioned how I think &lt;em&gt;Web&lt;/em&gt; developers should know JavaScript and CSS. If you&apos;re a &lt;em&gt;Java&lt;/em&gt; developer and you call yourself a web developer, you&apos;re letting your framework do too much of the work for you. I mentioned Rich Manalang&apos;s &lt;a href=&quot;http://blogs.atlassian.com/2012/01/modern-principles-in-web-development/&quot;&gt;Modern Principles in Web Development&lt;/a&gt;, where he talks about his core web development principles.
&lt;ul&gt;
&lt;li&gt;Designing for mobile first (even if you&#8217;re not building a mobile app)&lt;/li&gt;
&lt;li&gt;Build only single page apps&lt;/li&gt;
&lt;li&gt;Create and use your own REST API&lt;/li&gt;
&lt;li&gt;&#8220;Sex sells&#8221; applies to web apps&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;ve found these principles to be true in my own experience and suggested that if you want to be a web developer, the frameworks you might want to learn are not traditional JVM web frameworks, but rather &lt;a href=&quot;http://paulhammant.com/2012/02/13/client-side-mvc-frameworks-compared/&quot;&gt;client-side MVC frameworks&lt;/a&gt;. For those Java developers that don&apos;t want to be web developers, I suggest they strengthen their services development knowledge by reading &lt;a href=&quot;http://www.infoq.com/articles/webber-rest-workflow&quot;&gt;Hot to GET a Cup of Coffee&lt;/a&gt;.
&lt;/p&gt;
You can see my updated presentation below, &lt;a href=&quot;http://www.slideshare.net/mraible/comparing-jvm-web-frameworks-jfokus-2012&quot;&gt;on Slideshare&lt;/a&gt; or as a &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/Comparing_JVM_Web_Frameworks_Jfokus2012.pdf&quot;&gt;downloadable PDF&lt;/a&gt;. You can also &lt;a href=&quot;http://www.jfokus.se/jfokus/video.jsp?v=3084&quot;&gt;watch the video&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/11581955?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;/p&gt;
&lt;p&gt;I delivered my 2nd presentation on HTML5 with Play Scala, CoffeeScript and Jade on Wednesday morning. This talk is one of my favorites and I prepared for it over the last several weeks by adding &lt;a href=&quot;http://raibledesigns.com/rd/entry/secure_json_services_with_play&quot;&gt;JSON CRUD Services and SecureSocial&lt;/a&gt; to my HTML5 Fitness Tracking application. Right before we left for Jfokus, I was able to get everything to work, but didn&apos;t spend as much time as I&apos;d like working on the mobile client. If this talk gets accepted for &lt;a href=&quot;http://www.devoxx.com/display/FR12/Accueil&quot;&gt;Devoxx France&lt;/a&gt;, I plan on spending most of my time enhancing the mobile client. After my latest experience developing, I can see how Rich&apos;s first principle (above) makes a lot of sense.
&lt;/p&gt;
&lt;p&gt;Below is my presentation for this talk. Of course, it&apos;s &lt;a href=&quot;http://www.slideshare.net/mraible/html5-with-play-scala-coffeescript-and-jade-jfokus-2012&quot;&gt;on Slideshare&lt;/a&gt; and &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/HTML5_with_Play_Scala_CoffeeScript_and_Jade_Jfokus2012.pdf&quot;&gt;downloadable as a PDF&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/11582395?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;/p&gt;
&lt;p&gt;I also updated the &lt;a href=&quot;http://vimeo.com/36826202&quot;&gt;Developing Play More demo video&lt;/a&gt; to show my latest efforts.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe src=&quot;//player.vimeo.com/video/36826202?title=0&amp;amp;byline=0&amp;amp;portrait=0&quot; width=&quot;510&quot; height=&quot;287&quot; frameborder=&quot;0&quot; webkitAllowFullScreen mozallowfullscreen allowFullScreen&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;Delivering these talks at Jfokus was a lot of fun. Yes, it was a lot of work and stress to prepare them. However, I also learned a lot creating them and I hope the audience benefitted from that. 
&lt;/p&gt;
&lt;p&gt;  
&lt;a href=&quot;http://www.flickr.com/photos/mcginityphoto/8350751579/&quot; title=&quot;Jfokus 2012 by McGinityPhoto, on Flickr&quot;&gt;&lt;img src=&quot;//farm9.staticflickr.com/8371/8350751579_33fe72872a_t.jpg&quot; width=&quot;67&quot; height=&quot;100&quot; alt=&quot;Jfokus 2012&quot; style=&quot;border: 1px solid black; float: left; margin: 0 10px 0 0&quot;&gt;&lt;/a&gt;
The conference itself was incredible. I got to meet &lt;a href=&quot;https://twitter.com/peterhilton&quot;&gt;Peter Hilton&lt;/a&gt; and &lt;a href=&quot;https://twitter.com/javahelena&quot;&gt;Helena Hjert&#233;n&lt;/a&gt; as I was registering.
The speaker&apos;s dinner at &lt;a href=&quot;http://f12.se/&quot;&gt;F12&lt;/a&gt; was off-the-hook good and I had the pleasure of finally meeting &lt;a href=&quot;http://rickardoberg.wordpress.com/&quot;&gt;Rickard &#214;berg&lt;/a&gt;. 

&lt;/p&gt;
&lt;p&gt;I also attended some fantastic presentations, including Peter Hilton&apos;s &lt;a href=&quot;http://raibledesigns.com/rd/entry/play_framework_2_0_with&quot;&gt;Play Framework 2.0&lt;/a&gt;, &lt;a href=&quot;https://twitter.com/bodiltv&quot;&gt;Bodil Stokke&apos;s&lt;/a&gt; &lt;a href=&quot;http://bodil.github.com/coffeescript/#landing-slide&quot;&gt;CoffeeScript: JavaScript without the Fail&lt;/a&gt;, &lt;a href=&quot;http://twitter.com/pamelafox&quot;&gt;Pamela Fox&apos;s&lt;/a&gt; &lt;a href=&quot;http://client-side-storage.appspot.com&quot;&gt;Client-side Storage&lt;/a&gt; and &lt;a href=&quot;http://twitter.com/hseeberger&quot;&gt;Heiko Seeberger&apos;s&lt;/a&gt; Scala in Action. I don&apos;t know if Heiko has published any slides, but I&apos;m guessing not since most of his presentation was live coding. 
&lt;/p&gt;
&lt;p&gt;I have lots of good memories from Jfokus. Many thanks to &lt;a href=&quot;http://twitter.com/matkar&quot;&gt;Mattias&lt;/a&gt; for inviting me!</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/refreshing_appfuse_s_ui_with</id>
        <title type="html">Refreshing AppFuse&apos;s UI with Twitter Bootstrap</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/refreshing_appfuse_s_ui_with"/>
        <published>2012-01-31T17:12:17-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="twitter" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="bootstrap" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ui" scheme="http://roller.apache.org/ns/tags/" />
        <category term="css" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">The last time AppFuse had an update done to its look and feel was in way back in 2006. I&apos;ve done a lot of consulting since then, which has included a fair bit of page speed optimization, HTML5 development and integrating smarter CSS. It was way back in &apos;05 when we first started looking at adding a CSS Framework to AppFuse.  It was Mike Stenhouse&apos;s &lt;a href=&quot;http://www.contentwithstyle.co.uk/content/a-css-framework/&quot;&gt;CSS Framework&lt;/a&gt; that provided the &lt;a href=&quot;http://raibledesigns.com/rd/entry/a_css_framework&quot;&gt;inspiration&lt;/a&gt; and my &lt;a href=&quot;http://raibledesigns.com/rd/entry/css_framework_design_contest_final&quot;&gt;CSS Framework Design Contest&lt;/a&gt; that provided its current themes (&lt;a href=&quot;http://css.appfuse.org/themes/puzzlewithstyle&quot;&gt;puzzlewithstyle&lt;/a&gt;, &lt;a href=&quot;http://css.appfuse.org/themes/andreas01&quot;&gt;andreas01&lt;/a&gt; and &lt;a href=&quot;http://css.appfuse.org/themes/simplicity&quot;&gt;simplicity&lt;/a&gt;).
&lt;/p&gt;
&lt;p&gt;Since then, a lot of CSS Frameworks have been invented, including &lt;a href=&quot;http://www.blueprintcss.org/&quot;&gt;Blueprint&lt;/a&gt; in 2007 and &lt;a href=&quot;http://compass-style.org/&quot;&gt;Compass&lt;/a&gt; in 2008. However, neither has taken the world by storm like &lt;a href=&quot;http://twitter.github.com/bootstrap/&quot;&gt;Twitter Bootstrap&lt;/a&gt;. From &lt;a href=&quot;http://www.alistapart.com/articles/building-twitter-bootstrap/&quot;&gt;Building Twitter Bootstrap&lt;/a&gt;:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
A year-and-a-half ago, a small group of Twitter employees set out to improve our team&#8217;s internal analytical and administrative tools. After some early meetings around this one product, we set out with a higher ambition to create a toolkit for anyone to use within Twitter, and beyond. Thus, we set out to build a system that would help folks like us build new projects on top of it, and Bootstrap was conceived.&lt;br/&gt;
...&lt;br/&gt;
Today, it has grown to include dozens of components and has become the most popular project on GitHub with more than 13,000 watchers and 2,000 forks.&lt;/p&gt;
&lt;p&gt;&lt;p&gt;The fact that Bootstrap has become the most popular project on GitHub says a lot. For &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/AppFuse-next-td3634415.html&quot;&gt;AppFuse.next&lt;/a&gt;, I&apos;d like to integrate a lot of my learnings over the past few years, as well as support HTML5 and modern browsers as best we can. This means &lt;a href=&quot;http://code.google.com/speed/page-speed/docs/rules_intro.html&quot;&gt;page speed optimizations&lt;/a&gt;, getting rid of Prototype and Scriptaculous in favor of jQuery, adding &lt;a href=&quot;http://code.google.com/p/wro4j/&quot;&gt;wro4j&lt;/a&gt; for resource optimization and integrating &lt;a href=&quot;http://html5boilerplate.com/&quot;&gt;HTML5 Boilerplate&lt;/a&gt;. I&apos;ve used Twitter Bootstrap for my &lt;a href=&quot;http://raibledesigns.com/rd/entry/my_html5_with_play_scala&quot;&gt;&lt;em&gt;Play More!&lt;/em&gt; app&lt;/a&gt;, as well as some recent client projects. Its excellent documentation has made it easy to use and I love the way you can simply add classes to elements to make them transform into something beautiful.
&lt;/p&gt;
&lt;p&gt;Last week, I spent a couple late nights integrating &lt;a href=&quot;http://thinkvitamin.com/design/twitter-bootstrap-2-0/&quot;&gt;Twitter Bootstrap 2.0&lt;/a&gt; into the Struts 2 and Spring MVC versions of AppFuse. The layout was pretty straightforward thanks to &lt;a href=&quot;http://markdotto.com/bs2/docs/scaffolding.html&quot;&gt;Scaffolding&lt;/a&gt;. Creating the Struts Menu Velocity template to produce &lt;a href=&quot;http://markdotto.com/bs2/docs/javascript.html#dropdowns&quot;&gt;dropdowns&lt;/a&gt; wasn&apos;t too difficult. I added &lt;a href=&quot;http://markdotto.com/bs2/docs/base-css.html#tables&quot;&gt;class=&quot;table table-condensed&quot;&lt;/a&gt; to the list screen tables, &lt;a href=&quot;http://markdotto.com/bs2/docs/base-css.html#forms&quot;&gt;class=&quot;well form-horizontal&quot;&lt;/a&gt; to forms and &lt;a href=&quot;http://markdotto.com/bs2/docs/base-css.html#buttons&quot;&gt;class=&quot;btn primary&quot;&lt;/a&gt; to buttons. 
&lt;/p&gt;
&lt;p&gt;  
I also added validation errors with the &quot;help-inline&quot; class. This is also where things got tricky with Struts and Spring MVC. For the form elements in Bootstrap, they recommend you use a &quot;control-group&quot; element that contains your label and a &quot;controls&quot; element. The control contains the input/select/textarea and also the error message if there is one. Here&apos;s a sample element waiting for data: 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div class=&quot;control-group&quot;&amp;gt;
    &amp;lt;label for=&quot;name&quot; class=&quot;control-label&quot;&amp;gt;Name&amp;lt;/label&amp;gt;
    &amp;lt;div class=&quot;controls&quot;&amp;gt;
        &amp;lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;name&quot;&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Below is what that element should look like to display a validation error:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div class=&quot;control-group error&quot;&amp;gt;
    &amp;lt;label for=&quot;name&quot; class=&quot;control-label&quot;&amp;gt;Name&amp;lt;/label&amp;gt;
    &amp;lt;div class=&quot;controls&quot;&amp;gt;
        &amp;lt;input type=&quot;text&quot; id=&quot;name&quot; name=&quot;name&quot; value=&quot;&quot;&amp;gt;
        &amp;lt;span class=&quot;help-inline&quot;&amp;gt;Please enter your name.&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You can see this markup is pretty easy, you just need to add an &quot;error&quot; class to &lt;em&gt;control-group&lt;/em&gt; and span to show the error message. With Struts 2, this was pretty easy thanks to its customizable templates for its &lt;a href=&quot;http://struts.apache.org/2.x/docs/struts-tags.html&quot;&gt;tags&lt;/a&gt;. All I had to do was create a &quot;template/css_xhtml&quot; directory in &lt;em&gt;src/main/webapp&lt;/em&gt; and modify checkbox.ftl, controlfooter.ftl, controlheader-core.ftl and controlheader.ftl to match Bootstrap&apos;s conventions. 
&lt;/p&gt;
&lt;p&gt;
Spring MVC was a bit trickier. Since its tags don&apos;t have the concept of writing an entire control (label and field), I had to do a bit of finagling to get things to work. In the current implementation, Struts 2 forms have a single line for a &lt;em&gt;control-group&lt;/em&gt; and its &lt;em&gt;control-label&lt;/em&gt; and &lt;em&gt;controls&lt;/em&gt;.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;&amp;lt;s:textfield key=&quot;user.firstName&quot; required=&quot;true&quot;/&gt;&lt;/pre&gt;
&lt;p&gt;With Spring MVC, it&apos;s a bit more complex:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;spring:bind path=&quot;user.firstName&quot;&amp;gt;
&amp;lt;fieldset class=&quot;control-group${(not empty status.errorMessage) ? &apos; error&apos; : &apos;&apos;}&quot;&amp;gt;
&amp;lt;/spring:bind&amp;gt;
    &amp;lt;appfuse:label styleClass=&quot;control-label&quot; key=&quot;user.firstName&quot;/&amp;gt;
    &amp;lt;div class=&quot;controls&quot;&amp;gt;
        &amp;lt;form:input path=&quot;firstName&quot; id=&quot;firstName&quot; maxlength=&quot;50&quot;/&amp;gt;
        &amp;lt;form:errors path=&quot;firstName&quot; cssClass=&quot;help-inline&quot;/&amp;gt;
    &amp;lt;/div&amp;gt;
&amp;lt;/fieldset&amp;gt;
&lt;/pre&gt;
&lt;p&gt;You could probably overcome this verbosity with &lt;a href=&quot;http://today.java.net/pub/a/today/2003/11/14/tagfiles.html&quot;&gt;Tag Files&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Figuring out if a &lt;em&gt;control-group&lt;/em&gt; needed an error class before the input tag was rendered was probably the hardest part of this exercise. This was mostly due to Bootstrap&apos;s great documentation and useful examples (viewed by inspecting the markup). Below are some screenshots of the old screens and new ones. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center; vertical-align: top&quot;&gt;
&lt;a href=&quot;http://farm8.staticflickr.com/7173/6787781357_c4c65c7c74_b.jpg&quot; title=&quot;Old UI - Login&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7173/6787781357_c4c65c7c74_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;Old UI - Login&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm8.staticflickr.com/7142/6787781421_0c7851b414_b.jpg&quot; title=&quot;Old UI - Users&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7142/6787781421_0c7851b414_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;Old UI - Users&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;a href=&quot;http://farm8.staticflickr.com/7035/6787781725_3a1f0218c1_b.jpg&quot; title=&quot;Old UI - Edit Profile&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7035/6787781725_3a1f0218c1_t.jpg&quot; width=&quot;100&quot; height=&quot;82&quot; alt=&quot;Old UI - Edit Profile&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;

&lt;p&gt;  
&lt;p style=&quot;text-align: center; vertical-align: top&quot;&gt;
&lt;a href=&quot;http://farm8.staticflickr.com/7025/6787781477_ec2ac7a93b_b.jpg&quot; title=&quot;New UI - Login&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7025/6787781477_ec2ac7a93b_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;New UI - Login&quot;&gt;&lt;/a&gt;
  
&lt;a href=&quot;http://farm8.staticflickr.com/7015/6787781597_6558d94bb5_b.jpg&quot; title=&quot;New UI - Users&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7015/6787781597_6558d94bb5_t.jpg&quot; width=&quot;100&quot; height=&quot;60&quot; alt=&quot;New UI - Users&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
  
  &lt;a href=&quot;http://farm8.staticflickr.com/7010/6787781681_81b7977414_b.jpg&quot; title=&quot;New UI - Edit Profile&quot; rel=&quot;lightbox[appfuse-bootstrap]&quot;&gt;&lt;img src=&quot;//farm8.staticflickr.com/7010/6787781681_81b7977414_t.jpg&quot; width=&quot;100&quot; height=&quot;82&quot; alt=&quot;New UI - Edit Profile&quot; style=&quot;margin-left: 10px&quot;&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p style=&quot;color: #666; text-align: center&quot;&gt;Check out the &lt;a style=&quot;color: #666&quot; href=&quot;http://www.flickr.com/photos/mraible/sets/72157629094630763/&quot;&gt;full set on Flickr&lt;/a&gt; if you&apos;d like a closer look.
  &lt;/p&gt;
  &lt;p&gt;
Even though I like the look of the old UI, I can&apos;t help but think a lot of the themes are designed for blogs and content sites, not webapps. The old &lt;a href=&quot;http://wufoo.com/&quot;&gt;Wufoo&lt;/a&gt; forms were a lot better looking though. And if you&apos;re going to develop &lt;a href=&quot;http://blogs.atlassian.com/2012/01/modern-principles-in-web-development/&quot;&gt;kick-ass webapps&lt;/a&gt;, you need to make them look good. Bootstrap goes a long way in doing this, but it certainly doesn&apos;t replace a good UX Designer. Bootstap simply helps you get into HTML5-land, start using CSS3 and it takes the pain out of making things work cross-browser. Its fluid layouts and responsive web design seems to work great for business applications, which I&apos;m guessing AppFuse is used for the most. 
&lt;/p&gt;
&lt;p&gt;
I can&apos;t thank the Bootstrap developers enough for helping me make this all look good. With Bootstrap 2 &lt;a href=&quot;http://www.markdotto.com/2012/01/24/bootstrap-2-ready-for-testing-and-feedback/&quot;&gt;dropping this week&lt;/a&gt;, I can see myself using this more and more on projects. In the near future, I&apos;ll be helping integrate Bootstrap into AppFuse&apos;s &lt;a href=&quot;http://appfuse.547863.n4.nabble.com/Tapestry-5-3-2-td4339578.html&quot;&gt;Tapestry 5 and JSF versions&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;What do you think of this CSS change? Do you change your CSS and layout a fair bit when starting with AppFuse archetypes? What can we do to make AppFuse apps look better out-of-the-box?
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I &lt;a href=&quot;http://source.appfuse.org/changelog/appfuse/?cs=3593&quot;&gt;updated&lt;/a&gt; AppFuse to the final &lt;a href=&quot;http://raibledesigns.com/rd/entry/twitter_s_open_source_summit&quot;&gt;Bootstrap 2.0 release&lt;/a&gt;. Also, Johannes Geppert wrote a &lt;a href=&quot;http://www.jgeppert.com/2012/02/new-struts2-bootstrap-plugin-released/&quot;&gt;Struts 2 Bootstrap Plugin&lt;/a&gt;. I hope to integrate this into AppFuse in the near future.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/my_html5_with_play_scala</id>
        <title type="html">My HTML5 with Play Scala, CoffeeScript and Jade Presentation from Devoxx 2011</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/my_html5_with_play_scala"/>
        <published>2011-11-18T11:18:38-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="scala" scheme="http://roller.apache.org/ns/tags/" />
        <category term="play-more" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxx2011" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxx" scheme="http://roller.apache.org/ns/tags/" />
        <category term="html5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="playframework" scheme="http://roller.apache.org/ns/tags/" />
        <category term="video" scheme="http://roller.apache.org/ns/tags/" />
        <category term="coffeescript" scheme="http://roller.apache.org/ns/tags/" />
        <category term="presentation" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jade" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">This week, I had the pleasure of traveling to one of my favorite places in the world: Antwerp, Belgium. Like &lt;a href=&quot;http://raibledesigns.com/rd/entry/an_awesome_trip_to_amsterdam&quot;&gt;last year&lt;/a&gt;, I traveled with the lovely &lt;a href=&quot;http://mcginityphoto.com&quot;&gt;Trish McGinity&lt;/a&gt; and spoke at &lt;a href=&quot;http://www.devoxx.com/display/DV11/Home&quot;&gt;Devoxx 2011&lt;/a&gt;. This year, my talk was on developing a web/mobile app with HTML5, Play, Scala, CoffeeScript and Jade. I was inspired to learn Scala at the beginning of this year and added CoffeeScript and Jade to my learning list after talking to James Strachan at TSSJS 2011. You can read more about how my journey began in my &lt;a href=&quot;http://raibledesigns.com/rd/entry/integrating_scalate_and_jade_with&quot;&gt;first post about learning these technologies&lt;/a&gt;.
&lt;/p&gt;&lt;p&gt;I started developing with these technologies in August and wrote about my learnings throughout the process. Last week, while writing my presentation, I decided it&apos;d be fun to make my presentation into more of a story-telling-session than a learn-about-new-technologies session. To do this, I focused on talking a bit about the technologies, but more about my experience learning them. I also came up with a challenging idea: create a video that showed the development process, how hard it was to test the app and (hopefully) my success in getting it to work.&lt;/p&gt;
&lt;p&gt;It was all a very close call, but I&apos;m happy to say I pulled it off! I got the app to work on an iPhone (&lt;a href=&quot;http://raibledesigns.com/rd/entry/phonegap_to_the_rescue&quot;&gt;thanks to PhoneGap&lt;/a&gt;) last Saturday, finished the first draft of my presentation on Sunday night (after pulling an all-nighter) and finished editing the demo video on Wednesday night. My talk was on Thursday afternoon and I had a blast talking about my experience to such a large, enthusiastic audience. You can see the presentation below, &lt;a href=&quot;http://www.slideshare.net/mraible/html5-with-play-scala-coffeescript-and-jade-devoxx-2011&quot;&gt;on Slideshare&lt;/a&gt; or &lt;a href=&quot;http://static.raibledesigns.com/repository/presentations/HTML5_with_Play_Scala_CoffeeScript_and_Jade_Devoxx2011.pdf&quot;&gt;download the PDF&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/10204272?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;/p&gt;
&lt;p&gt;You can find the &quot;demo&quot; for this talk &lt;a href=&quot;http://www.youtube.com/watch?v=bBqtPPfM2xQ&quot;&gt;on YouTube&lt;/a&gt; or watch it below.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;iframe width=&quot;510&quot; height=&quot;289&quot; src=&quot;//www.youtube.com/embed/bBqtPPfM2xQ?rel=0&amp;amp;hd=1&quot; frameborder=&quot;0&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;/p&gt;
&lt;p&gt;One of the reasons I really enjoyed this talk is it only represents one milestone in my learning process. I plan on continuing to develop this application and learning more about HTML5, Scala, Play and CoffeeScript and Scalate/Jade. Now that &lt;a href=&quot;http://raibledesigns.com/rd/entry/play_2_0_a_web&quot;&gt;Play 2.0 Beta has been released&lt;/a&gt;, I plan on upgrading to it and leveraging its native CoffeeScript and LESS support. I hope to continue using &lt;a href=&quot;http://scalate.fusesource.org/&quot;&gt;Scalate&lt;/a&gt; and its &lt;a href=&quot;http://scalate.fusesource.org/documentation/jade.html&quot;&gt;Jade&lt;/a&gt; format. And it&apos;s very likely &lt;a href=&quot;http://phonegap.com/&quot;&gt;PhoneGap&lt;/a&gt; will continue to be &lt;em&gt;the bridge&lt;/em&gt; that allows everything to run in the background.&lt;/p&gt;
&lt;p&gt;I&apos;ve been talking with the &lt;a href=&quot;www.jfokus.se/&quot;&gt;Jfokus&lt;/a&gt; folks about doing this talk in Sweden in Feburary and &lt;a href=&quot;http://devoxx.fr&quot;&gt;Devoxx France&lt;/a&gt; about presenting there in April. 
&lt;/p&gt;
&lt;p&gt;Learning all these technologies has been a challenging, but fun experience so far. As the last slide in my presentation says, I encourage you to do something similar. Pick something new to learn, have fun doing it, but more importantly - get out there and &lt;em&gt;Play!&lt;/em&gt;
&lt;/p&gt;&lt;p&gt;&lt;strong&gt;Update Dec. 20th:&lt;/strong&gt; A video of this presentation is &lt;a href=&quot;http://parleys.com/d/2925&quot;&gt;now available on Parleys.com&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/hyperproductive_jsf_2_0_with</id>
        <title type="html">Hyperproductive JSF 2.0 with Ed Burns at Jazoon</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/hyperproductive_jsf_2_0_with"/>
        <published>2011-06-23T04:53:10-06:00</published>
        <updated>2011-06-23T10:53:10-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="edburns" scheme="http://roller.apache.org/ns/tags/" />
        <category term="productivity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jazoon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf2" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">This morning, I attended Ed Burn&apos;s Talk on &lt;a href=&quot;http://jazoon.com/Conference/Thursday-23-June/Edward-John-Burns&quot;&gt;Hyperproductive JSF 2.0&lt;/a&gt; at &lt;a href=&quot;http://jazoon.com&quot;&gt;Jazoon&lt;/a&gt;. As you might know, I&apos;ve been a critic of JSF for many years. However, it is &lt;a href=&quot;http://www.zeroturnaround.com/java-ee-productivity-report-2011/&quot;&gt;one of the most used Java web frameworks&lt;/a&gt;, so I was hoping to learn how it&apos;s improved in the latest version. Below are my notes from Ed&apos;s presentation.&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
Ed&apos;s Plan for our Time Investment:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Define a productive development environment&lt;/li&gt;
&lt;li&gt;JSF for greenfield and brownfield projects&lt;/li&gt;
&lt;li&gt;List the top 9 productivity killers with JSF projects and solutions&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;em&gt;&quot;I am always doing that which I cannot do, in order that I may learn how to do it.&quot; -- Pablo Picasso&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;
Software is an executable representation of knowledge, a byproduct of learning how to solve a problem. Knowledge is something that changes as more information comes in. A productive environment makes it as easy as possible to learn how to solve a problem. Learning is an iterative process. Early iterations don&apos;t need to be optimal. Later iterations do ... and they need to be maintainable. &lt;em&gt;First&lt;/em&gt; is the hardest. &lt;em&gt;Fast&lt;/em&gt; iterations are they key. Spring Roo and Play are examples of frameworks that make the first iteration very fast.
&lt;/p&gt;
&lt;p&gt;
You should use a tool to jumpstart JSF development: copy from an old project, use a Maven archetype or use your IDE. With greenfield development, you don&apos;t have to bother learning the byproduct of other people&apos;s learning. It&apos;s a great opportunity to pad your resume with the latest hot technologies. With brownfield development, it&apos;s vitally important to understand the existing solution and hidden assumptions. You&apos;re also much more constrained in your technology choices. If you want to change, you&apos;ll need to come up with a migration strategy, which can be difficult. JSF works well for both because it&apos;s not just a runtime framework, it&apos;s also a conceptual framework. You need to understand how your framework handles data conversion, validation, page flow, persistence integration, I18N, L10N, A11Y, Web standards and user friendliness. 
&lt;/p&gt;
&lt;p&gt;
Top 9 JSF Productivity Killers:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Time wasting deployment step&lt;/li&gt;
&lt;li&gt;The perils of &quot;there&apos;s more than one way to do it&quot;&lt;/li&gt;
&lt;li&gt;Lengthy and painful developer on-boarding process&lt;/li&gt;
&lt;li&gt;Misused logging and misunderstood error messages&lt;/li&gt;
&lt;li&gt;Phantoms&lt;/li&gt;
&lt;li&gt;Under-utilized developer tools&lt;/li&gt;
&lt;li&gt;Premature optimization&lt;/li&gt;
&lt;li&gt;Difficulty in doing TDD&lt;/li&gt;
&lt;li&gt;Lack of an app framework&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
&lt;strong&gt;Time wasting deployment step&lt;/strong&gt;&lt;br/&gt;
ZeroTurnaround solves this problem with JRebel, but there&apos;s other ways to do it. Some of the killers of flow state: 1) one large war file, 2) underutilizing dynamic language features, 3) complex server environment and 4) build process is redoing work unnecessarily. To stop the time wasting deployment step, the most important things you can do are as follows:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Configure your IDE correctly. In Eclipse, compile directly into WEB-INF/classes and use continuous compilation. With NetBeans, use GlassFish.&lt;/li&gt;
&lt;li&gt;Don&apos;t do control-flow programming in XML.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Ed then showed a simple demo that showed how you can use Groovy to create a JSF UI Component. He also mentioned that Groovy can be used to author any JSF artifact. The benefit of this is you can simply edit and save a .groovy file without having to recompile or redeploy. Unfortunately, using Groovy didn&apos;t eliminate the XML syntax for pages or the XML for defining UI components. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;The perils of &quot;there&apos;s more than one way to do it&quot;&lt;/strong&gt;&lt;br/&gt;
JSF is very flexible, but flexibility is, more often than not, abused. There&apos;s a lack of convention for common things (e.g. master-detail, JSF concepts like converter, validator, etc.). The best way to fix this is to establish the norms for a project and stick with them. For example, Neil Griffin has a &lt;a href=&quot;http://www.liferay.com/web/neil.griffin/blog/-/blogs/making-distinctions-between-different-kinds-of-jsf-managed-beans&quot;&gt;good blog entry&lt;/a&gt; for the different kind of managed beans you can create. Develop recommendations like Neil&apos;s and use them on all your projects.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Lengthy developer on-boarding process&lt;/strong&gt;&lt;br/&gt;
Stick with standards when possible (at least have a common project description and build system across projects). Be committed to periodic cleanup cycles, including documenting for re-use. Pick one JSF component library and stick with it. Support for mixing and switching component libraries has improved with JSF 2, but it&apos;s still recommended you use only one.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Misused logging and misunderstood error messages&lt;/strong&gt;&lt;br/&gt;
JSF is notorious for cryptic error messages and very long stack traces. It&apos;s still a problem, but the JSF Team is still working on improving them. Good tip: use the &amp;lt;ui:debug&gt; tag. Its &lt;em&gt;recordStateSize=&quot;true&quot;&lt;/em&gt; attribute can be especially useful. If you&apos;re using &lt;a href=&quot;http://www.primefaces.org/&quot;&gt;PrimeFaces&lt;/a&gt;, add &lt;em&gt;trace=true&lt;/em&gt; to request URLs.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Phantoms&lt;/strong&gt;&lt;br/&gt;
Phantoms is when running code is not the same as the code you are modifying or wrong version of library gets picked up. You should have the capability to hit breakpoints anywhere in your entire software stack, including core Java sources. This is one of the most useful things about open source software. Solutions to phantoms: 1) put a timestamp on every redeploy and have the timestamp appear in the system log 2) write the running library stack to the system log (each library and version being used) and make it easy to compare one developer&apos;s runtime stack with another&apos;s 3) consider doing all work in tightly controlled VMs (checkout the VM at the beginning of the day, do your work, commit your changes and throw your VM away at the end of the day). 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Under-utilizing developer tools&lt;/strong&gt;&lt;br/&gt;
Make sure everyone has the fastest machines available and as much screen real estate as desired. Hardware is much cheaper than developer time. Another tip is to use Hudson as your butler. It&apos;s not just the team CI server. In other words, take advantage of automation wherever you can.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Premature Optimization&lt;/strong&gt;&lt;br/&gt;
Keep in mind the trade-offs between readability and performance. When using frameworks such as JSF, don&apos;t try to outsmart the implementation. Rather, use the framework as intended and use open-source contributions to treat performance problems. Example, EL expressions got a lot faster between EE5 and EE6. If you spent time trying to optimize EL expressions, you might&apos;ve been wasting your time.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Difficulty in doing TDD&lt;/strong&gt;&lt;br/&gt;
Try to figure out why TDD is difficult in your company. For JSF, strongly consider JBoss&apos;s &lt;a href=&quot;http://www.jboss.org/jsfunit&quot;&gt;JSFUnit&lt;/a&gt;. Write your testcases to extend from Cactus ServletTestCase and leverage &lt;a href=&quot;http://htmlunit.sourceforge.net/&quot;&gt;HtmlUnit&lt;/a&gt; (JSFUnit does this for you).
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Lack of an app framework&lt;/strong&gt;&lt;br/&gt;
Create common components: login panel, CRUD components, etc. If you don&apos;t have an app framework, build one over time. 
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;
This was an interesting talk by Ed. The dynamics of the room where a bit interesting. Jazoon is held in a movie theater, much like Devoxx. However, it appears there&apos;s a spotlight on the speaker that makes it very difficult to see the audience. I don&apos;t remember having this problem at Devoxx. Ed asked the audience quite a few questions, but it seemed he had a lot of difficulty in seeing if folks raised their hands. This made for some periods of awkward silence.
&lt;/p&gt;
&lt;p&gt;
Personally, I was hoping to learn some new whizbang tips about JSF that I was not aware of. Unfortunately, I didn&apos;t learn anything new and wasn&apos;t that impressed with the Groovy demo. 
&lt;/p&gt;
&lt;p&gt;
I think Ed&apos;s tips about things outside of JSF were good, especially buying developers good hardware. I&apos;ve seen many companies, including my &lt;a href=&quot;http://www.overstock.com&quot;&gt;current client&lt;/a&gt;, skimp on developer hardware and cause developer frustration because of it. I think it&apos;s great when companies provide developers top-of-the-line hardware and eliminate frustration over CPU and memory resources. LinkedIn and Time Warner Cable both provide their developers with Mac Pros and MacBook Pros as well as huge monitors. IMO, this is one of the best benefits you can provide your engineers.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_2_1_released</id>
        <title type="html">AppFuse 2.1 Released!</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_2_1_released"/>
        <published>2011-04-04T09:38:05-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ibatis" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse-light" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jpa" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://appfuse.org&quot;&gt;&lt;img src=&quot;//static.appfuse.org/images/appfuse-icon.gif&quot; class=&quot;picture&quot; style=&quot;border: 0&quot;&gt;&lt;/a&gt;
The AppFuse Team is pleased to announce the release of AppFuse 2.1. This release includes upgrades to all dependencies to bring them up-to-date with their latest releases. Most notable are JPA 2, JSF 2, Tapestry 5 and Spring 3. In addition, we&apos;ve migrated from XFire to CXF and enabled REST for web services. There&apos;s even a new &lt;b&gt;appfuse-ws&lt;/b&gt; archetype that leverages &lt;a href=&quot;http://enunciate.codehaus.org&quot;&gt;Enunciate&lt;/a&gt; to generate web service endpoints, documentation and downloadable clients. This release fixes many issues with archetypes, improving startup time and allowing jetty:run to be used for quick turnaround while developing. For more details on specific changes see the &lt;a href=&quot;http://appfuse.org/display/APF/Release+Notes+2.1.0&quot; title=&quot;Release Notes 2.1.0&quot;&gt;release notes&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What is AppFuse?&lt;/strong&gt;&lt;br/&gt;AppFuse is an open source project and application that uses open source frameworks to help you develop Web applications with Java quickly and efficiently. It was originally developed to eliminate the ramp-up time when building new web applications. At its core, AppFuse is a project skeleton, similar to the one that&apos;s created by your IDE when you click through a wizard to create a new web project. If you use &lt;a href=&quot;http://appfuse.org/display/APF/Using+JRebel+with+IntelliJ+IDEA&quot;&gt;JRebel with IntelliJ&lt;/a&gt;, you can achieve zero-turnaround in your project and develop features without restarting the server.
&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Release Details&lt;/b&gt;&lt;br/&gt;
&lt;a href=&quot;http://static.appfuse.org/archetypes.html&quot;&gt;Archetypes&lt;/a&gt; now include all the source for the web modules so using jetty:run and your IDE will work much smoother now. The backend is still embedded in JARs, enabling you to choose with persistence framework (Hibernate, iBATIS or JPA) you&apos;d like to use. If you want to modify the source for that, &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+Core+Classes&quot;&gt;add the core classes to your project&lt;/a&gt; or run &quot;appfuse:full-source&quot;. &lt;/p&gt;

&lt;p&gt;AppFuse comes in a number of different flavors. It offers &quot;light&quot;, &quot;basic&quot; and &quot;modular&quot; and archetypes. Light archetypes use an embedded H2 database and contain a simple CRUD example. Light archetypes allow code generation and full-source features, but do not currently support Stripes or Wicket. Basic archetypes have web services using CXF, authentication from Spring Security and features including signup, login, file upload and CSS theming. Modular archetypes are similar to basic archetypes, except they have multiple modules which allows you to separate your services from your web project.&lt;/p&gt;

&lt;p&gt;AppFuse provides archetypes for JSF, Spring MVC, Struts 2 and Tapestry 5. The light archetypes are available for these frameworks, as well as for Spring MVC + FreeMarker, Stripes and Wicket. You can see demos of these archetypes at &lt;a href=&quot;http://demo.appfuse.org&quot;&gt;http://demo.appfuse.org&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For information on creating a new project, please see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;If you have questions about AppFuse, please read the &lt;a href=&quot;http://appfuse.org/display/APF/FAQ&quot;&gt;FAQ&lt;/a&gt; or join the &lt;a href=&quot;http://appfuse.org/display/APF/Mailing+Lists&quot;&gt;user mailing list&lt;/a&gt;. If you find any issues, please report them on the mailing list or &lt;a href=&quot;http://issues.appfuse.org/secure/CreateIssue%21default.jspa&quot;&gt;create an issue in JIRA&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks to everyone for their help contributing patches, writing documentation and participating on the mailing lists.&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; padding-top: 5px; color: #666&quot;&gt;We greatly appreciate the help from &lt;a href=&quot;http://appfuse.org/display/APF/Sponsors&quot; title=&quot;Sponsors&quot; style=&quot;color: #666&quot;&gt;our sponsors&lt;/a&gt;, particularly &lt;a href=&quot;http://www.atlassian.com/c/NPOS/10160&quot; style=&quot;color: #666&quot;&gt;Atlassian&lt;/a&gt;, &lt;a href=&quot;http://contegix.com&quot; style=&quot;color: #666&quot;&gt;Contegix&lt;/a&gt; and &lt;a href=&quot;http://www.jetbrains.com&quot; style=&quot;color: #666&quot;&gt;JetBrains&lt;/a&gt;. Atlassian and Contegix are especially awesome: &lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_now_powered_by_contegix&quot; style=&quot;color: #666&quot;&gt;Atlassian has donated licenses to all its products and Contegix has donated an entire server&lt;/a&gt; to the AppFuse project.&lt;/p&gt;&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/adding_search_to_appfuse</id>
        <title type="html">Adding Search to AppFuse with Compass</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/adding_search_to_appfuse"/>
        <published>2011-03-15T17:11:12-06:00</published>
        <updated>2012-11-08T14:19:27-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="search" scheme="http://roller.apache.org/ns/tags/" />
        <category term="compass" scheme="http://roller.apache.org/ns/tags/" />
        <category term="elasticsearch" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Over 5 years ago, I recognized that &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; needed to have a search feature and &lt;a href=&quot;http://issues.appfuse.org/browse/APF-267&quot;&gt;entered an issue in JIRA&lt;/a&gt;. Almost 4 years later, a &lt;a href=&quot;http://code.google.com/p/pagingappfuse/wiki/CompassSearching&quot;&gt;Compass Tutorial&lt;/a&gt; was created and shortly after &lt;a href=&quot;http://www.kimchy.org/&quot;&gt;Shay Banon&lt;/a&gt; (Compass Founder), sent in a &lt;a href=&quot;http://issues.appfuse.org/browse/APF-267?focusedCommentId=12620&amp;page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12620&quot;&gt;patch&lt;/a&gt;. From the message he sent me:&lt;/p&gt;
&lt;div class=&quot;quote&quot; style=&quot;margin-left: 0; margin-bottom: 10px&quot;&gt;
&lt;p&gt;A quick breakdown of enabling search:
&lt;/p&gt;
&lt;ol style=&quot;margin-bottom: 0&quot;&gt;
&lt;li&gt;Added Searchable annotations to the User and Address.&lt;/li&gt;
&lt;li&gt;Defined Compass bean, automatically scanning the model package for mapped searchable classes. It also automatically integrates with Spring transaction manager, and stores the index on the file system ([work dir]/target/test-index).&lt;/li&gt;
&lt;li&gt;Defined CompassTemplate (similar in concept to HibernateTemplate).&lt;/li&gt;
&lt;li&gt;Defined CompassSearchHelper. Really helps to perform search since it does pagination and so on.&lt;/li&gt;
&lt;li&gt;Defined CompassGps, basically it allows for index operation allowing to completely reindex the data from the database. JPA and Hiberante also automatically mirror changes done through their API to the index. iBatis uses AOP. &lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
&lt;p&gt;Fast forward 2 years and I finally found the time/desire to put a UI on the backend Compass implementation that Shay provided. Yes, I realize that &lt;a href=&quot;http://www.kimchy.org/the_future_of_compass/&quot;&gt;Compass is being replaced by ElasticSearch&lt;/a&gt;. I may change to use ElasticSearch in the future; now that the search feature exists, I hope to see it evolve and improve.
&lt;/p&gt;
&lt;p&gt;Since Shay&apos;s patch integrated the necessary Spring beans for indexing and searching, the only thing I had to do was to implement the UI. Rather than having an &quot;all objects&quot; results page, I elected to implement it so you could search on an entity&apos;s list screen. I started with Spring MVC and added a search() method to the UserController:
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@RequestMapping(method = RequestMethod.GET)
public ModelAndView handleRequest(@RequestParam(required = false, value = &quot;q&quot;) String query) throws Exception {
    if (query != null &amp;&amp; !&quot;&quot;.equals(query.trim())) {
        return new ModelAndView(&quot;admin/userList&quot;, Constants.USER_LIST, search(query));
    } else {
        return new ModelAndView(&quot;admin/userList&quot;, Constants.USER_LIST, mgr.getUsers());
    }
}

public List&amp;lt;User&amp;gt; search(String query) {
    List&amp;lt;User&amp;gt; results = new ArrayList&amp;lt;User&amp;gt;();
    CompassDetachedHits hits = compassTemplate.findWithDetach(query);
    log.debug(&quot;No. of results for &apos;&quot; + query + &quot;&apos;: &quot; + hits.length());
    for (int i = 0; i &amp;lt; hits.length(); i++) {
        results.add((User) hits.data(i));
    }
    return results;
}
&lt;/pre&gt;
&lt;p&gt;At first, I used &lt;em&gt;compassTemplate.find()&lt;/em&gt;, but got an error because I wasn&apos;t using an OpenSessionInViewFilter. I decided to go with findWithDetach() and added the following search form to the top of the userList.jsp page:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;form method=&quot;get&quot; action=&quot;${ctx}/admin/users&quot; id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;input type=&quot;text&quot; size=&quot;20&quot; name=&quot;q&quot; id=&quot;query&quot; value=&quot;${param.q}&quot;
           placeholder=&quot;Enter search terms&quot;/&amp;gt;
    &amp;lt;input type=&quot;submit&quot; value=&quot;&amp;lt;fmt:message key=&quot;button.search&quot;/&amp;gt;&quot;/&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p style=&quot;color: #666; margin-left: 20px&quot;&gt;&lt;em&gt;NOTE: I tried using HTML5&apos;s &amp;lt;input type=&quot;search&quot;&amp;gt;, but found &lt;a href=&quot;http://lists.canoo.com/pipermail/webtest/2011q1/013697.html&quot; style=&quot;color: #666&quot;&gt;Canoo WebTest doesn&apos;t support it.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Next, I wrote a unit test to verify everything worked as expected. I found I had to call compassGps.index() as part of my test to make sure my index was created and up-to-date.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public class UserControllerTest extends BaseControllerTestCase {
    @Autowired
    private CompassGps compassGps;
    @Autowired
    private UserController controller;

    public void testSearch() throws Exception {
        compassGps.index();
        ModelAndView mav = controller.handleRequest(&quot;admin&quot;);
        Map m = mav.getModel();
        List results = (List) m.get(Constants.USER_LIST);
        assertNotNull(results);
        assertTrue(results.size() &amp;gt;= 1);
        assertEquals(&quot;admin/userList&quot;, mav.getViewName());
    }
}
&lt;/pre&gt;
&lt;p&gt;After getting this working, I started integrating similar code into AppFuse&apos;s other web framework modules (Struts, JSF and Tapestry). When I was finished, they all looked pretty similar from a UI perspective.
&lt;/p&gt;
&lt;p&gt;&lt;strong style=&quot;color: #666&quot;&gt;Struts:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;form method=&quot;get&quot; action=&quot;${ctx}/admin/users&quot; id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;input type=&quot;text&quot; size=&quot;20&quot; name=&quot;q&quot; id=&quot;query&quot; value=&quot;${param.q}&quot;
           placeholder=&quot;Enter search terms...&quot;/&amp;gt;
    &amp;lt;input type=&quot;submit&quot; value=&quot;&amp;lt;fmt:message key=&quot;button.search&quot;/&amp;gt;&quot;/&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong style=&quot;color: #666&quot;&gt;JSF:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;h:form id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;h:inputText id=&quot;q&quot; name=&quot;q&quot; size=&quot;20&quot; value=&quot;#{userList.query}&quot;/&amp;gt;
    &amp;lt;h:commandButton value=&quot;#{text&amp;#91;&apos;button.search&apos;&amp;#93;}&quot; action=&quot;#{userList.search}&quot;/&amp;gt;
&amp;lt;/h:form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong style=&quot;color: #666&quot;&gt;Tapestry:&lt;/strong&gt;&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;div id=&quot;search&quot;&amp;gt;
&amp;lt;t:form method=&quot;get&quot; t:id=&quot;searchForm&quot;&amp;gt;
    &amp;lt;t:textfield size=&quot;20&quot; name=&quot;q&quot; t:id=&quot;q&quot;/&amp;gt;
    &amp;lt;input t:type=&quot;submit&quot; value=&quot;${message:button.search}&quot;/&amp;gt;
&amp;lt;/t:form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/pre&gt;
&lt;p&gt;One frustrating thing I found was that &lt;a href=&quot;http://tapestry.1045711.n5.nabble.com/Is-there-any-way-to-render-the-quot-get-quot-method-of-form-td2643651.html&quot;&gt;Tapestry doesn&apos;t support method=&quot;get&quot;&lt;/a&gt; and AFAICT, neither does JSF 2. With JSF, I had to make my UserList bean session-scoped or the query parameter would be null when it listed the results. Tapestry took me the longest to implement, mainly because I had issues figuring out how it&apos;s easy-to-understand-once-you-know onSubmit() handlers worked and I had the proper @Property and @Persist annotations on my &quot;q&quot; property. &lt;a href=&quot;http://www.crazymcphee.net/x/2009/08/26/tapestry-5-web-framework/&quot;&gt;This tutorial&lt;/a&gt; was the greatest help for me. Of course, now that it&apos;s all finished, the code looks pretty intuitive.&lt;/p&gt;
&lt;p&gt;Feeling proud of myself for getting this working, I started integrating this feature into AppFuse&apos;s code generation and found I had to add quite a bit of code to the generated list pages/controllers. 
&lt;/p&gt;
&lt;p&gt;
So I went on a bike ride...&lt;/p&gt;
&lt;p&gt;While riding, I thought of a much better solution and added the following search method to AppFuse&apos;s GenericManagerImpl.java. In the code I added to pages/controllers previously, I&apos;d already refactored to use CompassSearchHelper and I continued to do so in the service layer implementation.
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
@Autowired
private CompassSearchHelper compass;

public List&amp;lt;T&amp;gt; search(String q, Class clazz) {
    if (q == null || &quot;&quot;.equals(q.trim())) {
        return getAll();
    }

    List&amp;lt;T&amp;gt; results = new ArrayList&amp;lt;T&amp;gt;();

    CompassSearchCommand command = new CompassSearchCommand(q);
    CompassSearchResults compassResults = compass.search(command);
    CompassHit&amp;#91;&amp;#93; hits = compassResults.getHits();

    if (log.isDebugEnabled() &amp;amp;&amp;amp; clazz != null) {
        log.debug(&quot;Filtering by type: &quot; + clazz.getName());
    }

    for (CompassHit hit : hits) {
        if (clazz != null) {
            if (hit.data().getClass().equals(clazz)) {
                results.add((T) hit.data());
            }
        } else {
            results.add((T) hit.data());
        }
    }

    if (log.isDebugEnabled()) {
        log.debug(&quot;Number of results for &apos;&quot; + q + &quot;&apos;: &quot; + results.size());
    }

    return results;
}
&lt;/pre&gt;
&lt;p&gt;This greatly simplified my page/controller logic because now all I had to do was call manager.search(query, User.class) instead of doing the Compass login in the controller. Of course, it&apos;d be great if I didn&apos;t have to pass in the Class to filter by object, but that&apos;s the &lt;a href=&quot;http://javanotepad.blogspot.com/2007/09/instanceof-doesnt-work-with-generics.html&quot;&gt;nature of generics and type erasure&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Other things I learned along the way:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To index on startup, I added compassGps.index() to the StartupListener.&lt;/a&gt;.
&lt;li&gt;In unit tests that leveraged transactions around methods, I had to call compassGps.index() before any transactions started.&lt;/li&gt;
&lt;li&gt;To scan multiple packages for searchable classes, I had to add a &lt;a href=&quot;http://forum.compass-project.org/thread.jspa?threadID=216821&amp;tstart=0&quot;&gt;LocalCompassBeanPostProcessor&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But more than anything, I was reminded it always helps to take a bike ride when you don&apos;t like the design of your code. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
This feature and many more will be in AppFuse 2.1, which I hope to &lt;a href=&quot;http://issues.appfuse.org/secure/IssueNavigator.jspa?mode=hide&amp;requestId=10160&quot; title=&quot;Open Issues for 2.1&quot;&gt;finish by the end of the month&lt;/a&gt;. In the meantime, please feel free to try out the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;latest snapshot&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/jsr_303_and_web_framework</id>
        <title type="html">JSR 303 and JVM Web Framework Support</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/jsr_303_and_web_framework"/>
        <published>2011-03-08T11:33:24-07:00</published>
        <updated>2012-11-08T14:30:37-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsr303" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vaadin" scheme="http://roller.apache.org/ns/tags/" />
        <category term="lift" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Emmanuel Bernard recently sent an email to the JSR 303 Experts Group about the next revision of the Bean Validation JSR (303). Rather than sending the proposed changes privately, he &lt;a href=&quot;http://in.relation.to/Bloggers/JSRBeanValidation11WhatToPutIn&quot;&gt;blogged about them&lt;/a&gt;. I left a comment with what I&apos;d like to see:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
+1 for Client-side validation. I&apos;d love to see an API that web frameworks can hook into to add &quot;required&quot; to their tags for HTML5. Or some service that can be registered so the client can make Ajax requests to an API to see if an object is valid.
&lt;/p&gt;
&lt;p&gt;Emmanuel replied that most of the necessary API already exists for this, but frameworks have been slow to adopt it.
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Hi Matt,
&lt;br/&gt;&lt;br/&gt;
The sad thing is that the API is present on the Bean Validation side but presentation frameworks are slow to adopt it and use it :(
&lt;br/&gt;&lt;br/&gt;
RichFaces 4 now has support for it but I wished more presentation frameworks had worked on the integration. If you can convince a few people or have access to a few people, feel free to send them by me :)
&lt;br/&gt;&lt;br/&gt;
The integration API is &lt;a href=&quot;http://people.redhat.com/~ebernard/validation/#constraintmetadata&quot;&gt;described here&lt;/a&gt;. Let me know if you think some parts are missing or should be improved. We should definitely do some more buzz around it.
&lt;/p&gt;
&lt;p&gt;In the interest of generating more buzz around it, I decided to do some research and see what JVM Frameworks support JSR 303. Here&apos;s what I&apos;ve come up with so far (in no particular order):
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://relation.to/Bloggers/RichFaces4ClientSideValidation&quot;&gt;RichFaces 4 - Client Side Validation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://tapestry.apache.org/bean-validation.html&quot;&gt;Tapestry&apos;s JSR 303 - Bean Validation Library&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://blog.zenika.com/index.php?post/2010/02/24/Wicket-JSR-303-Validators&quot;&gt;Wicket JSR-303 Validators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://static.springsource.org/spring/docs/3.0.x/reference/validation.html#validation-mvc-jsr303&quot;&gt;Configuring a JSR-303 Validator for use by Spring MVC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/gwt-validation/&quot;&gt;GWT Validation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://dev.vaadin.com/ticket/3156&quot;&gt;Vaadin Bean Validation JSR 303 support&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://wstrange.wordpress.com/2009/12/07/inline-field-validation-in-scalalift-using-jpa-and-jsr-303/&quot;&gt;Inline field validation in Scala/Lift using JPA and JSR 303&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Struts 2 has an &lt;a href=&quot;https://issues.apache.org/jira/browse/WW-2563&quot;&gt;open issue&lt;/a&gt;, but doesn&apos;t seem to support JSR 303. Since I did a quick-n-dirty google search for most of these, I&apos;m not sure if they support client-side JavaScript or HTML5&apos;s required. If you know of other JVM-based web frameworks that support JSR 303, please let me know in the comments. </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/upgrading_to_jsf_2</id>
        <title type="html">Upgrading to JSF 2</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/upgrading_to_jsf_2"/>
        <published>2011-03-07T13:24:53-07:00</published>
        <updated>2011-03-07T19:30:33-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="urlrewritefilter" scheme="http://roller.apache.org/ns/tags/" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="richfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tomahawk" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="facelets" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last week, I spent a few hours upgrading &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; from JSF 1.2 to JSF 2.0. In reality, I upgraded from &lt;a href=&quot;http://myfaces.apache.org&quot;&gt;MyFaces&lt;/a&gt; 1.2.7 to 2.0.4, but all JSF implementations should be the same, right? All in all, it was a pretty easy upgrade with a few minor AppFuse-specific things. My goal in upgrading was to do the bare minimum to get things working and to leave integration of JSF 2 features for a later date.&lt;/p&gt;

&lt;p&gt;In addition to upgrading MyFaces, I had to upgrade Tomahawk by changing the dependency&apos;s artifactId to &lt;strong&gt;tomahawk20&lt;/strong&gt;. I was also able to remove the following listener from my web.xml:
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;listener&gt;
    &amp;lt;listener-class&gt;org.apache.myfaces.webapp.StartupServletContextListener&amp;lt;/listener-class&gt;
&amp;lt;listener&gt;
&lt;/pre&gt;
&lt;p&gt;After that, I discovered that MyFaces uses a new URI (/javax.faces.resource/) for serving up some of its resource files. I kindly asked Spring Security to ignore these requests by adding the following to my security.xml file.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;intercept-url pattern=&quot;/javax.faces.resource/**&quot; filters=&quot;none&quot;/&gt;
&lt;/pre&gt;
&lt;p&gt;Since JSF 2 includes Facelets by default, I tried removing Facelets as a dependency. After doing this, I received the following error:
&lt;/p&gt;
&lt;pre&gt;
ERROR [308855416@qtp-120902214-7] ViewHandlerWrapper.fillChain(158) | Error instantiation parent Faces ViewHandler
java.lang.ClassNotFoundException: com.sun.facelets.FaceletViewHandler
        at org.codehaus.plexus.classworlds.strategy.SelfFirstStrategy.loadClass(SelfFirstStrategy.java:50)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:244)
        at org.codehaus.plexus.classworlds.realm.ClassRealm.loadClass(ClassRealm.java:230)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:401)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:363)
        at org.ajax4jsf.framework.ViewHandlerWrapper.fillChain(ViewHandlerWrapper.java:144)
        at org.ajax4jsf.framework.ViewHandlerWrapper.calculateRenderKitId(ViewHandlerWrapper.java:68)
        at org.apache.myfaces.lifecycle.DefaultRestoreViewSupport.isPostback(DefaultRestoreViewSupport.java:179)
        at org.apache.myfaces.lifecycle.RestoreViewExecutor.execute(RestoreViewExecutor.java:113)
        at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:171)
        at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
&lt;/pre&gt;
&lt;p&gt;Figuring this was caused by the following element in my web.xml ...
&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;context-param&amp;gt;
    &amp;lt;param-name&amp;gt;org.ajax4jsf.VIEW_HANDLERS&amp;lt;/param-name&amp;gt;
    &amp;lt;param-value&amp;gt;com.sun.facelets.FaceletViewHandler&amp;lt;/param-value&amp;gt;
&amp;lt;/context-param&amp;gt;
&lt;/pre&gt;
&lt;p&gt;... I removed it and tried again. This time I received a NoClassDefFoundError:&lt;/p&gt;
&lt;pre&gt;
java.lang.NoClassDefFoundError: com/sun/facelets/tag/TagHandler
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
        at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
        at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:392)
        at org.mortbay.jetty.webapp.WebAppClassLoader.loadClass(WebAppClassLoader.java:363)
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Class.java:247)
        at org.apache.myfaces.shared_impl.util.ClassUtils.classForName(ClassUtils.java:184)
        at org.apache.myfaces.view.facelets.util.ReflectionUtil.forName(ReflectionUtil.java:67)
&lt;/pre&gt;
&lt;p&gt;Since everything seemed to work with Facelets in the classpath, I decided to save this headache for a later date. I entered two issues in AppFuse&apos;s JIRA, one for &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1234&quot;&gt;removing Facelets&lt;/a&gt; and one for &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1233&quot;&gt;replacing Ajax4JSF with RichFaces&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;The next issue I encountered was redirecting from AppFuse&apos;s password hint page. The navigation-rule for this page is as follows:&lt;/p&gt;
&lt;pre class=&quot;brush: xml; toolbar: false&quot;&gt;
&amp;lt;navigation-rule&amp;gt;
    &amp;lt;from-view-id&amp;gt;/passwordHint.xhtml&amp;lt;/from-view-id&amp;gt;
    &amp;lt;navigation-case&amp;gt;
        &amp;lt;from-outcome&amp;gt;success&amp;lt;/from-outcome&amp;gt;
        &amp;lt;to-view-id&amp;gt;/login&amp;lt;/to-view-id&amp;gt;
        &amp;lt;redirect/&amp;gt;
    &amp;lt;/navigation-case&amp;gt;
&amp;lt;/navigation-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;With JSF 2.0, the rule changes the URL to /login.xhtml when redirecting (where it was left as /login with 1.2) and it was caught by the security setting in my web.xml that prevents users from viewing raw templates.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;security-constraint&amp;gt;
    &amp;lt;web-resource-collection&amp;gt;
        &amp;lt;web-resource-name&amp;gt;Protect XHTML Templates&amp;lt;/web-resource-name&amp;gt;
        &amp;lt;url-pattern&amp;gt;*.xhtml&amp;lt;/url-pattern&amp;gt;
    &amp;lt;/web-resource-collection&amp;gt;
    &amp;lt;auth-constraint/&amp;gt;
&amp;lt;/security-constraint&amp;gt;
&lt;/pre&gt;
&lt;p&gt;To solve this issue, I had to make a couple of changes:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Comment out the security-constraint in web.xml and move it to Spring Security&apos;s security.xml file.
&lt;pre class=&quot;brush: xml; toolbar: false&quot; style=&quot;margin: 5px 0 0 0&quot;&gt;
&amp;lt;intercept-url pattern=&quot;/**/*.xhtml&quot; access=&quot;ROLE_NOBODY&quot;/&gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Add a rule to urlrewrite.xml that redirects back to login (since login.xhtml doesn&apos;t exist and I&apos;m using extensionless URLs).
&lt;pre class=&quot;brush: xml&quot; style=&quot;margin: 5px 0 0 0&quot;&gt;
&amp;lt;rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^/login.xhtml$&amp;lt;/from&amp;gt;
    &amp;lt;to type=&quot;redirect&quot;&amp;gt;%{context-path}/login&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After getting the Password Hint feature passing in the browser, I tried running the integration tests (powered by &lt;a href=&quot;http://webtest.canoo.com&quot;&gt;Canoo WebTest&lt;/a&gt;). The Password Hint test kept failing with the following error:
&lt;/p&gt;
&lt;pre&gt;
[ERROR] /Users/mraible/dev/appfuse/web/jsf/src/test/resources/web-tests.xml:51: JavaScript error loading
page http://localhost:9876/appfuse-jsf-2.1.0-SNAPSHOT/passwordHint?username=admin: syntax error (http://
localhost:9876/appfuse-jsf-2.1.0-SNAPSHOT/javax.faces.resource/oamSubmit.js.jsf?ln=org.apache.myfaces#122)
&lt;/pre&gt;
&lt;p&gt;Figuring this was caused by my hack to &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/passwordHint.xhtml?r=2866&quot;&gt;submit the form when the page was loaded&lt;/a&gt;, I turned to &lt;a href=&quot;http://ocpsoft.com/prettyfaces/&quot;&gt;Pretty Faces&lt;/a&gt;, which allows you to call a method directly from a URL. After adding the Pretty Faces dependencies to my pom.xml, I created a src/main/webapp/WEB-INF/pretty-config.xml file with the following XML:&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;url-mapping&amp;gt;
    &amp;lt;pattern value=&quot;/editProfile&quot;/&amp;gt;
    &amp;lt;view-id value=&quot;/userForm.jsf&quot;/&amp;gt;
    &amp;lt;action&amp;gt;#{userForm.edit}&amp;lt;/action&amp;gt;
&amp;lt;/url-mapping&amp;gt;

&amp;lt;url-mapping&amp;gt;
    &amp;lt;pattern value=&quot;/passwordHint/#{username}&quot;/&amp;gt;
    &amp;lt;view-id value=&quot;/passwordHint.jsf&quot;/&amp;gt;
    &amp;lt;action&amp;gt;#{passwordHint.execute}&amp;lt;/action&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;This allowed me to remove both editProfile.xhtml and passwordHint.xhtml, both of which simply auto-submitted forms.&lt;/p&gt;
&lt;p&gt;At this point, I figured I&apos;d be good to go and ran my integration tests again. The first thing I discovered was that &quot;.jsf&quot; was being tacked onto my pretty URL, most likely by the UrlRewriteFilter. Adding the following to my PasswordHint.java class solved this.
&lt;/p&gt;
&lt;pre class=&quot;brush: java; toolbar: false&quot;&gt;
if (username.endsWith(&quot;.jsf&quot;)) {
    username = username.substring(0, username.indexOf(&quot;.jsf&quot;));
}
&lt;/pre&gt;
&lt;p&gt;The next thing was a cryptic error that took me a while to figure out.&lt;/p&gt;
&lt;pre&gt;
DEBUG [1152467051@qtp-144702232-0] PasswordHint.execute(38) | Processing Password Hint...
2011-03-05 05:48:52.471:WARN::/passwordHint/admin
com.ocpsoft.pretty.PrettyException: Exception occurred while processing &amp;lt;:#{passwordHint.execute}&gt; null
        at com.ocpsoft.pretty.faces.beans.ActionExecutor.executeActions(ActionExecutor.java:71)
        at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.processEvent(PrettyPhaseListener.java:214)
        at com.ocpsoft.pretty.faces.event.PrettyPhaseListener.afterPhase(PrettyPhaseListener.java:108)
        at org.apache.myfaces.lifecycle.PhaseListenerManager.informPhaseListenersAfter(PhaseListenerManager.java:111)
        at org.apache.myfaces.lifecycle.LifecycleImpl.executePhase(LifecycleImpl.java:185)
        at org.apache.myfaces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
        at javax.faces.webapp.FacesServlet.service(FacesServlet.java:189)
&lt;/pre&gt;
&lt;p&gt;Digging into the bowels of MyFaces, I discovered a class was looking for a viewId with an extension and no view-id was being set. Adding the following to the top of my execute() method solved this.
&lt;/p&gt;
&lt;pre class=&quot;brush: java; toolbar: false&quot;&gt;
getFacesContext().getViewRoot().setViewId(&quot;/passwordHint.xhtml&quot;);
&lt;/pre&gt;
&lt;p&gt;After making this change, all AppFuse&apos;s integration tests are passing and the upgrade seems complete. The only other issues I encountered were logging-related. The first is an error about Tomahawk that doesn&apos;t seem to affect anything.
&lt;/p&gt;
&lt;pre&gt;
Mar 5, 2011 6:44:01 AM com.sun.facelets.compiler.TagLibraryConfig loadImplicit
SEVERE: Error Loading Library: jar:file:/Users/mraible/.m2/repository/org/apache/myfaces/tomahawk/tomahawk20/1.1.10/tomahawk20-1.1.10.jar!/META-INF/tomahawk.taglib.xml
java.io.IOException: Error parsing [jar:file:/Users/mraible/.m2/repository/org/apache/myfaces/tomahawk/tomahawk20/1.1.10/tomahawk20-1.1.10.jar!/META-INF/tomahawk.taglib.xml]: 
        at com.sun.facelets.compiler.TagLibraryConfig.create(TagLibraryConfig.java:410)
        at com.sun.facelets.compiler.TagLibraryConfig.loadImplicit(TagLibraryConfig.java:431)
        at com.sun.facelets.compiler.Compiler.initialize(Compiler.java:87)
        at com.sun.facelets.compiler.Compiler.compile(Compiler.java:104)
&lt;/pre&gt;
&lt;p&gt;The second is excessive logging from MyFaces. As far as I can tell, this is because MyFaces switched to java.util.logging instead of commons logging. With all the frameworks that AppFuse leverages, I think it has all the logging frameworks in its classpath now. I was hoping to fix this by &lt;a href=&quot;http://old.nabble.com/Turn-down-logging-in-2.0.4--td31068698.html&quot;&gt;posting a message to the mailing list&lt;/a&gt;, but haven&apos;t received a reply yet.
&lt;/p&gt;
&lt;pre&gt;
[WARNING] [talledLocalContainer] Mar 5, 2011 6:50:25 AM org.apache.myfaces.config.annotation.TomcatAnnotationLifecycleProvider newInstance
[WARNING] [talledLocalContainer] INFO: Creating instance of org.appfuse.webapp.action.BasePage
[WARNING] [talledLocalContainer] Mar 5, 2011 6:50:25 AM org.apache.myfaces.config.annotation.TomcatAnnotationLifecycleProvider destroyInstance
[WARNING] [talledLocalContainer] INFO: Destroy instance of org.appfuse.webapp.action.BasePage
&lt;/pre&gt;
&lt;p&gt;After successfully upgrading AppFuse, I turned to AppFuse Light, where things were &lt;a href=&quot;http://source.appfuse.org/changelog/appfuse-light/?cs=243&quot;&gt;much easier&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Now that AppFuse uses JSF 2, I hope to start leveraging some of its &lt;a href=&quot;http://www.ibm.com/developerworks/java/library/j-jsf2fu1/index.html&quot;&gt;new features&lt;/a&gt;. If you&apos;re yearning to get started with them today, I invite you to &lt;a href=&quot;http://appfuse.org/display/APF/Source+Repository&quot;&gt;grab the source&lt;/a&gt; and start integrating them yourself.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/upcoming_conferences_tssjs_in_las</id>
        <title type="html">Upcoming Conferences: TSSJS in Las Vegas and 33rd Degree in Krak&#243;w, Poland</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/upcoming_conferences_tssjs_in_las"/>
        <published>2011-02-25T15:14:59-07:00</published>
        <updated>2012-11-08T14:31:01-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="ujug" scheme="http://roller.apache.org/ns/tags/" />
        <category term="uberconf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tssjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="conference" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vegas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="poland" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jazoon" scheme="http://roller.apache.org/ns/tags/" />
        <category term="33degree" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">It&apos;s that time of year again - the beginning of Conference Season. I generally like to speak at a few conferences a year and 2011 is no different. For March Madness, I&apos;ll be heading to Las Vegas to speak at &lt;a href=&quot;http://javasymposium.techtarget.com&quot;&gt;TheServerSide Java Symposium&lt;/a&gt;. I&apos;ll be giving updated talks similar to the ones I gave at last year&apos;s &lt;a href=&quot;http://www.therichwebexperience.com/conference/fort_lauderdale/2010/11/speakers/matt_raible&quot;&gt;Rich Web Experience&lt;/a&gt; in Fort Lauderdale:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/my_everything_you_ever_wanted&quot;&gt;Everything You Ever Wanted To Know About Online Video&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks&quot;&gt;Comparing JVM Web Frameworks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You might remember my Comparing JVM Web Frameworks talk from &lt;a href=&quot;http://raibledesigns.com/rd/entry/an_awesome_trip_to_amsterdam&quot;&gt;Devoxx 2010&lt;/a&gt; and some of the &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_i_calculated_ratings_for&quot;&gt;interesting debate&lt;/a&gt; it caused. I&apos;ve done some minor updates to my video presentation and some updates to my JVM Web Frameworks presentation as well. Most notably, I&apos;ll be including some findings from &lt;a href=&quot;http://ptrthomas.wordpress.com&quot;&gt;Peter Thomas&apos;s&lt;/a&gt; &lt;a href=&quot;http://code.google.com/p/perfbench/&quot;&gt;perfbench project&lt;/a&gt;. I also hope to update &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt; to JSF 2 and integrate extensionless URLs in AppFuse Light. Marcin Zajaczkowski was nice enough to provide an upgrade to &lt;a href=&quot;http://issues.appfuse.org/browse/EQX-209&quot;&gt;Wicket 1.4.15&lt;/a&gt;, so it&apos;ll be interesting to see how well Wicket supports extensionless URLs. 
&lt;/p&gt;
&lt;p&gt;In April, I&apos;ll be presenting Comparing JVM Web Frameworks at the &lt;a href=&quot;http://33degree.org/&quot;&gt;33rd Degree Conference&lt;/a&gt; in Krak&#243;w, Poland. While I studied in Russia a couple summers in college, I&apos;ve never been to Poland, so I&apos;m really looking forward to this trip. With any luck, I&apos;ll have AppFuse 2.1 released by then and my knowledge of all its web frameworks&apos; latest versions will be update-to-date. As you know, it&apos;s unlikely I&apos;ll recommend a &lt;em&gt;best&lt;/em&gt; web framework (because there isn&apos;t one), but I hope to provide some techniques you can use to decide the best framework for your particular needs.&lt;/p&gt;
&lt;p&gt;In addition to Vegas and Poland, there&apos;s a couple other events I might speak at in the next few months: the &lt;a href=&quot;http://www.ujug.org/&quot;&gt;Utah Java Users Group&lt;/a&gt; (possibly in April), &lt;a href=&quot;http://jazoon.com/&quot;&gt;Jazoon&lt;/a&gt; and &lt;a href=&quot;http://uberconf.com/conference/denver/2011/07/home&quot;&gt;&#220;ber Conf&lt;/a&gt; (if my proposals are accepted). For these events, I&apos;m hoping to present the following talk:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
&lt;strong&gt;Webapp Security: Develop. Penetrate. Protect. Relax.&lt;/strong&gt;&lt;br/&gt;
In this session, you&apos;ll learn how to implement authentication in your Java web applications using Spring Security, Apache Shiro and good ol&apos; Java EE Container Managed Authentication. You&apos;ll also learn how to secure your REST API with OAuth and lock it down with SSL.
&lt;br/&gt;&lt;br/&gt;
After learning how to develop authentication, I&apos;ll introduce you to OWASP, the OWASP Top 10, its Testing Guide and its Code Review Guide. From there, I&apos;ll discuss using WebGoat to verify your app is secure and commercial tools like webapp firewalls and accelerators.&lt;/p&gt;
&lt;/p&gt;
&lt;p&gt;If you&apos;re planning on attending &lt;a href=&quot;http://javasymposium.techtarget.com&quot;&gt;TSSJS&lt;/a&gt; or &lt;a href=&quot;http://33degree.org/&quot;&gt;33rd Degree&lt;/a&gt;, hopefully I&apos;ll see you there. </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/implementing_extensionless_urls_with_tapestry</id>
        <title type="html">Implementing Extensionless URLs with Tapestry, Spring MVC, Struts 2 and JSF</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/implementing_extensionless_urls_with_tapestry"/>
        <published>2011-02-10T16:53:27-07:00</published>
        <updated>2011-02-11T00:04:52-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="tapestry5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="extensionlessurls" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">For the past couple of weeks, I&apos;ve spent several evening hours implementing extensionless URLs in &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;. I&apos;ve been wanting to do this ever since I &lt;a href=&quot;http://raibledesigns.com/rd/entry/extensionless_urls_in_java_web&quot;&gt;wrote about how to do it&lt;/a&gt; a few years ago. This article details my experience and will hopefully help others implement this feature in their webapps.
&lt;/p&gt;
&lt;p&gt;First of all, I used the &lt;a href=&quot;http://www.tuckey.org/urlrewrite/&quot;&gt;UrlRewriteFilter&lt;/a&gt;, one of my favorite Java open source projects. Then I followed a pattern I found in Spring&apos;s &quot;mvc-basic&quot; sample app from &lt;a href=&quot;http://blog.springsource.com/2009/12/21/mvc-simplifications-in-spring-3-0/&quot;&gt;MVC Simplifications in Spring 3.0&lt;/a&gt;. The app has since changed (because SpringSource integrated UrlRewriteFilter-type functionality in Spring MVC), but the pattern was basically path-matching instead of extension-mapping. That is, the &quot;dispatcher&quot; for the web framework was mapped to /app/* instead of *.html. 
&lt;/p&gt;
&lt;p&gt;
Prior to the move to extensionless URLs, AppFuse used *.html for its mapping and this seemed to cause users problems when they wanted to serve up static HTML files. To begin with, I removed all extensions from URLs in tests (&lt;a href=&quot;http://webtest.canoo.com&quot;&gt;Canoo WebTest&lt;/a&gt; is used for testing the UI). I also did this for any links in the view pages and redirects in the Java code. This provided a decent foundation to verify my changes worked. Below are details about each framework I did this for, starting with the one that was easiest and moving to hardest.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tapestry 5&lt;/strong&gt;&lt;br/&gt;
Tapestry was by far the easiest to integrate extensionless URLs into. This is because it&apos;s a native feature of the framework and was already integrated as part of &lt;a href=&quot;http://issues.appfuse.org/browse/APF-1116&quot;&gt;Serge Eby&apos;s Tapestry 5 implementation&lt;/a&gt;. In the end, the only things I had to do where 1) add a couple entries for CXF (mapped to /services/*) and DWR (/dwr/*) to my urlrewrite.xml and 2) change the UrlRewriteFilter so it was only mapped to REQUEST instead of both REQUEST and FORWARD. Below are the mappings I added for CXF and DWR.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;urlrewrite default-match-type=&quot;wildcard&quot;&amp;gt;
    ...
    &amp;lt;rule&amp;gt;
        &amp;lt;from&amp;gt;/dwr/**&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/dwr/$1&amp;lt;/to&amp;gt;
    &amp;lt;/rule&amp;gt;
    &amp;lt;rule&amp;gt;
        &amp;lt;from&amp;gt;/services/**&amp;lt;/from&amp;gt;
        &amp;lt;to&amp;gt;/services/$1&amp;lt;/to&amp;gt;
    &amp;lt;/rule&amp;gt;
&amp;lt;/urlrewrite&amp;gt;
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Spring MVC&lt;/strong&gt;&lt;br/&gt;
I had a fair amount of experience with Spring MVC and extensionless URLs. Both the Spring MVC applications we developed last year at Time Warner Cable used them. To change from a *.html mapping to /app/* was pretty easy and involved removing more code than I added. Previously, I had a &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/common/src/main/java/org/appfuse/webapp/filter/StaticFilter.java?r=3250&quot;&gt;StaticFilter&lt;/a&gt; that looked for HTML files and if it didn&apos;t find them, it dispatched to Spring&apos;s DispatcherServlet. I was able to remove this class and make the web.xml file quite a bit cleaner. 
&lt;/p&gt;
&lt;p&gt;To make UrlRewriteFilter and Spring Security play well together, I had to move the securityFilter so it came &lt;em&gt;after&lt;/em&gt; the rewriteFilter and add an INCLUDE dispatcher so included JSPs would have a security context available to them. 
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;rewriteFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&amp;lt;filter-mapping&amp;gt;
    &amp;lt;filter-name&amp;gt;securityFilter&amp;lt;/filter-name&amp;gt;
    &amp;lt;url-pattern&amp;gt;/*&amp;lt;/url-pattern&amp;gt;
    &amp;lt;dispatcher&amp;gt;REQUEST&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;FORWARD&amp;lt;/dispatcher&amp;gt;
    &amp;lt;dispatcher&amp;gt;INCLUDE&amp;lt;/dispatcher&amp;gt;
&amp;lt;/filter-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The only other things I had to change were &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/spring/src/main/webapp/WEB-INF/security.xml?r2=3458&amp;r1=3379&quot;&gt;security.xml&lt;/a&gt; and &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/spring/src/main/webapp/WEB-INF/dispatcher-servlet.xml?r2=3458&amp;r1=3334&quot;&gt;dispatcher-servlet.xml&lt;/a&gt; to remove the .html extensions. The urlrewrite.xml file was fairly straightforward. I used the following at the bottom as a catch-all for dispatching to Spring MVC.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule&amp;gt;
    &amp;lt;from&amp;gt;/**&amp;lt;/from&amp;gt;
    &amp;lt;to&amp;gt;/app/$1&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&amp;lt;outbound-rule&amp;gt;
    &amp;lt;from&amp;gt;/app/**&amp;lt;/from&amp;gt;
    &amp;lt;to&amp;gt;/$1&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
Then I added a number of other rules for j_security_check, DWR, CXF and static assets (/images, /scripts, /styles, /favicon.ico). You can view the &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/spring/src/main/webapp/WEB-INF/urlrewrite.xml?r=HEAD&quot;&gt;current urlrewrite.xml in FishEye&lt;/a&gt;. The only major issue I ran into was that Spring Security recorded protected URLs as /app/URL so I had to add a rule to redirect when this happened after logging in.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule&amp;gt;
    &amp;lt;from&amp;gt;/app/**&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;true&quot; type=&quot;redirect&quot;&amp;gt;%{context-path}/$1&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&lt;/pre&gt;

&lt;p&gt;&lt;strong&gt;Struts 2&lt;/strong&gt;&lt;br/&gt;
Using extensionless URLs with Struts 2 is likely pretty easy thanks to the &lt;a href=&quot;http://struts.apache.org/2.1.8/docs/convention-plugin.html&quot;&gt;Convention Plugin&lt;/a&gt;. Even though this plugin is included in AppFuse, it&apos;s not configured with the proper &lt;a href=&quot;http://struts.apache.org/2.1.8/docs/converting-application-from-codebehind-to-convention-plugin.html&quot;&gt;constants&lt;/a&gt; and I have struts.convention.action.disableScanning=true in struts.xml. It looks like I had to do this when I &lt;a href=&quot;http://appfuse.markmail.org/thread/ktbqtx2mslvrkjkq&quot;&gt;upgraded from Struts 2.0.x to Struts 2.1.6&lt;/a&gt;. It&apos;s true AppFuse&apos;s Struts 2 support could use a bit of love to be aligned with Struts 2&apos;s recommended practices, but I didn&apos;t want to spend the time doing it as part of this exercise. 
&lt;/p&gt;
&lt;p&gt;With Struts 2, I tried the path-mapping like I did with Spring MVC, but ran into issues. Instead, I opted to use an &quot;.action&quot; extension by changing &lt;code&gt;struts.action.extension&lt;/code&gt; from &quot;html&quot; to &quot;action,&quot; in struts.xml. Then I had to do a bunch of filter re-ordering and dispatcher changes. Before, with a .html extension, I had all filters mapped to /* and in the following order.&lt;/p&gt;
&lt;table class=&quot;comparison&quot; style=&quot;width: 250px&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Filter Name&lt;/th&gt;&lt;th&gt;Dispatchers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;securityFilter&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;rewriteFilter&lt;/td&gt;
&lt;td&gt;request, forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts-prepare&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sitemesh&lt;/td&gt;
&lt;td&gt;request, forward, include&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;staticFilter&lt;/td&gt;
&lt;td&gt;request, forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Similar to Spring MVC, I had to remove the rewriteFilter in front of the securityFilter and I was able to remove the staticFilter. I also had to map the struts filter to *.action instead of /* to stop Struts from trying to catch static asset and DWR/CXF requests. Below is the order of filters and their dispatchers that seems to work best.
&lt;table class=&quot;comparison&quot; style=&quot;width: 250px&quot;&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Filter Name&lt;/th&gt;&lt;th&gt;Dispatchers&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;rewriteFilter&lt;/td&gt;
&lt;td&gt;request&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;securityFilter&lt;/td&gt;
&lt;td&gt;request, forward, include&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts-prepare&lt;/td&gt;
&lt;td&gt;request, forward&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;sitemesh&lt;/td&gt;
&lt;td&gt;request, forward, include&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;struts&lt;/td&gt;
&lt;td&gt;forward&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;From there, it was a matter of modifying &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/struts/src/main/webapp/WEB-INF/urlrewrite.xml?r=HEAD&quot;&gt;urlrewrite.xml&lt;/a&gt; to have the following catch-all and rules for static assets, j_security_check and DWR/CXF.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^(&amp;#91;^?&amp;#93;*)/(&amp;#91;^?/\.&amp;#93;+)(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;true&quot;&amp;gt;$1/$2.action$3&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&amp;lt;outbound-rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^(.*)\.action(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;false&quot;&amp;gt;$1$2&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;JSF&lt;/strong&gt;&lt;br/&gt;
JSF was by far the most difficult to get extensionless URLs working with. I&apos;m not convinced it&apos;s impossible, but I spent a several hours over a few days and was unsuccessful in completely removing them. I was able to make things work so I could request pages without an extension, but found when clicking buttons and links, the extension would often show up in the URL. I&apos;m also still using JSF 1.2, so it&apos;s possible that upgrading to 2.0 would solve many of the issues I encountered. &lt;/p&gt;
&lt;p&gt;For the time being, I&apos;ve changed my FacesServlet mapping from *.html to *.jsf. As with Struts, I had issues when I tried to map it to /app/*. Other changes include &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/WEB-INF/web.xml?r1=3384&amp;r2=3458#l188&quot;&gt;changing the order of dispatchers and filters&lt;/a&gt;, the good ol&apos; catch-all in &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/WEB-INF/urlrewrite.xml?r=HEAD&quot;&gt;urlrewrite.xml&lt;/a&gt; and &lt;a href=&quot;http://source.appfuse.org/browse/appfuse/trunk/web/jsf/src/main/webapp/WEB-INF/security.xml?r1=3384&amp;r2=3458#l188&quot;&gt;modifying security.xml&lt;/a&gt;. For some reason, I wasn&apos;t able to get file upload working without adding an exception to the outbound-rule.&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;rule match-type=&quot;regex&quot;&amp;gt;
    &amp;lt;from&amp;gt;^(&amp;#91;^?&amp;#93;*)/(&amp;#91;^?/\.&amp;#93;+)(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;true&quot;&amp;gt;$1/$2.jsf&amp;lt;/to&amp;gt;
&amp;lt;/rule&amp;gt;
&amp;lt;outbound-rule match-type=&quot;regex&quot;&amp;gt;
  &amp;lt;!-- TODO: Figure out how to make file upload work w/o using *.jsf --&amp;gt;
    &amp;lt;condition type=&quot;path-info&quot;&amp;gt;selectFile&amp;lt;/condition&amp;gt;
    &amp;lt;from&amp;gt;^(.*)\.jsf(\?.*)?$&amp;lt;/from&amp;gt;
    &amp;lt;to last=&quot;false&quot;&amp;gt;$1$2&amp;lt;/to&amp;gt;
&amp;lt;/outbound-rule&amp;gt;
&lt;/pre&gt;
&lt;p&gt;I also spent a couple hours trying to get &lt;a href=&quot;http://ocpsoft.com/prettyfaces/&quot;&gt;Pretty Faces&lt;/a&gt; to work. I wrote about my issues &lt;a href=&quot;http://ocpsoft.com/support/topic/rewrite-every-jsf&quot;&gt;on the forums&lt;/a&gt;. I tried writing a custom Processor to strip the extension, but found that I&apos;d get into an infinite loop where the processor kept getting called. To workaround this, I tried using Spring&apos;s RequestContextHolder to ensure the processor only got invoked once, but that proved fruitless. Finally, I tried inbound &lt;em&gt;and&lt;/em&gt; outbound custom processors, but failed to get those working. The final thing I tried was url-mappings for each page in pretty-config.xml.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;url-mapping&amp;gt;
  &amp;lt;pattern value=&quot;/admin/users&quot;/&amp;gt;
  &amp;lt;view-id value=&quot;/admin/users.jsf&quot;/&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&amp;lt;url-mapping&amp;gt;
  &amp;lt;pattern value=&quot;/mainMenu&quot;/&amp;gt;
  &amp;lt;view-id value=&quot;/mainMenu.jsf&quot;/&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;The issue with doing this was that some of the navigation rules in my faces-config.xml stopped working. I didn&apos;t spend much time trying to diagnose the problem because I didn&apos;t like having to add an entry for each page in the application. The one nice thing about Pretty Faces is it did allow me to do things like the following, which I formerly did with a form that auto-submitted when the page loaded.
&lt;/p&gt;
&lt;pre class=&quot;brush: xml&quot;&gt;
&amp;lt;url-mapping&amp;gt;
  &amp;lt;pattern value=&quot;/passwordHint/#{username}&quot;/&amp;gt;
  &amp;lt;view-id value=&quot;/passwordHint.jsf&quot;/&amp;gt;
  &amp;lt;action&amp;gt;#{passwordHint.execute}&amp;lt;/action&amp;gt;
&amp;lt;/url-mapping&amp;gt;
&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;
My journey implementing extensionless URLs was an interesting one, and I solidified my knowledge about ordering of filters, dispatchers and the UrlRewriteFilter. I still think I have more to learn about properly implementing extensionless URLs in Struts 2 and JSF and I hope to do that in the near future. I believe Struts&apos; Convention Plugin will help me and JSF 2 + Pretty Faces will hopefully work nicely too. Of course, it&apos;d be great if all Java Web Frameworks had an easy mechanism for producing and consuming extensionless URLs. In the meantime, thank goodness for the UrlRewriteFilter.
&lt;/p&gt;
&lt;p&gt;If you&apos;d like to try AppFuse and its shiny new URLs, see the &lt;a href=&quot;http://appfuse.org/display/APF/AppFuse+QuickStart&quot;&gt;QuickStart Guide&lt;/a&gt; and choose the 2.1.0-SNAPSHOT version.

</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/making_code_generation_smarter_with</id>
        <title type="html">Making Code Generation Smarter with Maven</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/making_code_generation_smarter_with"/>
        <published>2011-01-21T15:26:43-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="overstock.com" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jamon" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">As you might&apos;ve read in my &lt;a href=&quot;http://raibledesigns.com/rd/entry/2010_a_year_in_review&quot;&gt;last entry&lt;/a&gt;, I recently started a new gig with &lt;a href=&quot;http://www.overstock.com&quot;&gt;Overstock.com&lt;/a&gt;. On my first day, I was quickly immersed into the development process by joining the Conversion Team. The Conversion Team is responsible for developing the checkout UI and handling payments from customers. I quickly discovered Overstock was mostly a Linux + Eclipse Shop and did my best to get my favorite &lt;a href=&quot;http://raibledesigns.com/rd/entry/using_jrebel_with_intellij_idea&quot;&gt;Mac + IntelliJ + JRebel&lt;/a&gt; installed and configured. Thanks to my new Team Lead, I was able to get everything up and running the first day, as well as checkin my first contribution: making &lt;em&gt;mvn jetty:run&lt;/em&gt; work so I didn&apos;t have to use my IDE to deploy to Tomcat.
&lt;/p&gt;
&lt;p&gt;In setting up my environment, I couldn&apos;t help but notice running &lt;em&gt;jetty:run&lt;/em&gt; took quite a while to run each time. Specifically, the build process took 45 seconds to start executing the Jetty plugin, then another 23 seconds to startup after that. The first suspicious thing I noticed was that the UI templates were being re-generated and compiled on each execution. The UI Templating Framework at Overstock is &lt;a href=&quot;http://www.jamon.org/&quot;&gt;Jamon&lt;/a&gt;, and is described as follows:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Jamon is a text template engine for Java, useful for generating dynamic HTML, XML, or any text-based content. In a typical Model-View-Controller architecture, Jamon clearly is aimed at the View (or presentation) layer.
&lt;br/&gt;&lt;br/&gt;
Because it is compiled to non-reflective Java code, and statically type-checked, Jamon is ideally suited to support refactoring of template-based UI applications. Using mock objects -like functionality, Jamon also facilitates unit testing of the controller and view. 
&lt;/p&gt;
&lt;p&gt;To generate .java files from .jamon templates, we use the Jamon Plugin for Maven. Remembering that the &lt;a href=&quot;http://maven.apache.org/plugins/maven-compiler-plugin/&quot;&gt;Maven Compiler Plugin&lt;/a&gt; has an incremental-compile feature, I turned to its source code to find out how to implement this in the Jamon plugin. I was pleasantly surprised to find the &lt;a href=&quot;http://plexus.codehaus.org/plexus-components/plexus-compiler/plexus-compiler-api/apidocs/org/codehaus/plexus/compiler/util/scan/StaleSourceScanner.html&quot;&gt;StaleSourceScanner&lt;/a&gt;. This class allows you to easily compare two files to see if the source needs to re-examined for generation or compilation.&lt;/p&gt;
&lt;p&gt;I noticed the Jamon Plugin had the following code to figure out which files it should generate into .java files:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
private List&amp;lt;File&amp;gt; accumulateSources(File p_templateSourceDir)
{
  final List&amp;lt;File&amp;gt; result = new ArrayList&amp;lt;File&amp;gt;();
  if (p_templateSourceDir == null)
  {
    return result;
  }
  for (File f : p_templateSourceDir.listFiles())
  {
    if (f.isDirectory())
    {
      result.addAll(accumulateSources(f));
    }
    else if (f.getName().toLowerCase(Locale.US).endsWith(&quot;.jamon&quot;))
    {
      String filePath = f.getPath();
       // FIXME !?
      String basePath = templateSourceDir().getAbsoluteFile().toString();
      result.add(new File(filePath.substring(basePath.length() + 1)));
    }
  }
  return result;
}
&lt;/pre&gt;
&lt;p&gt;I changed it to be smarter and only generate changed templates with the following code:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
private List&amp;lt;File&amp;gt; accumulateSources(File p_templateSourceDir) throws MojoExecutionException
{
  final List&amp;lt;File&amp;gt; result = new ArrayList&amp;lt;File&amp;gt;();
  if (p_templateSourceDir == null)
  {
    return result;
  }
  SourceInclusionScanner scanner = getSourceInclusionScanner( staleMillis );
  SourceMapping mapping = new SuffixMapping( &quot;.jamon&quot;, &quot;.java&quot;);

  scanner.addSourceMapping( mapping );

  final Set&amp;lt;File&amp;gt; staleFiles = new LinkedHashSet&amp;lt;File&amp;gt;();

  for (File f : p_templateSourceDir.listFiles())
  {
    if (!f.isDirectory())
    {
      continue;
    }

    try
    {
      staleFiles.addAll( scanner.getIncludedSources(f.getParentFile(), templateOutputDir()));
    }
    catch ( InclusionScanException e )
    {
      throw new MojoExecutionException(
        &quot;Error scanning source root: \&apos;&quot; + p_templateSourceDir.getPath()
          + &quot;\&apos; &quot; + &quot;for stale files to recompile.&quot;, e );
    }
  }

  // Trim root path from file paths
  for (File file : staleFiles) {
    String filePath = file.getPath();
    String basePath = templateSourceDir().getAbsoluteFile().toString();
    result.add(new File(filePath.substring(basePath.length() + 1)));
  }
}
&lt;/pre&gt;
&lt;p&gt;This method references a getSourceInclusionScanner() method, which is implemented as follows:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
protected SourceInclusionScanner getSourceInclusionScanner( int staleMillis )
{
  SourceInclusionScanner scanner;

  if ( includes.isEmpty() &amp;amp;&amp;amp; excludes.isEmpty() )
  {
      scanner = new StaleSourceScanner( staleMillis );
  }
  else
  {
      if ( includes.isEmpty() )
      {
          includes.add( &quot;**/*.jamon&quot; );
      }
      scanner = new StaleSourceScanner( staleMillis, includes, excludes );
  }

  return scanner;
}
&lt;/pre&gt;
&lt;p&gt;If you&apos;re using Jamon and its Maven Plugin, you can view &lt;a href=&quot;http://sourceforge.net/tracker/index.php?func=detail&amp;amp;aid=3156388&amp;amp;group_id=138569&amp;amp;atid=741043&quot;&gt;my patch&lt;/a&gt; at SourceForge. If you&apos;re looking to include this functionality in your project, I invite you to look at the code I learned from in the Maven Compiler&apos;s &lt;a href=&quot;http://maven.apache.org/plugins/maven-compiler-plugin/xref/org/apache/maven/plugin/AbstractCompilerMojo.html#505&quot;&gt;AbstractCompilerMojo&lt;/a&gt; class.&lt;/p&gt;
&lt;p&gt;After making this change, I was able to reduce the build execution time by over 50%. Now it takes 20 seconds to hit the Jetty plugin and 42 seconds to finishing starting. Of course, in an ideal world, I&apos;d like to get this down to 20 seconds or less. Strangely enough, the easiest way to do this seems to be simple: &lt;strong&gt;use Linux&lt;/strong&gt;. 
&lt;/p&gt;
&lt;p&gt;
On the Linux desktop they provided me, it takes 12 seconds to hit the Jetty plugin and 23 seconds to finish starting. I&apos;d like to think this is a hardware thing, but it only get 20% faster on OS X when using an 8GB RAM + SSD machine (vs. a 4GB + 5400 drive). Since Overstock has &lt;a href=&quot;http://twitter.com/#!/mraible/status/22456049793499136&quot; title=&quot;I love it when clients give me a brand new MacBook Pro on my first day.&quot;&gt;provided me with a 4GB MacBook Pro&lt;/a&gt;, I&apos;m considering installing Ubuntu on it, just to see what the difference is.&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/5310291219/&quot; title=&quot;Sun over the Snowbird by mraible, on Flickr&quot;&gt;&lt;img src=&quot;//farm6.static.flickr.com/5129/5310291219_ffe75d84a7_t.jpg&quot; width=&quot;100&quot; height=&quot;75&quot; alt=&quot;Sun over the Snowbird&quot; class=&quot;picture&quot;/&gt;&lt;/a&gt;
In related news, Overstock.com is looking to hire a &lt;a href=&quot;http://www.overstock.com/javajobs&quot;&gt;whole bunch of Java Developers&lt;/a&gt; this year. The &lt;a href=&quot;http://twitter.com/#!/sammyland/status/27427352032059392&quot;&gt;pictures of the new Provo office&lt;/a&gt; look pretty sweet. Of course, you can also work at HQ, which is a mere 25 minutes from some of the best skiing in the world. Personally, I think Colorado&apos;s powder is better, but I can&apos;t argue with the convenience of no traffic. In addition to full-time gigs, they&apos;ve started hiring more remote contractors like myself, so they pretty much have something for everyone. So if you love Java, like to get some turns in before work, and aren&apos;t an asshole - you should 
&lt;script language=&quot;Javascript&quot; type=&quot;text/javascript&quot;&gt;
&lt;!--
document.write(&apos;&lt;a href=&quot;mai&apos;);
document.write(&apos;lto&apos;);
document.write(&apos;:&amp;#109;&amp;#97;&amp;#116;&amp;#116;&apos;);
document.write(&apos;@&apos;);
document.write(&apos;&amp;#114;&amp;#97;&amp;#105;&amp;#98;&amp;#108;&amp;#101;&amp;#100;&amp;#101;&amp;#115;&amp;#105;&amp;#103;&amp;#110;&amp;#115;&amp;#46;&amp;#99;&amp;#111;&amp;#109;&quot;&gt;&apos;);
document.write(&apos;contact me&lt;\/a&gt;&apos;);
// --&gt;
&lt;/script&gt;&lt;noscript&gt;&lt;a href=&quot;http://raibledesigns.com/contact.jsp&quot;&gt;contact me&lt;/a&gt;&lt;/noscript&gt;
 and I&apos;ll try to hook you up.&lt;/p&gt;
&lt;p id=&quot;update&quot;&gt;&lt;strong&gt;Update:&lt;/strong&gt; After writing this post, I received an email from &lt;a href=&quot;http://www.linkedin.com/pub/neil-hartner/4/800/852&quot;&gt;Neil Hartner&lt;/a&gt; questioning these numbers. Basically, he was able to get his MacBook Pro to run just as fast as Linux. Turns out, the reason my Mac was so much slower was because JRebel was configured in my MAVEN_OPTS. &lt;a href=&quot;http://www.zeroturnaround.com/jrebel/faq/#Does_JRebel_slow_my_system_down&quot;&gt;JRebel&apos;s FAQ&lt;/a&gt; does state the following:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
&lt;strong&gt;Does JRebel make the server start up slower?&lt;/strong&gt;&lt;br/&gt;
JRebel needs to do more work on startup (search more places for classes and resources, instrument classes, etc), so some slowdown can be expected. If it&apos;s larger than 50% please contact support@zeroturnaround.com.
&lt;/p&gt;
&lt;p&gt;
Since it&apos;s right around 50% slower, I guess there&apos;s no reason to call them. My guess is the best thing to do is remove JRebel from MAVEN_OPTS, but have an alias that can enable it, or simply run it from your IDE.&lt;/p&gt;&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/how_i_calculated_ratings_for</id>
        <title type="html">How I Calculated Ratings for My JVM Web Frameworks Comparison</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/how_i_calculated_ratings_for"/>
        <published>2010-12-06T11:55:18-07:00</published>
        <updated>2014-05-08T19:47:26-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="devoxx2010" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <category term="lift" scheme="http://roller.apache.org/ns/tags/" />
        <category term="comparingwebframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworksmatrix" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vaadin" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="flex" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="stripes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rubyonrails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxx" scheme="http://roller.apache.org/ns/tags/" />
        <category term="grails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="playframework" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">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;
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks</id>
        <title type="html">My Comparing JVM Web Frameworks Presentation from Devoxx 2010</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/my_comparing_jvm_web_frameworks"/>
        <published>2010-11-18T05:23:10-07:00</published>
        <updated>2015-08-23T18:57:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="stripes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rubyonrails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxx2010" scheme="http://roller.apache.org/ns/tags/" />
        <category term="playframework" scheme="http://roller.apache.org/ns/tags/" />
        <category term="lift" scheme="http://roller.apache.org/ns/tags/" />
        <category term="devoxx" scheme="http://roller.apache.org/ns/tags/" />
        <category term="grails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vaadin" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="flex" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">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;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_2</id>
        <title type="html">AppFuse 2.1 Milestone 2 Released</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_2"/>
        <published>2010-11-15T15:28:57-07:00</published>
        <updated>2010-11-15T22:37:10-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse-light" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="freemarker" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="stripes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ibatis" scheme="http://roller.apache.org/ns/tags/" />
        <category term="archetypes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jpa" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven3" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">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.
</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/re_moving_from_spring_to</id>
        <title type="html">RE: Moving from Spring to Java EE 6: The Age of Frameworks is Over</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/re_moving_from_spring_to"/>
        <published>2010-10-16T15:19:07-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="javaee" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="frameworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">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; </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/tssjs_2010_presentations_and_summary</id>
        <title type="html">My TSSJS 2010 Presentations and Summary</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/tssjs_2010_presentations_and_summary"/>
        <published>2010-03-19T17:29:08-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="future" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vegas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tssjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="flex" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">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.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/my_future_of_web_frameworks</id>
        <title type="html">My Future of Web Frameworks Presentation</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/my_future_of_web_frameworks"/>
        <published>2010-02-26T08:55:39-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="vegas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="theserverside" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jvm" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tssjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="future" scheme="http://roller.apache.org/ns/tags/" />
        <category term="presentation" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Earlier this week, I &lt;a href=&quot;http://twitter.com/mraible/status/9467279089&quot;&gt;tweeted about a history of web frameworks timeline&lt;/a&gt; I created for my upcoming &lt;a href=&quot;http://javasymposium.techtarget.com/html/frameworks.html#MRaibleFrameworks&quot;&gt;Future of Web Frameworks talk&lt;/a&gt; at &lt;a href=&quot;http://javasymposium.techtarget.com/&quot;&gt;TSSJS Vegas 2010&lt;/a&gt;. I immediately received a lot of feedback and requests for adding new frameworks and releases. The image below is the result of that Twitter conversation. Thanks to everyone who contributed.
&lt;/p&gt;
&lt;p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/4378559350/&quot; title=&quot;History of Web Frameworks&quot;&gt;&lt;img src=&quot;//farm5.static.flickr.com/4067/4378559350_13f0755403.jpg&quot; width=&quot;500&quot; height=&quot;239&quot; alt=&quot;History of Web Frameworks&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Back in &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_future_of_web_frameworks&quot;&gt;November&lt;/a&gt;, I wrote about my proposals for TSSJS. I&apos;ve been thinking a lot about web frameworks lately and I can&apos;t help but think we live in a very exciting time. As a Java developer, I&apos;ve been exposed to one of the most vibrant language ecosystems on the planet. As &lt;a href=&quot;http://www.javaworld.com/podcasts/jtech/2009/020909jtech-bray.html&quot;&gt;Tim Bray talks about&lt;/a&gt;, the Java Platform has 3 legs: the language, the virtual machine and a huge, immense library of APIs (both in the JDK and in open source libraries). The diagram below is something I created based on Tim&apos;s podcast.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.flickr.com/photos/mraible/4388528613/&quot; title=&quot;Java has 3 Legs&quot;&gt;&lt;img src=&quot;//farm5.static.flickr.com/4003/4388528613_18df5e164f_o.png&quot; width=&quot;418&quot; height=&quot;290&quot; alt=&quot;Java has 3 Legs&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Tim says, &quot;One of those legs is replaceable and that&apos;s the language.&quot; And he&apos;s right, there&apos;s many &lt;a href=&quot;http://blog.thinkrelevance.com/2008/9/24/java-next-overview&quot;&gt;Java.next&lt;/a&gt; languages that run efficiently on the JVM. This is one of the most exciting parts of being a Java web developer today. There&apos;s many proven web frameworks and languages that you can pick to build your next web application. 
&lt;/p&gt;
&lt;p&gt;
The best part is many of the best web frameworks run on the JVM. Not only that, but the best code editors are the IDEs that you&apos;re familiar with and have grown to love. Furthermore, much of the literature for Java.next languages is written &lt;em&gt;for&lt;/em&gt; Java developers. As someone who knows Java, you have wealth of web frameworks and languages just waiting for you to learn them. &lt;!--I think the biggest mistake you can make as developer is to stop learning. Just because you know one language/framework well doesn&apos;t mean you shouldn&apos;t learn about it&apos;s competition. Java vs. Scala, Maven vs. Ant, Rails vs. Grails, GWT vs. Flex, Tomcat vs. Jetty, Spring vs. Guice, Hibernate vs. iBATIS - your knowledge about more than one language/framework can be very rewarding.--&gt;
&lt;/p&gt;
&lt;p&gt;
To create my presentation on the future of web frameworks, I followed the outline I &lt;a href=&quot;http://raibledesigns.com/rd/entry/the_future_of_web_frameworks&quot;&gt;posted previously&lt;/a&gt;. I plan on explaining the evolution and history of web frameworks and how we got to where we are today. From there, I&apos;ll be speculating on what web applications we&apos;ll be developing in the future. Finally, I&apos;ll touch on the necessary features of web frameworks that will allow us to develop these applications. 
&lt;/p&gt;
&lt;p&gt;
Of course, I haven&apos;t actually presented this talk yet, so it&apos;s likely to change in the coming weeks before the conference. The good news is this gives you the opportunity to provide constructive criticism on this presentation and help make it better. I realize that a presentation rarely represents the conversation that takes place during a conference. However, I believe it can portray the jist of my thinking and lead to a meaningful conversation in the comments of this post.
Below is the presentation I created - thanks in advance for any feedback. 
&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;rel=0&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;rel=0&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;
For those who will be joining me at TSSJS ... it&apos;s gonna be a great show. St. Patrick&apos;s Day in Vegas, what more could you ask for? &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; This article has been &lt;a href=&quot;http://java.dzone.com/articles/my-future-web-frameworks&quot;&gt;re-posted on Javalobby&lt;/a&gt; and contains additional community feedback in the comments.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_1</id>
        <title type="html">AppFuse 2.1 Milestone 1 Released</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/appfuse_2_1_milestone_1"/>
        <published>2009-11-19T07:16:36-07:00</published>
        <updated>2014-05-08T19:47:26-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry" scheme="http://roller.apache.org/ns/tags/" />
        <category term="archetypes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse-light" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="freemarker" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="stripes" scheme="http://roller.apache.org/ns/tags/" />
        <category term="maven" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hibernate" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="myfaces" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ibatis" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jpa" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&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. </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/building_sofea_applications_with_gwt</id>
        <title type="html">Building SOFEA Applications with GWT and Grails</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/building_sofea_applications_with_gwt"/>
        <published>2009-11-12T09:30:09-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="evite" scheme="http://roller.apache.org/ns/tags/" />
        <category term="sofea" scheme="http://roller.apache.org/ns/tags/" />
        <category term="grails" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last night, I spoke at the &lt;a href=&quot;http://denverjug.org&quot;&gt;Denver Java User Group&lt;/a&gt; meeting. The consulting panel with &lt;a href=&quot;http://www.ambientideas.com/blog/&quot;&gt;Matthew&lt;/a&gt;, &lt;a href=&quot;http://www.augusttechgroup.com/tim/blog/&quot;&gt;Tim&lt;/a&gt; and &lt;a href=&quot;http://www.jroller.com/JamesGoodwill/&quot;&gt;Jim&lt;/a&gt; 
a lot of fun and I enjoyed delivering my &lt;a href=&quot;http://raibledesigns.com/rd/entry/consulting_sofea_grails_and_gwt&quot;&gt;Building SOFEA Applications with GWT and Grails&lt;/a&gt; presentation for the first time. The talk was mostly a story about how we &lt;a href=&quot;http://raibledesigns.com/rd/entry/enhancing_evite_com_with_gwt&quot;&gt;enhanced Evite.com with GWT and Grails&lt;/a&gt; and what we did to make both frameworks scale. I don&apos;t believe the presentation reflects the story format that well, but it&apos;s not about the presentation, it&apos;s about the delivery of 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;/p&gt;
&lt;p style=&quot;text-align:center&quot; id=&quot;__ss_2484656&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.slidesharecdn.com/swf/ssplayer2.swf?doc=sofeawithgwtandgrails-091112101640-phpapp01&amp;rel=0&amp;stripped_title=building-sofea-applications-with-gwt-and-grails&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=sofeawithgwtandgrails-091112101640-phpapp01&amp;rel=0&amp;stripped_title=building-sofea-applications-with-gwt-and-grails&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;If you&apos;d like to hear the story about this successful SOFEA implementation at a high-volume site, I&apos;d recommend attending the &lt;a href=&quot;http://www.therichwebexperience.com&quot;&gt;Rich Web Experience&lt;/a&gt; next month. If you attended last night&apos;s meeting and have any feedback on how this talk can be improved, I&apos;d love to hear it.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/the_future_of_web_frameworks</id>
        <title type="html">The Future of Web Frameworks at TSSJS</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/the_future_of_web_frameworks"/>
        <published>2009-11-10T13:24:39-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="vegas" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tssjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gears" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="html5" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://www.wayfaring.info/2009/08/09/caesars-palace-las-vegas/&quot; title=&quot;Caesars Palace, Las Vegas&quot;&gt;&lt;img src=&quot;//farm3.static.flickr.com/2757/4092935229_4324eb8af9_t.jpg&quot; width=&quot;100&quot; height=&quot;83&quot; alt=&quot;Caesars Palace&quot; style=&quot;border: 1px solid black&quot; class=&quot;picture&quot; /&gt;&lt;/a&gt;

For &lt;a href=&quot;http://javasymposium.techtarget.com/&quot;&gt;TSSJS Vegas 2010&lt;/a&gt;, I submitted two proposals for talks: &lt;em&gt;GWT vs. Flex Smackdown&lt;/em&gt; and &lt;em&gt;The Future of Web Frameworks&lt;/em&gt;. As of today, the 2nd is the only one that &lt;a href=&quot;http://javasymposium.techtarget.com/html/frameworks.html#MRaibleFrameworks&quot;&gt;shows up on the conference agenda&lt;/a&gt;, but hopefully the former will get accepted too. Here&apos;s a description of this talk:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
With rich Ajax applications and HTML5 on the horizon, are web frameworks still relevant? Java web frameworks like Struts and Spring MVC were all the rage 5 years ago. Component-based frameworks like Tapestry, JSF and Wicket made it easier to create re-usable applications. But what about the Mobile Web and offline applications?
&lt;br/&gt;&lt;br/&gt;
Are Titanium, Adobe Air and Gears the future? If you&apos;re embracing the RESTfulness of the web, do you even need a web framework, or can you use use JAX-RS with an Ajax toolkit?
&lt;br/&gt;&lt;br/&gt;
These questions and many more are examined, answered and debated in this lively session. Bring your opinions and experiences to this session to learn about what&apos;s dead, what&apos;s rising and what&apos;s here to stay. If you&apos;re a web framework fan, this session is sure to please.
&lt;/p&gt;
&lt;p&gt;I believe this talk will be a lot of fun to create and deliver. To create it, I&apos;d like to make it a collaborative effort with the web framework community (users and developers). To kick things off, below is an initial rough outline/agenda: &lt;/p&gt;
&lt;ul&gt;&lt;li&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Title&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Introduction&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Problem/Purpose&lt;/span&gt;&lt;/li&gt;&lt;li&gt;&lt;span style=&quot;font-weight: normal;&quot;&gt;Agenda&lt;/span&gt;&lt;/li&gt;&lt;ul&gt;&lt;li&gt;How did we get here?&lt;/li&gt;&lt;li&gt;Where are we going?&lt;/li&gt;&lt;li&gt;How do we get there?&lt;/li&gt;&lt;li&gt;Q and A&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;History of Web Frameworks&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Deep History (CGI, etc.)&lt;/li&gt;&lt;li&gt;Java&apos;s Rise&lt;/li&gt;&lt;li&gt;PHP&lt;/li&gt;&lt;li&gt;Rails -&amp;gt; Grails&lt;/li&gt;&lt;li&gt;Ajax Frameworks&lt;/li&gt;&lt;li&gt;RESTify!&lt;/li&gt;&lt;li&gt;SOFEA, APIs, etc.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;The Future&lt;/li&gt;&lt;ul&gt;&lt;li&gt;HTML5&lt;/li&gt;&lt;li&gt;GWT, Cappucino and Spoutcore (compare to Java and compilers)&lt;/li&gt;&lt;li&gt;The Binary Players (Flex, JavaFX and Silverlight)&lt;/li&gt;&lt;li&gt;Getting Rich&lt;/li&gt;&lt;li&gt;Speed (is it a problem? YES!)&lt;/li&gt;&lt;li&gt;IE 6 will die.&lt;/li&gt;&lt;li&gt;Chrome OS&lt;/li&gt;&lt;li&gt;The Mobile Web&lt;/li&gt;&lt;li&gt;Desktop Webapps (Titanium, AIR, etc.)&lt;/li&gt;&lt;li&gt;Or is this the present? Future is bleeding edge.&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Getting There: It&apos;s all about the APIs&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Allows for any client&lt;/li&gt;&lt;li&gt;Web Framework skills transfer to desktop - and phone!&lt;/li&gt;&lt;li&gt;Speed will continue to be *very* important&lt;/li&gt;&lt;li&gt;Innovation, something we haven&apos;t thought of&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Fallout&lt;/li&gt;&lt;ul&gt;&lt;li&gt;Interest in server-side frameworks will continue, but frameworks will become unmaintained&lt;/li&gt;&lt;li&gt;Ajax Frameworks will continue to innovate&lt;/li&gt;&lt;li&gt;HTML5 Frameworks?&lt;/li&gt;&lt;li&gt;IE 6 (hopefully!)&lt;/li&gt;&lt;li&gt;Desktop and Mobile with Web Technologies&lt;/li&gt;&lt;li&gt;Watch out for the next big thing! (or What do you think is the next big thing?)&lt;/li&gt;&lt;/ul&gt;&lt;li&gt;Conclusion&lt;/li&gt;&lt;li&gt;Q and A&lt;/li&gt;&lt;/ul&gt;
&lt;/p&gt;
&lt;p&gt;Is there anything I&apos;m missing that&apos;s important for the future of web frameworks? Are there items that should be removed? Any advice is most welcome.
&lt;/p&gt;
&lt;p style=&quot;border-top: 1px dotted silver; color: #666; font-style: italic; padding-top: 5px&quot;&gt;
Reminder: I&apos;ll be &lt;a href=&quot;http://raibledesigns.com/rd/entry/consulting_sofea_grails_and_gwt&quot;&gt;speaking at tomorrow&apos;s DJUG&lt;/a&gt; if you&apos;d like to discuss your thoughts in person.&lt;/p&gt;
&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/a_letter_to_the_appfuse</id>
        <title type="html">A Letter to the AppFuse Community</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/a_letter_to_the_appfuse"/>
        <published>2009-11-04T00:17:17-07:00</published>
        <updated>2009-11-04T07:32:42-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="seam" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rubyonrails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="letter" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springroo" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="grails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="play" scheme="http://roller.apache.org/ns/tags/" />
        <category term="community" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">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</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/the_2009_rich_web_experience</id>
        <title type="html">The 2009 Rich Web Experience</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/the_2009_rich_web_experience"/>
        <published>2009-08-11T22:16:24-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="nofluff" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="orlando" scheme="http://roller.apache.org/ns/tags/" />
        <category term="richwebexperience" scheme="http://roller.apache.org/ns/tags/" />
        <category term="conference" scheme="http://roller.apache.org/ns/tags/" />
        <category term="disneyworld" scheme="http://roller.apache.org/ns/tags/" />
        <category term="nofluffjuststuff" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://www.therichwebexperience.com/&quot;&gt;&lt;img src=&quot;//static.raibledesigns.com/repository/images/speakeratrichweb2009.jpg&quot; alt=&quot;Rich Web Experience 2009&quot; width=&quot;125&quot; height=&quot;125&quot; class=&quot;picture&quot;/&gt;&lt;/a&gt;
Late last year, I decided to take a year off from speaking at conferences. My reason was simple: I wanted to hunker down and do some learning. Ever since &lt;a href=&quot;http://raibledesigns.com/rd/entry/sofea_also_known_as_soui&quot;&gt;November 2007&lt;/a&gt;, I&apos;d been interested in getting into developing SOFEA applications. This year, I was able to accomplish that and I&apos;ve learned a lot about GWT and RESTful architectures in the process. Now I&apos;m happy to announce I&apos;ll be sharing my experiences at this year&apos;s &lt;a href=&quot;http://www.therichwebexperience.com/&quot;&gt;Rich Web Experience&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;I look forward to speaking on the following topics:&lt;/p&gt;
&lt;ul class=&quot;glassList&quot;&gt;
&lt;li&gt;&lt;a href=&quot;http://www.therichwebexperience.com/conference/speaker/topic_view?topicId=2103&quot;&gt;Web Frameworks of the Future: Flex, GWT, Grails, and Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.therichwebexperience.com/conference/speaker/topic_view?topicId=2104&quot;&gt;Building SOFEA Applications with Grails and GWT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first one might look familiar since I used the same title at &lt;a href=&quot;http://en.oreilly.com/oscon2008/public/schedule/detail/2651&quot;&gt;OSCON 2008&lt;/a&gt;. The difference is this time I plan to dive much deeper into the frameworks and help the audience learn more. I also plan to re-visit developing with Flex and Rails in the near future. If there&apos;s anything in particular you&apos;d like to see covered in the above talks, please leave a comment.
&lt;/p&gt;
&lt;p&gt;This is sure to be a fun conference. First of all, it&apos;s pretty close to Disney World. A few years back, TSS hosted the &quot;Java In Action&quot; conference in Disney World and while the conference didn&apos;t do too well, it was awesome being there with my family. I plan on taking my kids and having some fun when I&apos;m not speaking. Secondly, this conference is the first to offer all-inclusive pricing for attendees - registration, flight (continental U.S.) and 3 nights lodging. This should allow you to get approval without having to jump through the traditional travel hoops. Lastly, the &lt;a href=&quot;http://www.jsfsummit.com/conference/orlando/2009/12/home&quot;&gt;JSF Summit&lt;/a&gt; will be held concurrently and you get access to it at no additional cost.&lt;/p&gt;
&lt;p&gt;So come on down to Florida in December, listen to all the great speakers, have some fun with your family and look me up for a beer or two. You &lt;em&gt;know&lt;/em&gt; it&apos;ll be a good time! &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/integrating_gwt_with_spring_security</id>
        <title type="html">Integrating GWT with Spring Security</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/integrating_gwt_with_spring_security"/>
        <published>2009-08-06T08:50:15-06:00</published>
        <updated>2012-10-17T17:35:41-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="authentication" scheme="http://roller.apache.org/ns/tags/" />
        <category term="security" scheme="http://roller.apache.org/ns/tags/" />
        <category term="spring" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="springsecurity" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">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). </content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/how_to_do_cross_domain</id>
        <title type="html">How to do cross-domain GWT RPC with a ProxyServlet</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/how_to_do_cross_domain"/>
        <published>2009-08-05T16:06:12-06:00</published>
        <updated>2014-10-07T19:59:23-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="servlet" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rpc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last week, I started working on a new project using GWT. On my &lt;a href=&quot;http://raibledesigns.com/rd/entry/enhancing_evite_com_with_gwt&quot;&gt;last project&lt;/a&gt;, we used GWT &lt;a href=&quot;http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&amp;s=google-web-toolkit-doc-1-5&amp;t=DevGuideHttp&quot;&gt;HTTP Calls&lt;/a&gt; and my new project is using &lt;a href=&quot;http://code.google.com/docreader/#p=google-web-toolkit-doc-1-5&amp;s=google-web-toolkit-doc-1-5&amp;t=DevGuideRemoteProcedureCalls&quot;&gt;RPC&lt;/a&gt;. We&apos;ll likely migrate to a JSON backend eventually, but in the meantime, I wanted to be able to develop in hosted mode (localhost:8888) and call services on another host (localhost:8080), where the services are running in a JSF/Spring webapp.
&lt;/p&gt;
&lt;p&gt;At first, I thought it&apos;d be easy thanks to the handy-dandy ProxyServlet I mentioned in &lt;a href=&quot;http://raibledesigns.com/rd/entry/implementing_oauth_with_gwt&quot;&gt;Implementing OAuth with GWT&lt;/a&gt;. However, when I tried to hook it in and use it, I saw the following error in my server-side logs.&lt;/p&gt;
&lt;pre&gt;
java.lang.NullPointerException
        at javax.servlet.GenericServlet.getServletName(GenericServlet.java:322)
        at javax.servlet.GenericServlet.log(GenericServlet.java:277)
        at com.google.gwt.user.server.rpc.RemoteServiceServlet.doGetSerializationPolicy(RemoteServiceServlet.java:219)
        at com.google.gwt.user.server.rpc.RemoteServiceServlet.getSerializationPolicy(RemoteServiceServlet.java:117)
        at com.google.gwt.user.server.rpc.impl.ServerSerializationStreamReader.prepareToRead(ServerSerializationStreamReader.java:429)
        at com.google.gwt.user.server.rpc.RPC.decodeRequest(RPC.java:234)
&lt;/pre&gt;
&lt;p&gt;Looking at RemoteServiceServlet.java:219, there&apos;s a logging call that fails for some reason (at least in my application).
&lt;p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
/*
 * Check that the module path must be in the same web app as the servlet
 * itself. If you need to implement a scheme different than this, override
 * this method.
 */
if (modulePath == null || !modulePath.startsWith(contextPath)) {
  String message = &quot;ERROR: The module path requested, &quot;
      + modulePath
      + &quot;, is not in the same web application as this servlet, &quot;
      + contextPath
      + &quot;.  Your module may not be properly configured or your client and server code maybe out of date.&quot;;
  log(message, null);
}
&lt;/pre&gt;&lt;p&gt;In the above code, you might notice that GWT is checking to make sure the client is hosted in the same application as the server. After I figured this out, it was pretty easy to modify my ProxyServlet to trick GWT RPC into thinking the client was in the same web application. In the ProxyServlet&apos;s &lt;em&gt;handleContentPost&lt;/em&gt; method, I added the following code to replace &quot;localhost:8888/&quot; with &quot;localhost:8080/services/&quot; (in the content of the post to the server).
&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
if (contentType.startsWith(&quot;text/x-gwt-rpc&quot;)) {
    String clientHost = httpServletRequest.getLocalName();
    if (clientHost.equals(&quot;127.0.0.1&quot;)) {
        clientHost = &quot;localhost&quot;;
    }

    int clientPort = httpServletRequest.getLocalPort();
    String clientUrl = clientHost + ((clientPort != 80) ? &quot;:&quot; + 
                       clientPort : &quot;&quot;);
    String serverUrl = stringProxyHost + ((intProxyPort != 80) ? &quot;:&quot; + 
                       intProxyPort : &quot;&quot;) + httpServletRequest.getServletPath();
    postContent = postContent.replace(clientUrl , serverUrl);
}
&lt;/pre&gt;&lt;p&gt;After manipulating the posted content, I was successfully able to use GWT RPC cross-domain. 
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Woo hoo!&lt;/em&gt; 
&lt;/p&gt;
&lt;p&gt;
For your convenience, the full &lt;em&gt;handleContentPost()&lt;/em&gt; method is listed below.&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
private void handleContentPost(PostMethod postMethodProxyRequest, 
                               HttpServletRequest httpServletRequest) 
            throws IOException, ServletException {
    StringBuilder content = new StringBuilder();
    BufferedReader reader = httpServletRequest.getReader();
    for (;;) {
        String line = reader.readLine();
        if (line == null) break;
        content.append(line);
    }

    String contentType = httpServletRequest.getContentType();
    String postContent = content.toString();

    if (contentType.startsWith(&quot;text/x-gwt-rpc&quot;)) {
        String clientHost = httpServletRequest.getLocalName();
        if (clientHost.equals(&quot;127.0.0.1&quot;)) {
            clientHost = &quot;localhost&quot;;
        }

        int clientPort = httpServletRequest.getLocalPort();
        String clientUrl = clientHost + ((clientPort != 80) ? &quot;:&quot; + 
                           clientPort : &quot;&quot;);
        String serverUrl = stringProxyHost + ((intProxyPort != 80) ? &quot;:&quot; + 
                           intProxyPort : &quot;&quot;) + httpServletRequest.getServletPath();
        postContent = postContent.replace(clientUrl , serverUrl);
    }

    String encoding = httpServletRequest.getCharacterEncoding();
    debug(&quot;POST Content Type: &quot; + contentType + &quot; Encoding: &quot; + encoding,
          &quot;Content: &quot; + postContent);
    StringRequestEntity entity;
    try {
        entity = new StringRequestEntity(postContent, contentType, encoding);
    } catch (UnsupportedEncodingException e) {
        throw new ServletException(e);
    }
    // Set the proxy request POST data
    postMethodProxyRequest.setRequestEntity(entity);
}
&lt;/pre&gt;
&lt;a name=&quot;proxyServlet&quot;&gt;&lt;/a&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; In the comments, Ganesh asked for more details, so I figured it&apos;d be a good idea to post the full source code. First of all, &lt;a href=&quot;http://raibledesigns.com/rd/entry/how_to_do_cross_domain#proxyServlet&quot; onclick=&quot;($(&apos;#proxyServletCode&apos;).is(&apos;:visible&apos;) ? $(&apos;#proxyServletCode&apos;).hide() : $(&apos;#proxyServletCode&apos;).show()); return false&quot;&gt;click here&lt;/a&gt; to see the code for the ProxyServlet:
&lt;/p&gt;
&lt;div style=&quot;display: none&quot; id=&quot;proxyServletCode&quot;&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpMethod;
import org.apache.commons.httpclient.NameValuePair;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.commons.httpclient.methods.multipart.ByteArrayPartSource;
import org.apache.commons.httpclient.methods.multipart.FilePart;
import org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity;
import org.apache.commons.httpclient.methods.multipart.Part;
import org.apache.commons.httpclient.methods.multipart.StringPart;

/**
 * ProxyServlet from http://edwardstx.net/wiki/attach/HttpProxyServlet/ProxyServlet.java
 * (This seems to be a derivative of Noodle -- http://noodle.tigris.org/)
 * 
 * Patched to skip &quot;Transfer-Encoding: chunked&quot; headers, avoid double slashes
 * in proxied URLs, handle GZip and allow GWT RPC.
 */
public class ProxyServlet extends HttpServlet {

    private static final int FOUR_KB = 4196;

    /**
     * Serialization UID.
     */
    private static final long serialVersionUID = 1L;
    /**
     * Key for redirect location header.
     */
    private static final String STRING_LOCATION_HEADER = &quot;Location&quot;;
    /**
     * Key for content type header.
     */
    private static final String STRING_CONTENT_ENGINE_HEADER_NAME = &quot;Content-Type&quot;;
    /**
     * Key for content length header.
     */
    private static final String STRING_CONTENT_LENGTH_HEADER_NAME = &quot;Content-Length&quot;;
    /**
     * Key for host header
     */
    private static final String STRING_HOST_HEADER_NAME = &quot;Host&quot;;
    /**
     * The directory to use to temporarily store uploaded files
     */
    private static final File FILE_UPLOAD_TEMP_DIRECTORY = new File(System.getProperty(&quot;java.io.tmpdir&quot;));

    // Proxy host params
    /**
     * The host to which we are proxying requests. Default value is &quot;localhost&quot;.
     */
    private String stringProxyHost = &quot;localhost&quot;;
    /**
     * The port on the proxy host to wihch we are proxying requests. Default value is 80.
     */
    private int intProxyPort = 80;
    /**
     * The (optional) path on the proxy host to wihch we are proxying requests. Default value is &quot;&quot;.
     */
    private String stringProxyPath = &quot;&quot;;
    /**
     * Setting that allows removing the initial path from client. Allows specifying /twitter/* as synonym for twitter.com.
     */
    private boolean removePrefix;
    /**
     * The maximum size for uploaded files in bytes. Default value is 5MB.
     */
    private int intMaxFileUploadSize = 5 * 1024 * 1024;
    private boolean isSecure;
    private boolean followRedirects;

    /**
     * Initialize the &amp;lt;code&amp;gt;ProxyServlet&amp;lt;/code&amp;gt;
     * @param servletConfig The Servlet configuration passed in by the servlet container
     */
    public void init(ServletConfig servletConfig) {
        // Get the proxy host
        String stringProxyHostNew = servletConfig.getInitParameter(&quot;proxyHost&quot;);
        if (stringProxyHostNew == null || stringProxyHostNew.length() == 0) {
            throw new IllegalArgumentException(&quot;Proxy host not set, please set init-param &apos;proxyHost&apos; in web.xml&quot;);
        }
        this.setProxyHost(stringProxyHostNew);
        // Get the proxy port if specified
        String stringProxyPortNew = servletConfig.getInitParameter(&quot;proxyPort&quot;);
        if (stringProxyPortNew != null &amp;amp;&amp;amp; stringProxyPortNew.length() &amp;gt; 0) {
            this.setProxyPort(Integer.parseInt(stringProxyPortNew));
        }
        // Get the proxy path if specified
        String stringProxyPathNew = servletConfig.getInitParameter(&quot;proxyPath&quot;);
        if (stringProxyPathNew != null &amp;amp;&amp;amp; stringProxyPathNew.length() &amp;gt; 0) {
            this.setProxyPath(stringProxyPathNew);
        }
        // Get the maximum file upload size if specified
        String stringMaxFileUploadSize = servletConfig.getInitParameter(&quot;maxFileUploadSize&quot;);
        if (stringMaxFileUploadSize != null &amp;amp;&amp;amp; stringMaxFileUploadSize.length() &amp;gt; 0) {
            this.setMaxFileUploadSize(Integer.parseInt(stringMaxFileUploadSize));
        }
    }

    /**
     * Performs an HTTP GET request
     * @param httpServletRequest The {@link HttpServletRequest} object passed
     *                            in by the servlet engine representing the
     *                            client request to be proxied
     * @param httpServletResponse The {@link HttpServletResponse} object by which
     *                             we can send a proxied response to the client
     */
    public void doGet(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
            throws IOException, ServletException {
        // Create a GET request
        String destinationUrl = this.getProxyURL(httpServletRequest);
        debug(&quot;GET Request URL: &quot; + httpServletRequest.getRequestURL(),
              &quot;Destination URL: &quot; + destinationUrl);
        GetMethod getMethodProxyRequest = new GetMethod(destinationUrl);
        // Forward the request headers
        setProxyRequestHeaders(httpServletRequest, getMethodProxyRequest);
        setProxyRequestCookies(httpServletRequest, getMethodProxyRequest);
        // Execute the proxy request
        this.executeProxyRequest(getMethodProxyRequest, httpServletRequest, httpServletResponse);
    }

    /**
     * Performs an HTTP POST request
     * @param httpServletRequest The {@link HttpServletRequest} object passed
     *                            in by the servlet engine representing the
     *                            client request to be proxied
     * @param httpServletResponse The {@link HttpServletResponse} object by which
     *                             we can send a proxied response to the client
     */
    public void doPost(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse)
            throws IOException, ServletException {
        // Create a standard POST request
        String contentType = httpServletRequest.getContentType();
        String destinationUrl = this.getProxyURL(httpServletRequest);
        debug(&quot;POST Request URL: &quot; + httpServletRequest.getRequestURL(),
              &quot;    Content Type: &quot; + contentType,
              &quot; Destination URL: &quot; + destinationUrl);
        PostMethod postMethodProxyRequest = new PostMethod(destinationUrl);
        // Forward the request headers
        setProxyRequestHeaders(httpServletRequest, postMethodProxyRequest);
        setProxyRequestCookies(httpServletRequest, postMethodProxyRequest);
        // Check if this is a mulitpart (file upload) POST
        if (ServletFileUpload.isMultipartContent(httpServletRequest)) {
            this.handleMultipartPost(postMethodProxyRequest, httpServletRequest);
        } else {
            if (contentType == null || PostMethod.FORM_URL_ENCODED_CONTENT_ENGINE.equals(contentType)) {
                this.handleStandardPost(postMethodProxyRequest, httpServletRequest);
            } else {
                this.handleContentPost(postMethodProxyRequest, httpServletRequest);
            }
        }
        // Execute the proxy request
        this.executeProxyRequest(postMethodProxyRequest, httpServletRequest, httpServletResponse);
    }

    /**
     * Sets up the given {@link PostMethod} to send the same multipart POST
     * data as was sent in the given {@link HttpServletRequest}
     * @param postMethodProxyRequest The {@link PostMethod} that we are
     *                                configuring to send a multipart POST request
     * @param httpServletRequest The {@link HttpServletRequest} that contains
     *                            the mutlipart POST data to be sent via the {@link PostMethod}
     */
    @SuppressWarnings(&quot;unchecked&quot;)
    private void handleMultipartPost(PostMethod postMethodProxyRequest, HttpServletRequest httpServletRequest)
            throws ServletException {
        // Create a factory for disk-based file items
        DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
        // Set factory constraints
        diskFileItemFactory.setSizeThreshold(this.getMaxFileUploadSize());
        diskFileItemFactory.setRepository(FILE_UPLOAD_TEMP_DIRECTORY);
        // Create a new file upload handler
        ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
        // Parse the request
        try {
            // Get the multipart items as a list
            List&amp;lt;FileItem&amp;gt; listFileItems = (List&amp;lt;FileItem&amp;gt;) servletFileUpload.parseRequest(httpServletRequest);
            // Create a list to hold all of the parts
            List&amp;lt;Part&amp;gt; listParts = new ArrayList&amp;lt;Part&amp;gt;();
            // Iterate the multipart items list
            for (FileItem fileItemCurrent : listFileItems) {
                // If the current item is a form field, then create a string part
                if (fileItemCurrent.isFormField()) {
                    StringPart stringPart = new StringPart(
                            fileItemCurrent.getFieldName(), // The field name
                            fileItemCurrent.getString() // The field value
                            );
                    // Add the part to the list
                    listParts.add(stringPart);
                } else {
                    // The item is a file upload, so we create a FilePart
                    FilePart filePart = new FilePart(
                            fileItemCurrent.getFieldName(), // The field name
                            new ByteArrayPartSource(
                            fileItemCurrent.getName(), // The uploaded file name
                            fileItemCurrent.get() // The uploaded file contents
                            ));
                    // Add the part to the list
                    listParts.add(filePart);
                }
            }
            MultipartRequestEntity multipartRequestEntity = new MultipartRequestEntity(
                    listParts.toArray(new Part&amp;#91;&amp;#93;{}),
                    postMethodProxyRequest.getParams());
            postMethodProxyRequest.setRequestEntity(multipartRequestEntity);
            // The current content-type header (received from the client) IS of
            // type &quot;multipart/form-data&quot;, but the content-type header also
            // contains the chunk boundary string of the chunks. Currently, this
            // header is using the boundary of the client request, since we
            // blindly copied all headers from the client request to the proxy
            // request. However, we are creating a new request with a new chunk
            // boundary string, so it is necessary that we re-set the
            // content-type string to reflect the new chunk boundary string
            postMethodProxyRequest.setRequestHeader(STRING_CONTENT_ENGINE_HEADER_NAME, multipartRequestEntity.getContentType());
        } catch (FileUploadException fileUploadException) {
            throw new ServletException(fileUploadException);
        }
    }

    /**
     * Sets up the given {@link PostMethod} to send the same standard POST
     * data as was sent in the given {@link HttpServletRequest}
     * @param postMethodProxyRequest The {@link PostMethod} that we are
     *                                configuring to send a standard POST request
     * @param httpServletRequest The {@link HttpServletRequest} that contains
     *                            the POST data to be sent via the {@link PostMethod}
     */
    @SuppressWarnings(&quot;unchecked&quot;)
    private void handleStandardPost(PostMethod postMethodProxyRequest, HttpServletRequest httpServletRequest) {
        // Get the client POST data as a Map
        Map&amp;lt;String, String&amp;#91;&amp;#93;&amp;gt; mapPostParameters = (Map&amp;lt;String, String&amp;#91;&amp;#93;&amp;gt;) httpServletRequest.getParameterMap();
        // Create a List to hold the NameValuePairs to be passed to the PostMethod
        List&amp;lt;NameValuePair&amp;gt; listNameValuePairs = new ArrayList&amp;lt;NameValuePair&amp;gt;();
        // Iterate the parameter names
        for (String stringParameterName : mapPostParameters.keySet()) {
            // Iterate the values for each parameter name
            String&amp;#91;&amp;#93; stringArrayParameterValues = mapPostParameters.get(stringParameterName);
            for (String stringParamterValue : stringArrayParameterValues) {
                // Create a NameValuePair and store in list
                NameValuePair nameValuePair = new NameValuePair(stringParameterName, stringParamterValue);
                listNameValuePairs.add(nameValuePair);
            }
        }
        // Set the proxy request POST data
        postMethodProxyRequest.setRequestBody(listNameValuePairs.toArray(new NameValuePair&amp;#91;&amp;#93;{}));
    }

    /**
     * Sets up the given {@link PostMethod} to send the same content POST
     * data (JSON, XML, etc.) as was sent in the given {@link HttpServletRequest}
     * @param postMethodProxyRequest The {@link PostMethod} that we are
     *                                configuring to send a standard POST request
     * @param httpServletRequest The {@link HttpServletRequest} that contains
     *                            the POST data to be sent via the {@link PostMethod}
     */
    private void handleContentPost(PostMethod postMethodProxyRequest, HttpServletRequest httpServletRequest) throws IOException, ServletException {
        StringBuilder content = new StringBuilder();
        BufferedReader reader = httpServletRequest.getReader();
        for (;;) {
            String line = reader.readLine();
            if (line == null) break;
            content.append(line);
        }

        String contentType = httpServletRequest.getContentType();
        String postContent = content.toString();

        if (contentType.startsWith(&quot;text/x-gwt-rpc&quot;)) {
            String clientHost = httpServletRequest.getLocalName();
            if (clientHost.equals(&quot;127.0.0.1&quot;)) {
                clientHost = &quot;localhost&quot;;
            }

            int clientPort = httpServletRequest.getLocalPort();
            String clientUrl = clientHost + ((clientPort != 80) ? &quot;:&quot; + clientPort : &quot;&quot;);
            String serverUrl = stringProxyHost + ((intProxyPort != 80) ? &quot;:&quot; + intProxyPort : &quot;&quot;) + httpServletRequest.getServletPath();
            //debug(&quot;Replacing client (&quot; + clientUrl + &quot;) with server (&quot; + serverUrl + &quot;)&quot;);
            postContent = postContent.replace(clientUrl , serverUrl);
        }

        String encoding = httpServletRequest.getCharacterEncoding();
        debug(&quot;POST Content Type: &quot; + contentType + &quot; Encoding: &quot; + encoding,
              &quot;Content: &quot; + postContent);
        StringRequestEntity entity;
        try {
            entity = new StringRequestEntity(postContent, contentType, encoding);
        } catch (UnsupportedEncodingException e) {
            throw new ServletException(e);
        }
        // Set the proxy request POST data
        postMethodProxyRequest.setRequestEntity(entity);
    }

    /**
     * Executes the {@link HttpMethod} passed in and sends the proxy response
     * back to the client via the given {@link HttpServletResponse}
     * @param httpMethodProxyRequest An object representing the proxy request to be made
     * @param httpServletResponse An object by which we can send the proxied
     *                             response back to the client
     * @throws IOException Can be thrown by the {@link HttpClient}.executeMethod
     * @throws ServletException Can be thrown to indicate that another error has occurred
     */
    private void executeProxyRequest(
            HttpMethod httpMethodProxyRequest,
            HttpServletRequest httpServletRequest,
            HttpServletResponse httpServletResponse)
            throws IOException, ServletException {
        // Create a default HttpClient
        HttpClient httpClient = new HttpClient();
        httpMethodProxyRequest.setFollowRedirects(false);
        // Execute the request
        int intProxyResponseCode = httpClient.executeMethod(httpMethodProxyRequest);
        String response = httpMethodProxyRequest.getResponseBodyAsString();

        // Check if the proxy response is a redirect
        // The following code is adapted from org.tigris.noodle.filters.CheckForRedirect
        // Hooray for open source software
        if (intProxyResponseCode &amp;gt;= HttpServletResponse.SC_MULTIPLE_CHOICES /* 300 */ &amp;amp;&amp;amp; intProxyResponseCode &amp;lt; HttpServletResponse.SC_NOT_MODIFIED /* 304 */) {
            String stringStatusCode = Integer.toString(intProxyResponseCode);
            String stringLocation = httpMethodProxyRequest.getResponseHeader(STRING_LOCATION_HEADER).getValue();
            if (stringLocation == null) {
                throw new ServletException(&quot;Received status code: &quot; + stringStatusCode + &quot; but no &quot; + STRING_LOCATION_HEADER + &quot; header was found in the response&quot;);
            }
            // Modify the redirect to go to this proxy servlet rather that the proxied host
            String stringMyHostName = httpServletRequest.getServerName();
            if (httpServletRequest.getServerPort() != 80) {
                stringMyHostName += &quot;:&quot; + httpServletRequest.getServerPort();
            }
            stringMyHostName += httpServletRequest.getContextPath();
            if (followRedirects) {
                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);
                    //debug(&quot;redirecting: set jessionid (&quot; + cookie.getValue() + &quot;) cookie from URL&quot;);
                } else if (httpMethodProxyRequest.getResponseHeader(&quot;Set-Cookie&quot;) != null) {
	                Header header = httpMethodProxyRequest.getResponseHeader(&quot;Set-Cookie&quot;);
                    String&amp;#91;&amp;#93; cookieDetails = header.getValue().split(&quot;;&quot;);
					String&amp;#91;&amp;#93; nameValue = cookieDetails&amp;#91;0&amp;#93;.split(&quot;=&quot;);

					Cookie cookie = new Cookie(nameValue&amp;#91;0&amp;#93;, nameValue&amp;#91;1&amp;#93;);
					cookie.setPath(&quot;/&quot;);
					//debug(&quot;redirecting: setting cookie: &quot; + cookie.getName() + &quot;:&quot; + cookie.getValue() + &quot; on &quot; + cookie.getPath());
					httpServletResponse.addCookie(cookie);
                }
                httpServletResponse.sendRedirect(stringLocation.replace(getProxyHostAndPort() + this.getProxyPath(), stringMyHostName));
                return;
            }
        } else if (intProxyResponseCode == HttpServletResponse.SC_NOT_MODIFIED) {
            // 304 needs special handling.  See:
            // http://www.ics.uci.edu/pub/ietf/http/rfc1945.html#Code304
            // We get a 304 whenever passed an &apos;If-Modified-Since&apos;
            // header and the data on disk has not changed; server
            // responds w/ a 304 saying I&apos;m not going to send the
            // body because the file has not changed.
            httpServletResponse.setIntHeader(STRING_CONTENT_LENGTH_HEADER_NAME, 0);
            httpServletResponse.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
            return;
        }

        // Pass the response code back to the client
        httpServletResponse.setStatus(intProxyResponseCode);

        // Pass response headers back to the client
        Header&amp;#91;&amp;#93; 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;) || // don&apos;t copy gzip header
                    header.getName().equals(&quot;WWW-Authenticate&quot;)) { // don&apos;t copy WWW-Authenticate header so browser doesn&apos;t prompt on failed basic auth
                // proxy servlet does not support chunked encoding
            } else {
                httpServletResponse.setHeader(header.getName(), header.getValue());
            }
        }

        List&amp;lt;Header&amp;gt; responseHeaders = Arrays.asList(headerArrayResponse);

        if (isBodyParameterGzipped(responseHeaders)) {
            debug(&quot;GZipped: true&quot;);
            if (!followRedirects &amp;amp;&amp;amp; intProxyResponseCode == HttpServletResponse.SC_MOVED_TEMPORARILY) {
                response = httpMethodProxyRequest.getResponseHeader(STRING_LOCATION_HEADER).getValue();
                httpServletResponse.setStatus(HttpServletResponse.SC_OK);
                intProxyResponseCode = HttpServletResponse.SC_OK;
                httpServletResponse.setHeader(STRING_LOCATION_HEADER, response);
            } else {
                response = new String(ungzip(httpMethodProxyRequest.getResponseBody()));
            }
            httpServletResponse.setContentLength(response.length());
        }

        // Send the content to the client
        debug(&quot;Received status code: &quot; + intProxyResponseCode,
              &quot;Response: &quot; + response);

        httpServletResponse.getWriter().write(response);
    }


    /**
     * The response body will be assumed to be gzipped if the GZIP header has been set.
     *
     * @param responseHeaders of response headers
     * @return true if the body is gzipped
     */
    private boolean isBodyParameterGzipped(List&amp;lt;Header&amp;gt; responseHeaders) {
        for (Header header : responseHeaders) {
            if (header.getValue().equals(&quot;gzip&quot;)) {
                return true;
            }
        }
        return false;
    }

    /**
     * A highly performant ungzip implementation. Do not refactor this without taking new timings.
     * See ElementTest in ehcache for timings
     *
     * @param gzipped the gzipped content
     * @return an ungzipped byte&amp;#91;&amp;#93;
     * @throws java.io.IOException when something bad happens
     */
    private byte&amp;#91;&amp;#93; ungzip(final byte&amp;#91;&amp;#93; gzipped) throws IOException {
        final GZIPInputStream inputStream = new GZIPInputStream(new ByteArrayInputStream(gzipped));
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(gzipped.length);
        final byte&amp;#91;&amp;#93; buffer = new byte&amp;#91;FOUR_KB&amp;#93;;
        int bytesRead = 0;
        while (bytesRead != -1) {
            bytesRead = inputStream.read(buffer, 0, FOUR_KB);
            if (bytesRead != -1) {
                byteArrayOutputStream.write(buffer, 0, bytesRead);
            }
        }
        byte&amp;#91;&amp;#93; ungzipped = byteArrayOutputStream.toByteArray();
        inputStream.close();
        byteArrayOutputStream.close();
        return ungzipped;
    }

    public String getServletInfo() {
        return &quot;GWT Proxy Servlet&quot;;
    }

    /**
     * Retrieves all of the headers 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 setProxyRequestHeaders(HttpServletRequest httpServletRequest, HttpMethod httpMethodProxyRequest) {
        // Get an Enumeration of all of the header names sent by the client
        Enumeration enumerationOfHeaderNames = httpServletRequest.getHeaderNames();
        while (enumerationOfHeaderNames.hasMoreElements()) {
            String stringHeaderName = (String) enumerationOfHeaderNames.nextElement();
            if (stringHeaderName.equalsIgnoreCase(STRING_CONTENT_LENGTH_HEADER_NAME)) {
                continue;
            }
            // As per the Java Servlet API 2.5 documentation:
            //		Some headers, such as Accept-Language can be sent by clients
            //		as several headers each with a different value rather than
            //		sending the header as a comma separated list.
            // Thus, we get an Enumeration of the header values sent by the client
            Enumeration enumerationOfHeaderValues = httpServletRequest.getHeaders(stringHeaderName);
            while (enumerationOfHeaderValues.hasMoreElements()) {
                String stringHeaderValue = (String) enumerationOfHeaderValues.nextElement();
                // In case the proxy host is running multiple virtual servers,
                // rewrite the Host header to ensure that we get content from
                // the correct virtual server
                if (stringHeaderName.equalsIgnoreCase(STRING_HOST_HEADER_NAME)) {
                    stringHeaderValue = getProxyHostAndPort();
                }
                Header header = new Header(stringHeaderName, stringHeaderValue);
                // Set the same header on the proxy request
                httpMethodProxyRequest.setRequestHeader(header);
            }
        }
    }

    /**
     * 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&amp;#91;&amp;#93; 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());
        }
    }

    // Accessors
    private String getProxyURL(HttpServletRequest httpServletRequest) {
        // Set the protocol to HTTP
        String protocol = (isSecure) ? &quot;https://&quot; : &quot;http://&quot;;
        String stringProxyURL = protocol + this.getProxyHostAndPort();

        // simply use whatever servlet path that was part of the request as opposed to getting a preset/configurable proxy path
        if (!removePrefix) {
            stringProxyURL += httpServletRequest.getServletPath();
        }
        stringProxyURL += &quot;/&quot;;
        
        // Handle the path given to the servlet
        String pathInfo = httpServletRequest.getPathInfo();
        if (pathInfo != null &amp;amp;&amp;amp; pathInfo.startsWith(&quot;/&quot;)) {
            if (stringProxyURL != null &amp;amp;&amp;amp; stringProxyURL.endsWith(&quot;/&quot;)) {
                // avoid double &apos;/&apos;
                stringProxyURL += pathInfo.substring(1);
            }
        } else {
            stringProxyURL += httpServletRequest.getPathInfo();
        }
        // Handle the query string
        if (httpServletRequest.getQueryString() != null) {
            stringProxyURL += &quot;?&quot; + httpServletRequest.getQueryString();
        }
        
        return stringProxyURL;
    }

    private String getProxyHostAndPort() {
        if (this.getProxyPort() == 80) {
            return this.getProxyHost();
        } else {
            return this.getProxyHost() + &quot;:&quot; + this.getProxyPort();
        }
    }

    protected String getProxyHost() {
        return this.stringProxyHost;
    }

    protected void setProxyHost(String stringProxyHostNew) {
        this.stringProxyHost = stringProxyHostNew;
    }

    protected int getProxyPort() {
        return this.intProxyPort;
    }

    protected void setSecure(boolean secure) {
        this.isSecure = secure;
    }
    
    protected void setFollowRedirects(boolean followRedirects) {
        this.followRedirects = followRedirects;
    }

    protected void setProxyPort(int intProxyPortNew) {
        this.intProxyPort = intProxyPortNew;
    }

    protected String getProxyPath() {
        return this.stringProxyPath;
    }

    protected void setProxyPath(String stringProxyPathNew) {
        this.stringProxyPath = stringProxyPathNew;
    }

    protected void setRemovePrefix(boolean removePrefix) {
        this.removePrefix = removePrefix;
    }

    protected int getMaxFileUploadSize() {
        return this.intMaxFileUploadSize;
    }

    protected void setMaxFileUploadSize(int intMaxFileUploadSizeNew) {
        this.intMaxFileUploadSize = intMaxFileUploadSizeNew;
    }

    private void debug(String ... msg) {
        for (String m : msg) {
            System.out.println(&quot;&amp;#91;DEBUG&amp;#93; &quot; + m);
        }
    }
}
&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I generally subclass ProxyServlet to provide my own configuration:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public class MyProxyServlet extends ProxyServlet {

    @Override
    public void init(ServletConfig servletConfig) {
        setFollowRedirects(true);
        setRemovePrefix(false);
        setProxyPort(8080);
    }
}
&lt;/pre&gt;
&lt;p&gt;Here&apos;s another example that reads configuration settings from web.xml and proxies to a different domain name:&lt;/p&gt;
&lt;pre class=&quot;brush: java&quot;&gt;
public class AlternateHostProxyServlet extends ProxyServlet {

    @Override
    public void init(ServletConfig servletConfig) {

        setProxyHost(servletConfig.getInitParameter(&quot;proxyHost&quot;));

        String secure = servletConfig.getInitParameter(&quot;secure&quot;);
        if (secure != null) {
            setSecure(Boolean.valueOf(secure));
        }

        setFollowRedirects(false);
        setRemovePrefix(true);
        setProxyPort(80);
    }
}
&lt;/pre&gt;
&lt;p&gt;After you&apos;ve added these to your project, simply map the servlet (and its path) in your *.gwt.xml file (if you&apos;re using GWT) and your web.xml.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/ajax_framework_analysis_results</id>
        <title type="html">Ajax Framework Analysis Results</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/ajax_framework_analysis_results"/>
        <published>2009-04-23T20:34:44-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="ajax" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gxt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jquery" scheme="http://roller.apache.org/ns/tags/" />
        <category term="smartgwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="dojo" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yui" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="extjs" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Way back in January, I wrote about how my colleagues and I were &lt;a href=&quot;http://raibledesigns.com/rd/entry/choosing_an_ajax_framework&quot;&gt;evaluating Ajax frameworks&lt;/a&gt; to build a SOFEA-style architecture. To make our choice, we used the following process:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose a short list of frameworks to prototype with.&lt;/li&gt;
&lt;li&gt;Create an application prototype with each framework.&lt;/li&gt;
&lt;li&gt;Document findings and create a matrix with important criteria.&lt;/li&gt;
&lt;li&gt;Create presentation to summarize document.&lt;/li&gt;
&lt;li&gt;Deliver document, presentation and recommendation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;When I wrote that entry, we had just finished step 2 and were starting step 3. I first wrote this blog post a week later, when we delivered step 5. Here is the comparison and conclusion sections of the analysis document we composed.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Framework Comparison&lt;/strong&gt;&lt;br/&gt;
In order to evaluate the different frameworks against important criteria, we created a matrix with weights and ranks for each framework. This matrix shows how our weighting and rankings lead us to the winner for our project.  You can &lt;a href=&quot;http://spreadsheets.google.com/ccc?key=p2SLd279MTmShLQdCjfi0OQ&amp;hl=en&quot;&gt;view this matrix online&lt;/a&gt; or see below for a summary.
&lt;/p&gt;

&lt;iframe width=&apos;520&apos; height=&apos;500&apos; frameborder=&apos;0&apos; src=&apos;http://spreadsheets.google.com/pub?key=p2SLd279MTmShLQdCjfi0OQ&amp;output=html&amp;gid=0&amp;single=true&amp;widget=true&apos; style=&apos;margin: 0 auto&apos;&gt;&lt;/iframe&gt;

&lt;p style=&quot;text-align: left&quot;&gt;
&lt;strong&gt;Note:&lt;/strong&gt; Criteria whose values were identical across all candidates were weighted at zero. 
Charting capability was weighted at zero b/c we decided to use Flash for this.
&lt;/p&gt;

&lt;p&gt;This matrix indicates that &lt;strong&gt;GWT&lt;/strong&gt; is the best candidate for our team to develop SOFEA-style applications with.
In addition to the matrix, below are graphs that illustrate interesting (and possibly meaningless) statistics about each project. 
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;img src=&quot;//spreadsheets.google.com/pub?key=p2SLd279MTmShLQdCjfi0OQ&amp;amp;oid=1&amp;amp;output=image&quot; width=&quot;320&quot; alt=&quot;Number of Committers&quot;/&gt;
&lt;br/&gt;&lt;br/&gt;
&lt;!--img src=&quot;//spreadsheets.google.com/pub?key=p2SLd279MTmShLQdCjfi0OQ&amp;amp;oid=2&amp;amp;output=image&quot; width=&quot;320&quot; alt=&quot;Mailing List Traffic&quot;/&gt;
&lt;br/&gt;&lt;br/--&gt;
&lt;img src=&quot;//spreadsheets.google.com/pub?key=p2SLd279MTmShLQdCjfi0OQ&amp;amp;oid=3&amp;amp;output=image&quot; width=&quot;320&quot; alt=&quot;Books on Amazon&quot;/&gt;
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;

After working with the various frameworks, we believe that all the frameworks were very good and could be used to write applications with. If all weights are equal, these frameworks were almost even when compared against our evaluation criteria. The graph below illustrates this. 
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;img src=&quot;//spreadsheets.google.com/pub?key=p2SLd279MTmShLQdCjfi0OQ&amp;amp;oid=4&amp;amp;output=image&quot; width=&quot;320&quot; alt=&quot;Ranking with equal criteria weights&quot;/&gt;
&lt;/p&gt;
&lt;p&gt;Even after applying the weighted criteria, the evenness doesn&apos;t change a whole lot. &lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;img src=&quot;//spreadsheets.google.com/pub?key=p2SLd279MTmShLQdCjfi0OQ&amp;amp;oid=5&amp;amp;output=image&quot; width=&quot;320&quot; alt=&quot;Ranking with weighted criteria&quot; /&gt;
&lt;/p&gt;
&lt;p&gt;
Without considering the even or weighted criteria, we believe the decision all comes down to what the developers on the project feel they will be most comfortable with. If you&apos;re developing with Dojo or YUI, chances are you&apos;re &lt;em&gt;dressing up&lt;/em&gt; existing HTML and possibly using &lt;a href=&quot;http://www.alistapart.com/articles/understandingprogressiveenhancement&quot;&gt;progressive enhancement&lt;/a&gt; to add more rich functionality. On the other hand, Ext JS and GWT are similar to Swing programming where you build the UI with code (JavaScript for Ext JS, Java for GWT).
&lt;/p&gt;
&lt;p&gt;
The tools available for JavaScript development have gotten increasingly better in recent years. IntelliJ IDEA has a &lt;a href=&quot;http://www.jetbrains.com/idea/features/javascript_editor.html&quot;&gt;JavaScript Editor&lt;/a&gt; that provides many of the same features as its Java editor. &lt;a href=&quot;http://www.aptana.com/studio&quot;&gt;Aptana Studio&lt;/a&gt; also has excellent support for authoring and debugging JavaScript. However, we believe the Java debugging and authoring support in IDEs is much better. Furthermore, we are more familiar with organizing code in Java projects and feel more comfortable in this development environment. 
&lt;/p&gt;
&lt;p&gt;
Based on this evaluation, we believe that GWT is the best framework for our team to develop SOFEA-style applications with. 

&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Flash Forward to Today...&lt;/strong&gt;&lt;br/&gt;
The core GWT library from Google doesn&apos;t have a whole lot of widgets, nor do they look
good out-of-the-box.  So early on, we experimented with two alternative implementations
that continue to leverage GWT concepts and tools:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://extjs.com/products/gxt&quot;&gt;GXT&lt;/a&gt;: a GWT version of Ext JS&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://code.google.com/p/smartgwt&quot;&gt;SmartGWT&lt;/a&gt;: a GWT version of SmartClient&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Unfortunately, over the past few months, we&apos;ve found that both of these implementations are too heavy for our requirements, mostly because of the file size of the generated JavaScript code. For example, a feature I wrote generated a 275K *.cache.html file using GXT. After determining that was too slow to give users the initial &quot;pop&quot;, I re-wrote it &lt;em&gt;without&lt;/em&gt; GXT. After a day, we had an application with *.cache.html files of 133K. Yes, that&apos;s over a 50% reduction in size!&lt;a href=&quot;http://raibledesigns.com/rd/entry/ajax_framework_analysis_results#footnote-gxtmvc&quot;&gt;*&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;
Because of these findings, we are proceeding with the core GWT library from Google and adding in new components as needed.
It is cool to know you can make a UI &quot;pop&quot; with GWT, as long as you stick to the core - close-to-the-metal - components. For those applications that can afford an initial &quot;loading...&quot; state, I&apos;d definitely recommend looking at GXT and SmartGWT.
&lt;/p&gt;
&lt;p style=&quot;font-size: 90%&quot;&gt;&lt;a name=&quot;footnote-gxtmvc&quot;&gt;*&lt;/a&gt; To make refactoring easier, I copied &lt;a href=&quot;http://raibledesigns.com/rd/entry/gxt_s_mvc_framework&quot;&gt;GXT MVC&lt;/a&gt; into our source tree and modified all imports.&lt;/p&gt;
&lt;p&gt;















</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/my_drunk_on_software_interview</id>
        <title type="html">My Drunk on Software Interview</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/my_drunk_on_software_interview"/>
        <published>2009-04-05T22:23:57-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="sofea" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="drunkonsoftware" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ajax" scheme="http://roller.apache.org/ns/tags/" />
        <category term="flex" scheme="http://roller.apache.org/ns/tags/" />
        <category term="interview" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Back in February, I met up with &lt;a href=&quot;http://www.jamesward.com/blog/&quot;&gt;James Ward&lt;/a&gt; and &lt;a href=&quot;http://ectropic.com/wordpress/&quot;&gt;Jon Rose&lt;/a&gt; for a &lt;a href=&quot;http://www.drunkonsoftware.com/2009/04/05/episode-11-matt-raible/&quot;&gt;Drunk on Software interview&lt;/a&gt;. We enjoyed some &lt;a href=&quot;http://www.gordonbiersch.com/restaurants/index.php?pg=beer&quot;&gt;good beer&lt;/a&gt; and had a great conversation about SOFEA, open source and RIA. See larger video &lt;a href=&quot;http://www.drunkonsoftware.com/2009/04/05/episode-11-matt-raible/&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;embed src=&quot;//blip.tv/play/AfbqQpHGOw&quot; type=&quot;application/x-shockwave-flash&quot; width=&quot;500&quot; height=&quot;281.25&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot;&gt;&lt;/embed&gt; 
&lt;/p&gt;&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/gwt_and_appfuse</id>
        <title type="html">GWT and AppFuse</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/gwt_and_appfuse"/>
        <published>2009-03-04T22:50:26-07:00</published>
        <updated>2012-11-08T14:32:54-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="rest" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Someone recently sent me the following e-mail asking about GWT integration in &lt;a href=&quot;http://appfuse.org&quot;&gt;AppFuse&lt;/a&gt;.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
I see from your blog that you&apos;re spending some time with GWT at the moment. What&apos;s your plan, are you going to integrate GWT as another UI Option for AppFuse?
&lt;br/&gt;&lt;br/&gt;
The reason I&apos;m asking is that I actually checked out all of the AppFuse code from the svn repository yesterday, with the intention of starting off adding some GWT stuff in there. My intention was to start by getting a basic Maven archetype together for GWT as an AppFuse UI.
&lt;br/&gt;&lt;br/&gt;
However, if you&apos;re planning on doing this yourself in the near future, then there&apos;s no point in me starting doing it, I&apos;d have to learn how to write archetype&apos;s for a start (not that it looks too difficult) but you&apos;d obviously do it much quicker.
&lt;/p&gt;
&lt;p&gt;Being a good open-source developer, I moved the discussion to the developer mailing list and &lt;a href=&quot;http://www.nabble.com/Re%3A-GWT---Appfuse-to22184159s2369.html&quot;&gt;replied there&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&quot;quote&quot; style=&quot;margin-left: 0; margin-bottom: 10px&quot;&gt;
&lt;p&gt;It&apos;s likely I&apos;ll create a version of AppFuse Light with GWT, but I 
doubt I&apos;ll do it in the near future. I hope to release AppFuse 2.1 
first (which will include &quot;light&quot; archetypes). I wouldn&apos;t get your 
hopes up in waiting for me to do the work. However, I&apos;d be happy to 
assist you in doing it. AppFuse Light is now modular and uses the 
AppFuse backend. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven&quot;&gt;http://raibledesigns.com/rd/entry/appfuse_light_converted_to_maven&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Here&apos;s how I believe GWT should be integrated: 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Create an appfuse-ws archetype that serves up RESTful services 
(&lt;a href=&quot;http://issues.appfuse.org/browse/APF-897&quot;&gt;http://issues.appfuse.org/browse/APF-897&lt;/a&gt;). &lt;/li&gt;
&lt;li&gt; Create an appfuse-gwt archetype that consumes those services. This 
archetype would contain a proxy servlet that allows #1 to be on a 
separate host/port. &lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
In addition to #1, I hope to convert the Struts 2 and Spring MVC 
archetypes to use those frameworks&apos; REST support. 
&lt;/p&gt;
&lt;p style=&quot;margin-bottom: 0&quot;&gt;
For #2, we could use SmartGWT or GXT. SmartGWT might be better since 
Sanjiv is a committer on this project. &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;/div&gt;
&lt;p&gt;I know I&apos;ve been slacking on AppFuse development, but it &lt;em&gt;is&lt;/em&gt; ski season and running to work seems to drain my late-night coding ambitions. With that being said, I&apos;m committed to getting AppFuse 2.1 released by JavaOne (hopefully sooner). I figure it&apos;s a good week&apos;s worth of work and I&apos;ll probably have to do it late at night to find the time. That&apos;s OK though, I usually really start to enjoy it once I get into it.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/comparing_web_frameworks_book</id>
        <title type="html">Comparing Web Frameworks Book</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/comparing_web_frameworks_book"/>
        <published>2009-02-23T09:49:15-07:00</published>
        <updated>2012-11-08T14:33:13-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="zend" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rubyonrails" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="django" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts" scheme="http://roller.apache.org/ns/tags/" />
        <category term="book" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">A publisher recently sent me an e-mail asking some advice. They received a proposal for a book that compares CakePHP, Symfony, Zend, TurboGears, Django, Struts, RoR. Here&apos;s a quote from the proposal:
&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
We would like to compare a couple of frameworks and present their advantages and disadvantages in various applications.
&lt;br/&gt;&lt;br/&gt;
Obviously, that kind of manual would be very useful for readers who are starting their &apos;adventures&apos; with web applications, as it would facilitate their choosing the best framework for their particular application. The manuscript would offer a comparison of the most popular solutions (CakePHP, Symfony, Zend Framework, TurboGears, Django, Struts, Ruby on Rails) and demonstrate the main differences between each.
&lt;br/&gt;&lt;br/&gt;
Therefore, the target audience would mainly be project managers, responsible for deciding on the technologies to be used for in-house projects, as well as less experienced, web application beginners.
&lt;br/&gt;&lt;br/&gt;
Another purpose of the book would be to present &apos;good practices&apos; in various frameworks, such as code re-factoring, design patterns and application security. From this point of view, it could become a valuable asset for experienced and learner programmers alike.
&lt;/p&gt;
&lt;p&gt;Since I got a lot of feedback from my &lt;a href=&quot;http://twitter.com/mraible/status/1240791644&quot;&gt;tweet on this subject&lt;/a&gt;, I figured I&apos;d ask it here. 
&lt;/p&gt;
&lt;p&gt;
What do you think of such a book?&lt;/p&gt;
&lt;p&gt;
Here&apos;s my response:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
How do PHP books do these days? Of the list of frameworks (CakePHP,
Symfony, Zend Framework, TurboGears, Django, Struts, Ruby on Rails), I
think there&apos;s interest in Django and Rails, but not so much the
others. And Struts sucks, so having that as a comparison is obviously
going to make it look bad. I wouldn&apos;t buy it, but I&apos;m a Java guy
that&apos;s mostly interested in web frameworks that make developing
SOFEA-based applications easier. In my mind, these are Flex and GWT.
&lt;br/&gt;&lt;br/&gt;
The book I&apos;d like to see would cover developing RESTful backends and
SOFEA front-ends. RoR, Grails or Django could be used to develop the
backend and Flex, GWT and X could be for the front-end. In reality,
this is probably a tough book to write b/c things move so fast. If you
decide to do it, I&apos;d keep it short and sweet so you can get it to
market and update it quickly.
&lt;/p&gt;
&lt;p&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/what_s_the_best_java</id>
        <title type="html">What&apos;s the best Java Hosting Solution?</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/what_s_the_best_java"/>
        <published>2009-02-07T10:21:28-07:00</published>
        <updated>2009-03-04T15:42:50-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="kgbinternet" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="hosting" scheme="http://roller.apache.org/ns/tags/" />
        <category term="kattare" scheme="http://roller.apache.org/ns/tags/" />
        <category term="contegix" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">A friend recently asked me who I&apos;d recommend for a Java hosting provider. Since I get asked this question every-so-often, it seemed appropriate to post my answer here. 
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;http://www.kgbinternet.com&quot;&gt;KGB Internet&lt;/a&gt; - I use KGB for this site. I have my own JVM and have full control over what I want to install. I can control Tomcat versions and upgrade as needed. I don&apos;t know if I&apos;d recommend him for a business site as he can take up to 12 hours to respond to requests.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.kattare.com&quot;&gt;Kattare&lt;/a&gt; - These guys will give you your own Tomcat instance and seem to have reasonable prices. They do seem to take quite some time to respond to requests (24-48 hours). I have a free instance that I use for a non-profit, so that could be the reason.
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.contegix.com&quot;&gt;Contegix&lt;/a&gt; - These guys are far-and-away the best company for Java-based hosting. They&apos;re not cheap though. However, they have the best customer service in the business - often responding to e-mails in less than a minute.
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Do you agree with these recommendations? If not, who do you recommend for Java hosting and why?</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/choosing_an_ajax_framework</id>
        <title type="html">Choosing an Ajax Framework</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/choosing_an_ajax_framework"/>
        <published>2009-01-08T21:36:22-07:00</published>
        <updated>2009-01-09T04:42:59-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="comparison" scheme="http://roller.apache.org/ns/tags/" />
        <category term="extjs" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="dojo" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ajax" scheme="http://roller.apache.org/ns/tags/" />
        <category term="yui" scheme="http://roller.apache.org/ns/tags/" />
        <category term="frameworks" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">This past week, my colleagues and I have been researching Ajax Frameworks. We&apos;re working on a project that&apos;s following SOFEA-style architecture principles and we want the best framework for our needs. I&apos;m writing this post to see 1) if you, the community, agree with our selection process and 2) to learn about your experiences with the frameworks we&apos;re evaluating. Below is the process we&apos;re following to make our choice.
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Choose a short list of frameworks to prototype with.&lt;/li&gt;
&lt;li&gt;Create an application prototype with each framework.&lt;/li&gt;
&lt;li&gt;Document findings and create a matrix with important criteria.&lt;/li&gt;
&lt;li&gt;Create presentation to summarize document.&lt;/li&gt;
&lt;li&gt;Deliver document, presentation (with demos) and recommendation.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;For #1, we chose  &lt;a href=&quot;http://extjs.com/products/extjs/&quot;&gt;Ext JS&lt;/a&gt;, &lt;a href=&quot;http://dojotoolkit.org/&quot;&gt;Dojo&lt;/a&gt;, &lt;a href=&quot;http://developer.yahoo.com/yui/&quot;&gt;YUI&lt;/a&gt; and &lt;a href=&quot;http://code.google.com/intl/nl/webtoolkit/&quot;&gt;GWT&lt;/a&gt; because we feel these Ajax libraries offer the most UI widgets. We also considered Prototype/Scriptaculous, jQuery and MooTools, but decided against them because of their lack of UI widgets.&lt;/p&gt;
&lt;p&gt;For #2, we time-boxed ourselves to 3 days of development. In addition to basic functionality, we added several features (i.e. edit in place, drag and drop, calendar widgets, transitions, charts, grid) that might be used in the production application. We all were able to complete most of the functionality of the application. Of course, there&apos;s still some code cleanup as well as styling to make each app look good for the demo. The nice thing about doing this is we&apos;re able to look at each others code and see how the same thing is done in each framework. None of us are experts in any of the frameworks, so it&apos;s possible we could do things better. However, I think it&apos;s good we all started somewhat green because it shows what&apos;s possible for someone relatively new to the frameworks.&lt;/p&gt;
&lt;p&gt;For #3, we&apos;re creating a document with the following outline:&lt;/p&gt;
&lt;pre style=&quot;font-family: inherit; background: #CDFFCC; border: 1px solid #54FF52; width: 250px; padding-left: 20px&quot;&gt;
Introduction

Ajax Framework Candidates
(intro and explanation)

  Project Information
  (history)
  (license / cost)
  (number of committers)
  (support options)
  (mailing list traffic (nov/dec 2008))

Matrix and Notes

Conclusion
&lt;/pre&gt;
&lt;p&gt;For the Matrix referenced in the outline above, we&apos;re using a table with weights and ranks:&lt;/p&gt;

&lt;table class=&quot;comparison&quot; style=&quot;width: 500px&quot;&gt;
    &lt;thead&gt;
    &lt;tr&gt;
        &lt;th&gt;Weight&lt;/th&gt;
        &lt;th&gt;Criteria&lt;/th&gt;
        &lt;th&gt;Dojo&lt;/th&gt;
        &lt;th&gt;YUI&lt;/th&gt;
        &lt;th&gt;GWT&lt;/th&gt;
        &lt;th style=&quot;white-space: nowrap&quot;&gt;Ext JS&lt;/th&gt;
        &lt;th&gt;Notes&lt;/th&gt;
    &lt;/tr&gt;
    &lt;/thead&gt;
    &lt;tbody&gt;
    &lt;tr&gt;
        &lt;td&gt;#&lt;/td&gt;
        &lt;td&gt;Important Criteria for Customer&lt;/td&gt;
        &lt;td&gt;0..1&lt;/td&gt;
        &lt;td&gt;0..1&lt;/td&gt;
        &lt;td&gt;0..1&lt;/td&gt;
        &lt;td&gt;0..1&lt;/td&gt;
        &lt;td&gt;Notes about rankings&lt;/td&gt;
    &lt;/tr&gt;
    &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Our strategy for filling in this matrix:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Customer adjusts the weight for each criteria (removing/adding as needed) so all weights add up to 1.&lt;/li&gt;
&lt;li&gt;We rank each framework with 0, .5 or 1 where 0 = doesn&apos;t satisfy criteria, .5 = partially satisfies, 1 = satisfies.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The list of criteria provided to us by our client is as follows (in no particular order).&lt;/p&gt;
&lt;ul&gt;&lt;li&gt;Quality of Documentation/Tutorials/Self Help&lt;/li&gt;
&lt;li&gt;Browser support (most important browsers/versions based on web stats)&lt;/li&gt;
&lt;li&gt;Testability (esp. Selenium compatibility)&lt;/li&gt;
&lt;li&gt;Licensing&lt;/li&gt;
&lt;li&gt;Project health/adoption&lt;/li&gt;
&lt;li&gt;Performance&lt;/li&gt;
&lt;li&gt;Scalability&lt;/li&gt;
&lt;li&gt;Flexibility/extensibility&lt;/li&gt;
&lt;li&gt;Productivity (app dev, web dev)&lt;/li&gt;
&lt;li&gt;Richness of widget/component library&lt;/li&gt;
&lt;li&gt;Charting capability&lt;/li&gt;
&lt;li&gt;Ability to create new widgets&lt;/li&gt;
&lt;li&gt;Match to existing Java team skill-set&lt;/li&gt;
&lt;li&gt;Ease of deployment (on Ops, QA, Users)&lt;/li&gt;
&lt;li&gt;Degree of risk generally&lt;/li&gt;
&lt;li&gt;Ability to integrate with existing site (which includes Prototype)&lt;/li&gt;
&lt;li&gt;Easy to style with CSS&lt;/li&gt;
&lt;li&gt;Validation (esp. marking form elements invalid)&lt;/li&gt;
&lt;li&gt;Component Theme-ing/Decoration&lt;/li&gt;
&lt;li&gt;CDN Availability (i.e. Google&apos;s Ajax Libraries API or Ext CDN)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;What do you think? How could this process be improved? Of course, if you have framework answers (0, .5 or 1) for our matrix, we&apos;d love to hear your opinions.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/dojo_comet_support_in_java</id>
        <title type="html">Dojo/Comet support in Java Web Frameworks</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/dojo_comet_support_in_java"/>
        <published>2008-12-18T15:58:37-07:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="dojo" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry5" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="tapestry" scheme="http://roller.apache.org/ns/tags/" />
        <category term="comet" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://dojotoolkit.org/&quot; title=&quot;Dojo Toolkit&quot;&gt;&lt;img src=&quot;//farm4.static.flickr.com/3283/3118492275_8d4cb574d5_t.jpg&quot; width=&quot;100&quot; height=&quot;66&quot; alt=&quot;Dojo Logo&quot; class=&quot;picture&quot; style=&quot;border: 0; margin-top: -10px&quot; /&gt;&lt;/a&gt;
This week I&apos;m doing a research project for a client. The main purpose of the project is to find out which Java-based web framework works best with Dojo and Comet. Here&apos;s the key requirement from the client:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
It&apos;s all about Comet, we want Comet everywhere we can put it, but we want to isolate the icky bits of fiddling with pages with JavaScript. We&apos;re kind of wed to the Dojo implementation of the client-side bit, so we may as well use more of the Dojo widgets for a richer UI. For us, &quot;works best with&quot; needs to pay a certain amount of consideration to &quot;fits naturally with&quot;, if you understand what I mean. I know that any framework that lets you spit out raw HTML will let you hand code in your Dojo / Comet, but that&apos;s certain to become very tiresome very quickly.&lt;/p&gt;
&lt;p&gt;The candidate frameworks they asked me to look at are &lt;a href=&quot;http://wicket.apache.org&quot;&gt;Wicket&lt;/a&gt; and &lt;a href=&quot;http://tapestry.apache.org&quot;&gt;Tapestry 5&lt;/a&gt;. They&apos;re willing to upgrade to Struts 2 since they&apos;re already using Struts 1. However, they don&apos;t feel that action-based frameworks naturally lead to rich UIs, so they&apos;d prefer a component-based framework. They&apos;re currently using &lt;a href=&quot;http://seamframework.org&quot;&gt;Seam&lt;/a&gt; for an administration-type application and feel it&apos;s too heavy for their customer-facing application.&lt;/p&gt;
&lt;p&gt;Here&apos;s what I&apos;ve found so far in my research. Please let me know if anything is incorrect.
&lt;ul&gt;
&lt;li&gt;Tapestry 5 doesn&apos;t have Dojo or Comet support (Prototype and Scriptaculous are the &lt;a href=&quot;http://tapestry.apache.org/tapestry5/tapestry-core/guide/ajax.html&quot;&gt;baked-in Ajax frameworks&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Struts 2 has old (version 0.4.3) and somewhat deprecated &lt;a href=&quot;http://struts.apache.org/2.0.11/docs/ajax-tags.html&quot;&gt;Dojo support&lt;/a&gt;. The developers seem to be in favor of removing it and promoting people hand-code Dojo instead. Struts 2 doesn&apos;t have support for Comet.&lt;/li&gt;
&lt;li&gt;Wicket has &lt;a href=&quot;http://wicketstuff.org/confluence/display/STUFFWIKI/wicketstuff-dojo-1.1&quot;&gt;support for Dojo 1.1 that includes Comet support&lt;/a&gt;. This was written by Stefan Fu&#223;enegger and &lt;a href=&quot;http://www.nabble.com/Dojo-1.1-integration-available-from-wicketstuff-td20625220.html#a20625220&quot;&gt;posted to the mailing list last month&lt;/a&gt;. I e-mailed Stefan and asked him about documentation. His response: &quot;I lost my ambition to document it properly since I didn&apos;t receive any feedback on the mailing list. :)&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;At this point, it seems that if the client &lt;em&gt;really&lt;/em&gt; wants to use Dojo, they should use Wicket, and possibly pay Stefan to document it properly. However, they&apos;re willing to consider other options, as long as they have Comet support.
&lt;/p&gt;
&lt;p&gt;
One option I thought of is to use DWR and its &lt;a href=&quot;http://directwebremoting.org/dwr/reverse-ajax&quot;&gt;Reverse Ajax/Comet support&lt;/a&gt;. Another option would be to add better Dojo support to Tapestry 5. However, I don&apos;t think this is possible since the Prototype/Scriptaculous code is generated by the framework and would likely require a changes to switch it to Dojo. 
&lt;/p&gt;
&lt;p&gt;Are there any other Java-based web frameworks that support easily creating Dojo widgets and working with Comet? &lt;a href=&quot;http://www.springsource.com/people/kdonald&quot;&gt;Keith Donald&lt;/a&gt; tweeted that &lt;a href=&quot;http://twitter.com/kdonald/status/1064067717&quot;&gt;Spring MVC has Dojo support&lt;/a&gt;. However, I believe it&apos;s only for widgets and it still requires you to write JavaScript. If your framework doesn&apos;t have Dojo/Comet support, how hard would it be to add it?&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; I also posted this question on LinkedIn. Make sure and check &lt;a href=&quot;http://www.linkedin.com/answers/technology/web-development/TCH_WDD/385881-5747&quot;&gt;my question&lt;/a&gt; for additional thoughts from folks.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/restful_web_applications_with_subbu</id>
        <title type="html">RESTful Web Applications with Subbu Allamaraju</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/restful_web_applications_with_subbu"/>
        <published>2008-10-24T09:52:02-06:00</published>
        <updated>2009-06-04T20:04:17-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="sofea" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appcelerator" scheme="http://roller.apache.org/ns/tags/" />
        <category term="softwaresummit" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="java" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rest" scheme="http://roller.apache.org/ns/tags/" />
        <category term="servlets" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Subbu works at Yahoo! developing standards, patterns and practices for HTTP web languages. In the past, he was a web service and Java developer. He was also a standards contributor at BEA and an author of books on Java EE. His current passion is HTTP and REST. Subbu confesses that he&apos;s not a web developer, has no interest in the internals of programming models used for web frameworks and he&apos;s only interested in the visible aspects of the architecture.
&lt;/p&gt;
&lt;p&gt;&quot;The Web is Mostly Restful&quot;&lt;/p&gt;
&lt;p&gt;Being RESTful in an abstract sense means:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Resources are named by URIs&lt;/li&gt;
&lt;li&gt;Resources have representations (Atom, HTML, JSON, XML)&lt;/li&gt;
&lt;li&gt;Resources contain contextual links to allow navigation of state&lt;/li&gt;
&lt;li&gt;There&apos;s a Uniform Interface&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
In the web today, some resources and URIs are personalized, but most are not. Some depend on sessions, but most do not. The consequence of a personalized UI with a non-unique URI is you cannot rely on browser caching. &lt;/p&gt;
&lt;p&gt;The web is full of different representations (HTML, XML, JS, PDF, CSS, Flash). The problem with HTML is you can&apos;t tell links that you want a particular representation based of a link. The links are hard-coded to be a particular content-type. However, some media types on responses are ignored. This is often a problem with browsers and whether the user has plugins installed.&lt;/p&gt;
&lt;p&gt;The Uniform Interface for the web is HTML and primarily links and forms (GET and POST). There&apos;s still some misconceptions (e.g. POST is secure). However, it&apos;s not about security, it&apos;s about idempotency and safety. You need to make sure you only use POST when you&apos;re changing data. POSTs are not repeatable. GET URIs are not always refreshable, which is quite unfortunate. Users shouldn&apos;t have to fight the back button.&lt;/p&gt;
&lt;p&gt;Caching is a fundamental aspect of the web. Even in a personalized site, most of the content can be cached. The web is read-only for the most part. However, many enterprise web applications don&apos;t take advantage of caching. This is fine when there&apos;s not that many users, but it&apos;s bad when you want to scale to thousands of users. There&apos;s several frameworks that use cache-busting and prefer backend caching over HTTP caching. These frameworks are not using the web like they should.&lt;/p&gt;
&lt;p&gt;Backend caching (e.g. Memcached) uses a non-uniform interface and you need to explicitly program to it. Frontend/HTTP caching has a uniform interface that&apos;s pluggable. Backend caching is generally more expensive to develop and deploy. There are cases where data should be cached on the backend, but you shouldn&apos;t focus all on backend caching w/o doing some frontend caching.
&lt;/p&gt;
&lt;p&gt;With Ajax, you get more opportunities to be RESTful. XMLHttpRequest is another HTTP client that can be programmed to. It has full support for the uniform interface, which allows content negotiation, optimistic concurrency and caching. Cross-domain hacks can be done with &amp;lt;script&gt; and &amp;lt;iframe&gt; to tunnel requests over GET. The W3C has been working for the last two years on how to do cross-domain Ajax w/o using hacks. The problem with current cross-domain implementations is they often use GET for everything, which isn&apos;t very RESTful. Subbu recommends using a proxy on the same domain if you do need to talk to other domains. This will allow your Ajax code to remain RESTful.
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web Frameworks&lt;/strong&gt;&lt;br/&gt;
Web development is hard because of all the moving pieces that exist. Because of this, many web frameworks have been created to solve the various problems. In 1997, there were servlets. They provided basic plumbing and closely reflected HTTP/1.1. Servlets provided a poor programming model, but it allowed a lot of frameworks to be built on top of it. We don&apos;t use servlets to write applications, only to write application frameworks. The second era came about in 2001 when Action-oriented frameworks became popular. In 2004, JSF and friends came to play. JSF is a component-based framework with known limitations (complex, slow, uses POST for almost everything, Ajax is difficult). These limitations have resulted in a number of third-party patches being developed to solve these issues.&lt;/p&gt;
&lt;p&gt;JSF was designed to use the request to create a component tree that maintains state. Unfortunately, the state is not something the developer has control over. It&apos;s not the state of the application, it&apos;s the state of the components. The client&apos;s knowledge of the state is mentioned with a cookie and the server keeps the state in the session. The problem with JSF is you don&apos;t have a choice of state in your application - you can&apos;t write stateless applications like you can with servlets.
&lt;/p&gt;
&lt;p&gt;JSF uses overloaded URIs for its resources. When you have one URI with multiple representations, there&apos;s no way to tell how a representation was chosen. JSF&apos;s compromise is to allow client-side state saving. However, they do this by putting hidden field in the form and requiring POST for navigation. 
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;JSF vs. REST&lt;/strong&gt;&lt;br/&gt;
Basically, these two are at opposite extremes. JSF is focused heavily on a UI component model. The people that developed it misinterpreted how the web works and made some fundamental questionable choices. You can patch it, but you can not fix it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Web 2.0 Frameworks&lt;/strong&gt;&lt;br/&gt;
GWT is a cross-compilation based framework. You write Java to generate JavaScript (b/c everyone hates writing JavaScript). It mashes client and server code into a single source. These layers communicate using GWT-RPC. Typical RPC concerns do not apply since code generation handles coupling and the client is downloaded from the same application. GWT-PRC does POSTs to the server and uses HTTP like a transport layer. To be fair, GWT does allow you to use a RequestBuilder to use the web like it should be used.
This class allows more control over HTTP requests, it supports GET and POST and it allows so-called RESTful layers (GWT-REST and GET-Restlet). GWT is focused heavily on ease-of-use, which is good. It&apos;s modeled after RPC and breaks the uniform interface and focuses on backend caching. Unlike JSF, GWT is fixable, but the community tends to use RPC instead of RequestBuilder.
&lt;/p&gt;
&lt;p&gt;SOFEA has a central promise of SOA. Business logic is a reusable service that changes less often. The presentation application calls those services and changes more often. The nice thing about this type of architecture is it allows a separation of concerns and loose coupling. However, it doesn&apos;t embrace REST like it should. Appcelerator is an implementation of SOFEA that has a Ruby on Rails-like usability. However, it uses a SOAP/HTTP style with messaging and POSTs to a single URI. Appcelerator is interesting, but it introduces a different style of coupling. It breaks URI opacity and client deals with POX instead of links. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Conclusion&lt;/strong&gt;&lt;br/&gt;
Don&apos;t fight the architecture of the web. Innovate and enhance instead of breaking. If nothing else, break judiciously. As developers, we should demand more from our frameworks and make sure they use the web and HTTP like it should be used.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/xebia_ria_framework_contest</id>
        <title type="html">Xebia RIA Framework Contest</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/xebia_ria_framework_contest"/>
        <published>2008-10-07T08:06:48-06:00</published>
        <updated>2012-11-08T14:33:55-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="silverlight" scheme="http://roller.apache.org/ns/tags/" />
        <category term="echo3" scheme="http://roller.apache.org/ns/tags/" />
        <category term="javafx" scheme="http://roller.apache.org/ns/tags/" />
        <category term="flex" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ria" scheme="http://roller.apache.org/ns/tags/" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="comparison" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Last year, I blogged about the &lt;a href=&quot;http://raibledesigns.com/rd/entry/xebia_web_framework_contest&quot;&gt;Xebia Web Framework Contest&lt;/a&gt; where Struts 2, GWT, Wicket and MyFaces (JSF) were all used to develop the same applications. It seems they&apos;ve done it again this year, &lt;a href=&quot;http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/&quot;&gt;comparing RIA frameworks&lt;/a&gt; (&lt;a href=&quot;http://translate.google.com/translate?u=http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/&amp;amp;hl=fr&amp;amp;ie=UTF-8&amp;amp;sl=fr&amp;amp;tl=en&quot;&gt;English translation&lt;/a&gt;) this time. 
&lt;/p&gt;
&lt;div style=&quot;margin-left: 0; margin-bottom: 10px&quot; class=&quot;quote&quot;&gt;
&lt;p&gt;Five teams were formed, five frameworks have been selected:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Flex 3 Flex 3&lt;/li&gt;
&lt;li&gt;Silverlight 2.0 beta 2 Silverlight 2.0 beta 2&lt;/li&gt;
&lt;li&gt;Google GWT 1.5 Google GWT 1.5&lt;/li&gt;
&lt;li&gt;Echo3 Echo3&lt;/li&gt;
&lt;li&gt;JavaFX Preview SDK JavaFX SDK Preview&lt;/li&gt;
&lt;/ul&gt;
&lt;p style=&quot;margin-bottom: 0&quot;&gt;The number of teams is limited, the list of frameworks is also selected, and we have therefore necessarily set aside some frameworks that would have certainly had their place in the contest. Examples Ext JS, Yahoo! UI, Curl, XUL, ZK or OpenLaszlo. If you have experience on one of these frameworks, feel free to share in the comments on this article! [&lt;a href=&quot;http://blog.xebia.fr/2008/10/03/ria-contest-flex-silverlight-gwt-echo3-javafx/&quot;&gt;Read More &amp;raquo;&lt;/a&gt;]&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;The winner? &lt;strong&gt;Flex&lt;/strong&gt; - which doesn&apos;t surprise me a whole lot.&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
After this day, the Flex team, has clearly demarcated from its competitors. After two sprints of development and ownership, it could devote the third and final sprint to get rich quick and easy application, focusing only on the features and user experience. It is thanks to the wealth of high-level components, the wealth of documentation available and a maturity framework that the team has made the Flex application&apos;s most successful.
&lt;/p&gt;
&lt;p&gt;Good stuff - thanks Xebia!</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/ajaxified_body</id>
        <title type="html">Ajaxified Body</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/ajaxified_body"/>
        <published>2008-10-03T14:33:09-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="appfuselight" scheme="http://roller.apache.org/ns/tags/" />
        <category term="sitemesh" scheme="http://roller.apache.org/ns/tags/" />
        <category term="ajax" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">I&apos;ve often wondered if it was possible to use Ajax to reload the main content of a web application without reloading the header, menu and footer. &lt;a href=&quot;http://www.opensymphony.com/sitemesh&quot;&gt;SiteMesh&lt;/a&gt; allows you to move these common elements to a &lt;em&gt;decorator&lt;/em&gt; that gets wrapped around each page. Below is a diagram of how SiteMesh works.
&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://farm4.static.flickr.com/3276/2908373749_1ce4581bba_o.png&quot; title=&quot;SiteMesh&quot; rel=&quot;lightbox[ajaxifiedbody]&quot;&gt;&lt;img src=&quot;//farm4.static.flickr.com/3276/2908373749_fff90b124b.jpg&quot; width=&quot;500&quot; height=&quot;344&quot; alt=&quot;SiteMesh&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
You can read the &lt;a href=&quot;http://today.java.net/pub/a/today/2004/03/11/sitemesh.html&quot;&gt;Introduction to SiteMesh&lt;/a&gt; article if you&apos;re interested in learning more about SiteMesh&apos;s basic features. By default, SiteMesh decorates &lt;code&gt;text/html&lt;/code&gt; responses and ignores any other content type (e.g. &lt;code&gt;image/gif&lt;/code&gt;). It also contains an &amp;lt;excludes&gt; configuration element that allows you to turn off decoration when a URL matches a certain pattern. For example, the following allows you to disable decoration when &quot;ajax=true&quot; is passed in the URL.
&lt;/p&gt;
&lt;pre&gt;
&amp;lt;excludes&amp;gt;
    &amp;lt;pattern&amp;gt;**ajax=true&amp;lt;/pattern&amp;gt;
&amp;lt;/excludes&amp;gt;
&lt;/pre&gt;
&lt;p&gt;
To optimize the loading of an application so the common elements aren&apos;t loaded for each page, it should be possible to create an &lt;strong&gt;Ajaxified Body&lt;/strong&gt; where the primary content area (PCA) of the site is loaded via Ajax rather than refreshing the whole page. The header, footer and navigation bar often stays the same from page-to-page, so it doesn&apos;t seem to make a whole lot of sense to load them each time the page loads. The image below shows the PCA (of an AppFuse Light application) as a grey square with a red border.
&lt;/p&gt;
&lt;p style=&quot;text-align: center; margin-bottom: 0&quot;&gt;
&lt;a href=&quot;http://farm4.static.flickr.com/3107/2909207040_f661f9e60e_o.png&quot; title=&quot;Ajaxified Body - AppFuse Light&quot; rel=&quot;lightbox[ajaxifiedbody]&quot;&gt;&lt;img src=&quot;//farm4.static.flickr.com/3107/2909207040_46c379c0ae.jpg&quot; width=&quot;500&quot; height=&quot;432&quot; alt=&quot;Ajaxified Body - AppFuse Light&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Implementing an &lt;strong&gt;Ajaxified Body&lt;/strong&gt; consists of the following steps:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Adding SiteMesh and moving common elements to a decorator.&lt;/li&gt;
&lt;li&gt;Remove common elements from each individual page (if you&apos;re using includes).&lt;/li&gt;
&lt;li&gt;Configure SiteMesh so decoration is disabled when the requested URL contains &quot;ajax=true&quot;.&lt;/li&gt;
&lt;li&gt;Write JavaScript that modifies all &amp;lt;a href=&quot;&quot;&gt; links (and buttons with onclick=&apos;location.href&apos;) in the PCA to have an onclick handler.&lt;/li&gt;
&lt;li&gt;The onclick handler should call a JavaScript function that loads the link&apos;s URL + ajax=true using XMLHttpRequest (XHR).&lt;/li&gt;
&lt;li&gt;Add XHR success handling to replace the PCA with the loaded content.&lt;/li&gt;
&lt;li&gt;Add XHR error handling to go to the URL normally when response.status != 200.&lt;/li&gt;
&lt;li&gt;Inspect the response HTML for &amp;lt;title&gt; element and replace document.title if exists.&lt;/li&gt;
&lt;li&gt;Inspect the response HTML for &amp;lt;head&gt; element and append to current &lt;head&gt; if exists.&lt;/li&gt;
&lt;li&gt;Inspect the response HTML for &amp;lt;script&gt; and &amp;lt;link&gt; elements (JavaScript and CSS) and evaluate them if they exist.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
As a proof of concept, I created a prototype using &lt;a href=&quot;https://appfuse-light.dev.java.net&quot;&gt;AppFuse Light&lt;/a&gt; (Prototype/Scriptaculous for Ajax). You can see a demo at the following URL. You can also &lt;a href=&quot;http://demo.raibledesigns.com/ajaxifiedbody/ajaxifiedbody.patch&quot;&gt;download a patch&lt;/a&gt; or &lt;a href=&quot;http://demo.raibledesigns.com/ajaxifiedbody/ajaxifiedbody-1.0.zip&quot;&gt;the source&lt;/a&gt; for this project. &lt;/p&gt;
&lt;p style=&quot;margin-left: 30px&quot;&gt;
&lt;a href=&quot;http://demo.raibledesigns.com/ajaxifiedbody&quot;&gt;http://demo.raibledesigns.com/ajaxifiedbody&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Below are a number of things I discovered while writing this prototype:
&lt;/p&gt;
&lt;ul class=&quot;glassList&quot;&gt;
&lt;li&gt;The hardest part of implementing this seems to be coding the exceptions. It&apos;s possible you&apos;ll have some links with existing onclick handlers and you may have to disable &quot;ajaxifying links&quot; for those links.&lt;/li&gt;
&lt;li&gt;A progress indicator is important or the page might load so fast that the user doesn&apos;t visually detect it changed. This can lead to a worse user experience because they don&apos;t see the flash of the blank page they&apos;re used to when a page load occurs.&lt;/li&gt;
&lt;li&gt;While forms can be submitted via Ajax, there&apos;s no harm in leaving existing form behavior in place where the full site is reloaded after submitting a form.&lt;/li&gt;
&lt;li&gt;If a particular page needs to change the common elements (header, menu, footer), it should be possible to do that with JavaScript after the PCA content loads.&lt;/li&gt;
&lt;li&gt;If the success/error indicator is outside the PCA, it may need to be populated and displayed/hidden with JavaScript after the PCA loads.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;m sure my implementation can be improved, but I&apos;m also curious to see what you think of this idea. I know it&apos;s not revolutionary, but it&apos;s something I&apos;m considering adding by default to AppFuse and AppFuse Light. Do any Ajax frameworks do something like this out-of-the-box?
&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update:&lt;/strong&gt; Thanks to everyone for the great feedback - keep it coming. I agree that adding history support is a must. I&apos;ll try to do that in the next day or two. This post has also been featured on &lt;a href=&quot;http://java.dzone.com/news/ajaxified-body&quot;&gt;Javalobby&lt;/a&gt; and &lt;a href=&quot;http://ajaxian.com/archives/ajaxified-body-when-to-refresh-the-page&quot;&gt;Ajaxian&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2:&lt;/strong&gt; &lt;a href=&quot;http://raibledesigns.com/rd/entry/ajaxified_body_now_with_back&quot;&gt;Added history support&lt;/a&gt;.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/what_s_wrong_with_jsf</id>
        <title type="html">What&apos;s wrong with JSF</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/what_s_wrong_with_jsf"/>
        <published>2008-08-25T18:53:31-06:00</published>
        <updated>2008-08-26T01:00:07-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="seam" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">The developers of Seam have come up with a list of &lt;a href=&quot;http://seamframework.org/Documentation/JSF2&quot;&gt;major issues with JSF&lt;/a&gt;. I&apos;m assuming many of these issues are fixed by Seam, but it&apos;s interesting to note how they&apos;ve somewhat admitted that JSF has many flaws. Note that there&apos;s a lot of references to Struts and WebWork.
&lt;/p&gt;
&lt;p&gt;
Hopefully many of these will be fixed in JSF 2. If REST support is an important feature for web frameworks, it&apos;ll be be interesting to see how the component frameworks handle it. It&apos;d be great if they provided native support. Oh wait, then they&apos;d be action-based frameworks. &lt;img src=&quot;https://raibledesigns.com/images/smileys/wink.gif&quot; class=&quot;smiley&quot; alt=&quot;;-)&quot; title=&quot;;-)&quot; /&gt;</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/gwt_and_rest</id>
        <title type="html">GWT and REST</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/gwt_and_rest"/>
        <published>2008-07-21T10:31:58-06:00</published>
        <updated>2008-07-21T16:36:42-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="gwt" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rest" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">I&apos;ve posted two message to the &lt;a href=&quot;http://groups.google.com/group/Google-Web-Toolkit&quot;&gt;GWT Google Group&lt;/a&gt; in the last couple of days. However, &lt;a href=&quot;http://groups.google.com/group/Google-Web-Toolkit/browse_thread/thread/0dbb7f08915229e5&quot;&gt;new member messages are moderated&lt;/a&gt; and neither has shown up yet. I&apos;m reposting my questions here in hopes of getting some answers.
&lt;/p&gt;
&lt;div class=&quot;smokey&quot; style=&quot;margin-bottom: 10px&quot;&gt;
&lt;p&gt;
Is there a way to easily use a REST backend with GWT? I tried &lt;a href=&quot;http://code.google.com/p/gwt-rest/&quot;&gt;GWT-REST&lt;/a&gt;. It works, but it seems to be centered towards Rails (I&apos;m using Grails) and it suffers from the &lt;a href=&quot;http://code.google.com/p/google-web-toolkit-doc-1-5/wiki/FAQ_SOP&quot;&gt;SOP issue&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href=&quot;http://www.gwtsite.com/how-to-access-web-services-with-gwt/&quot;&gt;JSONRequest&lt;/a&gt; looks promising for cross-domain support, but I can&apos;t
get it to work either. The provided examples work, but not my simple
hello world that returns:
&lt;/p&gt;
&lt;pre&gt;
{&quot;response&quot;:&quot;Hello World!&quot;}
&lt;/pre&gt;
&lt;p&gt;
Also, the example implementation only has GET support, not PUT, DELETE
or POST. I can post my REST backend on the public internet if anyone
is interested in seeing the issues I&apos;m having.
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Thanks in advance for any advice.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/re_which_is_the_hottest</id>
        <title type="html">RE: Which is the Hottest Java Web Framework?</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/re_which_is_the_hottest"/>
        <published>2008-06-10T22:39:08-06:00</published>
        <updated>2014-05-08T19:47:19-06:00</updated> 
        <category term="/Java" label="Java" />
        <category term="springmvc" scheme="http://roller.apache.org/ns/tags/" />
        <category term="webframeworks" scheme="http://roller.apache.org/ns/tags/" />
        <category term="jsf" scheme="http://roller.apache.org/ns/tags/" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="seam" scheme="http://roller.apache.org/ns/tags/" />
        <category term="wicket" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">&lt;a href=&quot;http://www.breakitdownblog.com&quot;&gt;The &quot;Break it Down&quot; Blog&lt;/a&gt; has a lengthy post on &lt;a href=&quot;http://www.breakitdownblog.com/which-is-the-hottest-java-web-framework-or-maybe-not-java/&quot;&gt;Which is the Hottest Java Web Framework? Or Maybe Not Java?&lt;/a&gt; Comparing Java Web Frameworks is hard because so many people are passionate about the framework they know best. Add a couple more like Flex and Ruby on Rails and its downright difficult. Nevertheless, this post is good in that it contains a lot of pretty trend graphs and it looks like the author has done some good research. It&apos;s likely the folks that will scream foul are the ones that did poor in the comparison (Tapestry and Stripes, I&apos;m talking about you).
&lt;/p&gt;
&lt;p&gt;
Surprising among the top Java Web Frameworks is the rise of Struts 2:&lt;/p&gt;
&lt;p style=&quot;text-align: center&quot;&gt;
&lt;a href=&quot;http://www.google.com/trends?q=(apache+wicket)+|+wicket%2C+(jboss+seam)%2C+(spring+mvc)+|+(spring+webflow)+|+(spring+web+flow)%2C+(struts+2)+|+(struts2)&amp;amp;ctab=0&amp;amp;geo=all&amp;amp;date=all&amp;amp;sort=0&quot;&gt;
&lt;img src=&quot;//farm4.static.flickr.com/3273/2569872382_c230627f2d.jpg&quot; alt=&quot;Google Trends Graph&quot; width=&quot;500&quot; height=&quot;270&quot; /&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;To quote:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
Which is much more interesting I think is how Wicket adoption has stayed almost flat while Struts 2 adoption has spiked. Spring MVC/WebFlow seems to be going no where fast and racing JBoss Seam there.
&lt;br/&gt;&lt;br/&gt;
The popularity of Struts 2 really caught me off guard with it being quite a bit different from Struts 1, I figured it got thrown into the &quot;just another web framework&quot; category, but I guess there is something in a name and it&apos;s doing quite well.
&lt;/p&gt;
&lt;p&gt;Regardless of what you think of the post and trends, you have to appreciate the amount of time the author put into it.</content>
    </entry>
    <entry>
        <id>https://raibledesigns.com/rd/entry/should_we_retool_appfuse_to</id>
        <title type="html">Should we change AppFuse to be Struts 2-specific?</title>
        <author><name>Matt Raible</name></author>
        <link rel="alternate" type="text/html" href="https://raibledesigns.com/rd/entry/should_we_retool_appfuse_to"/>
        <published>2008-05-29T08:29:44-06:00</published>
        <updated>2012-11-08T14:34:30-07:00</updated> 
        <category term="/Java" label="Java" />
        <category term="struts2" scheme="http://roller.apache.org/ns/tags/" />
        <category term="appfuse" scheme="http://roller.apache.org/ns/tags/" />
        <category term="rest" scheme="http://roller.apache.org/ns/tags/" />
        <content type="html">Dusty recently &lt;a href=&quot;http://www.nabble.com/Re%3A-RE%3A-Getting-ready-for-Struts-2.1.1-p17461105s2369.html&quot;&gt;posted&lt;/a&gt; an interesting idea to the AppFuse developers mailing list:&lt;/p&gt;
&lt;p class=&quot;quote&quot;&gt;
After thinking/coding/reading for a while I think the more interesting  
task is:  Retool AppFuse to be one or more Struts2 plugins based on  
various higher level app patterns.  (AppFuse Facebook, AppFuse  
Employee DB, AppFuse Blog, AppFuse Basic LDAP, AppFuse Basic Crowd).
&lt;br/&gt;&lt;br/&gt;
This all comes from the fact, that I have been wanting to refactor the  
AppFuse web layer for Struts.  One of the interesting aspects of  
AppFuse is that it works pretty much the same across all its web  
frameworks.  It does so with some lowest common denominator  
abstractions that can be ported and look and work the same across  
frameworks.  I have picked my tool(s): Struts 2 and Ruby On Rails when  
I want to pretend I am young again. I know Spring MVC, JSF, etc. but  
I have no desire to build significant apps on those platforms. It&apos;s  
not because they suck and Struts2 rules, it is because I know Struts 2  
the best, I am most efficient there and it provides everything I need  
to build great webapps (Let&apos;s not devolve to a framework debate). So,  
I would rather have a more Struts 2-specific web stack, that really  
leverages conventions born and raised there.  The nice thing about the  
Struts 2 web stack is that it is complemented nicely by AppFuse&apos;s data/service layer, since unlike Grails or Rails, Struts 2 has no data or service layer.
[&lt;a href=&quot;http://www.nabble.com/Re%3A-RE%3A-Getting-ready-for-Struts-2.1.1-p17461105s2369.html&quot;&gt;Read More &amp;raquo;&lt;/a&gt;]
&lt;/p&gt;
&lt;p&gt;Seems like a good idea to me. What do you think?&lt;/p&gt;
&lt;p&gt;Someday I&apos;d like to come up with a &quot;compatibility test&quot; that allows others to improve upon the ideas in AppFuse and develop their stacks independently. A suite of Selenium tests that require extensionless URLs might be a good start.</content>
    </entry>
</feed>

