<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:admin="http://webns.net/mvcb/" version="2.0">
  <channel>
    <title>SpringOne 2GX</title>
    <link>http://springone2gx.com</link>
    <description>The best value in the Java/Open Source conferencing space hands down</description>
    <item>
      <title>Geographically Distributed Agile Teams Have Choices for Their Lifecycles</title>
      <link>http://springone2gx.com/blog/johanna_rothman/2012/02/geographically_distributed_agile_teams_have_choices_for_their_lifecycles?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;I hope that by now you see that you have any number of choices for your lifecycle if you are geographically distributed team and you are transitioning to agile. I do recommend a servant leader agile project manager, for coordination and risk management. With people all over the world, it&amp;#8217;s difficult to coordinate the project, which leads to more risk.&lt;/p&gt;
&lt;p&gt;Scrum is often not the best approach to geographically distributed agile. That does not mean the distributed team should not go agile. It just means they should not use Scrum. If the distributed team can all travel to one place so they can get trained by the same Scrum trainer &lt;em&gt;together&lt;/em&gt;, and if they can take the opportunity to talk together to discuss what they need from the Scrum Master then maybe they can use Scrum, especially if they use their retrospectives well. It&amp;#8217;s a lot of responsibility for the team new to agile and new to Scrum. If you&amp;#8217;re a team new to agile and new to Scrum, and you try this, do yourself a favor and use a coach.&lt;/p&gt;
&lt;p&gt;Electronic tools do not always make seeing and managing the risk easier when you first start&amp;#8211;tools can prevent transparency until you understand what you are doing. I like starting with stickies or cards on a wall or board, and as the team members learn how to work, and what they, as a team need, then choosing a tool. I don&amp;#8217;t see how to choose a tool before you know what tool you need. One tip: do not allow your management to select a tool for you. You, as a team, can select a tool for yourself. You might start with digital pictures of your task board on a project wiki before you decide which tool to use.&lt;/p&gt;
&lt;p&gt;Let me recap:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.jrothman.com/blog/mpd/2012/01/agile-lifecycles-for-geographically-distributed-teams-part-1.html" target="_blank"&gt;Agile Lifecycles for Geographically Distributed Teams, Part 1&lt;/a&gt; discussed iterations and silo&amp;#8217;d teams.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.jrothman.com/blog/mpd/2012/01/agile-lifecycles-for-geographically-distributed-teams-part-2.html" target="_blank"&gt;Agile Lifecycles for Geographically Distributed Teams, Part 2&lt;/a&gt; discussed kanban and silo&amp;#8217;d teams.&lt;/p&gt;
&lt;p&gt;I got all hot under the collar and discussed &lt;a href="http://www.jrothman.com/blog/mpd/2012/02/why-an-agile-project-manager-is-not-a-scrum-master.html" target="_blank"&gt;Why an Agile Project Manager is Not a Scrum Master&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.jrothman.com/blog/mpd/2012/02/agile-lifecycles-for-geographically-distributed-teams-part-3.html" target="_blank"&gt;Agile Lifecycles for Geographically Distributed Teams, Part 3&lt;/a&gt; discussed iterations and kanban and silo&amp;#8217;d teams.&lt;/p&gt;
&lt;p&gt;You should also read &lt;a href="http://www.jrothman.com/2008/01/what-lifecycle-selecting-the-right-model-for-your-project/" target="_blank"&gt;What Lifecycle? Selecting the Right Model for Your Project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you have several teams all working towards one business goal, you have a program, and that is a different problem. Look for more blog posts on that, later.&lt;/p&gt;
&lt;p&gt;These are precisely the problems no one teaches you in project management certification courses. If you have read &lt;a href="http://www.jrothman.com/books/manage-it-your-guide-to-modern-pragmatic-project-management/" target="_blank"&gt;Manage It! Your Guide to Modern, Pragmatic Project Management&lt;/a&gt;, you know I consider knowledge of different lifecycles necessary for project managers.&lt;/p&gt;
&lt;p&gt;Project managers who try to control their teams better have a darn good reason&amp;#8211;these people are adults. They manage the rest of their lives. Are you trying to tell me they can&amp;#8217;t manage their work? And, these are the problems that can cause geographically distributed projects to fail, splat.&lt;/p&gt;
&lt;p&gt;If you want to learn to work more effectively on your geographically distributed team, please join Shane Hastie and me in a &lt;a href="../../../2012/01/working-effectively-in-geographically-distributed-agile-project-teams/" target="_blank"&gt;workshop&lt;/a&gt; April 17-18, 2012. We would love to have you.&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Qt6xDWwisfk:d5vdJNkKvfQ:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Qt6xDWwisfk:d5vdJNkKvfQ:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Qt6xDWwisfk:d5vdJNkKvfQ:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?i=Qt6xDWwisfk:d5vdJNkKvfQ:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Qt6xDWwisfk:d5vdJNkKvfQ:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?i=Qt6xDWwisfk:d5vdJNkKvfQ:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Qt6xDWwisfk:d5vdJNkKvfQ:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Qt6xDWwisfk:d5vdJNkKvfQ:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ManagingProductDevelopment/~4/Qt6xDWwisfk" height="1" width="1"/&gt;</description>
      <pubDate>Mon, 06 Feb 2012 13:00:19 CST</pubDate>
      <guid isPermaLink="true">http://www.jrothman.com/blog/mpd/?p=11128</guid>
      <dc:creator>Johanna Rothman</dc:creator>
    </item>
    <item>
      <title>Dependency Management with .NET – Doing it Right</title>
      <link>http://springone2gx.com/blog/baruch_sadogursky/2012/02/dependency_management_with_net__doing_it_right?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;div style="background-attachment:scroll;background-color:#f7f7f1;background-image:none;display:block;height:51px;line-height:15px;min-height:51px;width:95%;border:1px solid #e3e3d1;margin:0 5px 0 0;padding:5px 2px 3px 10px;"&gt;&lt;span style="color:#000000;"&gt;This post was originally posted on &amp;#8216;&lt;a title="From the Frog's Mouth" href="http://blogs.jfrog.com" target="_blank"&gt;From the Frog&amp;#8217;s Mouth&lt;/a&gt;&amp;#8216;.&lt;br /&gt;
&lt;/span&gt;&lt;span style="color:#000000;"&gt;You&amp;#8217;re welcome to comment here or &lt;a title="Dependency Management with .NET - Doing it Right" href="blogs.jfrog.org/2012/02/dependency-management-with-net-doing-it.html" target="_blank"&gt;there&lt;/a&gt;.&lt;/span&gt;&lt;strong&gt;&lt;span style="color:#000000;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/strong&gt;&lt;/div&gt;
&lt;p&gt;The problem of dependency management is neither new nor original, it exists in all development platforms, and .NET is no different.&lt;/p&gt;
&lt;p&gt;Let’s go through different solutions and see how they perform. I’ll list them here in no particular order.&lt;/p&gt;
&lt;h3&gt;&lt;span id="more-168"&gt;&lt;/span&gt;Keeping dependencies in your source control&lt;/h3&gt;
&lt;p&gt;That’s a very popular solution, and for a reason. The benefits are obvious. Here are some of them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;No setup. You already have your source control in place (hm, I hope you do!). Add \bin directory, and you are fine.&lt;/li&gt;
&lt;li&gt;No learning curve. Developers are used to work with source control.&lt;/li&gt;
&lt;li&gt;Shared. The whole team gets changes and updates from the server as they occur.&lt;/li&gt;
&lt;li&gt;Enterprisy (in a good way). The software is proven, backed up, DRP is done.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sounds good, doesn’t it? So, what’s wrong with it? Only one thing &amp;#8211; source control systems are designed to control, well, sources. As such they aren’t so great in controlling binaries. These are the shortcomings we all encountered during the years of Version Control System usage for dependencies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It isn’t a proxy. VCS can’t download the dependency you need from a central repository when you need one. You need to manually download it and add it to VCS. The history starts from there &amp;#8211; you just lost the  link to the original file. So, you work hard, and on top of it lost information; this repeat itself for each new dependency.&lt;/li&gt;
&lt;li&gt;Versioning mismatch. Source files are versioned by their content. VCSs know how to diff them and understand what changed. Binaries, on the other side, usually versioned by their name. From VCS point of view they are different entries, each one without any version history.&lt;/li&gt;
&lt;li&gt;Some very popular VCSs (like Subversion) can’t obliterate files. That means &amp;#8211; once a file was added, it stay in the repository forever. That’s not a big issue for small source files, but can become quite a pain when it comes to obsolete large binaries.&lt;/li&gt;
&lt;li&gt;Source control knows how to search sources. And, of course, the most important type of search is by content. Searching for binaries is different: what matters there is the location, structure of the file name and, in case of archived artifact, the contents of archive.&lt;/li&gt;
&lt;li&gt;The permissions scheme of VCSs is tailored for versioning sources (again!). For example, there is no override permission. That’s because overriding sources is something we do all the time (that’s what diff is for in VCS) &amp;#8211; it’s the same security level as, let&amp;#8217;s say, adding a new source file. With binaries the situation is very different. While adding new binaries is fine, overriding released binary is something that shouldn’t be done, one should have a special permission for it.&lt;/li&gt;
&lt;li&gt;Distributed VCSs, awesome by themselves, are particularly unsuited for handling big binary files. When cloning a remote repository to your machine &lt;a href="https://twitter.com/#%21/hlship/status/111143638163132417"&gt;you are bringing all the history of all the files in it&lt;/a&gt;. Now just think about all the huge binaries sitting there&amp;#8230;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As you see, the conclusion is simple &amp;#8211; we can do better. Let’s try something specialized for binaries.&lt;/p&gt;
&lt;h3&gt;GAC and WebGAC&lt;/h3&gt;
&lt;p&gt;Global Assembly Cache is, on contradictory to VCS ,tailored for storing binaries. It understands versions, prevents conflicts, and generally does a good job being your local dependencies storage. The main problem with GAC is being local, which means &amp;#8211; each and every developer should take the binaries from somewhere and install them in their local GAC. You see the troubles coming in that setup, don’t you? &lt;a href="http://www.lshift.net/blog/2010/02/27/webgac-minding-your-net-dependencies"&gt;WebGAC&lt;/a&gt; to the rescue here. It&amp;#8217;s essentially GAC shared by WebDAV and enables clients to fetch dependencies from the server, simplifying dependencies management for a team. Let’s do our pros/cons math. The benefits:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GAC is good, standard and proven solution for binaries management. It deals well with versions.&lt;/li&gt;
&lt;li&gt;WebGAC is a central binaries repository for a team. Every team member synchronizes with it.&lt;/li&gt;
&lt;li&gt;WebDAV is popular well-known HTTP extension with locking, security management, etc. Working with the Apache WebDAV module is generally straightforward.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Let’s see what won’t work so great with that solution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It isn’t a proxy. WebGAC can’t download the dependency you need from a central repository when you need one. You need to manually download it, add it to WebGAC and only then it becomes available to the team. Not only must you work for every version of every dependency needed, the link to the original file is lost.&lt;/li&gt;
&lt;li&gt;No notion of packages. GAC contains single dlls. You install them one by one. But think about NUnit, as an example. It contains about dozen of dlls along with various xml and configuration files. How can you install it to GAC?&lt;/li&gt;
&lt;li&gt;Security is cumbersome. You’ll need to configure Apache Server’s security, and even then it won’t be flexible enough to determine between deployer (a user that can publish private dependencies) and promoter (a user that can move dependencies from a private repository to a public one).&lt;/li&gt;
&lt;li&gt;Search is basic. WebDAV by itself only knows about files. It doesn’t care about the structure of the filename, or about the presence of Strong Names.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Looks like we still didn’t find what we are looking for, and then&amp;#8230;&lt;/p&gt;
&lt;h3&gt;Here comes NuGet&lt;/h3&gt;
&lt;p&gt;This is something else. &lt;a href="http://nuget.codeplex.com/"&gt;NuGet&lt;/a&gt; designed to be “a developer focused package management system for the .NET platform intent on simplifying the process of incorporating third-party libraries into a .NET application during development”. That’s exactly what we need. Let’s look how great it is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Manages packages, not dlls.&lt;/li&gt;
&lt;li&gt;Provides &lt;a href="http://nuget.org/packages"&gt;NuGet Gallery&lt;/a&gt; &amp;#8211; almost 4.5K (at the time of writing) packages are at your disposal for all your development needs.&lt;/li&gt;
&lt;li&gt;Supports binary versioning.&lt;/li&gt;
&lt;li&gt;Integrates with Visual Studio.&lt;/li&gt;
&lt;li&gt;Integrates with your build.&lt;/li&gt;
&lt;li&gt;Integrates with your build server (only &lt;a href="http://blogs.jetbrains.com/dotnet/2011/08/native-nuget-support-in-teamcity/"&gt;TeamCity&lt;/a&gt; at the moment of writing).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This tool&amp;#8217;s like a dream come true. So, what can I mention as downsides? Most of them are downsides of the NuGet Gallery, not NuGet itself. The Gallery is a young and relatively small project (just for the sake of comparison, Maven Central is 6 years old and contains more than 290K artifacts) and, as such, it has its downsides:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The content of submissions to the Gallery is (almost) unverified. Everyone can register, get the API key and start uploading whatever they like. Scary, isn&amp;#8217;t it? (yes, very scary).&lt;/li&gt;
&lt;li&gt;Being public, NuGet Gallery can’t be used for inter-team packages exchange. &lt;a href="http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds#Creating_Remote_Feeds"&gt;Private Remote Feeds&lt;/a&gt; are the recommended solution. Next we&amp;#8217;ll see if it is good enough.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Working with NuGet Remote Feeds&lt;/h3&gt;
&lt;p&gt;&lt;a href="http://docs.nuget.org/docs/creating-packages/hosting-your-own-nuget-feeds#Creating_Remote_Feeds"&gt;Remote Feeds&lt;/a&gt;, introduced in NuGet 1.4 are crucial need for any development team. It serves a dual purpose: it allows sharing 3rd party packages that aren’t available on Gallery (or even replaces the Gallery for those who can’t trust it) and it serves as a target for internal deployments &amp;#8211; both for team collaboration and for other usages, as making packages available to QA, or even serving them to the customers from the outside world (by using &lt;a href="http://chocolatey.org/"&gt;Chocolatey&lt;/a&gt;, for example). If that’s so right, what’s wrong? Here’s what:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You saw it coming: It isn’t a proxy. You know the score by now.&lt;/li&gt;
&lt;li&gt;It can’t aggregate. The NuGet Remote Feed exposing one monolithic repository: the one you have on your machine. It can’t aggregate NuGet packages from remote repositories, or expose number of local repositories (separated for security reasons, for example).&lt;/li&gt;
&lt;li&gt;You can’t attach your own metadata. Let’s say you want to annotate some package with compatibility information (e.g. works with certain browsers). No, can’t do.&lt;/li&gt;
&lt;li&gt;The repository is very simplistic. It doesn’t provide any web interface; it browsable and searchable only from a client &amp;#8211; be it Visual Studio or the command line interface (pretty basic by itself).&lt;/li&gt;
&lt;li&gt;Even the VS search interface is very basic (all you have is arbitrary sorting and free text search). It should be enough for starters but lack of searching inside the packages or by properties (from the previous bullet) will bite you eventually.&lt;/li&gt;
&lt;li&gt;The security scheme is even less than simplistic. All that&amp;#8217;s required to authenticate a deployment/delete of all the users at once is an API key. What about separation of duties? Some users should only be able to read, others only to annotate with metadata (QA team that tests compatibility in my previous example), and only small subgroup &amp;#8211; to deploy.  The all-or-nothing scheme is definitely insufficient.&lt;/li&gt;
&lt;li&gt;Storage format is suboptimal:
&lt;ul&gt;
&lt;li&gt;The packages are stored on the filesystem in a naive simple format. That fine for small repository,but as you grow, you&amp;#8217;d expect storage which more optimized for binaries.&lt;/li&gt;
&lt;li&gt;The metadata is not indexed. Again, fine for small repo, troubles are foreseen when it comes to scaling.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So, is there a good alternative to NuGet Remote Feed to be your in-house Gallery for NuGet packages? We, the proud makers of &lt;a href="http://www.jfrog.com/"&gt;Artifactory&lt;/a&gt;,  believe there is.&lt;/p&gt;
&lt;h3&gt;Meet Artifactory&lt;/h3&gt;
&lt;p&gt;&lt;a id="internal-source-marker_0.8537193675811334" href="http://www.jfrog.com/"&gt;Artifactory&lt;/a&gt; is an enterprise-grade Binary Repository that centralizes all aspects of managing software binaries. That means that we tackle all the problems mentioned above. We are developing Artifactory since 2006. Being used by millions of users for storing, sharing and managing binaries, we have gathered great feedback from our users.&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s what we&amp;#8217;ve learned:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Binary packages are different from sources (by being big and binary) and deserve smart storage.&lt;/li&gt;
&lt;li&gt;Binary packages are usually archives (be it jars, zips, rpms or nupkgs). They should be browsable and searchable without the need to download them locally to developer&amp;#8217;s machine.&lt;/li&gt;
&lt;li&gt;Big public repositories exist on the net, they need to be proxied smartly (variations, auditing, managing)&lt;/li&gt;
&lt;li&gt;Users come in different flavors. Their permissions should match possible responsibilities (and in the case of binary packages they are different from other cases).&lt;/li&gt;
&lt;li&gt;A binary repository holds critical information, it should be rock-solid, backed up, and DRP ready.&lt;/li&gt;
&lt;li&gt;Your software ends up being a package. We know how to help you&amp;#8230;
&lt;ul&gt;
&lt;li&gt;build it in a reproducible manner, integrating with your build tools and your build server.&lt;/li&gt;
&lt;li&gt;stage it to ensure the best quality.&lt;/li&gt;
&lt;li&gt;distribute it to your customers.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You get the gist behind Artifactory by watching this 2.5 minutes video: &lt;span style="text-align:center; display: block;"&gt;&lt;a href="http://blog.sadogursky.com/2012/02/06/dependency-management-with-net-doing-it-right/"&gt;&lt;img src="http://img.youtube.com/vi/aa4YBDUDWy0/2.jpg" alt="" /&gt;&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
If you’re not in the mood for movies (or ran out of popcorn), here’s quick recap:&lt;a href="http://jbaruch.files.wordpress.com/2012/02/nuget-poxy.png"&gt;&lt;img class="size-full wp-image-196 aligncenter" title="Artifactory" src="http://jbaruch.files.wordpress.com/2012/02/nuget-poxy.png?w=700&amp;#038;h=181" alt="" width="700" height="181" /&gt;&lt;/a&gt;&lt;br /&gt;
As you see, instead of working with a number of NuGet Feeds (NuGet Gallery, Orchard Gallery,  Remote Feeds from co-workers and from different teams) developers work with exactly one repository. It simplifies setup and daily work and centralizes management and maintenance.&lt;br /&gt;
The work is bi-directional, the users resolve their 3rd party dependencies from Artifactory and deploy their created packaged into it.&lt;/p&gt;
&lt;p&gt;Now let’s add a build server to the picture (literally):&lt;a href="http://jbaruch.files.wordpress.com/2012/02/nuget-build.png"&gt;&lt;img class="size-full wp-image-197 aligncenter" title="CI" src="http://jbaruch.files.wordpress.com/2012/02/nuget-build.png?w=700&amp;#038;h=322" alt="" width="700" height="322" /&gt;&lt;/a&gt;&lt;br /&gt;
Yup, with numbers this time. So, here we go:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Developers find and  fetch new 3rd party packages from Artifactory in Visual Studio. The packages are downloaded from Artifactory to the developer&amp;#8217;s machine. If the packages aren’t present in Artifactory it will look for them in remote galleries/feeds. On developer machines &lt;code&gt;packages.config&lt;/code&gt; is updated with the list of used packages.&lt;/li&gt;
&lt;li&gt;Developers commit their code and &lt;code&gt;packages.config&lt;/code&gt; (but not the binaries) to VCS.&lt;/li&gt;
&lt;li&gt;The Build server (as I already mentioned, &lt;a href="http://blogs.jetbrains.com/dotnet/2011/08/native-nuget-support-in-teamcity/"&gt;TeamCity&lt;/a&gt; now supports NuGet) takes the changes from the VCS.&lt;/li&gt;
&lt;li&gt;It builds the solution and packs the produced artifacts as NuGet packages.&lt;/li&gt;
&lt;li&gt;During the build it fetches the needed packages from Artifactory. If the packages aren’t present in Artifactory it will look for them in remote galleries/feeds.&lt;/li&gt;
&lt;li&gt;Once the packages are built they are deployed to Artifactory.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Built packages in Artifactory can be used by other teams (as their 3rd party dependencies), by QA for running tests and even by the end users (&lt;a href="http://chocolatey.org/"&gt;Chocolatey&lt;/a&gt; FTW), all this with fine-grained permissions and robust promotion procedures (moving a package between repositories with different visibility rules).&lt;br /&gt;
You know what? It deserves dedicated how-to blog post. I’ll link it here once published.&lt;/p&gt;
&lt;p&gt;Assuming you&amp;#8217;ve read up to this point, you&amp;#8217;ve gathered that starting from Artifactory version 2.5.0 we are proud to serve the .NET world with full NuGet support. We can proxy any remote NuGet feed (starting with NuGet Gallery, of course), we can host the packages that aren’t found on any remote NuGet feed, we can host the packages you produce and we can aggregate any number of repositories of any kind under single a URL. We provide you with an awesome UI for configuring your repositories, browsing and searching for your packages. We also feature smart storage that enables attaching searchable metadata on top of your binaries. We can do it all on the cloud with our &lt;a href="https://secure.artifactoryonline.com/art-online.php"&gt;SAAS version&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Hopefully , you&amp;#8217;re convinced by now and probably looking for the download link on our site (&lt;a href="https://secure.artifactoryonline.com/addons.php"&gt;here’s it&lt;/a&gt;, BTW, click on “Evalution”). If not, give it a try by playing with &lt;a href="http://repo.jfrog.org/artifactory/webapp/browserepo.html?pathId=nuget-gallery-cache:"&gt;our live demo&lt;/a&gt;. Look at the nuget-gallery cache: that’s how we proxy the NuGet Gallery. You’ll find some of the packages saved locally; once you&amp;#8217;ve selected a package, you’ll see all kinds of information about it: its name and size, who deployed it to Artifactory, where it came from (from NuGet Gallery, naturally for this is the NuGet Gallery cache) and the operations you can perform on this package (as anonymous the selection is naturally limited). Clicking on the triangle in the tree will open the package and let you dive into its content, including downloading specific files from the archive (click for full-size image):&lt;a href="http://jbaruch.files.wordpress.com/2012/02/browse-nupkg.png"&gt;&lt;img class=" wp-image-183 aligncenter" title="Browse Artifactory" src="http://jbaruch.files.wordpress.com/2012/02/browse-nupkg.png?w=548&amp;#038;h=378" alt="Browse Artifactory" width="548" height="378" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We, at JFrog, believe that Artifactory is the missing piece of the puzzle for a robust, agile .NET dependency management, which can make the development process easier compared to other alternatives.&lt;br /&gt;
We&amp;#8217;ll be happy to receive any insights, thoughts and comments on the ideas presented in this blog and/or your experience using Artifactory together with NuGet.&lt;/p&gt;
&lt;div class="main"&gt;
&lt;p&gt;Integrating, integrating, integrating. That’s what we do in Java enterprise development. Persisting objects with Hibernate wrapped by JPA using C3Po (or JTA?) (or MongoDB over Morphia?), processed with JBMP, created by JAXB (jackson-json?) from JAX-RS scheduled by Quartz … (a few dozen frameworks later) … all this glued with Spring (or Guice?) deployed on Jetty (or Tomcat, JBoss, Resin?) into cluster by Terracotta (or Hadoop, GigaSpaces, JBoss cache, Infinispam?). Ah, and all this built using &lt;span style="text-decoration:line-through;"&gt;Maven&lt;/span&gt; Gradle with Artifactory on Jenkins. I sure forgot ½ of the frameworks we constantly use.&lt;/p&gt;
&lt;p&gt;Generally we don’t mind much about the internals of the frameworks we use (as long as they are good) – the whole encapsulation stuff is the last &lt;a href="http://tech.puredanger.com/2010/02/25/questioning-oo/" target="_blank"&gt;undoubted&lt;/a&gt; good thing. But except for the API (part of which is the configuration) frameworks have another user-facing end – the logging. When we build a &lt;strong&gt;system&lt;/strong&gt; we want it to behave as one system – single configuration from one end, and single log from another (break it to different files, if you wish, but it should still be a unified logging system).&lt;/p&gt;
&lt;p&gt;The reality is that there is no standard de-facto for logging. The standard de-jure – &lt;a href="http://java.sun.com/javase/6/docs/technotes/guides/logging/" target="_blank"&gt;JUL&lt;/a&gt;, is not very popular because of its lack of functionality (compared to alternatives) and its suboptimal performance. And then there is &lt;a href="http://logging.apache.org/log4j/" target="_blank"&gt;Log4J&lt;/a&gt;, which almost became standard, but did not. And there is &lt;a href="http://logback.qos.ch/" target="_blank"&gt;logback&lt;/a&gt;, which is a Log4J &lt;a href="http://logback.qos.ch/reasonsToSwitch.html"&gt;trashover&lt;/a&gt;, and there are facades (&lt;a href="http://commons.apache.org/logging/" target="_blank"&gt;JCL&lt;/a&gt; and &lt;a href="http://www.slf4j.org/" target="_blank"&gt;SLF4J&lt;/a&gt;), which try to unite all this zoo, and some others, which you have probably never heard of, like &lt;a href="http://www.syslog4j.org/" target="_blank"&gt;syslog4j&lt;/a&gt;*, &lt;a href="http://www.theobjectguy.com/javalog/" target="_blank"&gt;logging framework by the Object Guy&lt;/a&gt;, &lt;a href="http://java-source.net/open-source/logging" target="_blank"&gt;jLo, MonoLog, Lumberjack, Houston, JTraceDump, qflog, LN2, TracingClassLoader, SMTPHandler, Log4Ant, Simple Log, Log Bridge, Craftsman Spy, Pencil, JDLabAgent, Trace Log, JDBC Logger, LimpidLog and Microlog&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Let it be, you’d say – why not have many logging tools, which are good and diverse! Well, the problem, as I’ve already mentioned, is that they leak out of the frameworks. Their diverse configuration leaks from one end, while their diverse output from another. Spring uses Log4J over JCL. So does Hibernate. Jetty uses Logback over SLF4J. Some (like Terracotta modules) use plain Log4J, Jersey uses JUL.  This means we end up with 5 separate configurations (Log4J, SLF4J, Logback, JCL and JUL) and 3 different types of log files (Log4j, Logback and JUL). What a system!&lt;/p&gt;
&lt;p&gt;To make the long story short – How can we achieve the desired consolidation? Clearly, we need a facade. There are two most commonly used – SLF4J and JCL. JCL is known for its &lt;a href="http://articles.qos.ch/classloader.html" target="_blank"&gt;classloader hell&lt;/a&gt;, SLF4J is newer, better performing, smarter, simplier to use and generally provides better quality for the same buck (well, no buck – both are open source, of course), so we’ll stick to it. SLF4J is an adapter – thin layer of API to and from different logging implementations. Yap, both ways. It means with SLF4J we can use JUL API on top and log using Log4J in the bottom!&lt;/p&gt;
&lt;p&gt;First we need to pick an actual logger. Log4j was considered the best choice up until recently (2006) when Ceki Gülcü decided he needed a fresh start and rewrote from scratch a new Java logging framework, just&lt;a href="http://xhab.blogspot.com/2007/03/new-logging-experience.html" target="_blank"&gt; better than log4j&lt;/a&gt;, called Logback. We can give it a try as our underlying logging implementation (we can switch in a moment, as we are using  good facade, remember?).&lt;/p&gt;
&lt;p&gt;So, here’s what we have to do:&lt;/p&gt;
&lt;ol&gt;
&lt;ol&gt;
&lt;li&gt;Establish our own good logging:
&lt;ol&gt;
&lt;ol&gt;
&lt;li&gt;Add Logback to our classpath&lt;/li&gt;
&lt;li&gt;Add SLF4J API to our classpath&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&lt;p&gt;Done here. Now our own brand new code will use top-notch logging.&lt;/li&gt;
&lt;li&gt;Now for the tricky part. Let’s make the example stack I listed above taking configuration from one source (our config files) and writing to one target (files, listed in our configuration)
&lt;ol&gt;
&lt;li&gt;All the tools using SLF4J will just work. That includes dozen of Apache projects, inc. Camel and Mina, some SpringSource projects and &lt;a href="http://www.slf4j.org/" target="_blank"&gt;many others&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Now let’s start rolling with all the rest. This is how you do it (click to enlarge):&lt;br /&gt;
&lt;a href="http://www.slf4j.org/images/bridging.png"&gt;&lt;img class="alignnone" title="Bridging architecture" src="http://www.slf4j.org/images/bridging.png" alt="Bridging architecture" width="297" height="162" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Jakarta Commons Logging:
&lt;ol&gt;
&lt;li&gt;Remove commons-logging.jar from your classpath. Usually, it is transitive dependency from the framework, so you need to instruct your build tool on how to do it. What a lucky coincidence, I just wrote &lt;span style="text-decoration:line-through;"&gt;short&lt;/span&gt; and instructive &lt;a title="Banning Transitive Dependencies With Maven2/3, Gradle and Ivy" href="../2011/06/22/banning-transitive-dependencies-with-maven23-gradle-and-ivy/"&gt;blog post&lt;/a&gt; about how to do it!&lt;/li&gt;
&lt;li&gt;Add jcl-over-slf4j.jar instead. It contains alternative commons-logging API implementation, so the code will run just fine.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Log4J:
&lt;ol&gt;
&lt;li&gt;Same goes here! Remove log4j.jar from your classpath (Again, it would usually be a transitive dependency from the framework, look &lt;a title="Banning Transitive Dependencies With Maven2/3, Gradle and Ivy" href="../2011/06/22/banning-transitive-dependencies-with-maven23-gradle-and-ivy/"&gt;here&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Add log4j-over-slf4j.jar instead. It contains alternative log4j API implementation, so the code will run just fine.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;JUL:
&lt;ol&gt;
&lt;li&gt;Well, you can’t remove JUL from classpath (it’s a part of the JRE, dude). For the same reason SLF4J can’t reimplement JUL’s API.&lt;/li&gt;
&lt;li&gt;Add jul-to-slf4j.jar. It will translate java.util.logging.LogRecord objects into their SLF4J equivalent.&lt;/li&gt;
&lt;li&gt;Install &lt;a href="http://www.slf4j.org/api/org/slf4j/bridge/SLF4JBridgeHandler.html"&gt;SLF4JBridgeHandler&lt;/a&gt; and &lt;a href="http://logback.qos.ch/manual/configuration.html#LevelChangePropagator"&gt;LevelChangePropagator&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Expect 20% decrease in performance (so use it wisely).&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;All done&lt;/strong&gt;. Now both our code and all the 3rd paries configured from single source and write to single target. Hooray!&lt;/p&gt;
&lt;p&gt;&lt;small&gt;* syslog4j claims it is cross-platform. Well,  I’ll just quote: “&lt;strong&gt;Is Syslog4j cross-platform?&lt;/strong&gt; Yes! Syslog4j UDP/IP and TCP/IP clients should work in any typical Java JRE environment.”&lt;/small&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;div class="meta group"&gt;
&lt;div class="signature"&gt;
&lt;p&gt;Written by jbaruch &lt;span class="edit"&gt;&lt;a class="post-edit-link" title="Edit Post" href="post.php?post=34&amp;amp;action=edit"&gt;Edit&lt;/a&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;22/06/2011 at 08:40&lt;/p&gt;
&lt;/div&gt;
&lt;div class="tags"&gt;
&lt;p&gt;Posted in &lt;a title="View all posts in Frameworks" href="http://blog.sadogursky.com/category/frameworks/" rel="category tag"&gt;Frameworks&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Tagged with &lt;a href="http://blog.sadogursky.com/tag/jcl/" rel="tag"&gt;jcl&lt;/a&gt;, &lt;a href="http://blog.sadogursky.com/tag/jul/" rel="tag"&gt;jul&lt;/a&gt;, &lt;a href="http://blog.sadogursky.com/tag/log/" rel="tag"&gt;log&lt;/a&gt;, &lt;a href="http://blog.sadogursky.com/tag/log4j/" rel="tag"&gt;log4j&lt;/a&gt;, &lt;a href="http://blog.sadogursky.com/tag/logback/" rel="tag"&gt;logback&lt;/a&gt;, &lt;a href="http://blog.sadogursky.com/tag/slf4j/" rel="tag"&gt;slf4j&lt;/a&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;br /&gt;Filed under: &lt;a href='http://blog.sadogursky.com/category/artifactory-2/'&gt;Artifactory&lt;/a&gt;, &lt;a href='http://blog.sadogursky.com/category/jfrog/'&gt;JFrog&lt;/a&gt; Tagged: &lt;a href='http://blog.sadogursky.com/tag/artifactory/'&gt;artifactory&lt;/a&gt;, &lt;a href='http://blog.sadogursky.com/tag/jfrog-2/'&gt;jfrog&lt;/a&gt;, &lt;a href='http://blog.sadogursky.com/tag/nuget/'&gt;nuget&lt;/a&gt;, &lt;a href='http://blog.sadogursky.com/tag/teamcity/'&gt;teamcity&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/jbaruch.wordpress.com/168/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/jbaruch.wordpress.com/168/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/jbaruch.wordpress.com/168/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/jbaruch.wordpress.com/168/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/jbaruch.wordpress.com/168/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/jbaruch.wordpress.com/168/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/jbaruch.wordpress.com/168/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/jbaruch.wordpress.com/168/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/jbaruch.wordpress.com/168/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/jbaruch.wordpress.com/168/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/jbaruch.wordpress.com/168/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/jbaruch.wordpress.com/168/" /&gt;&lt;/a&gt; &lt;a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/jbaruch.wordpress.com/168/"&gt;&lt;img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/jbaruch.wordpress.com/168/" /&gt;&lt;/a&gt; &lt;img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.sadogursky.com&amp;amp;blog=481424&amp;amp;post=168&amp;amp;subd=jbaruch&amp;amp;ref=&amp;amp;feed=1" width="1" height="1" /&gt;</description>
      <pubDate>Mon, 06 Feb 2012 08:00:18 CST</pubDate>
      <guid isPermaLink="true">http://jbaruch.wordpress.com/?p=168</guid>
      <dc:creator>Baruch Sadogursky</dc:creator>
    </item>
    <item>
      <title>HTML5 is the new DHTML</title>
      <link>http://springone2gx.com/blog/aaron_gustafson/2012/02/html5_is_the_new_dhtml?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>For all intents and purposes, &amp;ldquo;HTML5&amp;rdquo; has become a meaningless catch-all marketing phrase defining a platform rather than a specification. It&amp;rsquo;s &amp;ldquo;DHTML&amp;rdquo; all over again.&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/EasyReader?a=-24Cvi6XDdo:nNaC22dn3h0:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EasyReader?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EasyReader?a=-24Cvi6XDdo:nNaC22dn3h0:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EasyReader?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EasyReader?a=-24Cvi6XDdo:nNaC22dn3h0:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EasyReader?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/EasyReader?a=-24Cvi6XDdo:nNaC22dn3h0:JEwB19i1-c4"&gt;&lt;img src="http://feeds.feedburner.com/~ff/EasyReader?i=-24Cvi6XDdo:nNaC22dn3h0:JEwB19i1-c4" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/-24Cvi6XDdo" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 03 Feb 2012 13:00:44 CST</pubDate>
      <guid isPermaLink="true">http://blog.easy-designs.net/archives/2012/02/03/html5-is-the-new-dhtml/</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Agile Lifecycles for Geographically Distributed Teams, Part 3</title>
      <link>http://springone2gx.com/blog/johanna_rothman/2012/02/agile_lifecycles_for_geographically_distributed_teams_part_3?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;h2&gt;Example 3: Using a Project Manager with Iterations and Kanban and Silo&amp;#8217;d Teams&lt;/h2&gt;
&lt;p&gt;Here, the developers were in Cambridge, MA, the product owners were in San Francisco, the testers were in Bangalore, and the project manager was always flying somewhere, because the project manager was shared among several projects. The developers knew about timeboxed iterations, so they used timeboxes. Senior management had made the decision to fire all the local testers and buy cheaper tester time over the developers&amp;#8217; objections and move the testing to Bangalore. The Indian testers were very smart, and unfamiliar with the product, so the developers suggested the testers test feature by feature inside the iteration.&lt;/p&gt;
&lt;p&gt;The project manager suggested they use cumulative flow diagrams and cycle time measurements to make sure the developers were not developing &amp;#8220;too fast&amp;#8221; for the testers. The developers, still smarting over the loss of &amp;#8220;their testers&amp;#8221; were at first, peeved about this. They then realized the truth of this statement, and developed this kanban board.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.jrothman.com/blog/mpd/wp-content/uploads/2012/02/kanban.iteration.lifecycle.example1.jpg"&gt;&lt;img class="alignleft size-medium wp-image-11119" title="kanban.iteration.lifecycle.example1" src="http://www.jrothman.com/blog/mpd/wp-content/uploads/2012/02/kanban.iteration.lifecycle.example1-300x251.jpg" alt="" width="300" height="251" /&gt;&lt;/a&gt;You can see in this board, that four items are waiting to go into system test. Uh oh. The developers are out-producing what the testers can take. This is precisely what a kanban board can show you.&lt;/p&gt;
&lt;p&gt;The testers aren&amp;#8217;t stupid or slow. They are new. They cannot keep up with the developers. It&amp;#8217;s a fact of life, not a mystery of life. The developers have to act in some way to help the testers or the entire project will fail. The reason they are working in timeboxes as well as using kanban is that they have several contractual deliverables, that management, bless their tiny little hearts, committed to. The timebox allows the team or the product owners to meet with their customers and show them their progress. (They were deciding who would meet when I last worked with the team.) The kanban board help make the progress even more transparent.&lt;/p&gt;
&lt;p&gt;Iteration planning: The product owner and the project manager jointly work on the agile feature roadmap, and the product owner owns the roadmap responsibility for it. The product owner owns and generates the backlog. The product owner and the agile project manager present a strawman iteration backlog to the team at the start of the iteration. They have had difficulty finding iteration planning time that allows everyone to be awake and functioning, bless the senior managers&amp;#8217; little hearts.&lt;/p&gt;
&lt;p&gt;Daily commitment: They do a handoff, asking each other what they completed that day and what the impediments are. If you have read &lt;a href="http://www.jrothman.com/books/manage-it-your-guide-to-modern-pragmatic-project-management/" target="_blank"&gt;Manage It!&lt;/a&gt;, you know I modified the three questions to &amp;#8220;What did you complete, what are you planning to complete, what is in your way?&amp;#8221;&lt;/p&gt;
&lt;p&gt;Measurements: cumulative flow, average time to release a feature into the product. They are experimenting with burnup charts and impediment charts. They are still having trouble bringing the testers up to speed fast enough.&lt;/p&gt;
&lt;p&gt;Yes, they do retrospectives at the end of each iteration. Yes, the product owners own the backlogs.&lt;/p&gt;
&lt;p&gt;I&amp;#8217;ll summarize in the final part, the next entry.&lt;/p&gt;
&lt;p&gt;(Want to learn to work more effectively on your geographically distributed team? Join Shane Hastie and me in a &lt;a href="../../../2012/01/working-effectively-in-geographically-distributed-agile-project-teams/" target="_blank"&gt;workshop&lt;/a&gt; April 17-18, 2012.)&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Fqjv0A-gJOw:XsnazvO6yPg:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Fqjv0A-gJOw:XsnazvO6yPg:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Fqjv0A-gJOw:XsnazvO6yPg:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?i=Fqjv0A-gJOw:XsnazvO6yPg:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Fqjv0A-gJOw:XsnazvO6yPg:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?i=Fqjv0A-gJOw:XsnazvO6yPg:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Fqjv0A-gJOw:XsnazvO6yPg:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=Fqjv0A-gJOw:XsnazvO6yPg:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ManagingProductDevelopment/~4/Fqjv0A-gJOw" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 03 Feb 2012 11:01:37 CST</pubDate>
      <guid isPermaLink="true">http://www.jrothman.com/blog/mpd/?p=11118</guid>
      <dc:creator>Johanna Rothman</dc:creator>
    </item>
    <item>
      <title>Tutorial: jQuery Mobile, HTML5 Mobile App Connected to Parse Mobile Backend</title>
      <link>http://springone2gx.com/blog/max_katz/2012/02/tutorial_jquery_mobile_html5_mobile_app_connected_to_parse_mobile_backend?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;A few weeks ago I promised to publish a &lt;a href="http://mkblog.exadel.com/2011/12/pretty-darn-good-tools-building-a-mobile-app-with-tiggr-and-parse/" title="Pretty Darn Good Tools – Building a Mobile App With Tiggr and Parse"&gt;tutorial&lt;/a&gt; on how to build a mobile app and connect it to Parse backend. &lt;/p&gt;
&lt;p&gt;You can get the full tutorial &lt;a href="http://help.gotiggr.com/getting-started/building-a-mobile-app-connected-to-parse-com-mobile-backend" target="_blank"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You really have to try it yourself building a mobile app in &lt;a href="http://tiggzi.com" target="_blank"&gt;Tiggzi app builder&lt;/a&gt; and connecting it to &lt;a href="http://parse.com" target="_blank"&gt;Parse&lt;/a&gt; mobile backend is amazingly easy. You can literally build a real mobile app in about 30 minutes. Creating the actual backend is fast as well, takes about 2 minutes. Any backend object is instantly available via REST API and then used in the mobile app. &lt;/p&gt;
&lt;p&gt;Here is a general outline of the tutorial:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Sign up for &lt;a href="http://parse.com" target="_blank"&gt;Parse&lt;/a&gt; and create the mobile backend. The mobile backend object (class) is a list of text messages&lt;/li&gt;
&lt;li&gt;Build the mobile UI with jQuery Mobile and HTML5 (see screen shot below)&lt;/li&gt;
&lt;li&gt;Create and use REST service to load text messages (REST: &lt;code&gt;https://api.parse.com/1/classes/Words&lt;/code&gt;, GET request)&lt;/li&gt;
&lt;li&gt;Create and use REST service to create a new texg message, (REST: &lt;code&gt;https://api.parse.com/1/classes/Words&lt;/code&gt;, POST request)&lt;/li&gt;
&lt;li&gt;Update the mobile UI to include a Delete button (REST: &lt;code&gt;https://api.parse.com/1/classes/Words/objectId&lt;/code&gt;, DELETE request)&lt;/li&gt;
&lt;li&gt;Create and use REST service to delete a text message&lt;/li&gt;
&lt;li&gt;At any step in the tutorial, you can test the actual app in Web browser&lt;/li&gt;
&lt;li&gt; Optionally, update the look and feel of the app&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The final app looks like this:&lt;br /&gt;
&lt;img src="http://mkblog.exadel.com/wp-content/uploads/2012/02/screenshot_293.png" alt="" title="screenshot_293" width="250" height="397" class="alignnone size-full wp-image-4234" /&gt; &lt;/p&gt;</description>
      <pubDate>Thu, 02 Feb 2012 08:00:20 CST</pubDate>
      <guid isPermaLink="true">http://mkblog.exadel.com/?p=4233</guid>
      <dc:creator>Max Katz</dc:creator>
    </item>
    <item>
      <title>Why an Agile Project Manager is Not a Scrum Master</title>
      <link>http://springone2gx.com/blog/johanna_rothman/2012/02/why_an_agile_project_manager_is_not_a_scrum_master?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;A reader asked why the lifecycle in &lt;a href="http://www.jrothman.com/blog/mpd/2012/01/agile-lifecycles-for-geographically-distributed-teams-part-1.html" target="_blank"&gt;Agile Lifecycles for Geographically Distributed Teams, Part 1&lt;/a&gt; is not Scrum. It&amp;#8217;s not Scrum for these reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;The project manager and product owner start the release planning and ask the team if the release planning is ok. The team does not generate the initial draft of release planning itself. In Scrum, the team is supposed to generate all of the planning itself.&lt;/li&gt;
&lt;li&gt;The checkin is different from the Scrum standup and the objectives of the checkin are different. I did suggest to the teams that if you want to create a cross-functional team where the functions are separated, if you ask people how they are working together, you might help them work together. Sometimes those questions work, and sometimes they don&amp;#8217;t. It depends on the team and whether the people want to work together.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I didn&amp;#8217;t mention retrospectives or backlogs in my examples so far, because I took them for granted. Yes, both examples of these teams do perform retrospectives and have product backlogs. They also have agile feature roadmaps, which are on my list to blog about.&lt;/p&gt;
&lt;p&gt;The real difference is the difference between a Scrum Master and an Agile Project Manager. A Scrum Master is not a project manager. A scrum master does not manage risk by him or herself. A project manager will take on the risk management responsibility without asking the team.&lt;/p&gt;
&lt;p&gt;A Scrum Master has only allegiance to the team. A project manager has responsibility to the team &lt;em&gt;and&lt;/em&gt; to the organization. That means that the project manager might feel torn when the organization pressures the project manager to do something stupid. (Although, I just downloaded the Scrum Guide, and the Scrum Master&amp;#8217;s responsibilities have grown considerably since I took my CSM with Jeff way back in 2006.)&lt;/p&gt;
&lt;p&gt;But agile provides transparency when the organization asks the agile project manager to do something stupid, so it&amp;#8217;s easier to retain your integrity as a project manager.&lt;/p&gt;
&lt;p&gt;Want to move a feature higher in the backlog? Change the feature roadmap with the product owner and then change the backlog with the product owner. I expect the agile project manager to collaborate on the feature roadmap and the backlog with the product owner.&lt;/p&gt;
&lt;p&gt;Want to change the velocity of the team to please some crazed manager? Both the Scrum Master or the agile project manager protects the team in these ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Explain that velocity is not a productivity metric&lt;/li&gt;
&lt;li&gt;Say No and explain why&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.itjoblog.co.uk/2010/07/agile-management-new-schedule-game.html" target="_blank"&gt;Play the Double Your Velocity &lt;/a&gt;schedule game&lt;/li&gt;
&lt;li&gt;Or choose some other way to remove this management obstacle.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Agile makes it easy to protect the team. The question is this: does the Scrum Master have other responsibilities in addition to protecting the team or is the Scrum Master full time? An agile project manager tends to be full time on a geographically distributed team. Even on a geographically distributed team, a Scrum Master is not seen as a full time position. Bless their tiny little hearts, managers don&amp;#8217;t seem to understand that transitioning to agile, especially for silo&amp;#8217;d distributed teams with different cultural norms is non-trivial. They will make room for a project manager, but a Scrum Master? Oh no. Makes me nuts.&lt;/p&gt;
&lt;p&gt;Cut corners on quality? I don&amp;#8217;t see how. The team doesn&amp;#8217;t meet the acceptance criteria on the stories and doesn&amp;#8217;t meet their criteria of done for an iteration, and can&amp;#8217;t show a demo. How does that serve anyone?&lt;/p&gt;
&lt;p&gt;Help a team go faster? This is the one place where a project manager &lt;em&gt;may&lt;/em&gt; have an edge over a Scrum Master, and that&amp;#8217;s only because of education. An agile project manager is a project manager. That means he or she is actively studying project management, which means he or she is studying lean also, looking into work in progress. (I realize many project managers do not actively study project management.) I have high expectations of an agile project manager, and that is to limit WIP, work in progress, to measure cumulative flow. But, Johanna, that&amp;#8217;s a lean project manager. Yes, that&amp;#8217;s correct. Why not use all of the tools available to us at all times? This is not to help a team actually go faster, but to provide feedback to the team about their WIP. If everyone takes a story at the start of the iteration and everyone always works on their own story, it&amp;#8217;s likely the team is at the slowest possible velocity. It&amp;#8217;s worth knowing that, or at least retrospecting about the data. A project manager will gather the data. A Scrum Master, especially one who was not a trained project manager, may not know to gather the data.&lt;/p&gt;
&lt;p&gt;I have nothing against Scrum Masters. Some of my good friends are CSTs (Certified Scrum Trainers). However, they are not all project managers, and have not been project managers, and have not studied the field of project management. Some have been. And, the real issue is this: In a two or three day workshop, they cannot convey to a person who may or may not have been a practicing project manager all of their project knowledge.&lt;/p&gt;
&lt;p&gt;Organizations do not always pick project managers to be Scrum Masters. And, with good reason. Some project managers are command-and-control project managers. I suspect back in my long-ago past, I was. I gave it up long ago because it didn&amp;#8217;t work. Some people never gave up command-and-control project management. Those people are not good project managers for agile projects. They are terrible project managers for geographically distributed projects, where you must work through influence.&lt;/p&gt;
&lt;p&gt;You can have self-managing teams that are geographically distributed. You can have self-directed teams that are geographically distributed. But, they don&amp;#8217;t start that way. They evolve into self-directed and self-managing teams. They start as management-led teams.&lt;/p&gt;
&lt;p&gt;And, especially when they are silo&amp;#8217;d teams, they need the coordination of a project manager, someone who will manage the risk between the silos, and someone who has the organizational backing, and yes, someone who has the allegiance to the organization to say, &amp;#8220;We need to do this project&amp;#8221; to write the project charter.&lt;/p&gt;
&lt;p&gt;In a geographically distributed team, the agile project manager writes the project charter either with the team, or as a strawman for the people to edit and approve. Shane and I recommend that the people get together to write it together. We like it if people get together in person. We know how rarely that happens. (Penny wise, pound foolish.) So we teach people how to write a project charter when they are divided in space.&lt;/p&gt;
&lt;p&gt;Because until there is a project charter, there is no organizing principle for the silo&amp;#8217;d teams. Those developers in France, testers in Belarus, product managers and project manager in San Francisco, they all need something to coalesce around. The charter, which includes the project vision provides that. The iterations provide the project heartbeat.&lt;/p&gt;
&lt;p&gt;So, that&amp;#8217;s why I don&amp;#8217;t think &lt;a href="http://www.jrothman.com/blog/mpd/2012/01/agile-lifecycles-for-geographically-distributed-teams-part-1.html" target="_blank"&gt;Agile Lifecycles for Geographically Distributed Teams, Part 1&lt;/a&gt; is Scrum. It&amp;#8217;s close, but no cigar. I respect Ken and Jeff&amp;#8217;s work too much to call it Scrum when it&amp;#8217;s not.&lt;/p&gt;
&lt;p&gt;Now that I&amp;#8217;m mostly recovered from my cold, I can continue the series about lifecycles.&lt;/p&gt;
&lt;p&gt;(Want to learn to work more effectively on your geographically distributed team? Join Shane Hastie and me in a &lt;a href="../../../2012/01/working-effectively-in-geographically-distributed-agile-project-teams/" target="_blank"&gt;workshop&lt;/a&gt; April 17-18, 2012.)&lt;/p&gt;
&lt;div class="feedflare"&gt;
&lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=l5rftu71S1Q:IblcfQgxFlo:yIl2AUoC8zA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=yIl2AUoC8zA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=l5rftu71S1Q:IblcfQgxFlo:7Q72WNTAKBA"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=7Q72WNTAKBA" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=l5rftu71S1Q:IblcfQgxFlo:V_sGLiPBpWU"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?i=l5rftu71S1Q:IblcfQgxFlo:V_sGLiPBpWU" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=l5rftu71S1Q:IblcfQgxFlo:gIN9vFwOqvQ"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?i=l5rftu71S1Q:IblcfQgxFlo:gIN9vFwOqvQ" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=l5rftu71S1Q:IblcfQgxFlo:dnMXMwOfBR0"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=dnMXMwOfBR0" border="0"&gt;&lt;/img&gt;&lt;/a&gt; &lt;a href="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?a=l5rftu71S1Q:IblcfQgxFlo:cGdyc7Q-1BI"&gt;&lt;img src="http://feeds.feedburner.com/~ff/ManagingProductDevelopment?d=cGdyc7Q-1BI" border="0"&gt;&lt;/img&gt;&lt;/a&gt;
&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/ManagingProductDevelopment/~4/l5rftu71S1Q" height="1" width="1"/&gt;</description>
      <pubDate>Wed, 01 Feb 2012 13:00:26 CST</pubDate>
      <guid isPermaLink="true">http://www.jrothman.com/blog/mpd/?p=11105</guid>
      <dc:creator>Johanna Rothman</dc:creator>
    </item>
    <item>
      <title>HTML5 Cloud-based Mobile App Builder Now With jQuery Mobile version 1.0</title>
      <link>http://springone2gx.com/blog/max_katz/2012/01/html5_cloud_based_mobile_app_builder_now_with_jquery_mobile_version_1_0?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;&lt;img src="http://mkblog.exadel.com/wp-content/uploads/2012/01/screenshot_312.png" alt="" title="screenshot_312" width="550" height="293" class="alignnone size-full wp-image-4226" /&gt;&lt;/p&gt;
&lt;p&gt;In mid January we have released an update to &lt;a href="http://tiggzi.com" title="Tiggzi, mobile app builder"&gt;Tiggzi mobile app builder&lt;/a&gt; and now every app (new or old) is based on jQuery Mobile version 1.0. &lt;/p&gt;
&lt;p&gt;Now that there is a &lt;a href="http://tiggzi.com/pricing"&gt;Free plan&lt;/a&gt;, nothing should stop you from building your mobile app. &lt;/p&gt;</description>
      <pubDate>Tue, 31 Jan 2012 13:00:19 CST</pubDate>
      <guid isPermaLink="true">http://mkblog.exadel.com/?p=4225</guid>
      <dc:creator>Max Katz</dc:creator>
    </item>
    <item>
      <title>Static type checking and compilation in Groovy 2</title>
      <link>http://springone2gx.com/blog/guillaume_laforge/2012/01/static_type_checking_and_compilation_in_groovy_2?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description />
      <pubDate>Tue, 31 Jan 2012 11:00:16 CST</pubDate>
      <guid isPermaLink="true">static-type-checking-and-compilation-in-groovy-2</guid>
      <dc:creator>Guillaume LaForge</dc:creator>
    </item>
    <item>
      <title>This Week in Grails (2012-04)</title>
      <link>http://springone2gx.com/blog/burt_beckwith/2012/01/this_week_in_grails_2012_04_?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;Peter Ledbrook started a HOWTO series this week for Grails; the first one is on &lt;a target='_blank' href='http://pledbrook.github.com/grails-howtos/en/upgradeToGrails2.html'&gt;upgrading to Grails 2.0&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; and there&amp;#8217;s also a &lt;a target='_blank' href='http://pledbrook.github.com/grails-howtos/en/contributeToTheseGuides.html'&gt;HOWTO on writing HOWTOs&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;We could use your help finding invalid JIRA issues (e.g. already fixed or no longer an issue). Check out the section &amp;#8220;Reviewing issues&amp;#8221; in the &lt;a target='_blank' href='http://grails.org/Contribute'&gt;wiki page on contributing to Grails&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; for how to use the new &amp;#8220;Last Reviewed&amp;#8221; and &amp;#8220;Flagged&amp;#8221; fields.&lt;/p&gt;
&lt;p&gt;Tomas Lin wrote up his experiences &lt;a target='_blank' href='http://fbflex.wordpress.com/2012/01/27/deploying-grails-applications-on-appfog-first-impressions/'&gt;deploying Grails applications to AppFog&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;. It&amp;#8217;s great to know that there&amp;#8217;s another viable cloud provider for Grails developers.&lt;/p&gt;
&lt;p&gt;STS 2.9.0.M2 was &lt;a target='_blank' href='http://www.springsource.org/node/3377'&gt;released this week&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;. Check out the &lt;a target='_blank' href='http://download.springsource.com/release/STS/doc/STS-new_and_noteworthy-2.9.0.M2.pdf'&gt;new and noteworthy PDF&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; for what&amp;#8217;s been updated in the Groovy, Grails, and Gradle support.&lt;/p&gt;
&lt;p&gt;I released a &lt;a target='_blank' href='http://grails.org/plugin/ratpack'&gt;new plugin&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; this week, to support using &lt;a target='_blank' href='https://github.com/bleedingwolf/Ratpack'&gt;Ratpack&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; in a Grails application. Thanks to James Williams for &lt;a target='_blank' href='http://jameswilliams.be/blog/entry/233'&gt;his post&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; that got me started and inspired the plugin. And within a day there was already a &lt;a target='_blank' href='http://padcom13.blogspot.com/2012/01/grails-and-ratpack.html'&gt;blog post by Matthias Hryniszak&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; on using the plugin.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;If you want to keep up with these &amp;#8220;This Week in Grails&amp;#8221; posts you can access them directly via their &lt;a target="_blank" href="http://burtbeckwith.com/blog/?cat=32"&gt;category link&lt;img src="/blog/images/pop.gif"/&gt;&lt;/a&gt; or in an RSS reader with &lt;a target="_blank" href="http://feeds.feedburner.com/this-week-in-grails"&gt;the feed&lt;img src="/blog/images/pop.gif"/&gt;&lt;/a&gt; for just these posts.&lt;/p&gt;
&lt;hr/&gt;
&lt;p&gt;Translations of this post:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://observatoriodegrails.com/2012/01/31/esta-semana-en-grails-2012-04/'&gt;Traducción al español&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.groovyq.net/content/grails%E6%AF%8F%E5%91%A8%E8%A7%82%E5%AF%9F%EF%BC%882012-04%EF%BC%89'&gt;Grails每周观察&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://remoteexception.blogspot.com/2012/01/semana-grails-2012-04.html'&gt;Este artigo em Português&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.luca-canducci.com/2012/01/questa-settimana-in-grails-2012-04/'&gt;Traduzione Italiana&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.jp/news/2012-04.html'&gt;今週のGrails日本語版&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;div class="toc"&gt;
&lt;img src="/blog/images/folder_go.png"/&gt;&amp;nbsp;&lt;a href="#miscellaneous"&gt;Miscellaneous Items&lt;/a&gt;&lt;br /&gt;
&lt;img src="/blog/images/folder_go.png"/&gt;&amp;nbsp;&lt;a href="#plugins"&gt;Plugins&lt;/a&gt;&lt;br /&gt;
&lt;img src="/blog/images/folder_go.png"/&gt;&amp;nbsp;&lt;a href="#tweets"&gt;Interesting Tweets&lt;/a&gt;&lt;br /&gt;
&lt;img src="/blog/images/folder_go.png"/&gt;&amp;nbsp;&lt;a href="#jobs"&gt;Jobs&lt;/a&gt;&lt;br /&gt;
&lt;img src="/blog/images/folder_go.png"/&gt;&amp;nbsp;&lt;a href="#meetups"&gt;User groups and Conferences&lt;/a&gt;
&lt;/div&gt;
&lt;hr/&gt;
&lt;div id="miscellaneous"&gt;
&lt;h2&gt;Miscellaneous Items&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://developer4life.blogspot.com/2012/01/wizard-design-pattern.html'&gt;The Wizard Design Pattern&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Not Grails-specific, but an interesting approach, especially for DSLs and builders
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://assarconsulting.blogspot.com/2012/01/groovy-dsl-simple-example.html'&gt;Groovy DSL &amp;#8211; A Simple Example&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.tomcatexpert.com/blog/2012/01/24/apache-tomcat-7025-released'&gt;Apache Tomcat 7.0.25 released&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://blog.jelastic.com/2012/01/24/grails-on-jelastic/'&gt;Grails on Jelastic&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://plus.google.com/117411438136918964913/posts/axyCZk1P5L5'&gt;Have you upgraded a #grails application to version 2 yet? Let us know how it went!&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://ldaley.com/post/615966534/custom-grails-test'&gt;Custom Grails Test Types/Phases&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Older but cool
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://leanjavaengineering.wordpress.com/2012/01/26/c-r-a-p-metrics-for-grails/'&gt;C.R.A.P. metrics for Grails&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.jroller.com/melix/entry/static_compilation_for_groovy_poll'&gt;Static compilation for Groovy poll results&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.intelligrape.com/blog/2012/01/29/groovy-annotations-for-tostring-and-equalsandhashcode/'&gt;Groovy annotations for ToString and EqualsAndHashCode &lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
A good reminder, and useful tip about adding to the domain class template
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://refactr.com/blog/2012/01/grails-database-migration-gotchas/'&gt;Grails Database Migration Gotchas&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://schneide.wordpress.com/2012/01/23/upgrading-your-app-to-grails-2-0-0-better-wait-for-2-0-1/'&gt;Upgrading your app to Grails 2.0.0? Better wait for 2.0.1&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.tomcatexpert.com/blog/2012/01/24/using-tomcat-7-jdbc-connection-pool-production'&gt;Using the Tomcat 7 JDBC Connection Pool in Production&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.jroller.com/aalmiray/entry/grails_bootstrapping_data_with_domainbuilder'&gt;Grails: Bootstrapping data with DomainBuilder&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://mrhaki.blogspot.com/2012/01/groovy-goodness-solve-naming-conflicts.html'&gt;Groovy Goodness: Solve Naming Conflicts with Builders&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.jroller.com/melix/entry/static_type_checking_talk_from'&gt;Static type checking talk from Paris Groovy/Grails User Group&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.workopolis.com/EN/job/13616464'&gt;Java Groovy / Grails Developer in Toronto&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://sbglasius.tumblr.com/post/16691515147/grails-weceem-apache2'&gt;Grails, Weceem and Apache2&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Getting the GR8Conf sites running on new hardware
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://blog.andresteingress.com/2012/01/24/cachemanagers-diskstorepath/'&gt;CacheManager’s diskStorePath&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Interesting stuff on configuring Ehcache
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://observatoriodegrails.com/hoy/?date=2012-01-23'&gt;http://observatoriodegrails.com/hoy/?date=2012-01-23&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://observatoriodegrails.com/hoy/?date=2012-01-24'&gt;http://observatoriodegrails.com/hoy/?date=2012-01-24&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://observatoriodegrails.com/hoy/?date=2012-01-25'&gt;http://observatoriodegrails.com/hoy/?date=2012-01-25&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://observatoriodegrails.com/hoy/?date=2012-01-26'&gt;http://observatoriodegrails.com/hoy/?date=2012-01-26&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://observatoriodegrails.com/hoy/?date=2012-01-27'&gt;http://observatoriodegrails.com/hoy/?date=2012-01-27&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://forums.gradle.org/gradle/topics/this_week_in_gradle_2012_4'&gt;This Week in Gradle (2012-4)&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.springsource.org/node/3379'&gt;This Week in Spring, January 24th, 2012&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div id="plugins"&gt;
&lt;h2&gt;Plugins&lt;/h2&gt;
&lt;p&gt;There were 3 new plugins released:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/jquery-ui-timepicker'&gt;jquery-ui-timepicker&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.9.8.1. Provides resources for &lt;a href="http://trentrichardson.com/examples/timepicker/" target='_blank'&gt;http://trentrichardson.com/examples/timepicker/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/eco-resources'&gt;eco-resources&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.1. Compiles Eco templates to Javascript
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/ratpack'&gt;ratpack&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 1.0.1. Lets you use Ratpack inside Grails
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;and 17 updated plugins:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/atmosphere'&gt;atmosphere&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.4.2.1. Provides integration with the Atmosphere project, a portable AjaxPush/Comet and WebSocket framework
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/ckeditor'&gt;ckeditor&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 3.6.2.1. Implements the integration layer between Grails and the CKEditor web rich text editor.
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/date-formatting'&gt;date-formatting&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.2.5. Adds functions to the Date object to convert into various string formats
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/foundation'&gt;foundation&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 2.1.4.3. Provides the Foundation CSS framework resources
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/google-visualization'&gt;google-visualization&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.5. Provides a taglib for the interactive charts of the Google Visualization API
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/grails-melody'&gt;grails-melody&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 1.11. Integrates the JavaMelody system monitoring tool
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/gsp-taglib'&gt;gsp-taglib&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.3.2. Makes it possible to declare tags in a gsp in grails-app/taglib
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/jasper'&gt;jasper&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 1.5.2. Enables use of JasperReports
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/rich-domain'&gt;rich-domain&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 1.0.6. Provides dependency injection for POGOs that are not Grails domain classes
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/spring-security-mock'&gt;spring-security-mock&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 1.0.1. Mock authentication support for Spring Security
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/spring-security-saml'&gt;spring-security-saml&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 1.0.0.M11. SAML 2.x support for the Spring Security Plugin
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/spring-security-shibboleth-native-sp'&gt;spring-security-shibboleth-native-sp&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 1.0.2. Shibboleth Naitive SP support for the Spring Security grails plugin
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/syntax-highlighter'&gt;syntax-highlighter&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 3.0.83. Adds a Syntax Highlighter for displaying code samples in GSP pages
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/tiny-mce'&gt;tiny-mce&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 3.4.7. Integrates the TinyMce editor javascript and tags to embed the editor in your GSP pages
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/twitter4j'&gt;twitter4j&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.3.2. Send and receive Twitter messages using the twitter4j library
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/xwiki-rendering'&gt;xwiki-rendering&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.4. Convert texts using XWiki Rendering Framework
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://grails.org/plugin/zkui'&gt;zkui&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt; version 0.4.1. Seamlessly integrates ZK with Grails&amp;#8217; infrastructures; uses the Grails&amp;#8217; infrastructures such as GSP, controllers rather than zk&amp;#8217;s zul as in ZKGrails plugin
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div id="tweets"&gt;
&lt;h2&gt;Interesting Tweets&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/CedricChampeau/status/161145720496336897'&gt;@CedricChampeau&lt;/a&gt;: More details about my talk, static type checking at the Paris &lt;a href='https://search.twitter.com/search?q=%23groovy' target='_blank'&gt;#groovy&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23grails' target='_blank'&gt;#grails&lt;/a&gt; user group. &lt;a href="http://t.co/mUwPQcJD" target='_blank'&gt;http://t.co/mUwPQcJD&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/LondonGGUG/status/161823948487655424'&gt;@LondonGGUG&lt;/a&gt;: Anyone free and willing to talk about their &lt;a href='https://search.twitter.com/search?q=%23grails' target='_blank'&gt;#grails&lt;/a&gt; deployment setup at next GGUG? 20th Feb. Length 10-30 mins.
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/joshareed/status/161983137939849216'&gt;@joshareed&lt;/a&gt;: &amp;#8216;git clean -df&amp;#8217; is great for cleaning up all the images, css, js that a grails upgrade re-creates
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/wangjammer5/status/162155760539795456'&gt;@wangjammer5&lt;/a&gt;: Great discussions with &lt;a href='https://search.twitter.com/search?q=%23Grails' target='_blank'&gt;#Grails&lt;/a&gt; team this morning yielded this idea to replace install-plugin: &lt;a href="http://t.co/fQcHbXeJ" target='_blank'&gt;http://t.co/fQcHbXeJ&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/CodersUniverse/status/162163770276319232'&gt;@CodersUniverse&lt;/a&gt;: SpringPeople launches open house training in India: &amp;#8230; Tomcat, Apache, Groovy &amp;#038; Grails, Testing, Databases, Ope&amp;#8230; &lt;a href="http://t.co/DfnHxmk7" target='_blank'&gt;http://t.co/DfnHxmk7&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/fifthposition/status/162203342813143040'&gt;@fifthposition&lt;/a&gt;: Grails 2.0 and emacs shell-mode: &lt;a href="http://t.co/ruPXN0i2" target='_blank'&gt;http://t.co/ruPXN0i2&lt;/a&gt;. (Thanks to &lt;a href='https://twitter.com/#!/ataylor284' target='_blank'&gt;@ataylor284&lt;/a&gt; for this.) &lt;a href='https://search.twitter.com/search?q=%23grails' target='_blank'&gt;#grails&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23emacs' target='_blank'&gt;#emacs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/aalmiray/status/162281230547697664'&gt;@aalmiray&lt;/a&gt;: hacking groovy/javafx by day; griffon/grails by night. 2012 is certainly looking interesting as days pass by
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/gr8conf/status/162301816149770242'&gt;@gr8conf&lt;/a&gt;: We&amp;#8217;re happy to announce, that SpringSource is the premium sponsor of &lt;a href='https://search.twitter.com/search?q=%23gr8conf' target='_blank'&gt;#gr8conf&lt;/a&gt; Europe 2012. &lt;a href='https://search.twitter.com/search?q=%23groovy' target='_blank'&gt;#groovy&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23grails' target='_blank'&gt;#grails&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23gradle' target='_blank'&gt;#gradle&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23griffon' target='_blank'&gt;#griffon&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23vmware' target='_blank'&gt;#vmware&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/nhoussos/status/162830544617480192'&gt;@nhoussos&lt;/a&gt;: New release of Free/Open source applicant tracking (e-Recruitment) system by EKT (developed in Grails!): &lt;a href="http://t.co/n7qaC2Fy" target='_blank'&gt;http://t.co/n7qaC2Fy&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/jatin_Shephertz/status/162965950826684420'&gt;@jatin_Shephertz&lt;/a&gt;: I created group Grails 4 Newbie on Linkedin.: &lt;a href="http://t.co/FNjG7dEq" target='_blank'&gt;http://t.co/FNjG7dEq&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/bmuschko/status/163675327195906048'&gt;@bmuschko&lt;/a&gt;: Released &lt;a href='https://search.twitter.com/search?q=%23grails' target='_blank'&gt;#grails&lt;/a&gt; Google Visualization plugin v0.5: &lt;a href="http://t.co/LL6aqysm" target='_blank'&gt;http://t.co/LL6aqysm&lt;/a&gt;. New visualizations, minor bugfixes, JS API taglib, updated docs.
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div id="jobs"&gt;
&lt;h2&gt;Jobs&lt;/h2&gt;
&lt;hr/&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://seeker.dice.com/jobsearch/servlet/JobSearch?op=300&amp;#038;FREE_TEXT=grails&amp;#038;FRMT=0'&gt;Dice keyword search for Grails&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://jobsearch.monster.com/PowerSearch.aspx?q=grails'&gt;Monster keyword search for Grails&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.careerbuilder.com/Jobseeker/Jobs/JobResults.aspx?_ctl0%3A_ctl2%3AucQuickBar%3As_rawwords=grails'&gt;Careerbuilder keyword search for Grails&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/SpringSourceJob'&gt;SpringSourceJob Twitter feed&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://jobs.vmware.com/search?q=springsource'&gt;SpringSource job search at jobs.vmware.com&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.grailsjobs.com/view-job/396'&gt;Groovy/Grails Developer (contract) in Slovakia&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.grailsjobs.com/view-job/397'&gt;Sr. Developer Analyst (Grails) &amp;#8211; Columbus, Ohio&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://www.webcruiter.no/wcmain/advertviewpublic.aspx?oppdragsnr=1302686071&amp;#038;culture_id=DA&amp;#038;company_id=4662900&amp;#038;Link_source_id=&amp;#038;use_position_site_header=0'&gt;Freelance Grails/Java udviklere &amp;#8211; København&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/SaraJaneJones2/status/162630437922021376'&gt;@SaraJaneJones2&lt;/a&gt;: &lt;a href='https://twitter.com/#!/lakah' target='_blank'&gt;@lakah&lt;/a&gt; Hey John, I&amp;#8217;m looking for &lt;a href='https://search.twitter.com/search?q=%23groovy' target='_blank'&gt;#groovy&lt;/a&gt;/grails developer for a client in &lt;a href='https://search.twitter.com/search?q=%23nyc' target='_blank'&gt;#nyc&lt;/a&gt;. Would you have any referrals? Plz rt!
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://us1.campaign-archive1.com/?u=c4dba33aa421b27c3fc24b8c6&amp;#038;id=05edcb0485'&gt;Groovy / Grails Developer in NYC&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.grailsjobs.com/view-job/398'&gt;Java Groovy/Grails Developer &amp;#8211; Toronto, ON, Canada&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.jobg8.com/JobG8SearchFullView.aspx?jbid=2353&amp;#038;jid=4200854'&gt;Java/Grails Developer in Phoenix, AZ&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.ziprecruiter.com/job/Groovy-Grails-Developer/7a1a9cfb/'&gt;Groovy Grails Developer in NYC&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://careers.joelonsoftware.com/jobs/13095/sr-consultant-java-grails-ios-permanent-full-object-partners'&gt;Sr. Consultant (Java/Grails/iOS) at Object Partners in Minneapolis, MN&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.virtualvocations.com/job/remote-java-jvm-grails-developer-73521.html'&gt;Remote Java / JVM / Grails Developer&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/coryhodnett/status/161508257620443136'&gt;@coryhodnett&lt;/a&gt;: Looking for a Web Developer for Java Script, Grails, &amp;#038; AJAX contract.  Call me! 6022242486
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/mobiquityinc/status/161499479651004419'&gt;@mobiquityinc&lt;/a&gt;: Still looking for &lt;a href='https://search.twitter.com/search?q=%23mobile' target='_blank'&gt;#mobile&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23developers' target='_blank'&gt;#developers&lt;/a&gt;. Especially with &lt;a href='https://search.twitter.com/search?q=%23Cocos2D' target='_blank'&gt;#Cocos2D&lt;/a&gt; and &lt;a href='https://search.twitter.com/search?q=%23Grails' target='_blank'&gt;#Grails&lt;/a&gt; experience. &lt;a href='https://search.twitter.com/search?q=%23Jobs' target='_blank'&gt;#Jobs&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23Boston' target='_blank'&gt;#Boston&lt;/a&gt; &lt;a href='https://search.twitter.com/search?q=%23PVD' target='_blank'&gt;#PVD&lt;/a&gt;.
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.linkedin.com/updates?discuss=&amp;#038;scope=73776304&amp;#038;stype=M&amp;#038;type=U&amp;#038;topic=5567319485301395456&amp;#038;a=h_x8'&gt;Looking for Java Developers, Java / Grails developers&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/gsuhm/status/162224941427728385'&gt;@gsuhm&lt;/a&gt;: Are you a &lt;a href='https://search.twitter.com/search?q=%23grails' target='_blank'&gt;#grails&lt;/a&gt; developer in Atlanta? Drop me a note for a great opportunity&amp;#8230;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/jvandersande/status/162382772332281856'&gt;@jvandersande&lt;/a&gt;: 2 groovy/grails development roles for a new startup. Great company w/ a great story. Willing to look at java, python, ruby, etc engineers
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/errr_/status/162351328625049601'&gt;@errr_&lt;/a&gt;: Are you a bad ass Java developer? Do you know groovy and grails? Do you also know vmware? We NEED you!! Shoot me your resume!
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.bullhornreach.com/job/187981_java-dev-grails-nashville-tn'&gt;Java Dev &amp;#8211; Grails in Nashville&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://jobs.ipfhr.com/job/java-grailsgroovy-restful-web-services/650542'&gt;Java, Grails/Groovy, Restful Web Services&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.4europeanjobs.com/display_job/524548/Java_Devloper.html'&gt;Java Developer in Bristol, UK&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://annoncevisning.monster.dk/getjob.aspx?JobID=105876092'&gt;Java udviklere søges (Grails, Groovy, Spring) &amp;#8211; Sjælland &amp;#038; Hovedstad&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.postjobfree.com/job/jxc9lo/grails-remotely-re-done-java-vancouver-bc-v5z-1k7?id=ac073658413d4cf1b38113ee96128b5c'&gt;Contract Java Developer in Vancouver&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='www.linkedin.com/groups/Senior-Java-Grails-Groovy-Developer-39757.S.90634084?view=&amp;#038;gid=39757&amp;#038;type=member&amp;#038;item=90634084'&gt;Senior Java Grails/Groovy Developer (contract) in NYC&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='https://twitter.com/#!/DevelopmenGC/status/161812831874973696'&gt;@DevelopmenGC&lt;/a&gt;: Recherche Analyste programmeur Groovy (Grails) (Montréal)&lt;br /&gt;
Contactez : &lt;a href='mailto:cv@developmen.ca'&gt;cv@developmen.ca&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.jobsite.co.uk/job/lead-java-developer-architect-groovy-grails-941787085'&gt;Lead Java Developer / Architect &amp;#8211; Groovy, Grails in Northampton, UK&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;div id="meetups"&gt;
&lt;h2&gt;User groups and Conferences&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.springio.net/'&gt;Spring I/O 2012&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
February 16&lt;sup&gt;th&lt;/sup&gt; and 17&lt;sup&gt;th&lt;/sup&gt; in Madrid
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr/&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.meetup.com/Seattle-Groovy/events/49374702/'&gt;Thursday, February 9, 2012&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Seattle Groovy/Grails Users Group
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;a target='_blank' href='http://www.meetup.com/Seattle-Groovy/events/48327722/'&gt;March 8, 2012&lt;img src='/blog/images/pop.gif'/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Seattle Groovy/Grails Users Group
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
&lt;p class="wp-flattr-button"&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://burtbeckwith.com/blog/?flattrss_redirect&amp;amp;id=1204&amp;amp;md5=c7fc9a680eb9a067600881a7cb1631a1" title="Flattr" target="_blank"&gt;&lt;img src="http://burtbeckwith.com/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Tue, 31 Jan 2012 08:00:26 CST</pubDate>
      <guid isPermaLink="true">http://burtbeckwith.com/blog/?p=1204</guid>
      <dc:creator>Burt Beckwith</dc:creator>
    </item>
    <item>
      <title>Running Ratpack inside Grails</title>
      <link>http://springone2gx.com/blog/james_williams1/2012/01/running_ratpack_inside_grails?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;div&gt;When I would present on Ratpack at conferences, one of the main questions I'd get would be around the migration path from Ratpack to Grails. I'd usually answer noting that you could run Ratpack along side Grails. It turns out it is incredibly simple to run a Ratpack app inside Grails. I don't think it's a long term solution and best as an intermediary step to migrate from one side to the other.&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;1. Grab and build &lt;a href="http://github.com/bleedingwolf/Ratpack"&gt;Ratpack&lt;/a&gt;.&lt;/div&gt;&#xD;
&lt;div&gt;Provided you already have Gradle installed, run &lt;em&gt;gradle buildDistro&lt;/em&gt;. The only file you need is the main Ratpack-x.x file. Grails will provide the Groovy and servlet container run time for you. Add this to the lib directory of your Grails app.&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;2. Create your Ratpack app class.&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;Putting the script into a proper class, as shown below, makes it easier to reference it from our Servlet.&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;import java.text.SimpleDateFormat&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;import com.bleedingwolf.ratpack.*&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;class SampleApp {&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;			&lt;/span&gt;def app = Ratpack.app {&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;set 'port', 4999&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;get(&amp;quot;/&amp;quot;) {&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;					&lt;/span&gt;def ua = headers['user-agent']&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &lt;span class="Apple-tab-span" style="white-space:pre"&gt;			&lt;/span&gt;&amp;quot;Your user-agent: ${ua} from Ratpack&amp;quot;&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;}&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;get(&amp;quot;/foo/:name&amp;quot;) {&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;					&lt;/span&gt;&amp;quot;Hello, ${urlparams.name}&amp;quot;&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;}&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;get(&amp;quot;/person/:id&amp;quot;) {&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;					&lt;/span&gt;&amp;quot;Person #${urlparams.id}&amp;quot;&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;}&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;			&lt;/span&gt;}&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;			&lt;/span&gt;public static void main(String[] args) {&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;				&lt;/span&gt;SampleServlet.serve(new SampleApp().app)&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&amp;nbsp;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;			&lt;/span&gt;}&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;}&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;3. Subclass *RatpackServlet*.&lt;/div&gt;&#xD;
&lt;div&gt;If you don't mind getting an logging error, you can use something as simple as the following file:&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;&lt;code&gt;import com.bleedingwolf.ratpack.*&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;	&lt;/span&gt;class SampleServlet extends RatpackServlet {&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;			&lt;br /&gt;&#xD;
&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; void init() {&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;app = new SampleApp().app&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;} &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;	&lt;/span&gt;}&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;4. Add the servlet information to your application.&lt;/div&gt;&#xD;
&lt;div&gt;There is a really confusing way to do it using the resources.groovy file but I prefer just adding it to the web.xml by hand. Run&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;&lt;em&gt;grails install-templates&lt;/em&gt;&lt;/div&gt;&#xD;
&lt;div&gt;and navigate to src/templates/war/web.xml and add the following:&lt;/div&gt;&#xD;
&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;&lt;code&gt;&amp;lt;servlet&amp;gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;&amp;lt;servlet-name&amp;gt;SampleServlet&amp;lt;/servlet-name&amp;gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;	&lt;br /&gt;&#xD;
&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;lt;servlet-class&amp;gt;SampleServlet&amp;lt;/servlet-class&amp;gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;	&lt;br /&gt;&#xD;
&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;lt;/servlet&amp;gt;&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&lt;code&gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;	&lt;/span&gt;&amp;lt;servlet-mapping&amp;gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;/span&gt;&amp;lt;servlet-name&amp;gt;SampleServlet&amp;lt;/servlet-name&amp;gt;&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;		&lt;br /&gt;&#xD;
&lt;/span&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;url-pattern&amp;gt;/ratpack/*&amp;lt;/url-pattern&amp;gt;&lt;br /&gt;&#xD;
&lt;/code&gt;&lt;code&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;	&lt;/span&gt;&amp;lt;/servlet-mapping&amp;gt;&lt;/code&gt;&lt;/div&gt;&#xD;
&lt;div&gt;&amp;nbsp;&lt;/div&gt;&#xD;
&lt;div&gt;The servlet needs to be put on a url-pattern that isn't root (/*) so I used (/ratpack/*). Run &lt;em&gt;grails run-app&amp;nbsp;&lt;/em&gt;and you're all set.&lt;/div&gt;&#xD;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;</description>
      <pubDate>Sun, 29 Jan 2012 13:00:15 CST</pubDate>
      <guid isPermaLink="true">http://jameswilliams.be/blog/entry/2012/1/24/Running+Ratpack+inside+Grails</guid>
      <dc:creator>James Williams</dc:creator>
    </item>
    <item>
      <title>Tea leaf [Flickr]</title>
      <link>http://springone2gx.com/blog/aaron_gustafson/2012/01/tea_leaf_flickr_?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6776764157/" title="Tea leaf"&gt;&lt;img src="http://farm8.staticflickr.com/7143/6776764157_a709241120_m.jpg" width="240" height="240" alt="Tea leaf" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/sjEE5H8Bwbo" height="1" width="1"/&gt;</description>
      <pubDate>Sun, 29 Jan 2012 11:00:16 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6776764157</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>Grails plugin for Ratpack</title>
      <link>http://springone2gx.com/blog/burt_beckwith/2012/01/grails_plugin_for_ratpack?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;I saw James Williams&amp;#8217; post on &lt;a target="_blank" href="http://jameswilliams.be/blog/entry/233"&gt;Running Ratpack inside Grails&lt;img src="/blog/images/pop.gif"/&gt;&lt;/a&gt; earlier this week and thought that it should be implemented as a Grails plugin, so I started playing with it. There isn&amp;#8217;t much in the way of documentation yet, but what&amp;#8217;s there is at the &lt;a target="_blank" href="http://grails.org/plugin/ratpack"&gt;plugin portal page&lt;img src="/blog/images/pop.gif"/&gt;&lt;/a&gt;. The source for the plugin is &lt;a target="_blank" href="https://github.com/burtbeckwith/grails-ratpack"&gt;here&lt;img src="/blog/images/pop.gif"/&gt;&lt;/a&gt; if you have any fixes or suggestions.&lt;/p&gt;
&lt;p class="wp-flattr-button"&gt;&lt;/p&gt; &lt;p&gt;&lt;a href="http://burtbeckwith.com/blog/?flattrss_redirect&amp;amp;id=1198&amp;amp;md5=be5e851124ae8b0e393a629bf5758c41" title="Flattr" target="_blank"&gt;&lt;img src="http://burtbeckwith.com/blog/wp-content/plugins/flattr/img/flattr-badge-large.png" alt="flattr this!"/&gt;&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Sun, 29 Jan 2012 08:00:15 CST</pubDate>
      <guid isPermaLink="true">http://burtbeckwith.com/blog/?p=1198</guid>
      <dc:creator>Burt Beckwith</dc:creator>
    </item>
    <item>
      <title>Server side action methods on JSF ValueChange events using AJAX listeners</title>
      <link>http://springone2gx.com/blog/lincoln_baxter_iii/2012/01/server_side_action_methods_on_jsf_valuechange_events_using_ajax_listeners?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;How many hours have you wasted trying to get AJAX events working &amp;#8220;&lt;em&gt;just right&lt;/em&gt; in your fancy JSF 2 application, only to find that something just doesn&amp;#8217;t &lt;em&gt;quite work right&lt;/em&gt;? .. If you&amp;#8217;re like me, many. But I&amp;#8217;m about to show you a pattern that will make your heart sing. I have to thank &lt;a href="https://twitter.com/#!/brianleathem" target="_blank"&gt;Brian Leathem&lt;/a&gt; for his original idea to use CDI events in the ValueChangeListener, but when combined with a little &lt;code&gt;&amp;lt;f:ajax&amp;gt;&lt;/code&gt; magic, there&amp;#8217;s almost no limit to what you can do without writing a single line of JavaScript.&lt;span id="more-3140"&gt;&lt;/span&gt;&lt;/p&gt;
&lt;p&gt;The following example code was taken from our latest Project: &lt;a href='http://ocpsoft.com/socialpm/'&gt;SocialPM&lt;/a&gt;, a budding Agile Project Management tool. How many times have you tried something like this in a loop, only to find that you have no way of accessing the loop variable (in this case, &amp;#8216;s&amp;#8217;) in your ValueChangeListener?&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="xml" style="font-family:monospace;"&gt;&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;ui:repeat&lt;/span&gt; &lt;span style="color: #000066;"&gt;value&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{stories.list}&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;var&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
   ...
   &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;h:inputText&lt;/span&gt; &lt;span style="color: #000066;"&gt;id&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;priority&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;value&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{s.priority}&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;size&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;2&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;style&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;width: 20px;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
       &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;f:valueChangeListener&lt;/span&gt; &lt;span style="color: #000066;"&gt;binding&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{storyPriorityChanged}&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
       &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;f:ajax&lt;/span&gt; &lt;span style="color: #000066;"&gt;execute&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;@this save&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;render&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;@form&amp;quot;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;/h:inputText&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
   ...
   &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;h:commandLink&lt;/span&gt; &lt;span style="color: #000066;"&gt;id&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;save&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;value&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;Save&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;action&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{stories.saveAjax(s)}&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;style&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;display:none;&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;	
&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;/ui:repeat&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;


&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java" style="font-family:monospace;"&gt;@RequestScoped
@Named&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;storyPriorityChanged&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; StoryPriorityChanged &lt;span style="color: #000000; font-weight: bold;"&gt;implements&lt;/span&gt; ValueChangeListener
&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   @Override
   &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; processValueChange&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; ValueChangeEvent event&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;throws&lt;/span&gt; AbortProcessingException
   &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;...&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
      &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
         &lt;span style="color: #666666; font-style: italic;"&gt;// do something with our event, but, we have no reference to '#{s]'&lt;/span&gt;
         &lt;span style="color: #666666; font-style: italic;"&gt;// only to the old and new values of '#{s.priority}'&lt;/span&gt;
      &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There are a variety of reasons why something like this might not work, none of which are your fault &amp;#8211; most issues arise from subtleties in composite components, or looping constructs. But fortunately there is a solution, and it is called CDI.&lt;/p&gt;
&lt;h3&gt;A ValueChangeListener will execute before data is populated in the Model&lt;/h3&gt;
&lt;p&gt;And the ValueChange event is not an ActionEvent, so we cannot attach an &lt;code&gt;&amp;lt;f:setPropertyActionListener&amp;gt;&lt;/code&gt; to set the value in our backing bean. Yet another limitation &amp;#8211; there really should be an &lt;code&gt;&amp;lt;f:setPropertyOnValueChangedListener&amp;gt;&lt;/code&gt;, and while we could write one ourselves, that would be fairly inconvenient.&lt;/p&gt;
&lt;p&gt;Fortunately, there&amp;#8217;s a better way to do both of these things, and it all hinges on our friends CDI and &lt;code&gt;&amp;lt;f:ajax&amp;gt;&lt;/code&gt;. There are better ways to both make sure our loop instance variable is accessible, and also execute the command action.&lt;/p&gt;
&lt;h3&gt;A viable, reliable solution&lt;/h3&gt;
&lt;p&gt;Our code looks something like this, and before you start worrying about the fact that you need to write &amp;#8220;more&amp;#8221; or &amp;#8220;more complicated&amp;#8221; Java code, I&amp;#8217;ll explain why this method actually loosens the coupling between your UI and your Model/Controller:&lt;/p&gt;
&lt;p&gt;Notice here, that we are using the same ValueChange listener, but we are still not passing the value of &amp;#8216;s&amp;#8217;, our Story object, into the listener. We have also eliminated the need for invoking our &lt;code&gt;&amp;lt;h:commandLink&amp;gt;&lt;/code&gt; by instead using the &lt;code&gt;listener=""&lt;/code&gt; attribute on our &lt;code&gt;&amp;lt;f:ajax&amp;gt;&lt;/code&gt; tag. This allows us to invoke any server-side EL method when the Ajax event occurs. Using EL 2.0, we can pass our &lt;code&gt;Story&lt;/code&gt; &amp;#8216;s&amp;#8217; into the method as a parameter.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="xml" style="font-family:monospace;"&gt;&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;ui:repeat&lt;/span&gt; &lt;span style="color: #000066;"&gt;value&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{stories.list}&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;var&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
   ...
   &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;h:inputText&lt;/span&gt; &lt;span style="color: #000066;"&gt;id&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;priority&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;value&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{stories.current.priority}&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;class&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;span1&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;f:valueChangeListener&lt;/span&gt; &lt;span style="color: #000066;"&gt;binding&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{storyPriorityChanged}&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;f:ajax&lt;/span&gt; &lt;span style="color: #000066;"&gt;execute&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;@form&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;render&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;pr&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;listener&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{storyCommandListener.save(stories.current)}&amp;quot;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;/h:inputText&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
   ...	
&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;/ui:repeat&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3&gt;But we still don&amp;#8217;t have access to &amp;#8216;s&amp;#8217; in our ValueChangeListener, so what?&lt;/h3&gt;
&lt;p&gt;This is where we need to pull out a few tricks from our CDI and Java Patterns playbook, so the first thing we need to do is re-think our strategy.&lt;/p&gt;
&lt;p&gt;We know that the ValueChangeListener will be executed before our AJAX listener, so we need a way of performing our action without the &lt;code&gt;Story&lt;/code&gt; &amp;#8216;s&amp;#8217;. Wait, how are we going to do that? The answer is our good friend the Command pattern.&lt;/p&gt;
&lt;p&gt;The &lt;a href="http://en.wikipedia.org/wiki/Command_pattern" target="_blank"&gt;command pattern&lt;/a&gt; &amp;#8220;is a design pattern in which an object is used to represent and encapsulate all the information needed to call a method at a later time. This information includes the method name, the object that owns the method and values for the method parameters.&amp;#8221;&lt;/p&gt;
&lt;p&gt;We will combine the command pattern with CDI Events in order to pass this event to a listener which will later invoke all queued commands when we trigger it with our AJAX listener method.&lt;/p&gt;
&lt;p&gt;Our updated ValueChangeListener looks like this. Notice how we are not actually performing the operation yet, we are simply storing all information that we will need to perform this operation at a later time, when we do have access to our &lt;code&gt;Story&lt;/code&gt; &amp;#8216;s&amp;#8217;. Once we have prepared the &lt;code&gt;StoryCommand&lt;/code&gt; instance, we will fire it as a CDI event, using the the built in injected &lt;code&gt;Event&lt;StoryCommand&gt; changeEvent&lt;/code&gt; mechanism.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java" style="font-family:monospace;"&gt;@RequestScoped
@Named&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #0000ff;"&gt;&amp;quot;storyPriorityChanged&amp;quot;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; StoryPriorityChanged &lt;span style="color: #000000; font-weight: bold;"&gt;implements&lt;/span&gt; ValueChangeListener
&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   @Inject
   &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; Event&lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt;StoryCommand&lt;span style="color: #339933;"&gt;&amp;gt;&lt;/span&gt; changeEvent&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
   @Override
   &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; processValueChange&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; ValueChangeEvent event&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;throws&lt;/span&gt; AbortProcessingException
   &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      StoryCommand command &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; StoryCommand&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
&amp;nbsp;
         &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; &lt;span style="color: #003399;"&gt;Integer&lt;/span&gt; oldVal &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #003399;"&gt;Integer&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; event.&lt;span style="color: #006633;"&gt;getOldValue&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
         &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; &lt;span style="color: #003399;"&gt;Integer&lt;/span&gt; newVal &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #003399;"&gt;Integer&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; event.&lt;span style="color: #006633;"&gt;getNewValue&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
         @Override
         &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; perform&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;Story story&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
         &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
            &lt;span style="color: #000000; font-weight: bold;"&gt;if&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;...&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
               &lt;span style="color: #666666; font-style: italic;"&gt;// perform some action with the values from our event&lt;/span&gt;
            &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
         &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
      &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
      changeEvent.&lt;span style="color: #006633;"&gt;fire&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;command&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The events fired by our ValueChanceListener are captured by a method which &lt;code&gt;@Observes StoryCommand command&lt;/code&gt; events, and stores them in a list until we are ready to use them.&lt;/p&gt;
&lt;p&gt;The same class which observes these events is going to perform all queued commands when triggered by our AJAX listener: &lt;code&gt;listener="#{storyCommandListener.save(stories.current)}"&lt;/code&gt;. Now that we have access to our &lt;code&gt;Story&lt;/code&gt; &amp;#8216;s&amp;#8217;, we can run each command passing in the &lt;code&gt;Story&lt;/code&gt; on which it will operate.&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java" style="font-family:monospace;"&gt;@Named
@Stateless
@RequestScoped
&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; StoryCommandListener
&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   @PersistenceContext
   &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; EntityManager ss&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
   &lt;span style="color: #000000; font-weight: bold;"&gt;private&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;final&lt;/span&gt; List&lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt;StoryCommand&lt;span style="color: #339933;"&gt;&amp;gt;&lt;/span&gt; commands &lt;span style="color: #339933;"&gt;=&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;new&lt;/span&gt; ArrayList&lt;span style="color: #339933;"&gt;&amp;lt;&lt;/span&gt;StoryCommand&lt;span style="color: #339933;"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&amp;nbsp;
   &lt;span style="color: #000000; font-weight: bold;"&gt;protected&lt;/span&gt; StoryCommandListener&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
   &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; capture&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;@Observes StoryCommand command&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      &lt;span style="color: #000000; font-weight: bold;"&gt;this&lt;/span&gt;.&lt;span style="color: #006633;"&gt;commands&lt;/span&gt;.&lt;span style="color: #006633;"&gt;add&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;command&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&amp;nbsp;
   @TransactionAttribute
   &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; save&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;Story s&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
      &lt;span style="color: #000000; font-weight: bold;"&gt;for&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;StoryCommand c &lt;span style="color: #339933;"&gt;:&lt;/span&gt; commands&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt; &lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
         c.&lt;span style="color: #006633;"&gt;perform&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;s&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
      &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
      em.&lt;span style="color: #006633;"&gt;save&lt;/span&gt;&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;s&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Just for Reference, this is what our &lt;code&gt;StoryCommand&lt;/code&gt; class looks like:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="java" style="font-family:monospace;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;abstract&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;class&lt;/span&gt; StoryCommand
&lt;span style="color: #009900;"&gt;&amp;#123;&lt;/span&gt;
   &lt;span style="color: #000000; font-weight: bold;"&gt;public&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;abstract&lt;/span&gt; &lt;span style="color: #000066; font-weight: bold;"&gt;void&lt;/span&gt; perform&lt;span style="color: #009900;"&gt;&amp;#40;&lt;/span&gt;Story story&lt;span style="color: #009900;"&gt;&amp;#41;&lt;/span&gt;&lt;span style="color: #339933;"&gt;;&lt;/span&gt;
&lt;span style="color: #009900;"&gt;&amp;#125;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3&gt;Problem solved&lt;/h3&gt;
&lt;p&gt;We now have access to our &lt;code&gt;Story&lt;/code&gt; object in the logic that needs to be executed, but why is this better than simply updating the database in our AJAX listener method itself? We could just do this, after all:&lt;/p&gt;

&lt;div class="wp_syntax"&gt;&lt;div class="code"&gt;&lt;pre class="xml" style="font-family:monospace;"&gt;&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;ui:repeat&lt;/span&gt; &lt;span style="color: #000066;"&gt;value&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{stories.list}&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;var&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;s&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
   ...
   &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;h:inputText&lt;/span&gt; &lt;span style="color: #000066;"&gt;id&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;priority&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;value&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{stories.current.priority}&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;class&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;span1&amp;quot;&lt;/span&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
      &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;f:ajax&lt;/span&gt; &lt;span style="color: #000066;"&gt;execute&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;@form&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;render&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;pr&amp;quot;&lt;/span&gt; &lt;span style="color: #000066;"&gt;listener&lt;/span&gt;=&lt;span style="color: #ff0000;"&gt;&amp;quot;#{storyCommandListener.save(stories.current)}&amp;quot;&lt;/span&gt; &lt;span style="color: #000000; font-weight: bold;"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
   &lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;/h:inputText&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
   ...
&lt;span style="color: #009900;"&gt;&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;lt;/ui:repeat&lt;span style="color: #000000; font-weight: bold;"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;My answer is, it depends on if you want to aggregate more than one change command before you save events to the database. You can also do things with CDI events that would clutter up your other code, like for instance, when you want to log change events into a notification feed as we are doing in &lt;a href='http://ocpsoft.com/socialpm/'&gt;SocialPM&lt;/a&gt;. &lt;/p&gt;
&lt;p&gt;It is easier, cleaner, and a more decoupled system to have a second &lt;code&gt;@Observes&lt;/code&gt; method that creates a status update when users perform operations, as opposed to integrating the notification service with every method call. In the end, it is a trade-off, but the real benefit is that this approach, using AJAX listeners is a quick, reliable way to build in complex AJAX functionality to your JSF2 website.&lt;/p&gt;
&lt;p&gt;Cheers! If you want to check out more of this type of code in action, grab the &lt;a href="https://github.com/ocpsoft/socialpm/" target="_blank"&gt;SocialPM Source Code&lt;/a&gt; on GitHub, and give us a shout. We&amp;#8217;d love to have some more hands in this project!
&lt;/pre&gt;</description>
      <pubDate>Sat, 28 Jan 2012 16:00:18 CST</pubDate>
      <guid isPermaLink="true">http://ocpsoft.com/?p=3140</guid>
      <dc:creator>Lincoln Baxter III</dc:creator>
    </item>
    <item>
      <title>Review: Gradle Class with Luke Daley</title>
      <link>http://springone2gx.com/blog/howard_lewis_ship/2012/01/review_gradle_class_with_luke_daley?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;Last week, Luke Daly arrived in Portland to teach a three day &lt;a href="http://gradle.org/"&gt;Gradle&lt;/a&gt; class; the folks at Gradleware were nice enough let me audit the class (so it only cost me a couple of thousand dollars of lost billing revenue to attend).  My goals for the class was to gain a deeper understanding of how Gradle works, so that I could write more efficient builds, diagnose problems, and write my own plugins. The class scored very high on all of those counts!&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;Much of the first day was spent on basics, including a very useful introduction to the Groovy programming language (which is the basis of the &lt;a href="http://gradle.org/docs/current/dsl/index.html"&gt;Gradle DSL&lt;/a&gt;). Even though I have used Groovy pretty extensively for testing purposes over the last couple of years, there were features I've glossed over in the past that turned out to be very useful.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;The class is taught largely bottom up: from the basics of declaring tasks, then actions on tasks, and gradually working up towards defining tasks inputs and outputs. Compiling Java came pretty late, which seems curious since that's the primary job of Gradle, but this makes sense from a bottom-up approach as &lt;a href="http://gradle.org/docs/current/dsl/org.gradle.api.Project.html#org.gradle.api.plugins.JavaPluginConvention:sourceSets(groovy.lang.Closure)"&gt;SourceSets&lt;/a&gt; can then be described correctly. &lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;The class alternates between lecture and discussion, and short focused labs. At the end of the third day, we worked on tuning up our own builds, passing the video projector cable around ... we had a good time making the Tapestry build more efficient and readable, as well as adding new features to it.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;I'm feeling very good about my Gradle skills after attending the course; I've already been able to make further improvements to the Tapestry build subsequently, and I have plans for more involving things going forward. &lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;The return on investment for this class is a bit tricky; Gradle simply does so much straight out of the box, and even without a strong understanding of its structure, you can &lt;em&gt;kind of&lt;/em&gt; get it to do what you want just by guesswork and Googling. If you've been using Gradle for a while, I give this a cautious recommendation: getting back the three days of invested time may take a while to pay off. On the other hand, if you are currently dependent on Ant or Maven ... &lt;a href="http://gradle.org/training"&gt;sign up for the next class&lt;/a&gt; and get yourself switched over, today!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-4121218058413204699?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/stulP-4bay8" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 28 Jan 2012 13:00:07 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-4121218058413204699</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Reply To: Cross-Platform Mobile Visual Development – a Tool Comparison</title>
      <link>http://springone2gx.com/blog/max_katz/2012/01/reply_to_cross_platform_mobile_visual_development__a_tool_comparison?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;My reply to this &lt;a href="http://setandbma.wordpress.com/2012/01/23/mobile-visual-tool-comparison/" target="_blank"&gt;Cross-Platform Mobile Visual Development – a Tool Comparison&lt;/a&gt;.  I tried posting this in the comments but that didn&amp;#8217;t work. &lt;a href="http://tiggzi.com" target="_blank"&gt;Tiggzi: the cloud-based mobile app builde&lt;/a&gt;r should definitely be there. &lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Home page: &lt;/strong&gt;&lt;a href="http://tiggzi.com" target="_blank"&gt;http://tiggzi.com&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;Genesis:&lt;/strong&gt; The cloud-based HTML5 and hybrid mobile app builder.&lt;br /&gt;
&lt;strong&gt;Version: &lt;/strong&gt;Cloud (and white label)&lt;br /&gt;
&lt;strong&gt;Licensing:&lt;/strong&gt; Free and premium &amp;#8212; &lt;a href="http://tiggzi.com/pricing" target="_blank"&gt;http://tiggzi.com/pricing&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;Download:&lt;/strong&gt; Nothing to download, cloud-based&lt;br /&gt;
&lt;strong&gt;Documentation:&lt;/strong&gt; &lt;a href="http://help.gotiggr.com/videos" target="_blank"&gt;http://help.gotiggr.com/videos&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;Sample application:&lt;/strong&gt; http://tiggzi.com/common/showcase/browse.seam&lt;br /&gt;
&lt;strong&gt;Wikipedia:&lt;/strong&gt; &lt;a href="http://en.wikipedia.org/wiki/Mobile_application_development" target="_blank"&gt;http://en.wikipedia.org/wiki/Mobile_application_development&lt;/a&gt;&lt;br /&gt;
&lt;strong&gt;Additional:&lt;/strong&gt; The app is built with jQuery Mobile/HTML5. Connected to any REST API, tested, and exported as mobile Web, Android or iOS. PhoneGap is used for access to native device features.&lt;br /&gt;
&lt;strong&gt;Article on how to use:&lt;/strong&gt; &lt;a href="http://help.tiggzi.com/getting-started" target="_blank"&gt;http://help.tiggzi.com/getting-started&lt;/a&gt;, &lt;a href="http://www.google.com/url?sa=t&amp;#038;rct=j&amp;#038;q=tiggr%20and%20phonegap&amp;#038;source=web&amp;#038;cd=1&amp;#038;ved=0CCkQFjAA&amp;#038;url=http%3A%2F%2Fphonegap.com%2F2011%2F12%2F15%2Fbuilding-mobile-apps-in-the-cloud-with-tiggr-and-phonegap%2F&amp;#038;ei=-DgfT4WcBIrC2wWe-LmODw&amp;#038;usg=AFQjCNFSN47AzLgdKWPIaFRYMM3dM9soJQ" target="_blank"&gt;Tiggzi and PhoneGap&lt;/a&gt;. &lt;/p&gt;</description>
      <pubDate>Sat, 28 Jan 2012 11:00:07 CST</pubDate>
      <guid isPermaLink="true">http://mkblog.exadel.com/?p=4209</guid>
      <dc:creator>Max Katz</dc:creator>
    </item>
    <item>
      <title>Tapestry 5.4: Focus on JavaScript</title>
      <link>http://springone2gx.com/blog/howard_lewis_ship/2012/01/tapestry_5_4_focus_on_javascript?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;div&gt;
  &lt;p&gt;
       Tapestry 5.3.1 is out in the wild ... and if Tapestry is to
       stay relevant, Tapestry 5.4 is going to need to be something
       quite (r)evolutionary.
  &lt;/p&gt;

&lt;blockquote&gt;
  There was some confusion on the Tapestry developer mailing list in
  advance of this blog post; I'd alluded that it was coming, and some
  objected to such pronouncements coming out fully formed, without
  discussion. In reality, this is just a distillation of ideas, a
  starting point, and not a complete, finalized solution. If it's more
  detailed than some discussions of Tapestry's evolution in the past,
  that just means that the mailing list discussion and eventual
  implementation will be that much better informed.
&lt;/blockquote&gt;
  &lt;p&gt;
    In posts and other conversations, I've alluded to my vision for
    Tapestry 5.4. As always, the point of Tapestry is to allow
    developers to &lt;em&gt;code less, deliver more&lt;/em&gt;, and that has been
    the focus of Tapestry on the server side: everything drives that
    point: terseness of code and templates, live r2eloading, and
    excellent feedback are critical factors there. Much of what went
    into Tapestry 5.3 strengthened those points ... enhancements to
    Tapestry's meta-programming capabilities, improvements to the IoC
    container, and reducing Tapestry's memory footprint in a number of
    ways. I have one client reporting a 30% reduction in memory
    utilization, and another reporting a 30 - 40% improvement in
    execution speed.
  &lt;/p&gt;

  &lt;p&gt;
    Interestingly, I think that for Tapestry to truly stay relevant,
    it needs to shift much, much, more of the emphasis to the client
    side. For some time, Tapestry has been walking a fine line with
    regards to the critical question of &lt;em&gt;where does the application
    execute?&lt;/em&gt;  Pre-Ajax, that was an easy question: the
    application runs on the server, with at most minor JavaScript
    tricks and validations on the client.  As the use of Ajax has
    matured, and customer expectations for application behavior in the
    browser have expanded, it is no longer acceptable to say that
    Tapestry is page based, with limited Ajax
    enhancements. Increasingly, application flow and business logic
    need to execute in the browser, and the server-side's role is to
    orchestrate and facilitate the client-side application, as well as
    to act as a source and sink of data ultimately stored in a
    database.
  &lt;/p&gt;

  &lt;p&gt;
    As Tapestry's server-side has matured, the client side has not
    kept sufficient pace. Tapestry does include some excellent
    features, such as how it allows the server-side to drive
    client-side JavaScript in a modular and efficient way. However,
    that is increasingly insufficient ... and the tension caused by
    give-and-take between client-side and server-side logic has grown
    with each release.
  &lt;/p&gt;

  &lt;p&gt;
    Nowhere is this more evident than in how Tapestry addresses HTML
    forms. This has always been a tricky issue in Tapestry, because
    the dynamic rendering that can occur needs to be matched by
    dynamic form submission processing. In Tapestry, the approach is
    to serialize into the form instructions that will be used when the
    form is submitted (see the &lt;code&gt;store()&lt;/code&gt; method of the
    &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/FormSupport.html"&gt;FormSupport&lt;/a&gt;
    API). These instructions are used during the processing of the
    form submission request to re-configure the necessary components,
    and direct them to read their query parameters, perform
    validations, and push updated values back into server-side objects
    properties. If you've ever wondered what
    the &lt;code&gt;t:formdata&lt;/code&gt; hidden input field inside every
    Tapestry forms is about ... well, now you know: it's a serialized
    stream of Java objects, GZipped and MIME encoded.

  &lt;/p&gt;
  &lt;p&gt;
    However, relative to many other things in Tapestry, this is a bit
    clumsy and limited. You start to notice this when you see the
    tepid response to questions on the mailing list such as "&lt;em&gt;how
    to do cross-field validation?&lt;/em&gt;" Doing more complicated things,
    such as highly dynamic form layouts, or forms with even marginal
    relationships between fields, can be problematic (though still
    generally possible) ... but it requires a bit too much internal
    knowledge of Tapestry, and the in-browser results feel a bit
    kludgy, a bit clumsy. Tapestry starts to feel like it is getting
    in the way, and that's never acceptible.
  &lt;/p&gt;
  &lt;p&gt;
    Simply put, Tapestry's abstractions on forms and fields is
    both &lt;a href="http://en.wikipedia.org/wiki/Leaky_abstraction"&gt;leaky&lt;/a&gt;
    and insufficient. Tapestry is trying to do too much, and simply
    can't keep up with modern, reasonable demands in terms of
    responsiveness and useability inside the client. We've become used
    to pages rebuilding and reformatting themselves even while we're
    typing.  For Tapestry to understand how to process the form
    submission, it needs a model of what the form looks like on the
    client-side, and it simply doesn't have it. There isn't an
    effective way to do so without significantly restricting what is
    possible on the client side, or requiring much more data to be
    passed in requests, or stored server-side in the session.
  &lt;/p&gt;
  &lt;p&gt;
    The primary issue here is that overall form submission cycle,
    especially combined with Tapestry's need to serialize commands
    into the form (as the hidden &lt;code&gt;t:formdata&lt;/code&gt; field). Once
    you add Ajax to this mix, where new fields and rules are created
    dynamically (on the server side) and installed into the
    client-side DOM ... well, it gets harder and harder to manage.
    Add in a few more complications (such as a mix of transient and
    persistent Hibernate entities, or dynamic creation of sub-entities
    and relationships) into a form, it can be a brain burner getting
    Tapestry to do the right thing when the form is submitted: you
    need to understand exactly how Tapestry processes
    that &lt;code&gt;t:formdata&lt;/code&gt; information, and how to add your own
    callbacks into the callback stream to accomplish just exactly the
    right thing at just exactly the right time. Again, this is not the
    Tapestry way, where things are expected to &lt;em&gt;just work&lt;/em&gt;.
  &lt;/p&gt;
  &lt;p&gt;
    Further, there is some doubt about even the desirability of the
    overall model. In many cases, it makes sense to batch together a
    series of changes to individual properties ... but in many more,
    it is just as desirable for individual changes to filter back to
    the server (and the database) as the user
    navigates. Form-submit-and-re-render is
    a &lt;a href="http://en.wikipedia.org/wiki/IBM_3270"&gt;green screen&lt;/a&gt;
    style of user interaction. Direct interaction is the expectation
    now, and that's something Tapestry should embrace.
  &lt;/p&gt;
  &lt;p&gt;
    What's the solution, then? Well, it's still very much a moving
    target. The goal is to make creating client-side JavaScript
    libraries easier, to make it easier to integrate with libraries such
    as &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt; (and its vast library
    of extensions), make things simpler and more efficient on the
    client side, and not sacrifice the features that make Tapestry fun
    and productive in the first place.&lt;/p&gt;

  &lt;h3&gt;Overall Vision&lt;/h3&gt;

  &lt;p&gt;The overall vision breaks down into a number of steps:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Reduce or remove outside dependencies&lt;/li&gt;
    &lt;li&gt;Modularize JavaScript&lt;/li&gt;
    &lt;li&gt;Change page initializations to use modules&lt;/li&gt;
    &lt;li&gt;Embrace client-side controller logic&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;
    Of course, all of these steps depend on the others, so there isn't
    a good order to discuss them.
  &lt;/p&gt;

  &lt;h3&gt;Reducing and removing outside dependencies&lt;/h3&gt;

  &lt;p&gt;
    Tapestry's client-side strength has always been lots of "out of
    the box" functionality: client-side validation, Zones and other
    Ajax-oriented behaviors, and a well-integrated system for
    performing page-level initializations.
  &lt;/p&gt;
  &lt;p&gt;
    However, this strength is also a weakness, since that out of the
    box behavior is too tightly tied to the &lt;a href="http://prototypejs.org/"&gt;Prototype&lt;/a&gt; and
    &lt;a href="http://script.aculo.us/"&gt;Scriptaculous&lt;/a&gt; libraries ... reasonable choices in 2006, but
    out-of-step with the industry today. Not just in terms of the
    momentum behind jQuery, but also in terms of very different
    approaches, such
    as &lt;a href="http://www.sencha.com/"&gt;Sencha/ExtJS&lt;/a&gt; and
    others.&lt;/p&gt;

  &lt;p&gt;
    It was a conscious decision in 2006 to not attempt to create an
    abstraction layer before I understood all the abstractions. I've
    had the intermediate time to embrace those abstractions. Now the
    big problem is momentum and backwards compatibility.&lt;/p&gt;

  &lt;p&gt;
    Be removing unnecessary behaviors, such as animations, we can
    reduce Tapestry's client-side needs. Tapestry needs to be able
    to &lt;strong&gt;attach event handlers&lt;/strong&gt; to elements. It needs to
    be able to easily &lt;strong&gt;locate elements&lt;/strong&gt; via unique ids,
    or via &lt;strong&gt;CSS selectors&lt;/strong&gt;. It needs to be able
    to &lt;strong&gt;run Ajax requests&lt;/strong&gt; and handle the responses,
    including &lt;strong&gt;dynamic updates to elements&lt;/strong&gt;.&lt;/p&gt;
  &lt;p&gt;

    &lt;p&gt;All of these things are reasonable to abstract, and by making
    it even easier to execute JavaScript as part of a page render or
    page update
    (&lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/ajax/AjaxResponseRenderer.html"&gt;something
    already present in Tapestry 5.3&lt;/a&gt;), currently built-in features
    (such as animations) can be delegated to the application, which is
    likely a better choice in any case.&lt;/p&gt;

  &lt;h3&gt;Modularizing JavaScript&lt;/h3&gt;

  &lt;p&gt;
    Tapestry has always been careful about avoiding client-side
    namespace polution.  Through release 5.2, most of Tapestry's
    JavaScript was encapulated in the &lt;code&gt;Tapestry&lt;/code&gt; object. In
    Tapestry 5.3, a second object, &lt;code&gt;T5&lt;/code&gt; was introduced with
    the intention that it gradually replace the
    original &lt;code&gt;Tapestry&lt;/code&gt; object (but this post represents a
    change in direction).&lt;/p&gt;
  &lt;p&gt;
    However, that's not enough. Too often, users have created in-line
    JavaScript, or JavaScript libraries that defined "bare" variables
    and functions (that are ultimately added to the
    browser's &lt;code&gt;window&lt;/code&gt; object). This causes problems,
    including collisions between components (that provide competing
    definitions of objects and functions), or behavior that varies
    depending on whether the JavaScript was added to the page as part
    of a full-page render, or via an Ajax partial page render.&lt;/p&gt;
  &lt;p&gt;
    The right approach is to encourage and embrace some form of
    &lt;a href="http://yuiblog.com/blog/2007/06/12/module-pattern/"&gt;JavaScript
      module architecture&lt;/a&gt;, where there are no explicit global
    variables or functions, and that all JavaScript is evaluated
    inside a function, allowing for private variables and
    functions.&lt;/p&gt;
  &lt;p&gt;
    Currently, I'm thinking in terms of &lt;a href="http://requirejs.org/"&gt;RequireJS&lt;/a&gt; as
    the way to organize the JavaScript. Tapestry would faciliate
    organizing its own code into modules, as well as
    application-specific (or even page-specific) JavaScript
    modules. This would mean that de-referencing the &lt;code&gt;T5&lt;/code&gt;
    object would no longer occur (outside of some kind of temporary
    compatibility mode).&lt;/p&gt;
  &lt;p&gt;
    For example, clicking a button inside some container element
    might, under 5.3, publish an event using Tapestry's client-side
    publish/subscribe system. In the following example, the click
    events bubble up from the buttons (with the &lt;code&gt;button&lt;/code&gt;
    CSS class name) to a container element, and are then published
    under the topic name &lt;code&gt;button-clicked&lt;/code&gt;.
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1603920.js?file=53pubsubexample.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Consider this an abbreviated example, as it doesn't explain where
    the &lt;code&gt;element&lt;/code&gt; variable is defined or initialized; the
    important part is the interaction with Tapestry's client-side
    library: the reference to the &lt;code&gt;T5.pubsub.publish&lt;/code&gt; function.
  &lt;/p&gt;
  &lt;p&gt;
    Under 5.4, using the RequireJS &lt;code&gt;require&lt;/code&gt; function, this
    might be coded instead as:
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1603930.js?file=54pubsubexample.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Here, the &lt;code&gt;t5/pubsub&lt;/code&gt; module will be loaded by RequireJS and
    passed as a parameter into the function, which is automatically
    executed. So, this supports JavaScript modularization, and
    leverages RequireJS's ability to load modules on-the-fly, 
    as needed.
  &lt;/p&gt;
  &lt;p&gt;
    Notice the difference between the two examples; in the first
    example, coding as a module was &lt;em&gt;optional&lt;/em&gt; (but
    recommended), since the necessary &lt;code&gt;publish()&lt;/code&gt; function
    was accessible either way. In the 5.4 example, coding using
    JavaScript modules is virtually &lt;em&gt;required&lt;/em&gt;: the anonymous
    function passed to &lt;code&gt;require()&lt;/code&gt; is effectively a module,
    but its only through the use of &lt;code&gt;require()&lt;/code&gt; (or
    RequireJS's &lt;code&gt;define()&lt;/code&gt;) that the &lt;code&gt;publish()&lt;/code&gt;
    function can be accessed. &lt;/p&gt;
  &lt;p&gt;
    This is both the carrot and the stick; the carrot is how easy it
    is to declare dependencies and have them passed in to your
    function-as-a-module. The stick is that (eventually)
    the &lt;em&gt;only&lt;/em&gt; way to access those dependencies is by providing
    a module and declaring dependencies.
  &lt;/p&gt;
  &lt;h3&gt;Change page initializations to use modules&lt;/h3&gt;

  &lt;p&gt;
    Tapestry has a reasonably sophisticated system for allowing
    components to describe their JavaScript requirements as they
    render, in the form of
    the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/services/javascript/JavaScriptSupport.html"&gt;JavaScriptSupport&lt;/a&gt;
    environmental (an environmental is a kind of
    per-thread/per-request service object).  Methods on
    JavaScriptSupport allow a component to request that a JavaScript
    library be imported in the page (though this is most commonly
    accomplished using
    the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/annotations/Import.html"&gt;Import&lt;/a&gt;
    annotation), and to request the &lt;em&gt;initialization functions&lt;/em&gt;
    get executed.&lt;/p&gt;
  &lt;p&gt;
    Part of Tapestry's Ajax support is that in an Ajax request, the
    JavaScriptSupport methods can still be invoked, but a completely
    different implementation is responsible for integrating those
    requests into the overall reply (which in an Ajax request is a JSON object, rather
    than a simple stream of HTML).
  &lt;/p&gt;
  &lt;p&gt;
    Here's an example component from the TapX library:&lt;/p&gt;

&lt;script src="https://gist.github.com/1673763.js?file=Expando.java"&gt;&lt;/script&gt;

  &lt;p&gt;
    The @Import annotation directs that a stack (a set of related
    JavaScript libraries, defined elsewhere) be imported into the
    page; alternately, the component could import any number of
    specific JavaScript files, located either in the web application
    context folder, or on the classpath.&lt;/p&gt;
  &lt;p&gt;
    Inside the &lt;code&gt;afterRender()&lt;/code&gt; method, the code constructs
    a &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/json/JSONObject.html"&gt;JSONObject&lt;/a&gt;
    of data needed on the client side to perform the operation. The
    call to &lt;code&gt;addInitializerCall&lt;/code&gt; references a function by
    name: this function must be added to
    the &lt;code&gt;T5.Initializers&lt;/code&gt; namespace object.  Notice the
    naming: &lt;code&gt;tapxExpando&lt;/code&gt;: a prefix to identify the
    library, and to prevent collisions with any other application or
    library that also added its own functions to
    the &lt;code&gt;T5.initializers&lt;/code&gt; object.
  &lt;/p&gt;
  &lt;p&gt;
    The JavaScript library includes the function that will be invoked:
  &lt;/p&gt;
  &lt;script src="https://gist.github.com/1673810.js?file=tapx-core.js"&gt;&lt;/script&gt;
  &lt;p&gt;
    Under 5.4, this would largely be the same except:
  &lt;/p&gt;
  &lt;ul&gt;
    &lt;li&gt;There will be a specific Java package for each library (or the
      application) to store library modules.&lt;/li&gt;
    &lt;li&gt;The JavaScriptSupport environmental will have new methods to
      reference a function, inside a module, to invoke.&lt;/li&gt;
      &lt;li&gt;Stacks will consist not just of individual libraries, but
 also modules, following the naming and packaging
 convention.&lt;/li&gt;
  &lt;/ul&gt;

  &lt;h3&gt;Embrace client-side controller logic&lt;/h3&gt;

&lt;p&gt;
  The changes discussed so far only smooth out a few rough edges;
  they still position Tapestry code, running on the server, as driving
  the entire show. 
 &lt;/p&gt;

&lt;p&gt;
  As alluded to earlier; for any sophisticated user interface, the
  challenge is to coordinate the client-side user interface (in terms
  of form fields, DOM elements, and query parameters) with the
  server-side components; this is encoded into the
  hidden &lt;code&gt;t:formdata&lt;/code&gt; field. However, it is my opinion that
  for any dynamic form, Tapestry is or near the end of the road for
  this approach.&lt;/p&gt;
&lt;p&gt;Instead, it's time to embrace client-logic, written in JavaScript,
  in the browser. Specifically, break away from HTML forms, and
  embrace a more dynamic structure, one where "submitting" a form
  always works through an Ajax update ... and what is sent is not a
  simple set of query parameters and values, but a JSON representation
  of what was updated, changed, or created.
&lt;/p&gt;
&lt;p&gt;
  My specific vision is to
  integrate &lt;a href="http://documentcloud.github.com/backbone/"&gt;Backbone.js&lt;/a&gt;
  (or something quite similar), to move this logic solidly to the
  client side. This is a fundamental change: one where the client-side
  is free to change and reconfigure the UI in any way it likes, and is
  ultimately responsible for packaging up the completed data and
  sending it to the server.
&lt;/p&gt;
&lt;p&gt;
  When you are used to
  the &lt;a href="http://tapestry.apache.org/current/apidocs/org/apache/tapestry5/corelib/components/BeanEditForm.html"&gt;BeanEditForm&lt;/a&gt;
  component, this might feel like a step backwards, as you end up
  responsible for writing a bit more code (in JavaScript) to
  implement the user interface, input validations, and relationships
  between fields. However, as fun as BeanEditForm is, the declarative
  approach to validation on the client and the server has proven to be
  limited and limiting, especially in the face of cross-field
  relationships. We could attempt to extend the declarative nature,
  introducing rules or even scripting languages to establish the
  relationships ... or we could move in a situation that puts the
  developer back in the driver's seat.&lt;/p&gt;
&lt;p&gt;
  Further, there are some that will be concerned that this is a
  violation of
  the &lt;a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY
  pricipal&lt;/a&gt;; however I subscribe to different philosophy that
  client-side and server-side validation are fundamentally different
  in any case; this is discussed in an excellent
  &lt;a href="http://blog.ianbicking.org/2011/03/30/js-on-server-and-client-is-not-a-big-deal/"&gt;blog
  post by Ian Bickling&lt;/a&gt;.

&lt;p&gt;
  Certainly there will be components and services to assist with this
  process, in term of extracting data into JSON format, and converting
  JSON data into a set of updates to the server-side objects. There's
  also a number of security concerns that necessitate careful
  validation of what comes up from the client in the Ajax request.
  Further, there will be new bundled libraries to make it easier to
  build these dynamic user interfaces.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;
  In this vision of Tapestry's future, the server-side framework
  starts to shift from the focus of all behavior to
  the &lt;em&gt;facilitator&lt;/em&gt;: it paints the broad stokes on the server,
  but the key interactions end up working exclusively on the
  client. &lt;/p&gt;
&lt;p&gt;
  I'm sure this view will be controversial: after all, on the surface,
  what the community really wants is just "jQuery instead of
  Prototype". However, all of the factors described in the above
  sections are, I feel, critical to keeping Tapestry relevant by
  embracing the client-side in the way that the client-side
  demands.&lt;/p&gt;

&lt;p&gt;
  I think this change in focus is a big deal; I think it is also
  necessary for Tapestry to stay relevant in the medium to long
  term. I've heard from many individual developers (not necessarily
  Tapestry users) that what they really want is "just jQuery and a
  restful API"; I think Tapestry can be that restful API, but by
  leveraging many of Tapestry's other strengths, it can be a lot more.
  Building something right on the metal feels empowering ... until you
  hit all the infrastructure that Tapestry provides, including
  best-of-class exception reporting, on-the-fly JavaScript aggregation
  and minimization, and (of course) live class reloading during
  development.
java&lt;/p&gt;  
  &lt;p&gt;
    I'm eager to bring Tapestry to the forfront of web application
  development ... and to deliver it fast!  Monitor the Tapestry
  developer mailing list to see how this all plays out.&lt;/p&gt;
&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-7447306489952674714?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/mlpJ4i8ShSA" height="1" width="1"/&gt;</description>
      <pubDate>Sat, 28 Jan 2012 08:00:16 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-7447306489952674714</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>The apparent results of meeting room boredom [Flickr]</title>
      <link>http://springone2gx.com/blog/aaron_gustafson/2012/01/the_apparent_results_of_meeting_room_boredom_flickr_?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;&lt;a href="http://www.flickr.com/people/aarongustafson/"&gt;Aaron Gustafson&lt;/a&gt; posted a photo:&lt;/p&gt;
	
&lt;p&gt;&lt;a href="http://www.flickr.com/photos/aarongustafson/6771638329/" title="The apparent results of meeting room boredom"&gt;&lt;img src="http://farm8.staticflickr.com/7010/6771638329_c1a6abb6a3_m.jpg" width="240" height="240" alt="The apparent results of meeting room boredom" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://feeds.feedburner.com/~r/EasyReader/~4/Z82yBmu9YMg" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 27 Jan 2012 16:00:37 CST</pubDate>
      <guid isPermaLink="true">tag:flickr.com,2005:/photo/6771638329</guid>
      <dc:creator>Aaron Gustafson</dc:creator>
    </item>
    <item>
      <title>LinkedIn Etiquette</title>
      <link>http://springone2gx.com/blog/howard_lewis_ship/2012/01/linkedin_etiquette?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;I've used &lt;a href="http://linkedin.com"&gt;LinkedIn&lt;/a&gt; for many years now, long before I joined Facebook ... I liked the concept of never losing contact information with business contacts and technologist. It just seemed like a good idea (though I do sometimes wonder &lt;a href="http://www.youtube.com/watch?v=NcfXij6t4LA"&gt;if LinkedIn has any particular purpose&lt;/a&gt;).
&lt;p&gt;I tend to only connect with people I've met in person, or at least talked to on the phone.
&lt;p&gt;One thing that drives me crazy about LinkedIn is that you aren't forced to customize the message. As far as I'm concerned, the default message is like no message at all, and its a sign that you are just trolling for contacts. Just like you should always write a cover letter for a resume.
&lt;p&gt;So the first rule of LinkedIn is: &lt;strong&gt;always customize the message&lt;/strong&gt;. You chances of a connection go up significantly (at least with me) ... and with the default message, your chances drop down to near zero.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4110180-3214990755545065639?l=tapestryjava.blogspot.com' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/TapestryCentral/~4/7DjI04zp4n0" height="1" width="1"/&gt;</description>
      <pubDate>Fri, 27 Jan 2012 13:01:06 CST</pubDate>
      <guid isPermaLink="true">tag:blogger.com,1999:blog-4110180.post-3214990755545065639</guid>
      <dc:creator>Howard Lewis Ship</dc:creator>
    </item>
    <item>
      <title>Batch Update All Your Vendor Repositories</title>
      <link>http://springone2gx.com/blog/mike_girouard/2012/01/batch_update_all_your_vendor_repositories?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;I&amp;#8217;ve got just shy of 100 vendor repositories that I pull from for my side projects and client work. Updating them all has become quite a bother so I wrote this little guy to save me some time.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s certainly not perfect, and sometimes falls over, but this does the trick. This handles both Git and SVN repositories, but I&amp;#8217;m sure with a few extra lines you can make it work for whatever SCM you prefer to use.&lt;/p&gt;
&lt;p&gt;&lt;script src="https://gist.github.com/1674246.js"&gt; &lt;/script&gt;&lt;noscript&gt;&lt;a href="https://gist.github.com/1674246"&gt;https://gist.github.com/1674246&lt;/a&gt;&lt;/noscript&gt;&lt;/p&gt;
&lt;div style='clear:both'&gt;&lt;/div&gt;</description>
      <pubDate>Fri, 27 Jan 2012 11:01:20 CST</pubDate>
      <guid isPermaLink="true">http://www.lovemikeg.com/?p=413</guid>
      <dc:creator>Mike Girouard</dc:creator>
    </item>
    <item>
      <title>Tiggzi – The Cloud-based HTML5 and Hybrid Mobile App Builder, Now Free!</title>
      <link>http://springone2gx.com/blog/max_katz/2012/01/tiggzi__the_cloud_based_html5_and_hybrid_mobile_app_builder_now_free_?utm_source=blogitem&amp;utm_medium=rss&amp;utm_campaign=blogrss</link>
      <description>&lt;p&gt;&lt;img src="http://mkblog.exadel.com/wp-content/uploads/2012/01/screenshot_264.png" alt="" title="screenshot_264" width="113" height="47" class="alignnone size-full wp-image-4218" /&gt;&lt;/p&gt;
&lt;p&gt;Last week we have we have renamed our cloud-based mobile app builder to &lt;a href="http://tiggzi.com"&gt;Tiggzi&lt;/a&gt; (from Tiggr). &lt;a href="http://tiggzi.com" title="Tiggzi"&gt;Tiggzi&lt;/a&gt; is the most powerful and easy to use cloud-based mobile app builder. &lt;/p&gt;
&lt;h2&gt;Free Plan!&lt;/h2&gt;
&lt;p&gt;But, even more interesting news (for you) is that now we have a &lt;a href="http://tiggzi.com/pricing"&gt;Free plan&lt;/a&gt;. No credit card nothing, just sign up and start building your mobile app. &lt;/p&gt;
&lt;p&gt;&lt;img src="http://mkblog.exadel.com/wp-content/uploads/2012/01/screenshot_263-e1327620821552.png" alt="" title="screenshot_263" width="600" height="211" class="alignnone size-full wp-image-4216" /&gt;&lt;/p&gt;
&lt;p&gt;All the gotiggr.com links work and will continue working and we will be updating all the social media links. For now, use the links below to get help.&lt;/p&gt;
&lt;p&gt;&lt;a href="mailto:support@tiggzi.com"&gt;Email&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://tiggzi.com/forum" &gt;Forum&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://help.tiggzi.com" &gt;Docs and Getting Started&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://blog.tiggzi.com" &gt;Blog&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://twitter.com/gotiggr" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','http://twitter.com']);"&gt;Twitter&lt;/a&gt;&lt;br /&gt;
&lt;a href="http://facebook.com/gotiggr" onclick="javascript:_gaq.push(['_trackEvent','outbound-article','http://facebook.com']);"&gt;Facebook&lt;/a&gt;&lt;/p&gt;</description>
      <pubDate>Fri, 27 Jan 2012 08:03:03 CST</pubDate>
      <guid isPermaLink="true">http://mkblog.exadel.com/?p=4215</guid>
      <dc:creator>Max Katz</dc:creator>
    </item>
  </channel>
</rss>


