<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Paul Codding&#039;s Weblog &#187; Software</title>
	<atom:link href="http://www.paulcodding.com/blog/category/software/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.paulcodding.com/blog</link>
	<description>My miscellaneous ramblings and how-to&#039;s</description>
	<lastBuildDate>Sat, 17 Jul 2010 02:59:34 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Using Basecamp to keep track of SVN commits</title>
		<link>http://www.paulcodding.com/blog/2010/04/05/basecamp-managing-code/</link>
		<comments>http://www.paulcodding.com/blog/2010/04/05/basecamp-managing-code/#comments</comments>
		<pubDate>Tue, 06 Apr 2010 00:00:59 +0000</pubDate>
		<dc:creator>Paul Codding</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Basecamp]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Subversion]]></category>

		<guid isPermaLink="false">http://www.paulcodding.com/blog/?p=72</guid>
		<description><![CDATA[How can I ensure that I have merged all my changes into my branches?]]></description>
			<content:encoded><![CDATA[<p><strong>The Problem</strong></p>
<p><em>How can I ensure that I have merged all my changes into my branches?</em></p>
<p>I&#8217;ve been working on a project recently that includes a few developers, a lot of code, and multiple different code branches.  The code has quick release cycles, and the problem I run into more often than not is pushing releases out the door that are missing bug fixes that have been committed to trunk, but have inadvertently not made it into the release branch.  For me, this is made more difficult because of the speed of development, multiple developers and multiple different branches to merge the fixes into.  This is most likely a common problem, with a myriad of different process based solutions, but for me, it&#8217;s got to be quick, and it has to not impede my frantic work flow.</p>
<p>In general, solutions that work to help me have to be largely transparent and heavily automated.  That is why I came up with an idea to solve this problem of forgetting to merge in critical pieces of code that have been committed to trunk.  Here is an example layout of a source tree:</p>
<pre>trunk/
branches/product-version-1.0
branches/product-version-2.0
branches/product-version-3.0
branches/product-version-4.0
branches/product-version-5.0
branches/FeatureDevelopment</pre>
<p>
In this example situation we have a stable trunk, and a branch dedicated to each major version of the product as well as one branch used to perform feature development. The feature development branch,  in some cases, is not stable.  When either bug fixes, or features are ready to be committed they are done so in logical units that are well tested and documented with commit messages.  Then comes the task of merging all of those commits to all of the other branches that need the updated code.  How does one keep track of all of those commits by multiple developers working on the project, and ensure <strong>all</strong> of them make it in?</p>
<p><strong>The Solution</strong></p>
<p>In my case I use <a title="Basecamp" href="http://basecamphq.com/" target="_blank">Basecamp</a> heavily to manage Project To-Do&#8217;s, Documents, etc.  Because of this my solution makes use of Basecamp to create a <a href="http://developer.37signals.com/basecamp/to-do-list-items.shtml" target="_blank">To-Do</a> each time code is commited as a mechanism to remind me before I do a release to ensure <em>all</em> of the code has been merged.  Because I have limited time and energy to manually create To-Do&#8217;s each time I commit something, or tell all of my developers to do the same, this has to be automated.  Luckily Basecamp comes with a handy <a title="Basecamp API" href="http://developer.37signals.com/basecamp/" target="_blank">Basecamp API</a>.  Since I don&#8217;t feel like using curl to make all of my requests and handle responses myself I&#8217;ll make use of their <a href="http://developer.37signals.com/basecamp/basecamp.rb">Ruby wrapper</a> to do the XML preparation and HTTP response handling for me.</p>
<p>With this wrapper script I will be able to create my own script that will take the necessary information from the SVN commit message and create a To-Do.  The next question is how to make sure this script is called automatically when code is committed to SVN.  Enter the concept of the SVN post commit hook.  If you&#8217;ve ever created an SVN repository or inherited one you&#8217;ve probably seen the hooks directory.  To learn more about it take a look at the <em>Hook Scripts</em> section <a title="SVN Hooks" href="http://svnbook.red-bean.com/en/1.1/ch05s02.html" target="_blank">here</a>.  Basically every time a commit is made to the SVN repository, it will invoke a script.  In that script we will invoke our ruby script that will create the To-Do in Basecamp.</p>
<p>So, now we have our Basecamp API wrapper script, we know we&#8217;re going to add to SVN&#8217;s post commit hook script to call it, now we need to know how we&#8217;re going to get the information out of SVN as it relates to the commit message, and possibly who the committer was.  That is where we&#8217;ll use the <a title="svnlook documentation" href="http://svnbook.red-bean.com/en/1.1/ch09s03.html" target="_blank"><em>svnlook</em></a> utility.  Svnlook will give us a lot of information relating to a specific revision.  Here is an example of some of the information that can be gleaned from svnlook: author, changed, date, diff, dirs-changed, info, log.  That is just a subset of the options available to use with svnlook, but are the most pertinent in this case.</p>
<p>Now comes the actual script itself that will use svnlook and the Basecamp API to create the To-Do.  In my case, I want to only create a To-Do if I&#8217;m not merging code, and my continuous integration engine <a title="Apache Continuum" href="http://continuum.apache.org/" target="_blank">Continuum</a> is not building a release for me.  The code is pasted below.</p>
<p><strong>The Code</strong></p>
<pre>#!env ruby
#
#  add_commit_todo.rb
#  AddCommitTodo
#
#  Copyright 2010 Paul Codding
#  All rights reserved.
#
#  Released under the BSD license.

require File.dirname(__FILE__) + '/basecamp'
require 'time'

class AddCommitTodo
  PROJECT_NAME = "Your Project"
  TODO_LIST_NAME = "Your To-Do List that could be named 'Commits To Be Merged'"
  BASECAMP_URL = "yourcompany.basecamphq.com"
  BASECAMP_USER = "yourusername"
  BASECAMP_PASSWORD = "yourpassword"
  BASECAMP_USE_SSL = true
  SVNLOOK_PATH = "/usr/bin/svnlook"

  def initialize(repo_path, revision)
    if (repo_path &amp;&amp; revision)
      @repo_path = repo_path
      @revision = revision
      @session = Basecamp.establish_connection!(BASECAMP_URL, BASECAMP_USER, BASECAMP_PASSWORD, BASECAMP_USE_SSL)
    else
      usage()
      exit(1)
    end
  end

  def usage
    warn "Please specify the repo path and the revision... e.g. 'ruby add_commit_todo.rb /home/paul/svn/project 100'"
  end

  def add_todo
    # Determine the To-Do content using svnlook
    svn_log = `#{SVNLOOK_PATH} log #{@repo_path} --revision #{@revision}`
    svn_log.strip!
    puts "[D] SVN Log output for revision: #{@revision} - '#{svn_log}'"
    if svn_log.include?("erge") || svn_log.include?("maven")
      puts "[!] Not adding To-Do as this is a Merge operation"
    else
      # Find the correct project
      Basecamp::Project.find(:all).each { |project| project.name.eql?(PROJECT_NAME) ? @project = project : nil }
      Basecamp::TodoList.all(@project.id, false).each { |todo_list| todo_list.name.eql?(TODO_LIST_NAME) ? @todo_list = todo_list : nil }
      puts "[*] Adding merge To-Do to list: '#{@todo_list.name} (#{@todo_list.id})'"
      @todo_item = Basecamp::TodoItem.new(:todo_list_id =&gt; @todo_list.id)
      @todo_item.content = "[ r#{@revision} ] - #{svn_log}"
      @todo_item.responsible_party = "c#{@project.company.id}"
      @todo_item.notify = true
      puts "[*] Saving To-Do Item with content: '#{svn_log}'"
      @todo_item.save
    end
  end
end
act = AddCommitTodo.new(ARGV[0], ARGV[1])
act.add_todo</pre>
<p>The script can be downloaded <a href="http://www.paulcodding.com/add_commit_todo.rb">here</a>.</p>
<p><strong>Ways to Improve</strong></p>
<p>There are several things that could be added into this code, like the ability to automatically close out To-Do&#8217;s as the code is merged, or also create a Message in Basecamp to notify the team when bug fixes have been merged, etc.  There are also a number of other examples of Basecamp related post commit hooks <a href="http://lincolnloop.com/blog/2007/may/04/basecamp-svn-integration/" target="_blank">here</a> and <a href="http://webtypes.com/2006/03/31/subversion-post-commit-hook-using-basecamp-api" target="_blank">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulcodding.com/blog/2010/04/05/basecamp-managing-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ruby Connection Notifier</title>
		<link>http://www.paulcodding.com/blog/2008/09/27/ruby-connection-notifier/</link>
		<comments>http://www.paulcodding.com/blog/2008/09/27/ruby-connection-notifier/#comments</comments>
		<pubDate>Sun, 28 Sep 2008 02:15:42 +0000</pubDate>
		<dc:creator>Paul Codding</dc:creator>
				<category><![CDATA[Software]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Ruby]]></category>

		<guid isPermaLink="false">http://www.paulcodding.com/blog/?p=11</guid>
		<description><![CDATA[Lately I&#8217;ve been spending a lot of time at coffee shops in the morning, and because of that have spent a lot of time on wireless networks that are not exactly trustworthy. I always thought it would be nice to get a little notification on incoming established tcp/udp connections. Just to know. So I created [...]]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been spending a lot of time at coffee shops in the morning, and because of that have spent a lot of time on wireless networks that are not exactly trustworthy.  I always thought it would be nice to get a little notification on incoming established tcp/udp connections.  Just to know.  So I created this simple ruby script that uses Growl to notify you when an inbound connection is established.  Instead of using ruby/pcap to do the job, this script simply relies on the output of the Unix netstat command.  The code is below, it requires the Growl Ruby binding which is available <a href="http://growl.info/documentation/developer/ruby-support.php">here</a> and RubyCocoa which is available <a href="http://rubycocoa.sourceforge.net/HomePage">here</a>.</p>
<pre name="code" class="ruby">#!/usr/bin/ruby
#
#  connection_notifier.rb
#  ConnectionNotifier
#
#  Copyright 2009 Paul Codding
#  All rights reserved.
#
#  Released under the BSD license.
require 'rubygems'
require File.dirname(__FILE__) + '/Growl'

class Connection
  include Comparable
  attr_accessor :protocol, :local_ip, :remote_ip, :local_port, :remote_port, :id

  def initialize(connection_entry)
    pieces = connection_entry.split(" ")
    @protocol = pieces[0]
    @local_ip = pieces[3].split(".")[0..3].join(".")
    @remote_ip = pieces[4].split(".")[0..3].join(".")
    @local_port = pieces[3].split(".").last.to_i
    @remote_port = pieces[4].split(".").last.to_i
    @id = pieces[4].split(".").join()
  end

  def (other_connection)
    @id  other_connection.id
  end

  def to_s
    "#{@protocol} connection established from #{@remote_ip} to port #{@local_port}"
  end
end

class ConnectionNotifier
  GROWL_APP_NAME="Connection Notifier"

  def initialize
    @ports = Array.new(1024)
    @ports.fill { |port| port += 1}
    @connections = Array.new
    @growl = GrowlNotifier.new(GROWL_APP_NAME,['Ruby Connection Notifier'],nil,
              OSX::NSWorkspace.sharedWorkspace().iconForFileType_('rb'))
    @growl.register()

    # Pre-populate connections array so we're not automatically notified about
    # existing established connections
    check_for_new_connections(false)
    build_list_of_listening_ports()
  end

  # Poll for changes in netstat output
  def poll
    while true do
      sleep(2)
      check_for_new_connections(true)
    end
  end

  # Check for a new connection in the output of netstat
  def check_for_new_connections(notify)
    netstat_output = `netstat -na`
    for connection_entry in netstat_output do
      if connection_entry.include?("ESTABLISHED")
        connection = Connection.new(connection_entry)

        if connection.local_port != nil &amp;&amp; @ports.include?(connection.local_port.to_i) \
          &amp;&amp; !@connections.include?(connection)
          @connections &lt;&lt; connection
          if (notify)
            @growl.notify('Ruby Connection Notifier', 'Connection Established',
              connection.to_s)
          end
        end
      end
    end
  end

  def build_list_of_listening_ports
    netstat_output = `netstat -na`
    for connection_entry in netstat_output do
      if connection_entry.include?("LISTEN")
        connection = Connection.new(connection_entry)
        if !@ports.include?(connection.local_port)
          @ports &lt;&lt; connection.local_port
        end
      end
    end
  end
end

conn = ConnectionNotifier.new
conn.poll</pre>
<p>I&#8217;ve created a launch agent configuration for the script as well so it can start when you login.  The configuration and source code is located in the <a href="http://www.paulcodding.com/software/ConnectionNotifier.zip">ConnectionNotifier.zip</a> file.</p>
<p>To run the script, either execute the script directly, or place the <em>com.paulcodding.connection_notifier.agent.plist</em> file in your <em>~/Library/LaunchAgents</em> directory and log in again.  Just note that you need to update the path to the script within the agent file before it will work.  Once the script is running and you attempt a connection from an external machine, or the localhost you should see a growl notification like the image below.</p>
<div id="attachment_30" class="wp-caption alignnone" style="width: 327px"><a href="http://www.paulcodding.com/blog/wp-content/uploads/2008/09/connectionnotifer.png"><img class="size-full wp-image-30" src="http://www.paulcodding.com/blog/wp-content/uploads/2008/09/connectionnotifer.png" alt="Growl Notification" width="317" height="118" /></a><p class="wp-caption-text">Growl Notification</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.paulcodding.com/blog/2008/09/27/ruby-connection-notifier/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Using the OpenSessionInViewInterceptor for Spring + Hibernate3</title>
		<link>http://www.paulcodding.com/blog/2008/01/21/using-the-opensessioninviewinterceptor-for-spring-hibernate3/</link>
		<comments>http://www.paulcodding.com/blog/2008/01/21/using-the-opensessioninviewinterceptor-for-spring-hibernate3/#comments</comments>
		<pubDate>Mon, 21 Jan 2008 19:35:38 +0000</pubDate>
		<dc:creator>Paul Codding</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.paulcodding.com/blog/2008/01/21/using-the-opensessioninviewinterceptor-for-spring-hibernate3/</guid>
		<description><![CDATA[If you&#8217;re like me and have written Spring web applications using Hibernate for persistence, you&#8217;ve probably seen this error when using FetchType.LAZY in your @OneToMany annotation: &#8220;failed to lazily initialize a collection of role: your.Class.assocation no session or session was closed.&#8221; If you are using lazy loading rather than eager loading for obvious reasons, and [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re like me and have written Spring web applications using Hibernate for persistence, you&#8217;ve probably seen this error when using <code>FetchType.LAZY</code> in your <code>@OneToMany</code> annotation: &#8220;<em>failed to lazily initialize a collection of role: your.Class.assocation no session or session was closed</em>.&#8221;</p>
<p>If you are using lazy loading rather than eager loading for obvious reasons, and you&#8217;re trying to access associated objects in your view code, this error can be a bit difficult to resolve.  Luckily there is the <a href="http://static.springframework.org/spring/docs/2.5.1/api/org/springframework/orm/hibernate3/support/OpenSessionInViewInterceptor.html">OpenSessionInViewInterceptor</a>, or the <a href="http://static.springframework.org/spring/docs/2.5.1/api/org/springframework/orm/hibernate3/support/OpenSessionInViewFilter.html">OpenSessionInViewFilter</a>.  These solutions will keep the hibernate session open long enough for the view to render what is needed before it is closed, thus allowing you to access your lazy loaded associations without raising an exception.  The detail of what this functionality provides can be found on the Hibernate website <a href="http://www.hibernate.org/43.html">here</a>.</p>
<p>Now, how does one get this to work in their application?  Well, I&#8217;ve chosen to illustrate the basic steps necessary to implement the  OpenSessionInViewInterceptor.  You will need to modify 2 files.  These being your <code>applicationContext.xml</code>, and <code>YourApplication-servlet.xml</code> files.  We&#8217;ll start with the <code>applicationContext.xml</code> file.  You will need to place the following snippet after you&#8217;ve defined your <code>sessionFactory</code> bean.</p>
<pre name="code" class="xml">&lt;bean id="openSessionInViewInterceptor"
    class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor"&gt;
    &lt;property name="sessionFactory"&gt;
        &lt;ref local="sessionFactory"/&gt;
    &lt;/property&gt;
    &lt;property&gt; name="flushModeName"&gt;
        &lt;value&gt;FLUSH_AUTO&lt;/value&gt;
    &lt;/property&gt;
&lt;/bean&gt;</pre>
<p>What does the <code>FLUSH_AUTO</code> do?  Here is a quote from the javadoc for the interceptor:</p>
<blockquote><p>&#8220;This interceptor will by default not flush the Hibernate Session, with the flush mode being set to FlushMode.NEVER. It assumes that it will be used in combination with service layer transactions that handle the flushing: the active transaction manager will temporarily change the flush mode to FlushMode.AUTO during a read-write transaction, with the flush mode reset to FlushMode.NEVER at the end of each transaction.&#8221;</p></blockquote>
<p>We use the <code>FLUSH_AUTO</code> to automatically flush the session in this case because I am not using transactions.<br />
Now comes the edit to your <code>YourApplication-servlet.xml</code> file, or whatever file you&#8217;ve used to define your URL Mappings.  Add the following snippet to your URL mapping bean.</p>
<pre name="code" class="xml">&lt;property name="interceptors"&gt;
  &lt;list&gt;
    &lt;ref bean="openSessionInViewInterceptor" /&gt;
  &lt;/list&gt;
&lt;/property&gt;</pre>
<p>And that&#8217;s that, redeploy and you will no longer see that dreaded exception.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulcodding.com/blog/2008/01/21/using-the-opensessioninviewinterceptor-for-spring-hibernate3/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Spring, Hibernate, and Sitemesh</title>
		<link>http://www.paulcodding.com/blog/2008/01/11/spring-hibernate-and-sitemesh/</link>
		<comments>http://www.paulcodding.com/blog/2008/01/11/spring-hibernate-and-sitemesh/#comments</comments>
		<pubDate>Sat, 12 Jan 2008 04:48:37 +0000</pubDate>
		<dc:creator>Paul Codding</dc:creator>
				<category><![CDATA[Java]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Sitemesh]]></category>
		<category><![CDATA[Spring]]></category>

		<guid isPermaLink="false">http://www.paulcodding.com/blog/2008/01/11/spring-hibernate-and-sitemesh/</guid>
		<description><![CDATA[This week at work I&#8217;ve had the luxury of getting to sit down and write a sample application using a few of my favorite tools: Spring, and Hibernate-Annotations. New to this equation has been Sitemesh. I&#8217;ve been using Tiles for quite a while and have felt very comfortable with it, but at the same time [...]]]></description>
			<content:encoded><![CDATA[<p>This week at work I&#8217;ve had the luxury of getting to sit down and write a sample application using a few of my favorite tools: Spring, and Hibernate-Annotations.  New to this equation has been Sitemesh.  I&#8217;ve been using <a href="http://tiles.apache.org/">Tiles</a> for quite a while and have felt very comfortable with it, but at the same time a little annoyed with the amount of work and time it takes to use it.  As I sat down to pour out as many best practices as possible into this sample application I figured I should use the opportunity to take the time necessary to explore a new tool.  At first I had a hard time finding out just what it takes to use Sitemesh with Spring. I found some helpful hints here and there, but because this blog is meant to try to aggregate my searches into something useful for you (the reader), I will outline just what it takes to integrate Sitemesh into an application.</p>
<h4>Sitemesh Integration</h4>
<p>What do you have to do to integrate Sitemesh with your newly created Spring application?  Well, here is the list of prerequisites:</p>
<ul>
<li>Download Sitemesh from <a href="http://www.opensymphony.com/sitemesh/">OpenSymphony</a>.</li>
<li>Build the sitemesh-2.x.jar using ant.</li>
<li>Copy the sitemesh-2.x.jar to the <code>WEB-INF/lib</code> directory of your web application</li>
</ul>
<p>
Now we can move on to integrating Sitemesh into your web application.  To use sitemesh with your application only 1 file needs to be edited amazingly enough.  Open up your <code>web.xml</code> file and add this snippet:</p>
<pre>
&lt;!-- Sitemesh --&gt;
&lt;filter&gt;
	&lt;filter-name&gt;sitemesh&lt;/filter-name&gt;
	&lt;filter-class&gt;
		com.opensymphony.module.sitemesh.filter.PageFilter
	&lt;/filter-class&gt;
&lt;/filter&gt;

&lt;filter-mapping&gt;
	&lt;filter-name&gt;sitemesh&lt;/filter-name&gt;
	&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
</pre>
<p>So, now what?  The next step is to setup the directory structure and files necessary to make things work.  Refer to this <a href="http://www.opensymphony.com/sitemesh/decorators.html">page</a> on the OpenSymphony site detailing the creation of your first decorator, and creating the <code>WEB-INF/decorators.xml</code> file.  I&#8217;ve included a copy of my <code>main.jsp</code> file for reference:</p>
<pre>
&lt;%@ taglib uri="http://www.opensymphony.com/sitemesh/decorator"
	prefix="decorator"%&gt;
&lt;%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"&gt;
	&lt;head&gt;
		&lt;title&gt;&lt;spring:message code="application.title" /&gt;&lt;/title&gt;
		&lt;decorator:head /&gt;
		&lt;%@ include file="/WEB-INF/view/includes/style.jsp"%&gt;
		&lt;%@ include file="/WEB-INF/view/includes/js.jsp"%&gt;
	&lt;/head&gt;
	&lt;body&gt;
		&lt;div id="container"&gt;
			&lt;%@ include file="/WEB-INF/view/includes/header.jsp"%&gt;
			&lt;div id="internalWrapper"&gt;
				&lt;%@ include file="/WEB-INF/view/includes/links.jsp"%&gt;
				&lt;div id="content"&gt;
					&lt;decorator:body /&gt;
				&lt;/div&gt;
			&lt;/div&gt;
			&lt;%@ include file="/WEB-INF/view/includes/footer.jsp"%&gt;
		&lt;/div&gt;
	&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>So, how do you get your Controllers to spit out decorated pages?  Easy, just create a jsp that will be used as the content of the <code>&lt;decorator:body /&gt;</code> tag in the <code>main.jsp</code> file.  When you&#8217;re returning your <code>ModelAndView</code> just refer to that jsp like the example below:</p>
<pre>
public ModelAndView list(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
	List&lt;DomainObject&gt; userList = userService.findAll();
	request.setAttribute("userList", userList);
	return new ModelAndView("list.jsp", null);
}
</pre>
<p>Here is an example snippet of my url mapping for reference as to where the jsp is located:</p>
<pre>
&lt;prop key="/users/*.html"&gt;userController&lt;/prop&gt;
</pre>
<p>In this case my <code>list.jsp</code> is located in the <code>users</code> folder under my web root.</p>
<p>So, isn&#8217;t this easier than Tiles?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulcodding.com/blog/2008/01/11/spring-hibernate-and-sitemesh/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Project in the works</title>
		<link>http://www.paulcodding.com/blog/2007/08/19/project-in-the-works/</link>
		<comments>http://www.paulcodding.com/blog/2007/08/19/project-in-the-works/#comments</comments>
		<pubDate>Sun, 19 Aug 2007 14:35:40 +0000</pubDate>
		<dc:creator>Paul Codding</dc:creator>
				<category><![CDATA[OS X]]></category>
		<category><![CDATA[Software]]></category>

		<guid isPermaLink="false">http://www.paulcodding.com/blog/2007/08/19/project-in-the-works/</guid>
		<description><![CDATA[Well, I was able to spend some time this weekend to get my OpenBSD firewall back in action after a major HDD catastrophe. After getting my internal network back in order, I&#8217;ve decided to begin work on a few projects I&#8217;ve been thinking about. The first project involves the use of Growl, the notification system [...]]]></description>
			<content:encoded><![CDATA[<p>Well, I was able to spend some time this weekend to get my OpenBSD firewall back in action after a major HDD catastrophe.  After getting my internal network back in order, I&#8217;ve decided to begin work on a few projects I&#8217;ve been thinking about.</p>
<p>The first project involves the use of Growl, the notification system written for OS X, and snort.  Snort is a great little IDS that I&#8217;ve been working with for quite some time.  Ever since I checked out growl, I&#8217;ve been really excited to get something going that utilizes it.  Luckily the project with snort is perfect for it.  In short the project will use ruby to monitor the snort IDS alert logs for alerts and use Growl to send a notification to the user.  Growl does have ruby bindings&#8230;hence the choice of ruby.  I could use Objective-C, the only problem with that is that I don&#8217;t know the language <img src='http://www.paulcodding.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> .  So, ruby it is.  I will keep everyone posted on the progress/caveats.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.paulcodding.com/blog/2007/08/19/project-in-the-works/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
