<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-6841148002347889687</id><updated>2012-01-24T15:01:42.066-05:00</updated><category term='quick post'/><category term='knowing.net'/><category term='jetty-maven-plugin'/><category term='junit'/><category term='assertThat'/><category term='maven'/><category term='named parameters'/><category term='resolution'/><category term='syntax'/><category term='ASP.NET'/><category term='presentation'/><category term='Windows software'/><category term='inheritance'/><category term='realm'/><category term='loty'/><category term='getReturnType'/><category term='backlog'/><category term='spring'/><category term='software craftsmanship'/><category term='web service'/><category term='joe obrien'/><category term='Productivity Tools'/><category term='context switching'/><category term='eclipse'/><category term='getMethod'/><category term='DAO'/><category term='utility'/><category term='xml'/><category term='launchy'/><category term='MappingSqlQuery'/><category term='scala'/><category term='language learning'/><category term='java'/><category term='xsd'/><category term='After'/><category term='security'/><category term='Ohio'/><category term='hamcrest matchers'/><category term='jTrac'/><category term='pom'/><category term='role'/><category term='JdbcTemplate'/><category term='user'/><category term='re-cap'/><category term='desktop'/><category term='groovy'/><category term='mac'/><category term='AfterTransaction'/><category term='command-line'/><category term='ssl'/><category term='soapui'/><category term='testing'/><category term='BeforeTransaction'/><category term='.NET'/><category term='ruby'/><category term='AfterClass'/><category term='jdbc'/><category term='generic'/><category term='wsdl'/><category term='Columbus'/><category term='primer'/><category term='Before'/><category term='polyglot'/><category term='Matcher'/><category term='Transactional'/><category term='launchers'/><category term='response'/><category term='Parameterized'/><category term='apologetic'/><category term='analysis'/><category term='RowMapper'/><category term='dependency management'/><category term='jetty'/><category term='SqlUpdate'/><category term='productivity'/><category term='learning'/><category term='monodevelop'/><category term='ContextConfiguration'/><category term='VirtuaWin'/><category term='hibernate'/><category term='angst'/><category term='monotouch'/><category term='usergroup'/><category term='RunWith'/><category term='metaprogramming'/><category term='http status'/><category term='keytool-maven-plugin'/><category term='question'/><category term='web deployment descriptor'/><category term='hello_world'/><category term='properties'/><category term='monodroid'/><category term='ehcache'/><category term='Spring Note'/><category term='sql'/><category term='caching'/><category term='NamedParameterJdbcTemplate'/><category term='mono'/><category term='issue tracking'/><category term='BeforeClass'/><category term='beginner'/><category term='keystore'/><title type='text'>Active-Active Configuration</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-5350413039366975452</id><published>2012-01-24T15:00:00.001-05:00</published><updated>2012-01-24T15:01:42.071-05:00</updated><title type='text'>Making a Move Forward</title><content type='html'>Today I made some commitments to present some "lightning-talks" on .NET topics for my local .NET user group. I may be giving some discussions on C# basics, HTML5 topics, LESS(CSS), and JavaScript. Like many others who are working in the presentation/evangelism circuit, I feel that this will help force me into showing off some talents that I do have and learning some things that I currently don't know.&lt;br /&gt;
&lt;br /&gt;
Follow the Evansville .NET User Group &lt;a href="www.evansvillednug.com"&gt;homepage&lt;/a&gt; for more details.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-5350413039366975452?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/5350413039366975452/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=5350413039366975452' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5350413039366975452'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5350413039366975452'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2012/01/making-move-forward.html' title='Making a Move Forward'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-5204992701406269751</id><published>2011-10-28T11:41:00.000-04:00</published><updated>2011-10-28T11:58:46.060-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='generic'/><category scheme='http://www.blogger.com/atom/ns#' term='inheritance'/><category scheme='http://www.blogger.com/atom/ns#' term='getMethod'/><category scheme='http://www.blogger.com/atom/ns#' term='question'/><category scheme='http://www.blogger.com/atom/ns#' term='getReturnType'/><title type='text'>Java Problem: Generic Inheritance and Calling GetMethod().getReturnType()</title><content type='html'>&lt;p&gt;In my current project, I have classes which are modeled like the following. At some point, a method like &lt;code&gt;getReturnTypeForGetId()&lt;/code&gt; is called on classes &lt;code&gt;A&lt;/code&gt; and &lt;code&gt;B&lt;/code&gt;. Calling the method with &lt;code&gt;A&lt;/code&gt; returns &lt;code&gt;Integer&lt;/code&gt; as expected, but &lt;code&gt;B&lt;/code&gt; returns &lt;code&gt;Serializable&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;What am I missing here? Am I getting bitten by some heinous erasure thing, or am I just missing out on some sort of generic context-clobbering?&lt;/p&gt;

&lt;p&gt;&lt;b&gt;EDIT:&lt;/b&gt; Adding an over-ridden &lt;code&gt;getId()&lt;/code&gt; method to &lt;code&gt;B&lt;/code&gt; fixes the problem, but I would still like to understand what I am running into.&lt;/p&gt;

&lt;p&gt;I've also asked this question on &lt;a href="http://stackoverflow.com/questions/7931629/generic-inheritance-and-calling-getmethod-getreturntype"&gt;stackoverflow.&lt;/a&gt;&lt;/p&gt;

&lt;pre class="brush: java"&gt;
import java.io.Serializable;

public class WeirdTester {
    static interface Identifiable&amp;lt;T extends Serializable&gt; {
        T getId();
        void setId(final T id);
    }

    static abstract class BaseEntity&amp;lt;T extends Serializable&gt; implements Identifiable&amp;lt;T&gt; {
        private T id;
        public T getId() { return id; }
        public void setId(final T id) { this.id = id; }
    }

    static class A implements Identifiable&amp;lt;Integer&gt; {
        private Integer id;
        public Integer getId() { return id; }
        public void setId(final Integer id) { this.id = id; }
    }

    static class B extends BaseEntity&amp;lt;Integer&gt; {}

    @SuppressWarnings("unchecked")
    private static &amp;lt;T extends Serializable, Q extends Identifiable&amp;lt;T&gt;&gt; Class&amp;lt;T&gt; getReturnTypeForGetId(
            final Class&amp;lt;Q&gt; clazz) throws Exception {
        return (Class&amp;lt;T&gt;) clazz.getMethod("getId", (Class[])null).getReturnType();
    }

    public static void main(final String[] args) throws Exception {
        System.out.println(getReturnTypeForGetId(A.class));
        // CONSOLE: "class java.lang.Integer"
        System.out.println(getReturnTypeForGetId(B.class));
        // CONSOLE: "interface java.io.Serializable"
    }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-5204992701406269751?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/5204992701406269751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=5204992701406269751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5204992701406269751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5204992701406269751'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/10/java-problem-generic-inheritance-and.html' title='Java Problem: Generic Inheritance and Calling GetMethod().getReturnType()'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-6205311586134083199</id><published>2011-04-24T21:00:00.000-04:00</published><updated>2011-04-24T21:00:18.729-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monodevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='command-line'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Quick Hint: Command-line tools for MonoDevelop on Mac OS X</title><content type='html'>In doing some investigation for doing contract-first development for web services on .NET, I ran into the &lt;tt&gt;wsdl&lt;/tt&gt; command-line tool. Unfortunately, I was unable to find its equivalent in the MonoDevelop IDE. I finally did some digging around in the terminal and found the MonoDevelop command-line tools at: &lt;tt&gt;/Library/Frameworks/Mono.framework&lt;/tt&gt; or &lt;tt&gt;/Library/Frameworks/Mono.framework/Versions/current/bin&lt;/tt&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-6205311586134083199?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/6205311586134083199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=6205311586134083199' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6205311586134083199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6205311586134083199'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/04/quick-hint-command-line-tools-for.html' title='Quick Hint: Command-line tools for MonoDevelop on Mac OS X'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-6179361977243387154</id><published>2011-04-08T00:07:00.000-04:00</published><updated>2011-04-08T00:07:24.249-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monodevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='web service'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='beginner'/><title type='text'>Using MonoDevelop to Create an ASP.NET Web Service</title><content type='html'>&lt;p&gt;&lt;b&gt;NOTE&lt;/b&gt;: instructions below are for MonoDevelop 2.6 Beta 2 - built on 2011-04-06 03:37:58+0000&lt;/p&gt;

&lt;h2&gt;Getting Started&lt;/h2&gt;
&lt;p&gt;Create a new ASP.NET Web Application in MonoDevelop:
&lt;ol&gt;
&lt;li&gt;From the menu, select: &lt;i&gt;File &amp;rarr; New &amp;rarr; Solution&amp;hellip;&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Expand &lt;i&gt;C#&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Select &lt;i&gt;ASP.NET &amp;rarr; Web Application&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Enter a name for the ASP.NET project that will be created in the solution in &lt;i&gt;Name:&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Change the root location for the solution in &lt;i&gt;Location:&lt;/i&gt;, if desired.&lt;/li&gt;
&lt;li&gt;Change the name of the root solution in &lt;i&gt;Solution Name:&lt;/i&gt;, if desired.&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;

&lt;h2&gt;The Results &amp;ndash; I&lt;/h2&gt;
&lt;p&gt;What you have after executing the new ASP.NET Web Application project wizard is a solution containing one ASP.NET Web Application project. In the default project view in MonoDevelop, you'll find the following items:
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;Default.aspx&lt;/tt&gt; &amp;ndash; This is the default web form rendered and presented in the browser when &lt;tt&gt;http://&amp;lt;server&amp;gt;:&amp;lt;port&amp;gt;/&lt;/tt&gt; is accessed.
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;Default.aspx.cs&lt;/tt&gt; &amp;ndash; This C# file contains the developer-created common code and event handlers which can be used to affect the processing of the form.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;Default.aspx.designer.cs&lt;/tt&gt; &amp;ndash; This C# file contains the IDE-generated code for the page.&lt;/li&gt;
&lt;/ul&gt;
Both of the above files contain partial class definitions which are compiled together into a single code-behind class at runtime.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;Global.asax&lt;/tt&gt; &amp;ndash; This file contains the basic information which is available to the entire application.&lt;/li&gt;
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;Global.asax.cs&lt;/tt&gt; &amp;ndash; This C# file contains methods and event handlers for the entire application. These include event handlers for: application initialization, application termination, session handling, error handling, and request handling.&lt;/li&gt;
&lt;/ul&gt;
&lt;li&gt;&lt;tt&gt;web.config&lt;/tt&gt; &amp;ndash; This file contains the primary configuration for the application when deployed to a server. A secondary set of configuration options can be found in the server's &lt;tt&gt;Machine.config&lt;/tt&gt; file.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;If you go out to the location where you created the solution/project, you will also find a few other files:
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;/&amp;lt;solution name&amp;gt;/&amp;lt;solution name&amp;gt;.sln&lt;/tt&gt; &amp;ndash; This file contains configuration information for the entire "workspace" of projects.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;/&amp;lt;solution name&amp;gt;/&amp;lt;solution name&amp;gt;.userprefs&lt;/tt&gt; &amp;ndash; This file is generated by MonoDevelop and contains information specific to the user of the MonoDevelop application. The consensus is that this file should not be included in source-control.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;/&amp;lt;solution name&amp;gt;/&amp;lt;project name&amp;gt;/&amp;lt;project name&amp;gt;.csproj&lt;/tt&gt; &amp;ndash; This file contains configuration information for the particular project.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;/&amp;lt;solution name&amp;gt;/&amp;lt;project name&amp;gt;/&amp;lt;project name&amp;gt;.pidb&lt;/tt&gt; &amp;ndash; This binary file contains meta-data generated by MonoDevelop. The consensus is also that this file should not be included in source-control.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;

&lt;h2&gt;Setting Up the Web Service&lt;/h2&gt;
&lt;p&gt;Since I'm only really interested in exposing a web service using this project, I felt that I really don't need the &lt;tt&gt;Default.aspx.*&lt;/tt&gt; or &lt;tt&gt;Global.asax.*&lt;/tt&gt; files as they are currently not doing anything for the project. I deleted all five of the files.&lt;/p&gt;

&lt;p&gt;Create a new ASP.NET Web Service file in MonoDevelop:
&lt;ol&gt;
&lt;li&gt;In the Solution pad, right-click your project and select: &lt;i&gt;Add &amp;rarr; New File&amp;hellip;&lt;/i&gt;&lt;/li&gt;
&lt;li&gt;Select &lt;i&gt;ASP.NET &amp;rarr; Web Service&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;Enter a name for the file that will be created in the project in &lt;i&gt;Name:&lt;/i&gt;.&lt;/li&gt;
&lt;/ol&gt;&lt;/p&gt;

&lt;h2&gt;The Results &amp;ndash; II&lt;/h2&gt;
&lt;p&gt;After the ASP.NET web service wizard has completed, you'll find a new &lt;tt&gt;asmx&lt;/tt&gt; file in your project. This file will contain the basic &lt;tt&gt;WebService&lt;/tt&gt; directive, some using statements (&lt;tt&gt;System&lt;/tt&gt; and &lt;tt&gt;System.Web.Services&lt;/tt&gt;), a namespace, and a class definition.&lt;/p&gt;

&lt;h2&gt;Exposing a Method in the Web Service&lt;/h2&gt;
&lt;p&gt;Next, you'll want to create a method that you want to expose as a method on your web service. Add the &lt;tt&gt;WebMethod&lt;/tt&gt; attribute to it. Your &lt;tt&gt;asmx&lt;/tt&gt; file will now look something like this:&lt;/p&gt;
&lt;script type="syntaxhighlighter" class="brush: csharp"&gt;&lt;![CDATA[
&lt;%@ WebService Language="C#" Class="service.Service" %&gt;

using System;
using System.Web.Services;

namespace service {
    internal class Service {
        [WebMethod]
        public String doIt(String arg) {
            return "";
        }
    }
}
]]&gt;&lt;/script&gt;
&lt;p&gt;When you run this project, you can view a simple front-end for the service at &lt;tt&gt;http://localhost:8080/&amp;lt;web service file name&amp;gt;.asmx&lt;/tt&gt;. This web form is created at runtime by the ASP.NET container.&lt;/p&gt;

&lt;h2&gt;What? No code-behind?&lt;/h2&gt;
&lt;p&gt;While it is normally a good practice to separate a view from the code which contains its logic, as in an &lt;tt&gt;aspx&lt;/tt&gt; file, there is really no reason to do so in an &lt;tt&gt;asmx&lt;/tt&gt; file as there is no visual component which must be separated from the code.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-6179361977243387154?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/6179361977243387154/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=6179361977243387154' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6179361977243387154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6179361977243387154'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/04/using-monodevelop-to-create-aspnet-web.html' title='Using MonoDevelop to Create an ASP.NET Web Service'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-6134891192281626128</id><published>2011-04-07T10:58:00.000-04:00</published><updated>2011-04-07T10:58:37.759-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='monodevelop'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='monodroid'/><category scheme='http://www.blogger.com/atom/ns#' term='monotouch'/><category scheme='http://www.blogger.com/atom/ns#' term='mono'/><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><title type='text'>Getting Started with .NET on the Mac</title><content type='html'>&lt;p&gt; I'm setting out to learn .NET and get some experience creating a non-trivial project. Microsoft does provide Express &lt;i&gt;(free, Windows-only)&lt;/i&gt; editions of the Visual Studio application in a few flavors as well as basic version of IIS with ASP.NET and SQL Server. But, since my current personal development environment is a MacBook Pro (OSX 10.6.7), getting started with development on .NET can actually cost money &lt;i&gt;(mostly due to the Windows tax)&lt;/i&gt;. The primary development tool for .NET developers on non-Windows systems seems to be &lt;a href="http://www.mono-project.com"&gt;Mono&lt;/a&gt; with &lt;a href="http://www.monodevelop.com"&gt;MonoDevelop&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The latest stable release of Mono &lt;i&gt;(2.10.1)&lt;/i&gt; supports much of the functionality of the .NET 4.0 platform and some portions of Microsoft's extended .NET eco-system: &lt;i&gt;F#, IronRuby, IronPython, ASP.NET MVC(1, 2, and portions of 3)&lt;/i&gt;.&lt;/p&gt;

&lt;p&gt;The latest beta build of MonoDevelop &lt;i&gt;(2.6 beta 2)&lt;/i&gt; provides a lot of support for developing applications using C# and the rest of the CLR.&lt;/p&gt;

&lt;p&gt;I'll be using these in the coming months to do some experiments in the creation of a blogging engine in .NET. As part of proving that I can work in the .NET world. You can see the results of my experiments on my &lt;a href="https://github.com/wimplash/scratch-NET/tree/master/wbe"&gt;github&lt;/a&gt; page.&lt;/p&gt;

&lt;p&gt;Mono also provides two other interesting projects:
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://mono-android.net"&gt;Mono for Android&lt;/a&gt; -- run .NET applications on Android devices.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://monotouch.net"&gt;MonoTouch&lt;/a&gt; -- run .NET applications on iOS devices (iPhone, iTouch, iPad).&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-6134891192281626128?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/6134891192281626128/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=6134891192281626128' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6134891192281626128'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6134891192281626128'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/04/getting-started-with-net-on-mac.html' title='Getting Started with .NET on the Mac'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-4831520214002881495</id><published>2011-04-01T00:37:00.001-04:00</published><updated>2011-04-01T08:35:01.636-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='http status'/><category scheme='http://www.blogger.com/atom/ns#' term='response'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='soapui'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Testing Toolbelt: Testing non-xml attributes of responses in SoapUI</title><content type='html'>&lt;p&gt;I spend a large part of my time developing web services, so I spend a lot of my time testing web services. One of the major tools I have in my toolbelt for automating web service tests is &lt;a href="http://www.soapui.org"&gt;SoapUI&lt;/a&gt;. SoapUI does a lot of things, and even does a lot of things which I don't need, but it does the things I need very well. Today, I was trying to set up some testing for the security on my current project. As I was setting up the test request and pointing SoapUI at the appropriate endpoints with invalid http basic authorization credentials, I realized that there was no straight forward way to assert that the http response code was 401 (unauthorized) or 403 (forbidden). I did some digging, and found that you could create a Script Assertion (using Groovy) in the SOAP Test Step and use the pre-defined variable, &lt;tt&gt;messageExchange&lt;/tt&gt;, to examine contents and statistics for the test step.&lt;/p&gt;

&lt;h2&gt;Asserting that a SOAP request with no credentials was responded to with a 401&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
assert messageExchange.getResponseStatusCode() == 401
]]&gt;&lt;/script&gt;

&lt;h2&gt;Asserting that a SOAP request with invalid credentials was responded to with a 403&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
assert messageExchange.getResponseStatusCode() == 403
]]&gt;&lt;/script&gt;

&lt;p&gt;The Script Assertion also has access to two other pre-defined variables: &lt;tt&gt;context&lt;/tt&gt; and &lt;tt&gt;log&lt;/tt&gt;. &lt;tt&gt;context&lt;/tt&gt; contains methods which allow you to examine the request and response programmatically and &lt;tt&gt;log&lt;/tt&gt;, well I haven't had to use yet. These are posts for another day.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-4831520214002881495?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/4831520214002881495/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=4831520214002881495' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/4831520214002881495'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/4831520214002881495'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/04/testing-toolbelt-testing-non-xml.html' title='Testing Toolbelt: Testing non-xml attributes of responses in SoapUI'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-368721840261861165</id><published>2011-04-01T00:06:00.000-04:00</published><updated>2011-04-01T00:06:26.298-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jetty'/><category scheme='http://www.blogger.com/atom/ns#' term='jetty-maven-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='user'/><category scheme='http://www.blogger.com/atom/ns#' term='pom'/><category scheme='http://www.blogger.com/atom/ns#' term='ssl'/><category scheme='http://www.blogger.com/atom/ns#' term='web deployment descriptor'/><category scheme='http://www.blogger.com/atom/ns#' term='security'/><category scheme='http://www.blogger.com/atom/ns#' term='keytool-maven-plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='role'/><category scheme='http://www.blogger.com/atom/ns#' term='keystore'/><category scheme='http://www.blogger.com/atom/ns#' term='realm'/><title type='text'>Maven Note: Securing a temporary Jetty instance in the jetty-maven-plugin</title><content type='html'>&lt;p&gt;One of my tasks for the current iteration was to add security constraints to the J2EE web service that we are currently developing. This is the easy part. Simply define the appropriate &lt;tt&gt;security-constraint&lt;/tt&gt;, &lt;tt&gt;login-config&lt;/tt&gt;, and &lt;tt&gt;security-role&lt;/tt&gt; elements in the project's &lt;tt&gt;web.xml&lt;/tt&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;tt&gt;web.xml&lt;/tt&gt;&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;web-app xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_5.xsd"&gt;
  &lt;display-name&gt;...&lt;/display-name&gt;
  &lt;servlet&gt;...&lt;/servlet&gt;
  &lt;servlet-mapping&gt;...&lt;/servlet-mapping&gt;

  &lt;security-constraint&gt;
    &lt;display-name&gt;deny unauthorized users&lt;/display-name&gt;
    &lt;web-resource-collection&gt;
      &lt;web-resource-name&gt;global&lt;/web-resource-name&gt;
      &lt;url-pattern&gt;/&lt;/url-pattern&gt;
      &lt;url-pattern&gt;/*&lt;/url-pattern&gt;
    &lt;/web-resource-collection&gt;
    &lt;auth-constraint&gt;
      &lt;role-name&gt;AUTHORIZED_USER&lt;/role-name&gt;
    &lt;/auth-constraint&gt;
    &lt;user-data-constraint&gt;
      &lt;!-- All access to this area will be SSL protected --&gt;
      &lt;transport-guarantee&gt;CONFIDENTIAL&lt;/transport-guarantee&gt;
    &lt;/user-data-constraint&gt;
  &lt;/security-constraint&gt;

  &lt;login-config&gt;
    &lt;auth-method&gt;BASIC&lt;/auth-method&gt;
    &lt;realm-name&gt;APP&lt;/realm-name&gt;
  &lt;/login-config&gt;

  &lt;security-role&gt;
    &lt;description&gt;authorized user for application&lt;/description&gt;
    &lt;role-name&gt;AUTHORIZED_USER&lt;/role-name&gt;
  &lt;/security-role&gt;
&lt;/web-app&gt;
]]&gt;&lt;/script&gt;

&lt;p&gt;From the above, you can see that I defined an expected role, &lt;tt&gt;AUTHORIZED_USER&lt;/tt&gt;, an expected realm for http basic authentication, &lt;tt&gt;APP&lt;/tt&gt;, and a set of resources, &lt;tt&gt;/&lt;/tt&gt; and &lt;tt&gt;/*&lt;/tt&gt;, which can only be accessed through SSL by a user who is a member of the &lt;tt&gt;AUTHORIZED_USER&lt;/tt&gt; role. This is the easy part and should work for most application servers which are worth their salt.&lt;/p&gt;

&lt;h1&gt;Enter &lt;tt&gt;jetty-maven-plugin&lt;/tt&gt;&lt;/h1&gt;
&lt;p&gt;This project is already using the jetty-maven-plugin to run a test instance of the application. I thought it would be a good idea to make sure that the security on the localhost instance for testing would work in the same manner as the WebSphere server to which the application is to be deployed. This would help me to ensure that I, as a lazy programmer, would not have to change the functional tests (SoapUI) between localhost and dev.&lt;/p&gt;

&lt;p&gt;By default, the jetty instance created by executing &lt;tt&gt;mvn jetty:run-war&lt;/tt&gt; does not include a user realm for defining users and groups, a login service for handling attempted logins, or even the capability for handling SSL connections. In order to bring these components into the localhost instance, I had to make some changes to the configuration of my project's &lt;tt&gt;jetty-maven-plugin&lt;/tt&gt;. First, the changes for enabling the user realm and login service.&lt;/p&gt;

&lt;h2&gt;&lt;tt&gt;pom.xml&lt;/tt&gt; (version 1)&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
  ...
  &lt;build&gt;
    &lt;plugins&gt;
      ...
      &lt;plugin&gt;
        &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
        &lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;7.3.0.v20110203&lt;/version&gt;
        &lt;configuration&gt;
          ...
          &lt;userRealms&gt;
            &lt;userRealm implementation="org.mortbay.jetty.security.HashUserRealm"&gt;
              &lt;name&gt;APP&lt;/name&gt;
              &lt;config&gt;${project.build.directory}/test-classes/jetty-users.properties&lt;/config&gt;
            &lt;/userRealm&gt;
          &lt;/userRealms&gt;
          &lt;loginServices&gt;
            &lt;loginService implementation="org.eclipse.jetty.security.HashLoginService"&gt;
              &lt;name&gt;APP&lt;/name&gt;
              &lt;config&gt;${project.build.directory}/test-classes/jetty-users.properties&lt;/config&gt;
            &lt;/loginService&gt;
          &lt;/loginServices&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      ...
    &lt;/plugins&gt;
    ...
  &lt;/build&gt;
  ...
&lt;/project&gt;
]]&gt;&lt;/script&gt;

&lt;h2&gt;&lt;tt&gt;/src/test/resources/jetty-users.properties&lt;/tt&gt;&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: text"&gt;&lt;![CDATA[
test_user=test_user,AUTHORIZED_USER
]]&gt;&lt;/script&gt;

&lt;h1&gt;Using the &lt;tt&gt;keytool-maven-plugin&lt;/tt&gt; for generating a certificate for SSL&lt;/h1&gt;
&lt;p&gt;In order to enable server authentication, the Jetty instance needs to have access to a server certificate to be sent out in the SSL handshake. I did some investigation and found that there was a plugin, &lt;tt&gt;keytool-maven-plugin&lt;/tt&gt;, which would allow you to automate self-signed certificate generation in the maven execution. I modified the project's pom as follows:&lt;/&gt;

&lt;h2&gt;&lt;tt&gt;pom.xml&lt;/tt&gt; (version 2)&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
  ...
  &lt;build&gt;
    &lt;plugins&gt;
      ...
      &lt;plugin&gt;
        &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;keytool-maven-plugin&lt;/artifactId&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;phase&gt;generate-resources&lt;/phase&gt;
            &lt;id&gt;clean&lt;/id&gt;
            &lt;goals&gt;
              &lt;goal&gt;clean&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
          &lt;execution&gt;
            &lt;phase&gt;generate-resources&lt;/phase&gt;
            &lt;id&gt;genkey&lt;/id&gt;
            &lt;goals&gt;
              &lt;goal&gt;genkey&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
        &lt;configuration&gt;
          &lt;keystore&gt;${project.build.directory}/jetty-ssl.keystore&lt;/keystore&gt;
          &lt;dname&gt;cn=active-active.blogspot.com&lt;/dname&gt;
          &lt;keypass&gt;jetty6&lt;/keypass&gt;
          &lt;storepass&gt;jetty6&lt;/storepass&gt;
          &lt;alias&gt;jetty6&lt;/alias&gt;
          &lt;keyalg&gt;RSA&lt;/keyalg&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      ...
    &lt;/plugins&gt;
    ...
  &lt;/build&gt;
  ...
&lt;/project&gt;
]]&gt;&lt;/script&gt;

&lt;h1&gt;Adding SSL support to Jetty&lt;/h1&gt;
&lt;p&gt;Now, we have a way for the client to authenticate itself, a realm for assigning that client's roles, and a keystore. We just need to tell Jetty how to expose an SSL port to the world.&lt;/p&gt;

&lt;h2&gt;&lt;tt&gt;pom.xml&lt;/tt&gt; (version 3)&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;project xmlns="http://maven.apache.org/POM/4.0.0"
  ...
  &lt;build&gt;
    &lt;plugins&gt;
      ...
      &lt;plugin&gt;
        &lt;groupId&gt;org.mortbay.jetty&lt;/groupId&gt;
        &lt;artifactId&gt;jetty-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;7.3.0.v20110203&lt;/version&gt;
        &lt;configuration&gt;
          ...
          &lt;/userRealms&gt;
          &lt;connectors&gt;
            &lt;connector implementation="org.eclipse.jetty.server.nio.SelectChannelConnector"&gt;
              &lt;port&gt;8080&lt;/port&gt;
              &lt;maxIdleTime&gt;60000&lt;/maxIdleTime&gt;
            &lt;/connector&gt;
            &lt;connector implementation="org.eclipse.jetty.server.ssl.SslSocketConnector"&gt;
              &lt;port&gt;8443&lt;/port&gt;
              &lt;maxIdleTime&gt;60000&lt;/maxIdleTime&gt;
              &lt;keystore&gt;${project.build.directory}/jetty-ssl.keystore&lt;/keystore&gt;
              &lt;password&gt;jetty6&lt;/password&gt;
              &lt;keyPassword&gt;jetty6&lt;/keyPassword&gt;
            &lt;/connector&gt;
          &lt;/connectors&gt;
          &lt;loginServices&gt;
          ...
        &lt;/configuration&gt;
      &lt;/plugin&gt;
      ...
    &lt;/plugins&gt;
    ...
  &lt;/build&gt;
  ...
&lt;/project&gt;
]]&gt;&lt;/script&gt;

&lt;p&gt;A big thank-you to mrhaki and his article &lt;a href="http://mrhaki.blogspot.com/2009/05/configure-maven-jetty-plugin-for-ssl.html"&gt;Configure Maven Jetty Plugin for SSL Communication&lt;/a&gt; for the assist.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-368721840261861165?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/368721840261861165/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=368721840261861165' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/368721840261861165'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/368721840261861165'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/04/maven-note-securing-temporary-jetty.html' title='Maven Note: Securing a temporary Jetty instance in the jetty-maven-plugin'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-7392431532224835872</id><published>2011-01-23T22:51:00.001-05:00</published><updated>2011-11-25T14:42:22.422-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ContextConfiguration'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='AfterTransaction'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Transactional'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><category scheme='http://www.blogger.com/atom/ns#' term='BeforeTransaction'/><title type='text'>Testing Toolbelt: SpringJUnit4ClassRunner</title><content type='html'>&lt;p&gt;The &lt;tt&gt;org.springframework.test.context.junit4.SpringJUnit4ClassRunner&lt;/tt&gt; class is another implementation of the JUnit &lt;tt&gt;TestRunner&lt;/tt&gt; class which is used to enable various features of Spring for every run of the test class and every test within it. To use the features provided by the &lt;tt&gt;SpringJUnit4ClassRunner&lt;/tt&gt; class, you need to mark the class using the &lt;tt&gt;RunWith&lt;/tt&gt; annotation using &lt;tt&gt;SpringJUnit4ClassRunner&lt;/tt&gt; as its parameter.&lt;/p&gt;

&lt;p&gt;In addition to the custom test runner, you will want to mark the class with the &lt;tt&gt;ContextConfiguration&lt;/tt&gt; annotation. The &lt;tt&gt;ContextConfiguration&lt;/tt&gt; annotation is used to mark classes which will automatically read a Spring configuration file and use it to create an &lt;tt&gt;ApplicationContext&lt;/tt&gt;. By default, this file located at &lt;tt&gt;&amp;lt;package path&amp;gt;/&amp;lt;test class name&amp;gt;-context.xml&lt;/tt&gt;. Use the &lt;tt&gt;locations&lt;/tt&gt; argument to over-ride.&lt;/p&gt;

&lt;p&gt;The &lt;tt&gt;ApplicationContext&lt;/tt&gt; used by the Spring-integrated test will only be loaded once for the whole test class. This behavior can be over-ridden by annotating a test method with the &lt;tt&gt;DirtiesContext&lt;/tt&gt; annotation, which causes the &lt;tt&gt;ApplicationContext&lt;/tt&gt; to be reloaded after the test method completes.&lt;/p&gt;

&lt;h2&gt;Test Property Injection&lt;/h2&gt;

&lt;p&gt;Fresh versions of the properties for the test, including the class under test, can be automatically injected for every test, either by name or type.  A test class property marked with the &lt;tt&gt;Autowired&lt;/tt&gt; annotation will be automatically set by &lt;b&gt;type&lt;/b&gt; from the test's &lt;tt&gt;ApplicationContext&lt;/tt&gt;. However, if there are multiple instances of the property's type, it could be better to set the property by name. The &lt;tt&gt;Resource&lt;/tt&gt; is used to mark test class properties which should be set by &lt;b&gt;name&lt;/b&gt; from the test's &lt;tt&gt;ApplicationContext&lt;/tt&gt;.&lt;/p&gt;

&lt;h2&gt;Transaction Management&lt;/h2&gt;

&lt;p&gt;With the declaration of a &lt;tt&gt;TransactionManager&lt;/tt&gt; bean, and the use of the &lt;tt&gt;Transactional&lt;/tt&gt; annotation, transaction boundaries are declarative and are automatically managed. Simply fire up the test and forget about whether or not your integration test changed the state of the database you're using to test.&lt;/p&gt;

&lt;p&gt;The &lt;tt&gt;Transactional&lt;/tt&gt; annotation is used within transactional Spring tests to mark test classes and methods which should have a transactional nature applied to them. When used to annotate a test class, a transaction context will be created before each test method is executed. After each test method, the transaction will be rolled-back. This will add the overhead of creating and managing a transaction for every test method in that class, so it is usually better to annotate the test methods with &lt;tt&gt;@Transactional&lt;/tt&gt; instead. This will cause a similar effect to annotating the class, but only annotated test methods will be transactional.
Usage of this annotation requires a &lt;tt&gt;TransactionManager&lt;/tt&gt; named &lt;tt&gt;transactionManager&lt;/tt&gt; to be defined in the test's &lt;tt&gt;ApplicationContext&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Similar in purpose to the &lt;tt&gt;Before&lt;/tt&gt; and &lt;tt&gt;After&lt;/tt&gt; annotations provided by JUnit, methods decorated with either the &lt;tt&gt;BeforeTransaction&lt;/tt&gt; or &lt;tt&gt;AfterTransaction&lt;/tt&gt; annotation will be run before/after any test method which is affected by the &lt;tt&gt;Transactional&lt;/tt&gt; annotation (i.e. all methods in a class decorated with &lt;tt&gt;@Transactional&lt;/tt&gt;, or each annotated test method when marked individually. Methods annotated with the &lt;tt&gt;BeforeTransaction&lt;/tt&gt; or &lt;tt&gt;AfterTransaction&lt;/tt&gt; annotations must be public and return no value.&lt;/p&gt;

&lt;h2&gt;Integration Test Helper Classes&lt;/h2&gt;

&lt;p&gt;When using the &lt;tt&gt;SpringJUnit4ClassRunner&lt;/tt&gt;, you're given access to the &lt;tt&gt;ApplicationContext&lt;/tt&gt; instance and a simplified interface for interacting with your integration test database through &lt;tt&gt;JdbcTemplate&lt;/tt&gt;/&lt;tt&gt;SimpleJdbcTemplate&lt;/tt&gt;.&lt;/p&gt;

&lt;h2&gt;&lt;tt&gt;spring-testing-sample.java&lt;/tt&gt;&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: java"&gt;&lt;![CDATA[
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ITSpringExample {
  @Resource Object dependencyByName;
  @Autowired String dependencyByType;

  @BeforeTransaction
  public void preTransaction() {
    System.out.println("before transaction");
  }

  @AfterTransaction
  public void postTransaction() {
    System.out.println("after transaction");
  }

  @Transactional
  @Test public void test1() {
    // before this test, a transaction will be created
    // after this test, the transaction will be rolled-back
  }

  @Test public void test2() {
    // no transaction will be created around this test
  }

  @DirtiesContext
  @Test public void test3() {
    dependencyByName = null;
  }
}
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-7392431532224835872?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/7392431532224835872/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=7392431532224835872' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/7392431532224835872'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/7392431532224835872'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/testing-toolbelt-springjunit4classrunne.html' title='Testing Toolbelt: SpringJUnit4ClassRunner'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-8474419558837273826</id><published>2011-01-23T15:54:00.001-05:00</published><updated>2011-12-16T12:39:33.408-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Testing Toolbelt: Groovy</title><content type='html'>&lt;p&gt;&lt;a href="http://groovy.codehaus.org/"&gt;Groovy&lt;/a&gt;, the apparent golden child of Java, is a mostly dynamic-typed JVM language which seeks to add functionality to the core Java language such that writing and testing code is much easier and requires less boiler-plate code. Some of the features provided by Groovy that I have found useful for testing are:
&lt;dl&gt;
&lt;dt&gt;GroovyBean Properties and Constructors&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Groovy attempts to simplify the usage of bean-type object by providing some shortcuts for accesses and assignments. By default, every class accessed through Groovy code is decorated with a default constructor which takes a map (property-&gt;value), and a getter and setter for each field defined in the class (for which there is not already a getter/setter). The constructor is a simple way to provide values to properties of the new instance.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;properties-sample.groovy&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
class Customer {
  Integer id
  String name
  Date dob

  static void main(args) {
    /* note: the next statement is functionally equivalent to:
     * in Groovy:
     * def customer = new Customer()
     * customer.id = 1
     * customer.name = "Gromit"
     * customer.dob = new Date()
     * in Java (provided all of the set&lt;name&gt; methods were defined):
     * Customer customer = new Customer();
     * customer.setId(1);
     * customer.setName("Gromit");
     * customer.setDob(new Date());
     */
    def customer = new Customer(id:1, name:"Gromit", dob:new Date())
    // note: calls the getName() method defined below
    println("Hello ${customer.name}")
    // note: references the id field directly
    println("Your id is ${customer.id}")
    // ...not really, the Groovy compiler adds in a
    // default getter for the field.
  }

  public String getName() {
    println "in getter"
    return name
  }
}
]]&gt;&lt;/script&gt;
&lt;/dd&gt;
&lt;dt&gt;Token Replacement&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;In Groovy, the &lt;tt&gt;String&lt;/tt&gt; class is enhanced to allow for the use of tokens within a &lt;tt&gt;String&lt;/tt&gt; literal. These tokens are of the form &lt;tt&gt;${&amp;lt;property&amp;gt;}&lt;/tt&gt; and will use the properties values available at the time of creation. Refer back to the above example to see some at work.&lt;/p&gt;&lt;/dd&gt;
&lt;dt&gt;Collection Literals&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Easily create a list by using the &lt;tt&gt;[&lt;value&gt;]&lt;/tt&gt; syntax, a range by using the &lt;tt&gt;&amp;lt;start&amp;gt;..&amp;lt;end&amp;gt;&lt;/tt&gt; syntax, and a map by using the &lt;tt&gt;[&amp;lt;key&amp;gt;:&amp;lt;value&amp;gt;]&lt;/tt&gt; syntax.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;collection-sample.groovy&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
  def emptyList = []
  def list = [1, 2, 3, 4, 5, 6, 7, 8]
  def range = 1..8
  assert list == range
  def emptyMap = [:]
  def map = [1:2, 3:4, 5:6]
]]&gt;&lt;/script&gt;
&lt;/dd&gt;
&lt;dt&gt;Closures&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Closures are simply blocks of code surrounded by curly braces, which can be treated as reference types. Closures may declare arguments and may return values. Closures may be stored in variables.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;closure-sample.groovy&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
  // times is actually a method which takes a number
  // (the target of the call) and a closure
  // print 0 to 10 using a closure
  10.times {int var -&gt; println var} // explicit closure variable and type
  10.times {var -&gt; println var} // explicit closure variable
  10.times {println it} // no variable declaration
]]&gt;&lt;/script&gt;
&lt;/dd&gt;
&lt;dt&gt;Iteration (&lt;tt&gt;each&lt;/tt&gt;)&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Iteration of arrays, ranges, lists, and maps has been simplified by the addition of the &lt;tt&gt;each&lt;/tt&gt; method.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;each-sample.groovy&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
  // each is actually a method which takes an iterable
  // (the target of the call) and a closure
  // print 0 to 10 using a closure and a range (also an iterable)
  (0..10).each {int var -&gt; println var} // explicit closure variable and type
  (0..10).each {var -&gt; println var} // explicit closure variable
  (0..10).each {println it} // no variable declaration
  // print a map
  [1:10, 2:20, 3:30].each {key, value -&gt; println "${key}-${value}"}
]]&gt;&lt;/script&gt;
&lt;/dd&gt;
&lt;dt&gt;Coercion (Map and Closure)&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Any map or closure may be interpreted as an instance of a specific type simply by using &lt;tt&gt;as &amp;lt;type&amp;gt;&lt;/tt&gt;. This allows you to easily create stand-in objects, provided they have a public default (no-arg) constructor.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;coercion-sample.groovy&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
  def map1 = {println "hi"} as Map
  map1.get("george") // prints hi
  map1["george"] // different way of doing the same thing in Groovy
  def map2 = [get: {key -&gt; return "value"}] as HashMap
  map2["key"] = "hello"
  assert map2["key"] == "value"
]]&gt;&lt;/script&gt;
&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://groovy.codehaus.org/groovy-jdk/"&gt;GDK&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;Through the default meta-class implementations used by Groovy, many useful methods (many taking advantage of closures) have been added to the standard Java classes. There's too much to list here, but know that many of the above examples use GDK methods.&lt;/p&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;a href="http://groovy.codehaus.org/Unit+Testing"&gt;&lt;tt&gt;GroovyTestCase&lt;/tt&gt;&lt;/a&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;The &lt;tt&gt;GroovyTestCase&lt;/tt&gt; class contains a large portion of the testing functionality used by basic Groovy. Since the Groovy team have pledged backwards-compatibility with JDK 1.4, they have also stuck with the non-annotation-based version of JUnit(3.8.*) as a basis for their testing helper class. This is not as bad as it sounds, as many of the language features of Groovy make up for the missing capabilities of JUnit 4.4. Every test class defined using groovy must be a sub-class of &lt;tt&gt;GroovyTestCase&lt;/tt&gt;. Each test method must be public, return &lt;tt&gt;void&lt;/tt&gt;, and be named &lt;tt&gt;test&amp;lt;something&amp;gt;&lt;/tt&gt;.&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;tt&gt;assert*&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;all of the &lt;tt&gt;assert*&lt;/tt&gt; methods provided by JUnit are also present in the &lt;tt&gt;GroovyTestCase&lt;/tt&gt; class.&lt;/p&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;shouldFail(&amp;lt;Throwable&amp;gt;)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;similar to the &lt;tt&gt;Test&lt;/tt&gt; annotation when used with the &lt;tt&gt;expected&lt;/tt&gt; argument, the &lt;tt&gt;shouldFail&lt;/tt&gt; method takes a &lt;tt&gt;Throwable&lt;/tt&gt; class type and a closure, executes the closure, and fails if an instance of &lt;tt&gt;Throwable&lt;/tt&gt; is not thrown within the closure.&lt;/p&gt;
&lt;h3&gt;&lt;tt&gt;shouldFail-sample.groovy&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
  shouldFail(ArrayIndexOutOfBoundsException) {
    println (0..4)[10];
  }
]]&gt;&lt;/script&gt;
&lt;/dd&gt;
&lt;/dl&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;StubFor&lt;/tt&gt; and &lt;tt&gt;MockFor&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;&lt;p&gt;The &lt;tt&gt;StubFor&lt;/tt&gt;/&lt;tt&gt;MockFor&lt;/tt&gt; classes can be used within Groovy to create stand-in objects when coercion won't work or when you need to over-ride the behavior of a constructor.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;stubfor-sample.groovy&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: groovy"&gt;&lt;![CDATA[
  //can't use Map coercion, File does not have default constructor.
  def mockFileType = new MockFor(File)
  mockFileType.demand.exists { return true }
  mockFileType.use {
    def f = new File('DOES_NOT_EXIST.TXT')
    assertThat(f.exists, is(true))
  }
]]&gt;&lt;/script&gt;
&lt;/dd&gt;&lt;/dl&gt;

&lt;footer&gt;
&lt;h3&gt;References/Related:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.amazon.com/gp/product/1934356093/ref=as_li_ss_tl?ie=UTF8&amp;tag=activeactivec-20&amp;linkCode=as2&amp;camp=217145&amp;creative=399369&amp;creativeASIN=1934356093"&gt;Programming Groovy: Dynamic Productivity for the Java Developer (Pragmatic Programmers)&lt;/a&gt;&lt;img src="http://www.assoc-amazon.com/e/ir?t=activeactivec-20&amp;l=as2&amp;o=1&amp;a=1934356093&amp;camp=217145&amp;creative=399369" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;"/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/footer&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-8474419558837273826?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/8474419558837273826/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=8474419558837273826' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8474419558837273826'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8474419558837273826'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/testing-toolbelt-groovy.html' title='Testing Toolbelt: Groovy'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-7495499767057195926</id><published>2011-01-22T16:35:00.001-05:00</published><updated>2011-01-23T22:59:05.083-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring Note'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='SqlUpdate'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Spring Note: SqlUpdate</title><content type='html'>&lt;p&gt;The &lt;tt&gt;org.springframework.jdbc.object.SqlUpdate&lt;/tt&gt; class is another tool that I use a lot. This class encapsulates &lt;tt&gt;INSERT&lt;/tt&gt;, &lt;tt&gt;UPDATE&lt;/tt&gt;, and &lt;tt&gt;DELETE&lt;/tt&gt; queries as beans defined within your application context. In most situations, you  will be using the &lt;tt&gt;SqlUpdate&lt;/tt&gt; class as-is with multiple configurations within a DAO's context. Since the class is not abstract, it is quite easy to extend for creating dummy/mock instances for testing.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;ITSpringJdbc.java&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: java"&gt;&lt;![CDATA[
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ITSpringJdbc {
  @Resource SqlUpdate updateBean;
  @Resource JdbcTemplate jdbcTemplate;

  @Transactional
  @Test public void testUpdate() {
    final String[] args = { "T" };
    updateBean.update(args);
    final int count = jdbcTemplate.queryForInt(
      "select count(*) from DUAL where dummy = 'T'");
    assertThat(count, is(1));
  }
}
]]&gt;&lt;/script&gt;

&lt;h3&gt;&lt;tt&gt;ITSpringJdbc-context.xml&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"&gt;

  &lt;bean id="dataSource.properties"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
    &lt;property name="locations"&gt;
      &lt;list&gt;
        &lt;value&gt;classpath:connection.properties&lt;/value&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/bean&gt;

  &lt;bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
    &lt;property name="driverClassName" value="${driverClassName}" /&gt;
    &lt;property name="url" value="${uri}" /&gt;
    &lt;property name="username" value="${username}" /&gt;
    &lt;property name="password" value="${password}" /&gt;
  &lt;/bean&gt;

  &lt;bean id="updateBean"
    class="org.springframework.jdbc.object.SqlUpdate"&gt;
    &lt;property name="dataSource" ref="dataSource"/&gt;
    &lt;property name="sql"&gt;
      &lt;value&gt;
        insert into DUAL (dummy) values (?) 
      &lt;/value&gt;
    &lt;/property&gt;
    &lt;property name="types"&gt;
      &lt;list value-type="java.lang.Integer"&gt;
        &lt;util:constant
          static-field="java.sql.Types.VARCHAR" /&gt;
      &lt;/list&gt;
    &lt;/property&gt;
  &lt;/bean&gt;

  &lt;bean id="jdbcTemplate"
    class="org.springframework.jdbc.core.JdbcTemplate"&gt;
    &lt;property name="dataSource" ref="dataSource"/&gt;
  &lt;/bean&gt;
&lt;/beans&gt;
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-7495499767057195926?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/7495499767057195926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=7495499767057195926' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/7495499767057195926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/7495499767057195926'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/spring-note-sqlupdate.html' title='Spring Note: SqlUpdate'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-6501967906176939938</id><published>2011-01-22T02:25:00.001-05:00</published><updated>2011-01-23T22:57:52.921-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='usergroup'/><category scheme='http://www.blogger.com/atom/ns#' term='software craftsmanship'/><category scheme='http://www.blogger.com/atom/ns#' term='polyglot'/><category scheme='http://www.blogger.com/atom/ns#' term='Columbus'/><category scheme='http://www.blogger.com/atom/ns#' term='Ohio'/><title type='text'>New Group: Columbus Software Craftsmanship</title><content type='html'>&lt;p&gt;As you may or may not know, I have two homes: SW Indiana, and Columbus, Ohio. Since I spend 75% or more of my time in SW Indiana and there are few opportunities in this area for networking/learning the craft, I'm always happy to learn about new groups of like-minded people in my other home.&lt;/p&gt;

&lt;p&gt;I found this group through a random &lt;a href="https://twitter.com/marcpeabody/status/28479928127193088"&gt;tweet&lt;/a&gt; from Marc Peabody. He mentioned that they would be trying out some Scala Koans and included a link to the group's &lt;a href="http://groups.google.com/group/columbus-craftsmanship"&gt;Google Groups&lt;/a&gt; site. Since joining the group earlier today, I've found the details for the Scala Koans night and I've been informed of interest in running a &lt;a href="http://www.coderetreat.com/"&gt;Code Retreat&lt;/a&gt; event at the beginning of April in Columbus.&lt;/p&gt;

&lt;p&gt;I haven't made it to any meetings yet (they're still a pretty new group), but I've had some friendly conversations in e-mail with members of the group and have met some of the other members through NFJS, COJUG, CRB, etc... Sounds like it should be a pretty good time when I'm able to make it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-6501967906176939938?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/6501967906176939938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=6501967906176939938' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6501967906176939938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6501967906176939938'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/new-group-columbus-software.html' title='New Group: Columbus Software Craftsmanship'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-1598802528483900847</id><published>2011-01-22T02:06:00.001-05:00</published><updated>2011-01-23T22:58:33.440-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='xsd'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='wsdl'/><title type='text'>Maven note: exec-maven-plugin</title><content type='html'>&lt;p&gt;I'm currently working on a development package containing a series of &lt;tt&gt;.xsd&lt;/tt&gt; files which will be used to define the external interface for our web service. Due to some other project constraints, it was decided that this package also needed to include the &lt;tt&gt;.wsdl&lt;/tt&gt; files which will further define the web service.&lt;/p&gt;

&lt;p&gt;I'm a lazy &lt;i&gt;(the good kind)&lt;/i&gt; programmer, so I decided that I did not want to update these files every time the schema changed nor did I want to make anyone else figure it out later. I wrote a quick utility for creating the &lt;tt&gt;.wsdl&lt;/tt&gt; files, based on the current &lt;tt&gt;.xsd&lt;/tt&gt; files. Since we're already expecting to use Spring-WS for message dispatching, I wrote some file generation code around the &lt;tt&gt;org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition&lt;/tt&gt; class and wrote up a Spring configuration which put it all together.&lt;/p&gt;

&lt;p&gt;My next task was to figure out a way to get this utility to run within the context of the Maven &lt;tt&gt;package&lt;/tt&gt; phase. Since the code needed to generate the &lt;tt&gt;.wsdl&lt;/tt&gt; files was the only code in this development package, it made sense to hook into the &lt;tt&gt;prepare-package&lt;/tt&gt; phase instead of the &lt;tt&gt;generate-sources&lt;/tt&gt; phase. Now that I knew when the utility should run, I just needed to figure out a way to do it. One Google search later, and I had the &lt;tt&gt;&lt;a href="http://mojo.codehaus.org/exec-maven-plugin/"&gt;exec-maven-plugin&lt;/a&gt;&lt;/tt&gt;. This Maven plugin provides two goals which can be hooked into arbitrary phases in the Maven life cycle:
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;exec&lt;/tt&gt; -- execute an arbitrary executable from within the Maven runtime&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;java&lt;/tt&gt; -- execute the &lt;tt&gt;main&lt;/tt&gt; method, with arguments, of a specified class, from within the Maven runtime&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;So I set up my pom as shown below, and ran &lt;tt&gt;mvn package&lt;/tt&gt;. The end result was a &lt;tt&gt;.jar&lt;/tt&gt; file which contained both the &lt;tt&gt;.xsd&lt;/tt&gt; and the &lt;tt&gt;.wsdl&lt;/tt&gt; files we need. One &lt;tt&gt;mvn deploy&lt;/tt&gt; later and these files were now available to all who needed them.&lt;/p&gt;

&lt;h2&gt;pom.xml&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;project&gt;
  ...
  &lt;build&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.codehaus.mojo&lt;/groupId&gt;
        &lt;artifactId&gt;exec-maven-plugin&lt;/artifactId&gt;
        &lt;version&gt;1.2&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;phase&gt;prepare-package&lt;/phase&gt;
            &lt;goals&gt;
              &lt;goal&gt;java&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
        &lt;configuration&gt;
          &lt;mainClass&gt;my.utility.ClassName&lt;/mainClass&gt;
          &lt;arguments&gt;
            &lt;argument&gt;${project.build.outputDirectory}&lt;/argument&gt;
          &lt;/arguments&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
  ...
&lt;/project&gt;
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-1598802528483900847?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/1598802528483900847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=1598802528483900847' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/1598802528483900847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/1598802528483900847'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/maven-note-exec-maven-plugin.html' title='Maven note: exec-maven-plugin'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-3937292680231232617</id><published>2011-01-22T01:08:00.001-05:00</published><updated>2011-01-23T22:56:10.268-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='hamcrest matchers'/><category scheme='http://www.blogger.com/atom/ns#' term='assertThat'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Matcher'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><title type='text'>Testing Toolbelt: Hamcrest Matchers</title><content type='html'>The &lt;a href="http://code.google.com/p/hamcrest/"&gt;Hamcrest Matchers&lt;/a&gt; framework contains a series of &lt;tt&gt;Matcher&lt;/tt&gt; classes which help implement comparison and assertion methods in a type-safe, declarative manner. When used in tests, the Matchers framework will produce more legible test code and more helpful failure messages. The Matchers framework is partially included in the JUnit 4.4 package and some portions can be used effectively. But, the full power of the framework can only be unleashed by including the real Hamcrest Matchers jar within your testing environment.

&lt;h2&gt;Matchers&lt;/h2&gt;
The &lt;tt&gt;org.hamcrest.Matchers&lt;/tt&gt; class in the Hamcrest framework provides a series of methods, intended to be used with &lt;tt&gt;import static&lt;/tt&gt;, which supply various pre-defined &lt;tt&gt;org.hamcrest.core.Matcher&lt;/tt&gt; instances.
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;is&lt;/tt&gt; -- The simplest matcher, most times behaves just as syntactical sugar around other matchers. But, if an instance of &lt;tt&gt;Class&lt;/tt&gt; is passed, it behaves like the &lt;tt&gt;Matcher&lt;/tt&gt; produced by &lt;tt&gt;instanceOf&lt;/tt&gt;. If passed any other value, behaves like the &lt;tt&gt;Matcher&lt;/tt&gt; produced by &lt;tt&gt;equalsTo&lt;/tt&gt;. see &lt;tt&gt;org.hamcrest.core.Is&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;equalTo&lt;/tt&gt; -- Verifies that the test value is equal to the value used to instantiate the &lt;tt&gt;Matcher&lt;/tt&gt;. see &lt;tt&gt;org.hamcrest.core.IsEqual&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;instanceOf&lt;/tt&gt; -- Verifies that the test value is assignable to the &lt;tt&gt;Class&lt;/tt&gt; value used to instantiate the &lt;tt&gt;Matcher&lt;/tt&gt;. see &lt;tt&gt;org.hamcrest.core.IsInstanceOf&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;nullValue&lt;/tt&gt;/&lt;tt&gt;nonNullValue&lt;/tt&gt; -- Verifies that the test value is null-valued/not-null-valued. see &lt;tt&gt;org.hamcrest.core.IsNull&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;startsWith&lt;/tt&gt;/&lt;tt&gt;containsString&lt;/tt&gt;/&lt;tt&gt;endsWith&lt;/tt&gt; -- Verifies that the test value (&lt;tt&gt;String&lt;/tt&gt;\-typed) begins with, contains, or ends with the value used to instatiate the &lt;tt&gt;Matcher&lt;/tt&gt;. see &lt;tt&gt;org.hamcrest.core.StringStartsWith&lt;/tt&gt;, &lt;tt&gt;org.hamcrest.core.StringContains&lt;/tt&gt;, and &lt;tt&gt;org.hamcrest.core.StringEndsWith&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;arrayWithSize&lt;/tt&gt;/&lt;tt&gt;emptyArray&lt;/tt&gt;/&lt;tt&gt;hasSize&lt;/tt&gt;/&lt;tt&gt;empty&lt;/tt&gt; -- Verifies that the test value is an array/collection that either has the given number of elements/is empty. see &lt;tt&gt;org.hamcrest.core.IsArrayWithSize&lt;/tt&gt;, &lt;tt&gt;org.hamcrest.core.IsCollectionWithSize&lt;/tt&gt;, and &lt;tt&gt;org.hamcrest.core.IsEmptyCollection&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;lessThan&lt;/tt&gt;/&lt;tt&gt;lessThanOrEqualTo&lt;/tt&gt;/&lt;tt&gt;greaterThanOrEqualTo&lt;/tt&gt;/&lt;tt&gt;greaterThan&lt;/tt&gt; -- Verifies that the test value is strictly less than/less than/greater than/strictly greater than the provided value. see &lt;tt&gt;org.hamcrest.core.OrderingComparison&lt;/tt&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Examples&lt;/h2&gt;
&lt;script type="syntaxhighlighter" class="brush: java"&gt;&lt;![CDATA[
public class MatcherSample {

  @Test public void matcherSample() {
    // doesn't compile, type-safety in action
    // assertThat(1, is("VALUE"));

    // is, with a Class-typed operand...
    assertThat("VALUE", is(String.class));
    // ...is resolved to this...
    assertThat("VALUE", is(instanceOf(String.class)));
    // ...which is then unwrapped to this
    assertThat("VALUE", instanceOf(String.class));

    // is, with a reference-type operand...
    assertThat("VALUE", is("VALUE"));
    // ...is resolved to this...
    assertThat("VALUE", is(equalTo("VALUE")));
    // ... which is then unwrapped to this
    assertThat("VALUE", equalTo("VALUE"));

    // is, with a primitive value
    assertThat(1, is(1));

    // assert null-valued
    assertThat(null, is(nullValue()));
    // assert null-valued, checking type
    assertThat((String) null, is(nullValue(String.class)));
    // assert non-null
    assertThat("VALUE", is(notNullValue()));

    // Matchers for Strings
    // you could use is() with these, but is more readable without
    assertThat("VALUABLE", startsWith("VALU"));
    assertThat("VALUABLE", containsString("LUA"));
    assertThat("VALUABLE", endsWith("ABLE"));

    // Matchers for Arrays and Collections
    final String[] strings1 = {};
    assertThat(strings1, is(emptyArray()));
    assertThat(strings1, is(arrayWithSize(0)));
    assertThat(Arrays.asList(strings1), hasSize(0));
    final String[] strings2 = { "VALUE_1", "VALUE_2" };
    assertThat(strings2, is(arrayWithSize(2)));
    assertThat(strings2, is(arrayContaining("VALUE_1", "VALUE_2")));
    assertThat(Arrays.asList(strings2), hasSize(2));
    assertThat(Arrays.asList(strings2), contains("VALUE_1", "VALUE_2"));

    // Matchers for Numerics
    assertThat(1, is(lessThan(10)));
    assertThat(1, is(greaterThan(0)));
    assertThat(1, is(lessThanOrEqualTo(1)));
    assertThat(1, is(greaterThanOrEqualTo(1)));

    // use both/allOf/either/anyOf for composition of matchers
    // both/allOf is equivalent to and'ing the Matchers
    assertThat(1, is(both(greaterThan(0)).and(lessThan(10))));
    assertThat(1, is(allOf(greaterThan(0), lessThan(10))));
    // either/anyOf is equivalent to or'ing the Matchers
    assertThat(100, is(either(lessThan(0)).or(greaterThan(10))));
    assertThat(100, is(anyOf(lessThan(0), greaterThan(10))));
  }
}
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-3937292680231232617?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/3937292680231232617/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=3937292680231232617' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/3937292680231232617'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/3937292680231232617'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/testing-toolbelt-hamcrest-matchers.html' title='Testing Toolbelt: Hamcrest Matchers'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-8479698216578646424</id><published>2011-01-22T00:24:00.001-05:00</published><updated>2011-01-23T22:55:19.009-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='Parameterized'/><category scheme='http://www.blogger.com/atom/ns#' term='BeforeClass'/><category scheme='http://www.blogger.com/atom/ns#' term='After'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='RunWith'/><category scheme='http://www.blogger.com/atom/ns#' term='junit'/><category scheme='http://www.blogger.com/atom/ns#' term='Before'/><category scheme='http://www.blogger.com/atom/ns#' term='AfterClass'/><title type='text'>Testing Toolbelt: JUnit</title><content type='html'>&lt;p&gt;The &lt;a href="http://www.junit.org"&gt;JUnit&lt;/a&gt; framework is arguably the de-facto standard for unit testing java code, and is also the basis of many other testing frameworks (unit or otherwise). Using the JUnit framework, one can quickly run a test method, class, or suite and get one of three responses:
&lt;ul&gt;
&lt;li&gt;Success: All of the assertions in the test method passed, no fail calls were encountered, and no unexpected exceptions were thrown.&lt;/li&gt;
&lt;li&gt;Failure: One of the assertions in the test method failed or a fail call was encountered.&lt;/li&gt;
&lt;li&gt;Error: An unexpected &lt;tt&gt;java.lang.Throwable&lt;/tt&gt; was thrown within the test method's body.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;

&lt;p&gt;For the sake of brevity, and since I am mostly using Java 1.6 these days, this discussion will focus on JUnit 4.4 which is based on annotations and static imports instead of specially-named methods and the extension of the &lt;tt&gt;junit.framework.TestCase&lt;/tt&gt; class.&lt;/p&gt;

&lt;h2&gt;@Test&lt;/h2&gt;
&lt;p&gt;Every method that should be run as a test should be annotated with the &lt;tt&gt;org.junit.Test&lt;/tt&gt; annotation. The &lt;tt&gt;Test&lt;/tt&gt; annotation must be used on only &lt;tt&gt;public void&lt;/tt&gt; methods and the annotated method can only take parameters when used in conjunction with the &lt;tt&gt;Parameterized&lt;/tt&gt; annotation discussed below. The &lt;tt&gt;Test&lt;/tt&gt; annotation can take two optional arguments:
&lt;dl&gt;
&lt;dt&gt;&lt;tt&gt;expected&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;An optional argument to the &lt;tt&gt;Test&lt;/tt&gt; annotation which declares that the test method is expected to throw a &lt;tt&gt;Throwable&lt;/tt&gt; of the defined type. If the method does not throw a &lt;tt&gt;Throwable&lt;/tt&gt; of an appropriate type, the test will fail. If any other &lt;tt&gt;Throwable&lt;/tt&gt; escapes the method body, the test will be considered in error.&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;timeout&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;An optional argument to the &lt;tt&gt;Test&lt;/tt&gt; annotation which declares that the test method is expected to complete within the defined number of milliseconds. If the method does not return in time, the test fails.
&lt;/dd&gt;
&lt;/dl&gt;&lt;/p&gt;

&lt;h2&gt;@Before/@After/@BeforeClass/@AfterClass&lt;/h2&gt;
&lt;p&gt;Public methods marked with these annotations will be run before each test (&lt;tt&gt;setUp()&lt;/tt&gt;), after each test(&lt;tt&gt;tearDown()&lt;/tt&gt;), before each test suite, or after each test suite. These annotations are usually used to setup and reset the environment in which the tests are running.&lt;/p&gt;

&lt;h2&gt;Assert&lt;/h2&gt;
&lt;p&gt;The &lt;tt&gt;org.junit.Assert&lt;/tt&gt; class is expected to be used through the use of static imports, and contains a large number of static methods which can be used to ensure that the elements of a test are in an expected state. Each of the &lt;tt&gt;assert*&lt;/tt&gt; methods has two forms:
&lt;dl&gt;
&lt;dt&gt;&lt;tt&gt;assert*(actual, expected)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;performs the assertion and fails with a default failure message.&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;assert*(message, actual, expected)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;performs the assertion and fails with a custom failure message. (sometimes in addition to the default message)&lt;/dd&gt;
&lt;/dl&gt;&lt;/p&gt;

&lt;p&gt;Here are some of the main assertion methods:
&lt;dl&gt;
&lt;dt&gt;&lt;tt&gt;assertNull(param)&lt;/tt&gt;/&lt;tt&gt;assertNotNull(param)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;Asserts that the parameter is(not) null-valued.&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;assertTrue(param)&lt;/tt&gt;/&lt;tt&gt;assertFalse(param)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;Asserts that the parameter is true|false?&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;assertEquals(actual, expected)&lt;/tt&gt;/&lt;tt&gt;assertArrayEquals(actual, expected)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;Asserts that &lt;tt&gt;actual&lt;/tt&gt; and &lt;tt&gt;expected&lt;/tt&gt; are &lt;tt&gt;equal()&lt;/tt&gt;.&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;fail(message)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;Causes the current test to immediately fail. Use this when writing custom &lt;tt&gt;assert&lt;/tt&gt; methods or when creating new empty test methods.&lt;/dd&gt;
&lt;dt&gt;&lt;tt&gt;assertThat(actual, Matcher)&lt;/tt&gt;&lt;/dt&gt;
&lt;dd&gt;The entry point into the Hamcrest Matcher framework, which will be covered by itself in a different post. This method, when used in conjunction with a &lt;tt&gt;Matcher&lt;/tt&gt; instance is more capable, and produces more helpful failure output than the other JUnit &lt;tt&gt;assert*&lt;/tt&gt; methods.&lt;/dd&gt;
&lt;/dl&gt;
&lt;/p&gt;

&lt;h2&gt;Parameterized&lt;/h2&gt;
&lt;p&gt;The &lt;tt&gt;org.junit.runners.Parameterized&lt;/tt&gt; class is a non-default JUnit &lt;tt&gt;TestRunner&lt;/tt&gt; implementation which allows for the creation of a series of test class instances, one for each of the parameter sets defined in the parameter generation method. Each of these test class instances will then be executed.&lt;/p&gt;

&lt;p&gt;Every class which uses the &lt;tt&gt;Parameterized&lt;/tt&gt; class as a runner must provide a source method for the parameters. The parameter source method is marked using the &lt;tt&gt;org.junit.runners.Parameters&lt;/tt&gt; annotation. The parameter source method must be static and return a &lt;tt&gt;Collection&lt;/tt&gt; of values or arrays. Each element in the returned collection represents a single test class execution and will be passed to the constructor for a new instance of the test class. The constructor must accept the same number of arguments and those arguments must be of a compatible type to those contained in each element of the returned collection.
&lt;/p&gt;

&lt;h3&gt;An example of &lt;tt&gt;Parameterized&lt;/tt&gt; usage:&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: java"&gt;&lt;![CDATA[
/*
 * This test class, when run, produces results showing
 * three test runs with two successes and one failure.
 */
@RunWith(Parameterized.class)
public class ParameterizedTest {
  final Integer value;

  @Parameters public static Collection&lt;integer&gt; getParameters() {
    return Arrays.asList(1, 3, 10);
  }

  public ParameterizedTest(final Integer value) {
    this.value = value;
  }

  @Test public void isLessThanFive() {
    assertTrue(this.value &lt; 5);
  }
}
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-8479698216578646424?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/8479698216578646424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=8479698216578646424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8479698216578646424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8479698216578646424'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/testing-toolbelt-junit.html' title='Testing Toolbelt: JUnit'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-57615221315920290</id><published>2011-01-21T23:56:00.002-05:00</published><updated>2011-01-23T22:53:23.815-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='MappingSqlQuery'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='DAO'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring Note'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><category scheme='http://www.blogger.com/atom/ns#' term='RowMapper'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Spring Note: RowMapper/MappingSqlQuery</title><content type='html'>&lt;h1&gt;RowMapper&lt;/h1&gt;
&lt;p&gt;The &lt;tt&gt;RowMapper&lt;/tt&gt; class is an interface which defines only one method which turns a single row from a &lt;tt&gt;ResultSet&lt;/tt&gt; into a domain-useable object. While you can use a generic implementation of this class for producing column name/value &lt;tt&gt;Map&lt;/tt&gt;s, my typical usage has been to create domain objects from the result of a specific set of queries.&lt;/p&gt;

&lt;h1&gt;MappingSqlQuery&lt;/h1&gt;
&lt;p&gt;The &lt;tt&gt;MappingSqlQuery&lt;/tt&gt; class is intended to be used for &lt;tt&gt;SELECT&lt;/tt&gt; queries and can use a &lt;tt&gt;RowMapper&lt;/tt&gt; implementation to create a result &lt;tt&gt;List&lt;/tt&gt; of the appropriate type, hiding the intermediate &lt;tt&gt;ResultSet&lt;/tt&gt; from the outside world.&lt;/p&gt;

&lt;p&gt;These classes, when taken together, provide excellent tools for creating the read methods for DAO classes which are concise and testable.&lt;/p&gt;

&lt;h3&gt;&lt;tt&gt;ITSpringJdbc.java&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: java"&gt;&lt;![CDATA[
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class ITSpringJdbc {

  public class TestMapper implements RowMapper {
    @Override
    public Map&lt;String, String&gt; mapRow(final ResultSet rs, final int index)
        throws SQLException {
      final Map&lt;String, String&gt; m = new HashMap&lt;String, String&gt;();
      final ResultSetMetaData md = rs.getMetaData();
      for (int i = 0; i &lt; md.getColumnCount(); i++) {
        m.put(md.getColumnName(i), rs.getString(i));
      }
      return m;
    }
  }

  public class TestSelect extends MappingSqlQuery {
    final TestMapper mapper = new TestMapper();

    @Override
    protected Object mapRow(final ResultSet rs, final int index)
        throws SQLException {
      return mapper.mapRow(rs, index);
    }
  }

  @Resource TestSelect selectBean;
  @Resource TestMapper mappingBean;
  @Resource JdbcTemplate jdbcTemplate;

  @Test public void testSelect() {
    final String[] args = { "X" };
    final Object result = selectBean.findObject(args);
    assertThat(result, is(notNullValue());
    assertThat(result, is(Map.class));
    final Map map = (Map) result;
    assertThat(map, hasSize(1));
    assertThat(map.containsKey("dummy"), is(true));
    assertThat(map.get("dummy"), is("X"));
  }

  @Test public void testMapper() {
    final SqlRowSet rs = jdbcTemplate.queryForRowSet(
      "select dummy from table");
    final Object o = mappingBean.mapRow(rs, 0);
    assertThat(o, is(notNullValue());
    assertThat(o, is(Map.class));
    final Map map = (Map) o;
    assertThat(map, hasSize(1));
    assertThat(map.containsKey("dummy"), is(true));
    assertThat(map.get("dummy"), is("X"));
  }
}
]]&gt;&lt;/script&gt;

&lt;h3&gt;&lt;tt&gt;ITSpringJdbc-context.xml&lt;/tt&gt;&lt;/h3&gt;
&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:util="http://www.springframework.org/schema/util"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"&gt;

&lt;bean id="dataSource.properties"
  class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
  &lt;property name="locations"&gt;
    &lt;list&gt;
      &lt;value&gt;classpath:connection.properties&lt;/value&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="dataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
  &lt;property name="driverClassName" value="${driverClassName}" /&gt;
  &lt;property name="url" value="${uri}" /&gt;
  &lt;property name="username" value="${username}" /&gt;
  &lt;property name="password" value="${password}" /&gt;
&lt;/bean&gt;

&lt;bean id="selectBean"
  class="TestSelect"&gt;
  &lt;property name="dataSource" ref="dataSource" /&gt;
  &lt;property name="sql"&gt;
    &lt;value&gt;
      select dummy from table where dummy = ?
    &lt;/value&gt;
  &lt;/property&gt;
  &lt;property name="types"&gt;
    &lt;list value-type="java.lang.Integer"&gt;
      &lt;util:constant
        static-field="java.sql.Types.VARCHAR" /&gt;
    &lt;/list&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="mappingBean"
  class="TestMapper"/&gt;

&lt;bean id="jdbcTemplate"
  class="org.springframework.jdbc.core.JdbcTemplate"&gt;
  &lt;property name="dataSource" ref="dataSource"/&gt;
&lt;/bean&gt;
&lt;/beans&gt;
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-57615221315920290?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/57615221315920290/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=57615221315920290' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/57615221315920290'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/57615221315920290'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/spring-note-rowmappermappingsqlquery.html' title='Spring Note: RowMapper/MappingSqlQuery'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-8932702615309794305</id><published>2011-01-21T23:32:00.001-05:00</published><updated>2011-01-23T22:56:36.235-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apologetic'/><category scheme='http://www.blogger.com/atom/ns#' term='backlog'/><title type='text'>Clearing the Backlog</title><content type='html'>I've had several posts brewing in the background. I'm going to pump out a few posts tonight and finally bid them a fond adieu. So, here they come fast and furious, and maybe not as deep as I originally expected them to be.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-8932702615309794305?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/8932702615309794305/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=8932702615309794305' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8932702615309794305'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8932702615309794305'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2011/01/clearing-backlog.html' title='Clearing the Backlog'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-2182621533500799615</id><published>2010-06-30T09:26:00.001-04:00</published><updated>2010-06-30T13:44:24.281-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='knowing.net'/><category scheme='http://www.blogger.com/atom/ns#' term='language learning'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><title type='text'>Learning Ruby: Knowing.net Exercise #1</title><content type='html'>I've just finished exercise #1 from: &lt;a href="http://www.knowing.net/index.php/2006/06/16/15-exercises-to-know-a-programming-language-part-1/"&gt;knowing.net&lt;/a&gt;. Please feel free to critique this code, I am serious about learning Ruby and getting introduced to members of the community.&lt;br /&gt;

&lt;h2&gt;proj1.rb&lt;/h2&gt;&lt;script type="syntaxhighlighter" class="brush: ruby"&gt;&lt;![CDATA[
# Write a program that takes as its arguments one of the words ’sum’,
# ‘product’, ‘mean’, or ’sqrt’ followed by a series of numbers. The
# program applies the appropriate function to the series.

# the mathn library makes the Math.sqrt call below behave better in
# situations involving negative sums.
require 'mathn'

class Array
  def sum
    # missed the inject method on my first
    # skim of the 'Programming Ruby' appendix.
    self.inject {|sum, i| sum + i}.to_f
  end
  def product
    self.inject(1) {|product, i| product * i}.to_f
  end
  def mean
    self.sum / self.size
  end
  def sqrt
    Math.sqrt(self.sum)
  end
end

raise "usage: ruby proj1.rb {sum|product|mean|sqrt} {value}+" if ARGV.size &lt; 2

Allowed_commands = ["sum", "product", "mean", "sqrt"]
command = ARGV.shift.downcase
raise "unknown command: #{command}" unless Allowed_commands.include? command

# I don't like this line, is there a better
# way to do String -&gt; numeric conversions?
ARGV.collect! {|i| i.to_f}
puts eval ARGV.to_s + "." + command
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-2182621533500799615?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/2182621533500799615/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=2182621533500799615' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2182621533500799615'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2182621533500799615'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2010/06/learning-ruby-knowingnet-exercise-1.html' title='Learning Ruby: Knowing.net Exercise #1'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-5283809597507916045</id><published>2010-06-29T12:03:00.002-04:00</published><updated>2010-06-29T12:05:59.311-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring Note'/><category scheme='http://www.blogger.com/atom/ns#' term='dependency management'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='properties'/><category scheme='http://www.blogger.com/atom/ns#' term='testing'/><title type='text'>Spring Note: PropertyPlaceholderConfigurer</title><content type='html'>&lt;p&gt;Often there are Spring-related configuration options which don't belong inside the final jar/war for a Java application. Either because the options are different for each deployment environment or because the value of the option is sensitive (&lt;i&gt;passwords&lt;/i&gt;). The &lt;tt&gt;PropertyPlaceholderConfigurer&lt;/tt&gt; class attempts to remedy the management and injection of the values for these options. It reads one or more property files, optionally using system properties for defaults, and uses the values found to fill property placeholders of the form &lt;tt&gt;${property name}&lt;/tt&gt; found in the &lt;tt&gt;ApplicationContext&lt;/tt&gt; in which the configurer is defined.
&lt;dl&gt;
&lt;dt&gt;Advantages:&lt;/dt&gt;
&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;It provides a mechanism for externalizing configuration so that each environment can be configured differently without re-building the application.&lt;/li&gt;
&lt;li&gt;It provides a mechanism for injecting test properties at test-time without incurring much development overhead.&lt;/li&gt;
&lt;li&gt;Using the &lt;tt&gt;classpath:&amp;lt;file&amp;gt;&lt;/tt&gt; pseudo-uri enables developers to easily include default properties while still allowing users to over-ride the defaults by adding the location of a properties file to the application's classpath.&lt;/li&gt;
&lt;li&gt;The &lt;tt&gt;PropertyPlaceholderConfigurer&lt;/tt&gt; is extensible and provides a method, &lt;tt&gt;convertPropertyValue(String)&lt;/tt&gt;, which can be over-ridden in a sub-class to handle the encryption of properties.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;dt&gt;Disadvantages:&lt;/dt&gt;
&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;The configurer class does not re-load at a regular interval. Changing the properties managed by the configurer requires a restart of the application using it. This can be overcome in some limited situations through a custom sub-class, but for the most part, is not really supported by the Spring container.&lt;/li&gt;
&lt;li&gt;Only Spring-managed beans can take advantage of these properties.&lt;/li&gt;
&lt;/ul&gt;
&lt;/dd&gt;
&lt;/dl&gt;

&lt;h1&gt;Sample&lt;/h1&gt;

&lt;h2&gt;config.xml&lt;/h2&gt;&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
&lt;bean id="propertyConfigurer"
    class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"&gt;
  &lt;property name="location"&gt;
    &lt;value&gt;classpath:project.properties&lt;/value&gt;
  &lt;/property&gt;
&lt;/bean&gt;

&lt;bean id="dataSource"
    class="org.springframework.jdbc.datasource.DriverManagerDataSource"&gt;
  &lt;property name="driverClassName" value="${jdbc.driver}"/&gt;
  &lt;property name="url" value="${jdbc.url}"/&gt;
&lt;/bean&gt;
]]&gt;&lt;/script&gt;

&lt;h2&gt;project.properties&lt;/h2&gt;&lt;script type="syntaxhighlighter" class="brush: xml"&gt;&lt;![CDATA[
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:mydb
]]&gt;&lt;/script&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-5283809597507916045?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/5283809597507916045/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=5283809597507916045' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5283809597507916045'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5283809597507916045'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2010/06/spring-note-propertyplaceholderconfigur.html' title='Spring Note: PropertyPlaceholderConfigurer'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-8380001410964004889</id><published>2010-06-23T15:44:00.001-04:00</published><updated>2010-06-23T15:46:11.159-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='launchy'/><category scheme='http://www.blogger.com/atom/ns#' term='Productivity Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='launchers'/><category scheme='http://www.blogger.com/atom/ns#' term='utility'/><title type='text'>Productivity Tools: Launchy</title><content type='html'>&lt;p&gt;&lt;a href="http://www.launchy.net/"&gt;Launchy&lt;/a&gt; is a simple application indexer/launcher for Windows/Linux/Mac OS. It is an application which combines some of the features of the Spotlight and Dock tools in Mac OS. You set up Launchy with a set of folders and file extensions to scan, and it will create a catalog of the files found in those folders. Any of the cataloged files can then be opened quickly by pressing &lt;i&gt;alt+space&lt;/i&gt; at any time and then typing some, or all, of the file's name. It is important to note that Launchy does not catalog the contents of the files, only the files' names.&lt;/p&gt;

&lt;h2&gt;Lightweight&lt;/h2&gt;
&lt;p&gt;Except for the times that Launchy is rebuilding its catalog, you will never see Launchy utilizing your CPU. The index does appear to take up some memory (mine's currently at around 8MB), but that should be expected for this sort of application.&lt;/p&gt;

&lt;h2&gt;Filesystem Integration&lt;/h2&gt;
&lt;p&gt;Launchy integrates well with your filesystem. That is, you can start typing &lt;tt&gt;C:\Pro&lt;/tt&gt;, hit &lt;i&gt;tab&lt;/i&gt;, and then hit &lt;i&gt;enter&lt;/i&gt; to open up an Explorer window for the Program Files directory. You can use this functionality to get to any folder/file on your filesystem, even those not indexed by Launchy.&lt;/p&gt;

&lt;h2&gt;Plugins&lt;/h2&gt;
&lt;p&gt;Launchy includes a plugin system and includes some interesting plugins out of the box:
&lt;dl&gt;
&lt;dt&gt;Calcy/GCalc&lt;/dt&gt;
&lt;dd&gt;Allows you to do simple calculations and conversions from within Launchy.&lt;/dd&gt;
&lt;dt&gt;Controly&lt;/dt&gt;
&lt;dd&gt;Indexes the applets from the Control Panel.&lt;/dd&gt;
&lt;dt&gt;Runner&lt;/dt&gt;
&lt;dd&gt;Create custom commands to run against the command-line.&lt;/dd&gt;
&lt;dt&gt;Weby&lt;/dt&gt;
&lt;dd&gt;Integrates Launchy with your bookmarks and allows you to do searches against several online search engines from within Launchy.&lt;/dd&gt;
&lt;/dl&gt;&lt;/p&gt;

&lt;p&gt;I've also found one additional plugin that has been very useful, the &lt;a href="http://code.google.com/p/putty-launchy-plugin/"&gt;PuTTY plugin&lt;/a&gt;. This plugin adds all of the saved sessions from your PuTTY installation to Launchy's catalog. This gives you the capability to type &lt;tt&gt;ssh&lt;/tt&gt;, hit &lt;i&gt;tab&lt;/i&gt;, and see a list of saved PuTTY sessions.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-8380001410964004889?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/8380001410964004889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=8380001410964004889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8380001410964004889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8380001410964004889'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2010/06/productivity-tools-launchy.html' title='Productivity Tools: Launchy'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-3659080985670284751</id><published>2010-06-22T11:54:00.001-04:00</published><updated>2010-06-22T11:55:50.453-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='productivity'/><category scheme='http://www.blogger.com/atom/ns#' term='Productivity Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Windows software'/><category scheme='http://www.blogger.com/atom/ns#' term='desktop'/><category scheme='http://www.blogger.com/atom/ns#' term='context switching'/><category scheme='http://www.blogger.com/atom/ns#' term='VirtuaWin'/><category scheme='http://www.blogger.com/atom/ns#' term='utility'/><title type='text'>Productivity Tools: Virtual Desktops</title><content type='html'>&lt;p&gt;Virtual desktop systems allow me to set up multiple workspaces within my window manager, each of which contain a separate set of application windows which will only be shown when the workspace is activated. This is a powerful expansion of the idea of application switching (&lt;i&gt;alt+tab&lt;/i&gt;) as I can now switch easily between groups of applications, instead of just a single application. By creating task-related workspaces, I am able to stay focused on only the one or two tools that matter for the task I am currently working on, while still having other tools open for access later.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;While virtual desktops have been around for ages in the *nix world, Microsoft still refuses to include these capabilities out of the box. This has led to an array of 3&lt;sup&gt;rd&lt;/sup&gt; party tools that provide virtual desktops. I've tried several of these tools over the years, and VirtuaWin is the one which I keep returning to. &lt;a href="http://virtuawin.sourceforge.net/"&gt;VirtuaWin&lt;/a&gt; is a virtual desktop manager for Windows which gives you a set of virtual desktops and global keystrokes for switching between them.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;By default, VirutaWin provides you with two actions: move to another workspace (&lt;i&gt;win+&amp;larr;/&amp;uarr;/&amp;rarr;/&amp;darr;&lt;/i&gt;) and move to another workspace with the current window (&lt;i&gt;alt+win+&amp;larr;/&amp;uarr;/&amp;rarr;/&amp;darr;&lt;/i&gt;). There is also a module, Smart CoolName, which adds the ability to flash, for a few seconds, the name of the current desktop while switching desktops. You can also do some window management by clicking on the system-tray icon: switch to a specific window/desktop, move a specific window to the current desktop, and flag a window so that is is present on every desktop.&lt;br /&gt;
&lt;br /&gt;
&lt;p&gt;I can usually get away with just four desktops while I'm working:&lt;br /&gt;
&lt;dl&gt;&lt;dt&gt;Work&lt;/dt&gt;
&lt;dd&gt;IDE and documentation windows&lt;/dd&gt;
&lt;dt&gt;Support&lt;/dt&gt;
&lt;dd&gt;tools which support my work, like database clients and JIRA windows&lt;/dd&gt;
&lt;dt&gt;Comms&lt;/dt&gt;
&lt;dd&gt;my messaging clients and Outlook&lt;/dd&gt;
&lt;dt&gt;Other&lt;/dt&gt;
&lt;dd&gt;all the other application windows, work-related or not&lt;/dd&gt; &lt;/dl&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-3659080985670284751?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/3659080985670284751/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=3659080985670284751' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/3659080985670284751'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/3659080985670284751'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2010/06/productivity-tools-virtual-desktops.html' title='Productivity Tools: Virtual Desktops'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-2822508170812642719</id><published>2010-06-14T15:35:00.008-04:00</published><updated>2010-06-21T11:29:46.964-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sql'/><category scheme='http://www.blogger.com/atom/ns#' term='NamedParameterJdbcTemplate'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='JdbcTemplate'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='named parameters'/><category scheme='http://www.blogger.com/atom/ns#' term='jdbc'/><title type='text'>Spring Note: NamedParameterJdbcTemplate</title><content type='html'>While I've been using Spring in various capabilities for some time now, I've never run across a situation where I've needed to execute a sql query with a duplicated parameter from code utilizing Spring. The following is a simple example of the type of query I ran into:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: sql"&gt;--Query Version 1
select * from table_1 where ID = ?
union
select * from table_2 where ID = ?
&lt;/pre&gt;&lt;br /&gt;
Using the normal &lt;tt&gt;JdbcTemplate.query&lt;/tt&gt; method with this query would require you to create a two-element array which contains the same value in both elements. Silly DRY violation, right? Luckily, some of the folks behind the Spring JDBC packages decided to include a way to define queries where the values of parameters can be specified by name rather than by index. Here's an example using the named parameter syntax handled by the &lt;tt&gt;NamedParameterJdbcTemplate&lt;/tt&gt; class:&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: java"&gt;...
final String query = "select * from table_1 where ID = :id"
        + " union"
        + " select * from table_2 where ID = :id"

final Map&amp;lt;String, String&gt; params = new HashMap&amp;lt;String, String&gt;();
params.put("id", id);

final RowMapper mapper = new ExampleRowMapper();

// jdbcTemplate is an instance of NamedParameterJdbcTemplate which
// has been created in the Spring ApplicationContext using an
// appropriately-created DataSource.
final List results = jdbcTemplate.query(query, params, mapper);
...
&lt;/pre&gt;&lt;br /&gt;
&lt;h4&gt;Interesting note:&lt;/h4&gt;&lt;br /&gt;
After digging through the Spring's SVN repository, I found that the &lt;tt&gt;NamedParameterJdbcTemplate&lt;/tt&gt; class does not appear to rely on the &lt;tt&gt;CallableStatement&lt;/tt&gt; class for supporting the named parameter functionality. That means that using this class should be safe for all JDBC drivers(which support &lt;tt&gt;PreparedStatement&lt;/tt&gt;s), as the named parameters are handled above the JDBC driver's level.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-2822508170812642719?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/2822508170812642719/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=2822508170812642719' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2822508170812642719'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2822508170812642719'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2010/06/spring-note-namedparameterjdbctemplate.html' title='Spring Note: NamedParameterJdbcTemplate'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-8290269181894191254</id><published>2008-09-27T21:43:00.002-04:00</published><updated>2008-09-27T21:49:55.903-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quick post'/><category scheme='http://www.blogger.com/atom/ns#' term='syntax'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><category scheme='http://www.blogger.com/atom/ns#' term='primer'/><title type='text'>Quick Post: Scala Syntax Primer</title><content type='html'>I don't normally want to post and run, but this one was just too good to pass up: &lt;a href="http://jim-mcbeath.blogspot.com/2008/09/scala-syntax-primer.html"&gt;link&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-8290269181894191254?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/8290269181894191254/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=8290269181894191254' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8290269181894191254'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/8290269181894191254'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/09/quick-post-scala-syntax-primer.html' title='Quick Post: Scala Syntax Primer'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-7538747311244277371</id><published>2008-08-27T21:38:00.014-04:00</published><updated>2008-09-03T09:54:14.051-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='joe obrien'/><category scheme='http://www.blogger.com/atom/ns#' term='metaprogramming'/><category scheme='http://www.blogger.com/atom/ns#' term='re-cap'/><category scheme='http://www.blogger.com/atom/ns#' term='presentation'/><title type='text'>Meta-programming In Ruby</title><content type='html'>Last Wednesday (08.27.2008), I attended a presentation given by local ruby "hero" Joe O'Brien. He was presenting techniques for meta-programming in Ruby. Meta-programming is a general topic which applies to many languages, however Ruby provides some very basic methods which result in powerful meta-programming tools for creating dynamic run-time functionality and for enhancing the base language.
&lt;h1&gt;Meta-programming Methods&lt;/h1&gt;
Joe started the presentation with a run-down of some of the meta-programming methods exposed by the base object in Ruby.
&lt;ul&gt;
&lt;li&gt;&lt;tt&gt;send&lt;/tt&gt;--By using the &lt;tt&gt;send&lt;/tt&gt; method with a string value (method name) and a list of parameters you can dynamically choose a method to call. This method is provided in conjunction with the message-passing back-bone used by the Ruby interpreter.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;method_missing&lt;/tt&gt;--Implementations of the &lt;tt&gt;method_missing&lt;/tt&gt; message handler can be used to handle messages which are currently not understood by the receiving object. This is an expensive method to use, but can be used to add new functionality in response to an unknown message. ActiveRecord in Rails uses this method to create finder methods when a search is performed.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;eval&lt;/tt&gt;--Evaluate a string value as arbitrary Ruby code. &lt;span style="font-style:italic;font-weight:bold;"&gt;User beware&lt;/span&gt; Since this method takes a string argument as the code to be evaluated, any code in that string is not checked by the interpreter until the &lt;tt&gt;eval&lt;/tt&gt; statement is executed by the interpreter.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;define_method&lt;/tt&gt;--Pass a string value (method name) and a block in order to define a new method defined by the given block. This method takes a block as a parameter and is safer to use than the &lt;tt&gt;eval&lt;/tt&gt; method.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;methods&lt;/tt&gt;--Returns an array of the methods currently defined on an object. By calling &lt;tt&gt;methods&lt;/tt&gt; on an object and subtracting the result of calling &lt;tt&gt;methods&lt;/tt&gt; on that object's supertype, you can easily get a list of the methods defined only within that object.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;attr_reader&lt;/tt&gt;--The &lt;tt&gt;attr_reader&lt;/tt&gt; method is used to make a private field in an object accessible to other objects.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;attr_writer&lt;/tt&gt;--The &lt;tt&gt;attr_writer&lt;/tt&gt; method is used to make a private field in an object settable by other objects.&lt;/li&gt;
&lt;li&gt;&lt;tt&gt;attr_accessor&lt;/tt&gt;--The &lt;tt&gt;attr_accessor&lt;/tt&gt; method is used to make a private field in an object accessible and settable by other objects.&lt;/li&gt;
&lt;/ul&gt;
&lt;h1&gt;Example: Declarative Tests and Home-Grown Behavior Driven Development&lt;/h1&gt;
Joe, being a "test-first bigot" (his words, not mine), was uncomfortable with the idea that it took him nearly 10 lines of code to test one ActiveRecord &lt;tt&gt;has_many&lt;/tt&gt; association. He also expressed his dislike for creating test methods whose names look like &lt;tt&gt;test_a_description_of_the_test&lt;/tt&gt;. His iterative approach to creating a declarative version of this this test method started with the original 10 lines of code in his test method. He extracted that method into a method on the Test::Unit::TestCase class, &lt;tt&gt;test_that&lt;/tt&gt;, which took three arguments, the model under test, the expected &lt;tt&gt;has_many&lt;/tt&gt; association class, and a description of the test as a string. These parameters were used in conjunction with the &lt;tt&gt;define_method&lt;/tt&gt; method to create a new method at run-time which executed the original code. Using this technique, Joe stated that he was able to reduce the tests for many of the ActiveRecord capabilites to one-liners.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-7538747311244277371?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/7538747311244277371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=7538747311244277371' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/7538747311244277371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/7538747311244277371'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/08/meta-programming-in-ruby.html' title='Meta-programming In Ruby'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-6779433893677688043</id><published>2008-08-19T12:21:00.004-04:00</published><updated>2008-08-19T12:31:25.281-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='jTrac'/><category scheme='http://www.blogger.com/atom/ns#' term='issue tracking'/><title type='text'>Thanks jTrac, You're Doing a Fine Job</title><content type='html'>I just wanted to give a shout-out to the members of the &lt;a href="http://jtrac.info/"&gt;jTrac&lt;/a&gt; project. jTrac is an issue-tracking system which can be installed out of the box as a stand-alone server using Jetty and HSQLDB, or can be installed as a war in an existing server.

jTrac was very easy to install in our existing JBoss instance and required only a few settings and a directory for storing attachments and the application's HSQLDB database files. Once you have it installed and configured, you can create spaces for each of your applications. Each of these spaces can have a set of custom fields as well as a custom set of states and transitions. Write access to each space is limited to only members of that space. In addition you can make transistions dependent on a particular user role within the space.

The application seems to be mature enough to be feature complete, but does still have some minor nice-to-haves (book-markable searches, Eclipse Mylyn integration) and missing ui polish.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-6779433893677688043?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/6779433893677688043/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=6779433893677688043' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6779433893677688043'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6779433893677688043'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/08/thanks-jtrac-youre-doing-fine-job.html' title='Thanks jTrac, You&apos;re Doing a Fine Job'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-3475636089065071423</id><published>2008-07-29T16:42:00.005-04:00</published><updated>2008-09-03T09:37:20.471-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='resolution'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><title type='text'>Hibernate Bites... (revisited)</title><content type='html'>An update to &lt;a href="http://active-active.blogspot.com/2008/07/hibernate-bites.html"&gt;this post&lt;/a&gt;.

Okay, so we have been able to make the caching work with very little changes to our mappings. By moving the &lt;tt&gt;cache&lt;/tt&gt; element from the child entity definition into the collection declaration in the parent entity we have gotten the caching to work.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-3475636089065071423?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/3475636089065071423/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=3475636089065071423' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/3475636089065071423'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/3475636089065071423'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/07/hibernate-bites-revisited.html' title='Hibernate Bites... (revisited)'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-6746744621602530931</id><published>2008-07-29T13:16:00.019-04:00</published><updated>2010-06-30T13:43:37.815-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='knowing.net'/><category scheme='http://www.blogger.com/atom/ns#' term='language learning'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Finished Exercise #1 for Scala</title><content type='html'>I've just finished exercise #1 from: &lt;a href="http://www.knowing.net/index.php/2006/06/16/15-exercises-to-know-a-programming-language-part-1/"&gt;knowing.net&lt;/a&gt;. Please feel free to critique this code, I am serious about learning Scala and getting introduced to members of the community.&lt;br /&gt;
&lt;h2&gt;Calculator.scala&lt;/h2&gt;&lt;pre class="brush: scala"&gt;package activeactive
class Calculator {
  def main(args:Array[String]): Double = eval(args.toList)
    def eval(args:List[String]): Double = args match {
      case null =&gt;
        throw new IllegalArgumentException(
          "args cannot be null-valued")
      case Nil =&gt;
        throw new IllegalArgumentException(
          "You must provide a function name as the first argument")
      case "sum" :: rest =&gt; sum(convertList(rest))
      case "prod" :: rest =&gt; product(convertList(rest))
      case "mean" :: rest =&gt; mean(convertList(rest))
      case "sqrt" :: rest =&gt; sqrt(convertList(rest))
      case _ =&gt; throw new IllegalArgumentException(
        "invalid function name. Use 'sum', 'prod', 'mean', or 'sqrt'.")
    }
    def convertList(list: List[String]): List[Double] = list match {
      case Nil =&gt; Nil
      case x :: subList =&gt; x.toDouble :: convertList(subList)
    }
    def sum(list: List[Double]) =
      (0D :: list) reduceLeft ((x, y) =&gt; x+y)
    def product(list: List[Double]) =
      (1D :: list) reduceLeft ((x, y) =&gt; x*y)
    def mean(list: List[Double]) = list match {
      case Nil =&gt; throw new IllegalArgumentException(
        "The mean function requires at least one operand")
      case _ =&gt; sum(list) / list.size
    }
    def sqrt(list: List[Double]) =
      if (sum(list) &lt;= 0)
        throw new IllegalArgumentException(
          "the input values '" + list.toString +
            "' resulted in a sum &lt;= zero.")
      else if (sum(list) == 1D) 1D
      else Math.sqrt(sum(list))
}
&lt;/pre&gt;
&lt;b&gt;EDIT:&lt;/b&gt; updated knowing.net link.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-6746744621602530931?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/6746744621602530931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=6746744621602530931' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6746744621602530931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/6746744621602530931'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/07/finished-exercise-1-for-scala.html' title='Finished Exercise #1 for Scala'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-2318363297275948760</id><published>2008-07-28T19:01:00.005-04:00</published><updated>2008-09-03T09:38:20.878-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='caching'/><category scheme='http://www.blogger.com/atom/ns#' term='hibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='angst'/><category scheme='http://www.blogger.com/atom/ns#' term='analysis'/><category scheme='http://www.blogger.com/atom/ns#' term='ehcache'/><title type='text'>Hibernate Bites...</title><content type='html'>&lt;span style="font-style:italic;"&gt;...us in the butt&lt;/span&gt;

Our team recently chose to use Hibernate for handling read-only access to data in our configuration and archive databases. Our primary decision for doing this was to use the baked-in caching provided by ehcache. Since then, we have had three major releases, the first two each containing a bit more hibernate than the previous, and the third, our architecture re-design, in which we spread Hibernate into all of the read-only data access classes.

Our love affair with Hibernate was deep and passionate. Then disaster struck. During the verification of the installation of our new architecture to the disaster recovery environment, we found that many of our web-service responses were taking much longer than our service-level agreement allowed, &lt;span style="font-weight:bold;"&gt;significantly&lt;/span&gt; longer.

One full week later, we have determined that most of the &lt;tt&gt;SessionFactory&lt;/tt&gt; instances which we thought were caching, were in fact not caching. One particular request to our web service caused 43000 queries to be generated from one repeated (x1000) entity retrieval. This problem did not rear its ugly head in the primary environment because the app server and the database are much closer together on the network in the primary environment. The network timing differences were not great between our primary and disaster recovery environments, but when 43000 queries are being issued, each little bit adds up.

We diagnosed our problems with a simple jsp that used &lt;tt&gt;SessionFactory.getStatistics()&lt;/tt&gt; to get the collected statistics and then used &lt;tt&gt;Statistics.getEntityStatistics()&lt;/tt&gt;, &lt;tt&gt;Statistics.getQueryStatistics()&lt;/tt&gt;, and &lt;tt&gt;Statistics.getSecondLevelCacheStatistics()&lt;/tt&gt; to display counts for cache misses, entity loads, cache puts, and cache hits. When you have caches defined that are not being used correctly, you will see more misses than puts, or you will see no misses and many puts.

To solve our problems, we are looking at modifying some of the basic assumptions we had about how Hibernate does caching. We are removing some of the mappings in which a parent class was created simply to have one single object to retrieve for each id instead of a list of child objects. We are also now making use of the query cache in the situations in which we are using &lt;tt&gt;Criteria.list&lt;/tt&gt;.

In the future, we are looking to spread the use of Spring's &lt;tt&gt;JdbcTemplate&lt;/tt&gt;, &lt;tt&gt;Select&lt;/tt&gt;, and &lt;tt&gt;Update&lt;/tt&gt; classes in conjunction with directly using ehcache or a home-grown caching solution.

&lt;span style="font-weight:bold;"&gt;Lesson Learned:&lt;/span&gt;  Make sure that you are verifying that your &lt;tt&gt;SessionFactory&lt;/tt&gt; instances are actually caching your cacheable entities as early in the project as you can. If you can, make sure that your integration tests are asserting cache statistics, both in the query cache and in the entity cache.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-2318363297275948760?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/2318363297275948760/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=2318363297275948760' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2318363297275948760'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2318363297275948760'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/07/hibernate-bites.html' title='Hibernate Bites...'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-5041229564391450260</id><published>2008-07-27T20:41:00.011-04:00</published><updated>2011-10-13T14:18:42.852-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='loty'/><category scheme='http://www.blogger.com/atom/ns#' term='hello_world'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>HelloWorld in Scala with the Eclipse Plug-in</title><content type='html'>The Eclipse plug-in for Scala makes you jump through two hoops before letting you run your application from the Run... menu: &lt;ol&gt;&lt;li&gt;Your main object must extend Application.&lt;/li&gt;
&lt;li&gt;Since main is now overridden, you must use the override keyword on the method definition.&lt;/li&gt;
&lt;/ol&gt;&lt;pre class="brush:scala"&gt;package activeactive
object Main extends Application {
  override def main(args:Array[String]) {
    println("Hello World!")
  }
}
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-5041229564391450260?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/5041229564391450260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=5041229564391450260' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5041229564391450260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/5041229564391450260'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/07/helloworld-in-scala-with-eclipse-plug.html' title='HelloWorld in Scala with the Eclipse Plug-in'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-6841148002347889687.post-2149261066277723322</id><published>2008-07-27T10:49:00.008-04:00</published><updated>2010-06-30T13:44:01.497-04:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='knowing.net'/><category scheme='http://www.blogger.com/atom/ns#' term='language learning'/><category scheme='http://www.blogger.com/atom/ns#' term='learning'/><category scheme='http://www.blogger.com/atom/ns#' term='scala'/><title type='text'>Learning Scala</title><content type='html'>I attended Stuart Halloway's dynamic language shoot-out presentation at NFJS last night.  Ruby, Clojure, and Scala are the three languages in which he spent his time. Stuart claimed that each of these languages were made to run on the JVM in order to piggy-back on the penetration of the JVM in the enterprise. The choice of language you make is mostly unimportant, most of these interesting languages on the JVM provide the same general additions to Java running on the JVM.

I intend to learn Scala this year. I feel that Ruby has a lot of penetration in the software development field, but that Scala is the up-and-coming language. I believe that the concepts and idioms in the languages are common enough to allow me to easily learn Ruby next year.

My plan of attack for learning Scala:
&lt;ol&gt;&lt;li&gt;Install Eclipse 3.4.&lt;/li&gt;&lt;li&gt;Install the Scala plug-in from: &lt;a href="http://www.scala-lang.org/tools/eclipse/index.html"&gt;http://www.scala-lang.org/tools/eclipse/index.html&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Create a working hello world program.
&lt;/li&gt;&lt;li&gt;Complete the exercises from: &lt;a href="http://www.knowing.net/index.php/2006/06/16/15-exercises-to-know-a-programming-language-part-1/"&gt;http://www.knowing.net/index.php/2006/06/16/15-exercises-to-know-a-programming-language-part-1/&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Decide on a personal project for using Scala.&lt;/li&gt;&lt;li&gt;Complete the personal project.&lt;/li&gt;&lt;li&gt;Find a suitable open-source project using Scala.&lt;/li&gt;&lt;li&gt;Learn more about the project's eco-system.&lt;/li&gt;&lt;li&gt;Contribute to the project's mailing list.&lt;/li&gt;&lt;li&gt;Submit patches to the project.
&lt;/li&gt;&lt;li&gt;Decide on a work project using Scala.&lt;/li&gt;&lt;li&gt;Complete the work project.&lt;/li&gt;&lt;li&gt;Lather, rinse, repeat.
&lt;/li&gt;&lt;/ol&gt;

&lt;b&gt;EDIT:&lt;/b&gt; updated knowing.net link.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6841148002347889687-2149261066277723322?l=active-active.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://active-active.blogspot.com/feeds/2149261066277723322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=6841148002347889687&amp;postID=2149261066277723322' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2149261066277723322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/6841148002347889687/posts/default/2149261066277723322'/><link rel='alternate' type='text/html' href='http://active-active.blogspot.com/2008/07/learning-scala.html' title='Learning Scala'/><author><name>Ryan Ransford</name><uri>https://profiles.google.com/113385470546565690629</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-rXqI2w3ECfg/AAAAAAAAAAI/AAAAAAAAAC0/aI9iEGO-HUU/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry></feed>
