<?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-11388923</id><updated>2012-01-29T21:31:13.243-06:00</updated><category term='acceptance testing'/><category term='virtualization'/><category term='underscore.js'/><category term='test-driven design'/><category term='javascript'/><category term='finance'/><category term='apple'/><category term='development'/><category term='ipad'/><category term='maven'/><category term='web development'/><category term='database migrations'/><category term='os x'/><category term='tomcat'/><category term='cocoa'/><category term='c#'/><category term='objective-c'/><category term='grails'/><category term='gradle'/><category term='iphone'/><category term='agile'/><category term='mocking'/><category term='spring'/><category term='consulting'/><category term='rails'/><category term='test driven development'/><category term='.net'/><category term='eclipse'/><category term='user story'/><category term='training'/><category term='hardware'/><category term='performance tuning'/><category term='linux'/><category term='backbone.js'/><category term='agile tdd'/><category term='jQuery'/><category term='grails groovy development'/><category term='java'/><category term='refactoring'/><category term='politics'/><category term='agile &quot;unit testing&quot; tdd'/><category term='cucumber'/><category term='music'/><category term='intellij'/><category term='concurrency'/><category term='networking'/><category term='flex'/><category term='oracle'/><category term='pair programming'/><category term='jquery javascript ajax ria'/><category term='groovy'/><category term='mac'/><category term='hunting'/><category term='unit testing'/><category term='behavior-driven development'/><category term='design'/><category term='version control'/><category term='requirements'/><category term='ubuntu'/><category term='mercurial'/><category term='coffeescript'/><category term='social issues'/><category term='itunes'/><category term='nhibernate'/><category term='subversion'/><title type='text'>Bart's Blog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default?start-index=101&amp;max-results=100'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>234</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-11388923.post-5130241586169952401</id><published>2012-01-28T16:55:00.001-06:00</published><updated>2012-01-29T10:33:00.738-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><title type='text'>Understanding the power of isolated object testing</title><content type='html'>&lt;p&gt;I spent some time last night watching J.B. Rainsberger's excellent InfoQ presentation entitled &lt;a href="http://www.infoq.com/presentations/integration-tests-scam"&gt; "Integration Tests are a Scam"&lt;/a&gt;.  I've been recently contemplating why I favor unit testing (or as J.B. calls it, &lt;strong&gt;isolated object testing&lt;/strong&gt;) over integration testing and I found his presentation particularly relevant.  I highly recommend watching it.  He also has a series of blog entries that support the presentation (Parts &lt;a href="http://www.jbrains.ca/permalink/integrated-tests-are-a-scam-part-1"&gt;1&lt;/a&gt;, &lt;a href="http://www.jbrains.ca/permalink/part-2-some-hidden-costs-of-integration-tests"&gt;2&lt;/a&gt;, and &lt;a href="http://www.jbrains.ca/permalink/part-3-the-risks-associated-with-lengthy-tests"&gt;3&lt;/a&gt;).  I also recommend reading those.  They're truly gems.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;Testing to prove basic correctness&lt;/h2&gt;&lt;p&gt;I find many developers using integrated tests as a way to prove the basic correctness of the class or system under test.  J.B. &lt;a href="http://www.jbrains.ca/permalink/interlude-basic-correctness"&gt;writes&lt;/a&gt; that "While integration tests offer value in other contexts, too many programmers use them to show basic correctness, and when they do that they waste a tremendous amount of time and effort."  Integrated testing can be used within a project (I'm personally fond of acceptance testing), but integrated testing should not be used to prove basic correctness of your code.   Focused, isolated object tests (aka unit tests using test doubles) should be used for this endeavor.  If you discover behavior that a collaborator demonstrates and you have not accounted for in your isolated object tests, you should mimic this behavior in your test doubled collaborator contracts.  You want to cover as much of your code with isolated object tests.  We'll talk more about contract tests later.    &lt;br /&gt;&lt;br /&gt;J.B. mentions using an integrated test to learn about how a collaborator might support its contract, but that this integrated test is not included in the basic correctness test suite.  I'm wondering if there isn't some other test suite here that we could use to keep integrated tests that support our learning the runtime and external dependencies.  This test suite would be run periodically, but is not part of the whole continuous integration process of building a software system.  Need to noodle on this more.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;Isolated object testing&lt;/h2&gt;&lt;p&gt;J.B. states in his aforementioned presentation that he does not use the term "unit testing" and instead favors a more focused term of "isolated object testing".  He makes a point to call out the &lt;em&gt;isolated&lt;/em&gt; word; these tests isolate the class under test by using &lt;em&gt;test doubles&lt;/em&gt; to stub or mock the collaborators of the class under test.  These tests focus on a single object and a singular behavior.  Any collaborations are realized using test doubles.&lt;br /&gt;&lt;br /&gt;I tend to agree that the phrase "unit testing" is a weak phrase describing the type of testing that we use to drive design of a single class and a single method.  These tests focus on the responsibility of a single method of a single class.  These tests also help you focus on understanding the contracts of collaboration between this class under test and its collaborators.  This is really where the design part of the equation comes in.  Classes that are hard to test are screaming out that the design is wrong.  The tests are saying you have too much responsibility in the class under test or there are too many collaborators.  Using your fast isolated object tests, you can engage in a reactive design activity, moving responsibilities out of the class under test, create new collaborators, and other design changes to make .&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;The collaboration contract&lt;/h2&gt;&lt;p&gt;J.B. rightfully makes a big deal about contracts (&lt;em&gt;aka&lt;/em&gt; interfaces) to explicitly specify collaboration protocols between objects.  He mentions that in Domain-Driven Design, popularized by the Eric Evans book of the same name, three concepts can be used to express a domain-driven model:  Values, Entities, and Services.  All Services should have contracts and those contracts manifest themselves as interfaces.  By specifying interfaces, we explicitly declare the protocol supported by each interface implementation.  Constraining ourselves to interface types when specifying collaborations results in looser coupled systems, which is considered a "Good Thing".  When engaging in isolated object testing, J.B. details the concept of collaboration tests and the closely associated contract tests.  This concept of collaboration tests and contract tests is something new to me and is a big reason the presentation was so valuable in my eyes.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h2&gt;Collaboration tests and contract tests&lt;/h2&gt;&lt;p&gt;After watching the presentation, I seem to be doing a pretty good job of using collaboration tests, but I'm not making the association to contract tests.  &lt;strong&gt;Collaboration tests&lt;/strong&gt; prove that the client interacts with its collaborators correctly; the client sends the correct messages and message arguments to the collaborator and appropriately handles all outputs from the collaborator.  This is traditionally what I have used mock objects for and that seems to be what J.B. is arguing one should do for collaboration testing.  &lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Contract testing&lt;/strong&gt;, on the other hand, deals with testing that an interface implementation accurately respects the interface it is implementing.  Does the implementor support the contract it declares to support?   I haven't typically written these types of tests, but I'm going to start.  Interestingly, I don't see a lot of this sort of testing &lt;em&gt;in the wild&lt;/em&gt;.  The part I really dig about contract tests as Rainsberger explains them is that they can be reused across interface implementations.  He uses the List interface and two of its implementations, ArrayList and LinkedList, and details how to use implementation inheritance in the tests to DRY up your contract tests.  &lt;br /&gt;&lt;br /&gt;It really gets interesting when he declares that for every collaboration test that implies that a test double behavior, there better be a corresponding contract test that demonstrates that the interface implementation(s) actually does support that behavior.  Same goes for values returned: if a test double returns a value in a collaboration test, there should be a contract test that demonstrates that the real implementation(s) does actually return that value.  This is where I think selective, &lt;em&gt;integrated&lt;/em&gt; learning tests can help you discover how your classes on the edges of a system may act when integrated to real external dependencies.  But again, those integrated tests are not providing basic code correctness semantics.  They're in your project to help you learn, but are not part of the isolated object tests suite.  Don't lump them with your isolated tests and don't run them as part of your code/update repos/run tests/commit cadence.  This learning test suite should be run periodically during the day, but not part of the CI build process.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2&gt;The death spiral of integrated testing for proving basic code correctness&lt;/h2&gt;&lt;p&gt;&lt;br /&gt;Both Rainsberger's tutorial presentation and his blog postings go into great detail to the fallacy of using integrated testing to prove code correctness.  I won't rehash what he has to say about it.  My conclusions that I draw from his material are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Focus on isolated object tests and isolation techniques and learn how to do collaboration and contract testing.&lt;/li&gt;&lt;li&gt;If you need to learn, by all means, write an integrated test.  If you need to reproduce a defect, initially write it as an integrated test.  However, in all cases, take what you have learned and replicate that in your isolated object test suite.  Replicate the behavior you discovered in the integration test(s) with test doubles.  This will ensure that your isolated object tests stay true to the behavior of the integrated system.&lt;/li&gt;&lt;li&gt;Don't get sucked into the downward death spiral of using integrated testing to guide your test-driven design efforts.  It will only cause you pain.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;br /&gt;J.B.'s series on Integrated Tests are a Scam can be found &lt;a href="http://www.jbrains.ca/series/integrated-tests-are-a-scam"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5130241586169952401?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5130241586169952401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2012/01/understanding-power-of-isolated-object.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5130241586169952401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5130241586169952401'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2012/01/understanding-power-of-isolated-object.html' title='Understanding the power of isolated object testing'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5129996825879818241</id><published>2011-11-18T12:21:00.001-06:00</published><updated>2011-11-18T13:39:32.983-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Spring Security Grails plugin 1.2.4 and transparent password encoding in the User domain object</title><content type='html'>Just spent some significant time today integrating Spring Security Grails plugin 1.2.4.  It should have been a quick integration but I got stuck on some new functionality that has been added to the generated User domain object that this plugin generates when using the quick start script.  You should now set the password on this domain object using the cleartext string.  Look at the User domain object (you may have it named something else, but it's the domain object that represents the user).  This domain class is now handling the encoding of the password transparently.  I copied some code from another Grails app that was doing the encoding of the password explicitly.  You should no longer do this--it will cause problems when attempting to authenticate.  Basically I was doubly encoding the password, the plugin definitely does not like that.  Here's what the plugin generates for a user domain object in 1.2.4:&lt;br /&gt;&lt;br /&gt;&lt;pre style="line-height: 100%;font-family:monospace;background-color:#ffffff; border-width:0.01mm; border-color:#000000; border-style:solid;padding:4px;font-size:14pt;"&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt; 1 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;class User {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt; 2 &lt;br /&gt; 3 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    transient springSecurityService&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt; 4 &lt;br /&gt; 5 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    String username&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt; 6 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    String password&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt; 7 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    boolean enabled&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt; 8 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    boolean accountExpired&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt; 9 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    boolean accountLocked&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;10 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    boolean passwordExpired&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;11 &lt;br /&gt;12 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    static constraints = {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;13 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        username blank: false, unique: true&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;14 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        password blank: false&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;15 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;16 &lt;br /&gt;17 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    static mapping = {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;18 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        password column: '`password`'&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;19 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;20 &lt;br /&gt;21 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    Set&amp;lt;Role&amp;gt; getAuthorities() {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;22 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        UserRole.findAllByUser(this).collect { it.role } as Set&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;23 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;24 &lt;br /&gt;25 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    def beforeInsert() {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;26 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        encodePassword()&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;27 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;28 &lt;br /&gt;29 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    def beforeUpdate() {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;30 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        if (isDirty('password')) {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;31 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;            encodePassword()&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;32 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;33 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;34 &lt;br /&gt;35 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    protected void encodePassword() {&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;36 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;        password = springSecurityService.encodePassword(password)&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;37 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;    }&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#800000;background-color:#f0f0f0;"&gt;38 &lt;/span&gt;&lt;span style="background-color:#ffffff;"&gt;}&lt;/span&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Notice that the domain object now has a springSecurityService injected into it.  There's also some GORM callbacks that will be called before the state of the domain object is saved and updated in the database.  This is where the encoding now occurs--you should not be doing the encoding explicitly yourself.&lt;br /&gt;&lt;br /&gt;Lesson learned!&lt;br /&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5129996825879818241?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5129996825879818241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/11/just-spent-some-significant-time-today.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5129996825879818241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5129996825879818241'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/11/just-spent-some-significant-time-today.html' title='Spring Security Grails plugin 1.2.4 and transparent password encoding in the User domain object'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2869065883304309181</id><published>2011-10-13T00:49:00.001-05:00</published><updated>2011-10-13T00:49:50.805-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='underscore.js'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails GSPs consume Underscore.js ERB-style interpolation delimiters</title><content type='html'>If you are planning to do any work with Grails and Underscore.js (or Backbone.js) and you have view templates maintained in Groovy Server Pages (GSP) with Underscore.js ERB-style interpolation markup, watch out!  GSP will eat up the Underscore.js interpolation markup (&lt;code&gt;&amp;lt;%= %&amp;gt;&lt;/code&gt;) before Underscore ever gets a chance to use it.  I assume evaluations would also be consumed by GSP.  Took me a while to figure this out, so I thought I'd raise it up as a concern.  &lt;a href="http://documentcloud.github.com/underscore/#template"&gt;Underscore.js&lt;/a&gt; does give you a way to change the delimiters using regexes.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2869065883304309181?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2869065883304309181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/10/grails-gsps-consume-underscorejs-erb.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2869065883304309181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2869065883304309181'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/10/grails-gsps-consume-underscorejs-erb.html' title='Grails GSPs consume Underscore.js ERB-style interpolation delimiters'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2104955730416368340</id><published>2011-10-12T14:39:00.001-05:00</published><updated>2011-10-12T15:14:42.446-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='backbone.js'/><category scheme='http://www.blogger.com/atom/ns#' term='coffeescript'/><category scheme='http://www.blogger.com/atom/ns#' term='jQuery'/><title type='text'>Rationale for CoffeeScript's 'Fat Arrow' syntax</title><content type='html'>I gave a CoffeeScript presentation last night at our local Groovy Users of Minnesota meet up.  One of the questions that came up last night had to do with CoffeeScript's fat arrow (=&gt;) syntax, which will both define a new function and bind the new function to the current value of &lt;strong&gt;this&lt;/strong&gt;.  This is super helpful for callback-based libraries, such as jQuery.  &lt;br /&gt;&lt;br /&gt;I was building a Backbone.View today (in JavaScript) and had to deal with &lt;strong&gt;this&lt;/strong&gt; binding.  In my JavaScript, I wanted to call fadeOut on the view's &lt;strong&gt;el&lt;/strong&gt; property (which happens to be a jQuery wrapped element).  Without using the jQuery proxy method to bind &lt;strong&gt;this&lt;/strong&gt; appropriately, my statement of 'this.el.fadeOut();' will not work.  The &lt;strong&gt;this&lt;/strong&gt; reference is no longer the view at the point I'm using it in the anonymous function; the context for &lt;strong&gt;this&lt;/strong&gt; has changed within the anonymous function declaration.  The correct JavaScript code is below.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var MyView = Backbone.View.extend({&lt;br /&gt;&lt;br /&gt;    initialize: function() {&lt;br /&gt;        this.template = _.template($('#my-template').html(), this.model.toJSON());&lt;br /&gt;        this.render();&lt;br /&gt;    },&lt;br /&gt;&lt;br /&gt;    render: function() {&lt;br /&gt;        this.el.html(this.template);&lt;br /&gt;        return this;&lt;br /&gt;    },&lt;br /&gt;&lt;br /&gt;    events: {&lt;br /&gt;        "click button#doSomethingButton": "doSomething",&lt;br /&gt;    },&lt;br /&gt;&lt;br /&gt;    doSomething: function(e) {&lt;br /&gt;        this.model.set({someValue: $('#someValueTextField').val()});&lt;br /&gt;        var promise = this.model.doSomethingOnModel();&lt;br /&gt;        promise.done(&lt;strong&gt;$.proxy(function() {&lt;br /&gt;            this.el.fadeOut();&lt;br /&gt;        }, this)&lt;/strong&gt;).fail(function() {&lt;br /&gt;            alert('Failed to check sequence uniqueness.');&lt;br /&gt;        });&lt;br /&gt;    }                                               &lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So how does this relate to CoffeeScript?  Well, the fat arrow operator is performing the proxying of the 'this' reference for you.  If I wrote the above in CoffeeScript, I could write the &lt;strong&gt;done&lt;/strong&gt; callback as:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;…&lt;br /&gt;promise.done =&gt; @el.fadeOut()&lt;br /&gt;…&lt;br /&gt;&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Chaining the done and the fail callbacks would necessitate the use of parentheses, but still very succinct.  Score one for CoffeeScript!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2104955730416368340?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2104955730416368340/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/10/rationale-for-coffeescript-arrow-syntax.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2104955730416368340'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2104955730416368340'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/10/rationale-for-coffeescript-arrow-syntax.html' title='Rationale for CoffeeScript&amp;#39;s &amp;#39;Fat Arrow&amp;#39; syntax'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-573914464035877997</id><published>2011-10-05T12:22:00.001-05:00</published><updated>2011-10-05T12:22:35.684-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Using JDBC URLs containing LDAP URI to connect to Oracle databases within Grails</title><content type='html'>&lt;p&gt;I'm working on a Grails application that needs to connect to a Oracle database using a LDAP context.  The URL format is something like the following:&lt;/p&gt;&lt;pre&gt;jdbc:oracle:thin:@ldap://tns.mycompany.com:389/marketing,cn=OracleContext,dc=com,dc=marketing&lt;/pre&gt;&lt;p&gt;I'm also not using the Grails DataSource.groovy configuration for this.  I'm managing a separate DataSource in the resources.groovy using Spring DSL.  I'm using the org.springframework.jdbc.datasource.DriverManagerDataSource.  I have not tried this with the standard DataSource.groovy stuff.  When I first tried using this, I would get an exception with the following text: "javax.naming.NotContextException Not an instance of DirContext".  There seems to be a bug with the Spring LDAP and the SimpleNamingContextBuilder class.  Basically the SimpleNamingContextBuilder returns a Context implementation, not a DirContext implementation.  You can work around this in Grails by adding the following to the Config.groovy file:&lt;/p&gt;&lt;pre&gt;grails.naming.entries = null&lt;/pre&gt;&lt;p&gt;Problem solved.  The DataSource now bootstraps correctly and I can go on my merry way.  Kudos to Luke Daley for bringing this to my attention.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-573914464035877997?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/573914464035877997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/10/using-jdbc-urls-containing-ldap-uri-to.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/573914464035877997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/573914464035877997'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/10/using-jdbc-urls-containing-ldap-uri-to.html' title='Using JDBC URLs containing LDAP URI to connect to Oracle databases within Grails'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7085019765215049300</id><published>2011-10-03T23:53:00.001-05:00</published><updated>2011-10-03T23:55:22.213-05:00</updated><title type='text'>Hiking around in Big Woods State Parks</title><content type='html'>Some photos from our family hike through Big Woods State Park near Nerstrand, MN.  Beautiful fall colors.  Not quite peak in this area, but we'll take it.  Awesome weather.&lt;br /&gt;&lt;br /&gt;&lt;table style="width:194px;"&gt;&lt;tr&gt;&lt;td align="center" style="height:194px;background:url(https://picasaweb.google.com/s/c/transparent_album_background.gif) no-repeat left"&gt;&lt;a href="https://picasaweb.google.com/chris.bartling/BigWoodsStatePark?authuser=0&amp;authkey=Gv1sRgCJ-vsP7hyau8zAE&amp;feat=embedwebsite"&gt;&lt;img src="https://lh3.googleusercontent.com/-MMAxlnaTywM/ToqO0zuiknE/AAAAAAABbCk/bBGZHuStO44/s160-c/BigWoodsStatePark.jpg" width="160" height="160" style="margin:1px 0 0 4px;"&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="text-align:center;font-family:arial,sans-serif;font-size:11px"&gt;&lt;a href="https://picasaweb.google.com/chris.bartling/BigWoodsStatePark?authuser=0&amp;authkey=Gv1sRgCJ-vsP7hyau8zAE&amp;feat=embedwebsite" style="color:#4D4D4D;font-weight:bold;text-decoration:none;"&gt;Big Woods State Park&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7085019765215049300?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7085019765215049300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/10/hiking-around-in-big-woods-state-parks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7085019765215049300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7085019765215049300'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/10/hiking-around-in-big-woods-state-parks.html' title='Hiking around in Big Woods State Parks'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='https://lh3.googleusercontent.com/-MMAxlnaTywM/ToqO0zuiknE/AAAAAAABbCk/bBGZHuStO44/s72-c/BigWoodsStatePark.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1990992308942239563</id><published>2011-09-07T22:18:00.001-05:00</published><updated>2011-09-07T22:18:59.658-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='coffeescript'/><title type='text'>CoffeeScript presentations</title><content type='html'>&lt;p&gt;I did the first CoffeeScript presentation this past August to the Ruby Users of Minnesota (RUM) group and it looks like I'll be doing a second take on the presentation to the Groovy Users of Minnesota (GUM) here in October.  If you're interested in the presentation and the examples, you can find them &lt;a href="https://bitbucket.org/cebartling/coffeescript-stuff"&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1990992308942239563?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1990992308942239563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/09/coffeescript-presentations.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1990992308942239563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1990992308942239563'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/09/coffeescript-presentations.html' title='CoffeeScript presentations'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6337857449488847557</id><published>2011-09-06T22:49:00.001-05:00</published><updated>2011-09-06T22:52:18.367-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='performance tuning'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Tracing and profiling SQL in Grails using log4jdbc</title><content type='html'>&lt;p&gt;I spent some time today tracing and profiling SQL in one of the Grails applications that I support.  I was looking around for proxy JDBC driver and happened on &lt;a href="http://code.google.com/p/log4jdbc/"&gt;log4jdbc&lt;/a&gt;.  It's similar to p6spy, but it seems to be actively developed and supported.  Downloaded the driver, dropped it in my lib directory, and changed the logging and datasource configurations a bit in Grails and I was up and running.  Very handy.  I made copious use of the SQL timings profiling today.  There are many other options for tracing and profile with this tool.  Here are my changes to Config.groovy for enabling SQL timings to all SQL statements:&lt;/p&gt;&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;Config.groovy change to enable logging of SQL information from log4jdbc:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family: monospace; white-space: pre;"&gt;log4j = { &lt;/span&gt;&lt;span style="font-family: monospace; white-space: pre;"&gt;&lt;br /&gt; info 'org.codehaus.groovy.grails.web.servlet', &lt;/span&gt;&lt;span style="font-family: monospace; white-space: pre;"&gt;&lt;br /&gt; ...&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: monospace; white-space: pre;"&gt; 'grails.app',&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: monospace; white-space: pre;"&gt; 'jdbc.sqltiming'&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: monospace; white-space: pre;"&gt;} &lt;/span&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="text-decoration: underline;"&gt;DataSource.groovy changes to enable log4jdbc:&lt;/span&gt;&lt;/p&gt;&lt;pre&gt;development {       &lt;br /&gt;    dataSource {&lt;br /&gt;        driverClassName = "net.sf.log4jdbc.DriverSpy"&lt;br /&gt;        url = "jdbc:log4jdbc:mysql://localhost/mydb-DEV?useUnicode=true&amp;amp;characterEncoding=UTF-8&amp;amp;useCursorFetch=true&amp;amp;autoReconnect=true"&lt;br /&gt;    }   &lt;br /&gt;}&lt;/pre&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt;Can't say enough good things about this tool.  Really helped me zero in on some queries that were performing poorly with large data sets.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6337857449488847557?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6337857449488847557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/09/tracing-and-profiling-sql-in-grails.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6337857449488847557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6337857449488847557'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/09/tracing-and-profiling-sql-in-grails.html' title='Tracing and profiling SQL in Grails using log4jdbc'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1259552270291693300</id><published>2011-08-24T21:26:00.001-05:00</published><updated>2011-08-24T21:26:25.459-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='concurrency'/><title type='text'>Identifying producer/consumer scenarios in the wild</title><content type='html'>&lt;p&gt;I've been working on a data import process the past couple of days, trying to solve some memory issues (OOMEs).  Essential we have a reader (the producer) and a writer (the consumer).  The writer part of this scenario operates much slower than the reader part.  The reader part is implemented as an iterator, so it only produces enough work for the writer to consume.  As this design evolved over time, parallel execution of the writer was added, in an effort to speed up the overall writing process.  The coordination of the parallelization is an ExecutorService implementation.  With this executor service now in place, the iteration of the reader can operate independently of the writer.  Thus, the consumer now starts creating lots of tasks that are then submitted to the executor service, where they queue up.  The executor service is not bounded, so it just keeps accepting tasks.  This wouldn't be a problem if the number of tasks were small and the memory footprint of those tasks was low, but that is not our situation.  Thus, we keep blowing out our Java VM process with OOMEs.  We're in the process of fixing this issue, using a bounded concurrent collection to handle the buffering of items between the reader and the executor service and ultimately the writer.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1259552270291693300?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1259552270291693300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/08/identifying-producerconsumer-scenarios.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1259552270291693300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1259552270291693300'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/08/identifying-producerconsumer-scenarios.html' title='Identifying producer/consumer scenarios in the wild'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1613057333587649162</id><published>2011-08-24T21:00:00.001-05:00</published><updated>2011-08-24T21:00:55.368-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>In support of Groovy's dynamic method dispatch</title><content type='html'>&lt;p&gt;Came across a design issue today where we really could have used Groovy's dynamic dispatch and multi-method support to invoke the proper method based on the interrogation of the runtime type of an object instance passed as a parameter to the method.  This &lt;a href="http://mrhaki.blogspot.com/2009/09/groovy-goodness-multimethods-or.html"&gt;blog posting by MrHaki&lt;/a&gt; gives a great description of how Groovy solves this problem without the need of a double dispatch pattern implementation.  We're writing our code in Java, so we don't get the Groovy goodness of dynamic method dispatch and multi-methods.  We resorted to a double dispatch implementation to solve our problem.  We &lt;strong&gt;&lt;em&gt;did not&lt;/em&gt;&lt;/strong&gt; use the instanceof operator and a whole bunch of conditionals.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1613057333587649162?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1613057333587649162/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/08/in-support-of-groovy-dynamic-method.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1613057333587649162'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1613057333587649162'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/08/in-support-of-groovy-dynamic-method.html' title='In support of Groovy&amp;#39;s dynamic method dispatch'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7740985291171431315</id><published>2011-08-07T22:27:00.000-05:00</published><updated>2011-08-07T22:27:18.404-05:00</updated><title type='text'>Book review: Clean Coder</title><content type='html'>&lt;a href="http://www.goodreads.com/book/show/11486819-clean-coder-the" style="float: left; padding-right: 20px"&gt;&lt;img alt="Clean Coder, The: A Code of Conduct for Professional Programmers" border="0" src="http://ecx.images-amazon.com/images/I/51BSQqef%2B6L._SX106_.jpg" /&gt;&lt;/a&gt;&lt;a href="http://www.goodreads.com/book/show/11486819-clean-coder-the"&gt;Clean Coder, The: A Code of Conduct for Professional Programmers&lt;/a&gt; by &lt;a href="http://www.goodreads.com/author/show/45372.Robert_C_Martin"&gt;Robert C. Martin&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;My rating: &lt;a href="http://www.goodreads.com/review/show/195891151"&gt;3 of 5 stars&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Decent follow-up to Clean Code.  Much of the book has been talked about in other avenues.  The professional attitude discussion was decent, but mostly common sense.  I liked the book, but have seen the content before.  Nothing really new here.  Definitely meant more for new developers and would wholeheartedly recommend it for that group of people.&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;&lt;a href="http://www.goodreads.com/review/list/5381802-christopher-bartling"&gt;View all my reviews&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7740985291171431315?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7740985291171431315/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/08/book-review-clean-coder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7740985291171431315'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7740985291171431315'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/08/book-review-clean-coder.html' title='Book review: Clean Coder'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3846600161062361483</id><published>2011-08-07T22:21:00.000-05:00</published><updated>2011-08-07T22:21:04.166-05:00</updated><title type='text'>Book review: The Great Derangement</title><content type='html'>&lt;a href="http://www.goodreads.com/book/show/1948003.The_Great_Derangement" style="float: left; padding-right: 20px;"&gt;&lt;img alt="The Great Derangement: A Terrifying True Story of War, Politics, and Religion at the Twilight of the American Empire" border="0" src="http://photo.goodreads.com/books/1266934202m/1948003.jpg" /&gt;&lt;/a&gt;&lt;a href="http://www.goodreads.com/book/show/1948003.The_Great_Derangement"&gt;The Great Derangement: A Terrifying True Story of War, Politics, and Religion at the Twilight of the American Empire&lt;/a&gt; by &lt;a href="http://www.goodreads.com/author/show/34394.Matt_Taibbi"&gt;Matt Taibbi&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;My rating: &lt;a href="http://www.goodreads.com/review/show/195888210"&gt;3 of 5 stars&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Not nearly as good at Griftopia, also by Taibbi.  Kind of wanders and there doesn't seem to be any real plot to this book.  Kind of wonder if Matt was still on drugs when he wrote this thing.  The religion parts were semi-interesting, the political insights were boring.  Can't recommend this.  Some good parts, but the whole doesn't make for a good read.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.goodreads.com/review/list/5381802-christopher-bartling"&gt;View all my reviews&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3846600161062361483?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3846600161062361483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/08/book-review-great-derangement.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3846600161062361483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3846600161062361483'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/08/book-review-great-derangement.html' title='Book review: The Great Derangement'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-8005705719499305673</id><published>2011-07-25T16:19:00.001-05:00</published><updated>2011-07-25T16:19:18.598-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gradle'/><title type='text'>Controlling transitive dependency resolution in Gradle</title><content type='html'>&lt;p&gt;Just hit this so I thought I would write up a quick entry.  I'm trying to get Hibernate and Apache CXF to work together.  I have a Gradle build.  I ran my test suite and I am seeing issues with CGLib classes.  After a little bit of research, it seems there's an issue between the ASM library that Hibernate's CGLib uses and the one that Apache CXF uses.  Solution is to exclude cglib-2.1_3.jar and use cglib-nodep-2.1_3.jar instead.  To do this in Gradle:&lt;/p&gt;&lt;pre&gt;configurations {&lt;/pre&gt;&lt;pre&gt;   all*.exclude group: 'cglib', module: 'cglib'&lt;/pre&gt;&lt;pre&gt;   ...&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;pre&gt;&lt;br /&gt;&lt;/pre&gt;&lt;pre&gt;dependencies {&lt;/pre&gt;&lt;pre&gt;   compile group: 'cglib', name: 'cglib-nodep', version: '2.1_3'&lt;/pre&gt;&lt;pre&gt;   ...&lt;/pre&gt;&lt;pre&gt;}&lt;/pre&gt;&lt;p&gt;Adding these lines to the build.gradle file allow me to remove the cglib-2.1_3.jar dependency and instead specify the nodep version instead.  Pretty slick.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-8005705719499305673?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/8005705719499305673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/07/controlling-transitive-dependency.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8005705719499305673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8005705719499305673'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/07/controlling-transitive-dependency.html' title='Controlling transitive dependency resolution in Gradle'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7973553198729982273</id><published>2011-07-14T21:25:00.001-05:00</published><updated>2011-07-14T21:25:56.524-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Sharing a 27" Cinema Display using an Atlona AT-MDP21 KVM switch</title><content type='html'>&lt;p&gt;Quick blog post here.  Hooked up an Atlona AT-MDP21 2x1 Mini DisplayPort KVM switch to my 2009 Mac Pro and my 2010 MacBook Air.  Both run the 27" Cinema Display at its highest native resolution, 2560 x 1440.  Atlona documentation states highest resolution is 1920 x 1200.  Easy to set up and I have the Cinema Display USB in the back working between the two computers.  The only downside is the slight 1-2 second pause when switch the KVM from one computer to another.  Not a big deal.  Highly recommended.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7973553198729982273?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7973553198729982273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/07/sharing-27-cinema-display-using-atlona.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7973553198729982273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7973553198729982273'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/07/sharing-27-cinema-display-using-atlona.html' title='Sharing a 27&amp;quot; Cinema Display using an Atlona AT-MDP21 KVM switch'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2793473338484765856</id><published>2011-06-24T22:50:00.000-05:00</published><updated>2011-06-24T22:50:11.230-05:00</updated><title type='text'></title><content type='html'>&lt;a href="http://www.goodreads.com/book/show/10587014-kingpin" style="float: left; padding-right: 20px"&gt;&lt;img alt="Kingpin: How One Hacker Took Over the Billion-Dollar Cybercrime Underground" border="0" src="http://ecx.images-amazon.com/images/I/51eCAV63sBL._SX106_.jpg" /&gt;&lt;/a&gt;&lt;a href="http://www.goodreads.com/book/show/10587014-kingpin"&gt;Kingpin: How One Hacker Took Over the Billion-Dollar Cybercrime Underground&lt;/a&gt; by &lt;a href="http://www.goodreads.com/author/show/4353912.Kevin_Poulsen"&gt;Kevin Poulsen&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;My rating: &lt;a href="http://www.goodreads.com/review/show/178678186"&gt;5 of 5 stars&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Awesome non-fiction.  Author does a great job keeping the drama and action going.  I couldn't put this book down after I started reading it.  Interesting to watch Max Butler's (aka Max Vision) downward spiral into cybercrime and black hat hacking.  Very eye opening to read the details of how these talented hackers can cloak their infiltration and syphon information from computers for weeks or months.  &lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;&lt;a href="http://www.goodreads.com/review/list/5381802-christopher-bartling"&gt;View all my reviews&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2793473338484765856?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2793473338484765856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/06/kingpin-how-one-hacker-took-over.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2793473338484765856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2793473338484765856'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/06/kingpin-how-one-hacker-took-over.html' title=''/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1220981028380300656</id><published>2011-06-17T09:02:00.002-05:00</published><updated>2011-06-17T09:02:25.207-05:00</updated><title type='text'>Zero Day by Mark Russinovich</title><content type='html'>&lt;a href="http://www.goodreads.com/book/show/9763010-zero-day" style="float: left; padding-right: 20px"&gt;&lt;img alt="Zero Day" border="0" src="http://photo.goodreads.com/books/1301992716m/9763010.jpg" /&gt;&lt;/a&gt;&lt;a href="http://www.goodreads.com/book/show/9763010-zero-day"&gt;Zero Day&lt;/a&gt; by &lt;a href="http://www.goodreads.com/author/show/3075959.Mark_Russinovich"&gt;Mark Russinovich&lt;/a&gt;&lt;br/&gt;&lt;br /&gt;My rating: &lt;a href="http://www.goodreads.com/review/show/177448504"&gt;4 of 5 stars&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Pretty good cyber-thriller. I think this is Marks' first novel. Knowledgeable author. The plot is very plausible and believable. A fair amount of technical information around malware, rootkits, computer viruses. A fun read. Very quick read and I found myself not wanting to put it down, especially after I got to the second half of the book. The last third of the book is like a runaway freight train of suspense. Recommended!&lt;br /&gt;&lt;br/&gt;&lt;br/&gt;&lt;br /&gt;&lt;a href="http://www.goodreads.com/review/list/5381802-christopher-bartling"&gt;View all my reviews&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1220981028380300656?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1220981028380300656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/06/zero-day-by-mark-russinovich.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1220981028380300656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1220981028380300656'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/06/zero-day-by-mark-russinovich.html' title='Zero Day by Mark Russinovich'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7835963065025358576</id><published>2011-03-27T16:07:00.001-05:00</published><updated>2011-05-01T21:21:50.000-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails JAR dependencies with classifiers</title><content type='html'>&lt;p&gt;Quick post on specifying Grails dependencies in BuildConfig.groovy.  The recommended way to suck in JAR dependencies in Grails is to use the dependencies DSL maintained in &lt;strong&gt;BuildConfig.groovy&lt;/strong&gt;.  I had a need to bring down a dependency that has a classifier attribute on it.  Didn't really find anything definitive on how to do it, but it seemed like following a convention might do the trick.  Here's how I solved the issue:&lt;/p&gt;&lt;pre style="font-size: 14px;"&gt;&lt;span style="color: #0044fc;"&gt;repositories&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;  grailsPlugins()&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;  grailsHome()&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;  grailsCentral()&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;  mavenCentral()&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;  ebr() &lt;span style="color: #a9a9a9;"&gt;// SpringSource Enterprise Bundle Repository&lt;/span&gt;&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;}&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;&lt;span style="color: #0044fc;"&gt;dependencies&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;  runtime group:&lt;span style="color: #008d12;"&gt;'net.sf.json-lib'&lt;/span&gt;, name:&lt;span style="color: #008d12;"&gt;'json-lib'&lt;/span&gt;, version:&lt;span style="color: #008d12;"&gt;'2.4'&lt;/span&gt;, classifier:&lt;span style="color: #008d12;"&gt;'jdk15'&lt;/span&gt;&lt;/pre&gt;&lt;pre style="font-size: 14px;"&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7835963065025358576?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7835963065025358576/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/03/grails-jar-dependencies-with.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7835963065025358576'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7835963065025358576'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/03/grails-jar-dependencies-with.html' title='Grails JAR dependencies with classifiers'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1193216627369229016</id><published>2011-03-05T13:04:00.001-06:00</published><updated>2011-03-05T13:28:28.045-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='finance'/><category scheme='http://www.blogger.com/atom/ns#' term='social issues'/><category scheme='http://www.blogger.com/atom/ns#' term='politics'/><title type='text'>Griftopia by Matt Taibbi</title><content type='html'>&lt;p&gt;I recently read this book after seeing Alan Cooper had read it and stated that it was a terrifying book.  I wondered what would be so terrifying about "Bubble Machines, Vampire Squids, and the Long Con That is Breaking America".  After reading it, I wouldn't characterize it as terrifying as much as I would characterize it as infuriating.  The incompetence, greed, self-interest, and gluttony that is repeatedly portrayed in the book is extremely infuriating to me as a hardworking American citizen that pays taxes.  The book chronicles some of the most audacious power grabs this nation has ever seen, and in most instances, those power grabs are happening during the past two decades.  Taibbi chronicles why the Tea Party is chasing its own tail, lambasts Alan Greenspan as "a one-in-a-billion asshole that has made America the mess it is today", and details the mortgage, commodities, and wealth fund scams that we, American taxpayers, have had to endure the last couple of years.  The book is written in a no-holds barred fashion with a fair amount of profanity thrown in to spice up the prose. It's an entertaining read, but also very thought provoking and sheds some interesting light on the current political climate, especially around Obamacare and the health insurance industry.  Very highly recommended.&lt;/p&gt;&lt;p&gt;&lt;img title="griftopia-e1296531461300.jpg" src="http://www.openlettersmonthly.com/issue/wp-content/uploads/2011/02/griftopia-e1296531461300.jpg" border="0" alt="griftopia-e1296531461300.jpg" /&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1193216627369229016?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1193216627369229016/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/03/book-review-griftopia-by-matt-taibbi.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1193216627369229016'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1193216627369229016'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/03/book-review-griftopia-by-matt-taibbi.html' title='Griftopia by Matt Taibbi'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5724797491675417952</id><published>2011-03-04T11:25:00.002-06:00</published><updated>2011-03-04T11:26:56.885-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maven'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Groovy Remote Control plugin via Maven</title><content type='html'>&lt;p&gt;I had some issues getting the Groovy Remote Control plugin to pull down through Maven today.  The documentation that is currently in place today is not correct.  Here is the fragments of my Maven POM that enabled me to pull the plugin as a dependency:&lt;/p&gt;&lt;p&gt;&lt;script src="https://gist.github.com/855210.js?file=gistfile1.xml"&gt;&lt;/script&gt;&lt;br /&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5724797491675417952?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5724797491675417952/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/03/groovy-remote-control-plugin-via-maven.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5724797491675417952'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5724797491675417952'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/03/groovy-remote-control-plugin-via-maven.html' title='Groovy Remote Control plugin via Maven'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6854637845724744235</id><published>2011-02-27T21:21:00.001-06:00</published><updated>2011-02-27T21:21:08.576-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='requirements'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='user story'/><title type='text'>It's all about the conversations!</title><content type='html'>&lt;p&gt;More pondering as I contemplate my previous consulting gig.  This time, I'm considering requirements discovery.  Pre-agile, people would write large requirements documents, hoping to document all the requirements needed for the developers to build a system that would satisfy the customers.  Unfortunately, this view of discovering all the requirements ahead of time is awfully naive.  Things change.  Requirements go undiscovered.   Requirements that are captured are not thought out as well as we would like and when it comes time to implement the requirements in software, the requirements don't make sense or are plain wrong.  Thus, large efforts to capture all the requirements has some amount of wasted effort.  This effort focuses most of the conversations at the beginning of the project.  Conversations after the requirements document has been written and signed off is discouraged; it's viewed as evidence that there are errors in the requirements document.  There doesn't seem to be any room for learning with requirements documents.&lt;/p&gt;&lt;p&gt;Now we have agile methods and the user story.  User stories are not requirements.  They're a planning tool for the agile team.  They are a statement of value that the business would like built.  There may or may not be acceptance criteria associated with the user story, depending on where the user story is in its lifecycle.  The most important part of the user story is the conversations that need to happen to flesh the story out so the feature value can be realized in the product.  This detail seems to escape a lot of people trying to use user stories to build products.  User stories give me the freedom to have conversations with all interested parties regarding the statement of value.  I learn &lt;em&gt;just-in-time&lt;/em&gt; about the requirements as I implement the feature.  The business learns about how those requirements they communicated manifest themselves in a product.  And we both have the freedom to adjust, learning about the product along the way.&lt;/p&gt;&lt;p&gt;The above statements about user stories does not preclude one from using prepared, written documentation to feed the conversation.  My previous gig, we have a lot of federal government documentation regarding reporting and calculation requirements.  These requirements are set in stone by the government.  Yet, there needs to be conversations as to how those requirements will be accomplished across releases and sprints.  This is where the conversations come back to the forefront.&lt;/p&gt;&lt;p&gt;User stories allow me to deliver value to the business or customer in bite-size portions.  Value is delivered in small increments, thus I can deliver these more frequently and solicit feedback from the business or customer.  When I have short feedback loops in place, I can nimbly change my course if I need to.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6854637845724744235?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6854637845724744235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/02/it-all-about-conversations.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6854637845724744235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6854637845724744235'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/02/it-all-about-conversations.html' title='It&amp;#39;s all about the conversations!'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6875218894162327100</id><published>2011-02-27T21:17:00.001-06:00</published><updated>2011-02-27T21:17:30.037-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='database migrations'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Agile database modeling</title><content type='html'>&lt;p&gt;My previous project has me doing a lot of introspection lately.  One of the recurring themes that I have been noodling on has been evolving a data model using agile development techniques.  The applications being built on this project are based on the .NET platform.  The development group is currently using the Database Project template in Visual Studio 2010 but looking to support a database migration process here soon.  The VS 2010 Database Project template does an admirable job of keeping track of all the DDL for your project, but it offers nothing for refactoring your database over time and migrating a production database.  It seems like the template is meant for rebuilding the database from the ground up, thus there is no concept of database schema changes or migrations.&lt;/p&gt;&lt;p&gt;The database will evolve over time.  Development groups should learn how to build their data model incrementally over many iterations and releases.  Database migration tools can be very helpful in your quest to evolving your database over time.  Tools like &lt;a href="http://www.liquibase.org/"&gt;Liquibase&lt;/a&gt; and &lt;a href="http://guides.rubyonrails.org/migrations.html"&gt;Rails migrations&lt;/a&gt; are very good at supporting this sort of development behavior.  There are tools on the .NET platform that do this sort of thing.&lt;/p&gt;&lt;p&gt;Another thing that has caused quite a bit of headache is the desire of the data group (data architects and DBAs) to try to get out ahead of the developers some ways and build out much more of the data model than the developers need for the current sprint.  We have found that when your data modeling efforts are not driven from user stories that they tend not to align with the efforts of completing the user stories.   Thus developers and data people end up conversing about data model changes that could have been avoided in the first place by waiting for the right time to initiate changes to the data model.  My advice for building an operational data store that one or more applications will be developed on top of: don't try to develop the entire data model upfront.  You will inevitably end up changing the data model to support requirements as they change (hopefully you're using stories to guide your development).  Typically your application developers will have constraints and needs that need to be accommodated in the data model.  As the data person, you need to be communicating with them and working from user stories.  Ideally, the data people are part of the project team and are dedicated to the agile process.  We really did not have that on this project.  I think that caused issues and slowed us down a bit.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.agiledata.org/essays/databaseRefactoring.html"&gt;Refactoring Databases&lt;/a&gt; should be required reading for development groups.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6875218894162327100?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6875218894162327100/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/02/agile-database-modeling.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6875218894162327100'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6875218894162327100'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/02/agile-database-modeling.html' title='Agile database modeling'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2796194860222980359</id><published>2011-02-27T20:55:00.001-06:00</published><updated>2011-02-27T20:55:17.886-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance testing'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><title type='text'>Great experience with Acceptance Test Driven Development (ATDD) and SpecFlow</title><content type='html'>&lt;p&gt;I recently left a .NET gig where I was brought in to bring agile and craftsmanship behaviors to the entire project team.  One of the more successful endeavors was the acceptance test-driven development (ATDD) effort.  I was lucky enough to bring Joel Levandoski (&lt;a class="user-profile-link" style="color: #2fc2ef !important; text-decoration: underline; cursor: pointer; padding: 0px; margin: 0px; border: 0px initial initial;" title="Joel Levandoski" href="http://twitter.com/#!/joellevandoski"&gt;&lt;strong style="font-weight: bold; padding: 0px; margin: 0px; border: 0px initial initial;"&gt;joellevandoski&lt;/strong&gt;&lt;/a&gt;) on board to head up this effort.  Joel is an awesome developer and on this project, he was running as the lead QA resource, bringing automated testing to the group.  The QA group traditionally had not done automated testing, so we had a bit of learning to do.  Joel did a fabulous job of learning a new tool (SpecFlow for .NET) and training other QA people on its use.&lt;/p&gt;&lt;p&gt;Our QA developers created acceptance tests from the acceptance criteria specified in the user stories.  We spent a lot of time evolving our user stories, but by the end of the first six months, I think we finally have a format that we like and that will facilitate communication between all the participants on the project.  Our acceptance tests were written using &lt;a href="http://www.specflow.org/"&gt;SpecFlow&lt;/a&gt;, a Gherkin-compliant BDD testing framework for the .NET platform.  SpecFlow is an amazing tool and its integration with Visual Studio is pretty nice.  Having this integration with the IDE is a great selling point to using SpecFlow; SpecFlow specifications can be translated to normal xUnit tests using the VS integration.  SpecFlow generates a stub unit test driver class for every feature file and it's compliant with several unit testing frameworks.  This SpecFlow feature allows it to run directly from the various GUI unit test runners.  This is a nice convenience.  We used the MSTest generation strategy baked into SpecFlow.&lt;/p&gt;&lt;p&gt;Initially we used &lt;a href="http://watin.sourceforge.net/"&gt;WatiN&lt;/a&gt; for testing our ASP.NET MVC app, but later migrated to an application suite of web and Silverlight applications.  Therefore, we gravitated to using &lt;a href="http://www.telerik.com/products/web-testing-tools/webaii-framework-features.aspx"&gt;WebAii from Telerik&lt;/a&gt;.  This tool worked well for testing both web and Silverlight environments.&lt;/p&gt;&lt;p&gt;Our specifications were very focused on actions and outcomes to those actions.  We took a concerted effort to push the details of the steps into the fixture code.  Keep the specifications light and to the point.  We followed the &lt;a href="http://www.concordion.org/Technique.html"&gt;technique advice from Concordion.org&lt;/a&gt;.  Doing this really made our specifications communicate the intent of "what" was being tested, not the "how" the test worked.&lt;/p&gt;&lt;p&gt;Many thanks to Joel Levandoski and Tim Anderson for driving the ATDD efforts forward and making this effort a reality.  There were numerous times that I would find Joel writing specifications during sprint planning as the rest of the group was reviewing user stories and associated acceptance criteria for the upcoming sprint.  This is incredibly powerful to come out of sprint planning with a good portion of your acceptance tests executable (all fail as inconclusive).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2796194860222980359?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2796194860222980359/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/02/great-experience-with-acceptance-test.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2796194860222980359'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2796194860222980359'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/02/great-experience-with-acceptance-test.html' title='Great experience with Acceptance Test Driven Development (ATDD) and SpecFlow'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3004724513991800789</id><published>2011-01-12T22:55:00.001-06:00</published><updated>2011-01-15T11:49:35.219-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='user story'/><title type='text'>Tweaking your user story mapping efforts</title><content type='html'>&lt;p&gt;I had a great day leading a business group through a user story mapping session at my current client.  Story mapping is technique that Jeff Patton has popularized for &lt;a href="http://www.agileproductdesign.com/blog/the_new_backlog.html"&gt;giving your product backlog some structure&lt;/a&gt;.  I've done a couple of these user story mapping sessions with pretty good success.  Today, we changed up a couple of things with the session and saw some good results.  Thought it might be worth a blog posting.&lt;/p&gt;&lt;p&gt;First, identify your high-level activities and lay them out across a wall.  We used large Post-It sheets and attached one high-level activity to each sheet.  By doing this, we could move activities and associated tasks around the room, allowing us to rearrange priorities easily.&lt;/p&gt;&lt;p&gt;Next, give the customer/business group five (5) minutes to come up with as many tasks as they can think of for each high-level activity.  Time-boxing the effort keeps you on a regular cadence.  Post the task Post-Its on the large Post-It sheets in no particular order.  Move from one activity to the next, spending the same amount of time on each.  Don't worry about duplicate tasks or the prioritization of the tasks.  You'll come back to these, culling and prioritizing the tasks associated with each activity.&lt;/p&gt;&lt;p&gt;After harvesting the tasks for each activity, go back to each activity and cull out the duplicate tasks and prioritize the tasks according to Jeff Patton's story mapping technique.  We spent 20 minutes on each activity and were able to get a backbone of tasks defined, with other non-core tasks associated with the activity.&lt;/p&gt;&lt;p&gt;Another technique for ensuring that high priority tasks percolate to the &lt;em&gt;walking skeleton&lt;/em&gt; row of the story map is to give the business people sticky dots to place on the tasks that they think are core.  We had our business folks put their initials on the sticky dots so we knew who voted up the task.  The dots stand out on the story map and the business really liked using this prioritization technique.  Having the initials on the dots gives you added information regarding who is connected to what stories.&lt;/p&gt;&lt;p&gt;Now that the tasks are prioritized, you can walk your story mapping and talk about it with your customers/business people.  Walking the story map ensures that the ordering of the activities and tasks makes sense and nothing has been missed.  By tweaking our story mapping session today, we were able to keep everyone in the business group engaged and the conversations flowing.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3004724513991800789?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3004724513991800789/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/01/tweaking-your-user-story-mapping.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3004724513991800789'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3004724513991800789'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/01/tweaking-your-user-story-mapping.html' title='Tweaking your user story mapping efforts'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2456924573349176193</id><published>2011-01-11T19:40:00.001-06:00</published><updated>2011-01-11T19:40:56.472-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='rails'/><title type='text'>PeepCode has new Rails 3 videos up</title><content type='html'>&lt;p&gt;If you're interested in getting up and running with Rails 3, I recommend PeepCode's videos.&lt;/p&gt;&lt;p&gt;&lt;a href="https://peepcode.com/pages/rails-3-screencasts"&gt;https://peepcode.com/pages/rails-3-screencasts&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2456924573349176193?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2456924573349176193/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/01/peepcode-has-new-rails-3-videos-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2456924573349176193'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2456924573349176193'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/01/peepcode-has-new-rails-3-videos-up.html' title='PeepCode has new Rails 3 videos up'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5098493075738604550</id><published>2011-01-11T19:39:00.001-06:00</published><updated>2011-01-11T20:43:45.242-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='nhibernate'/><category scheme='http://www.blogger.com/atom/ns#' term='c#'/><title type='text'>Testing as a learning sandbox</title><content type='html'>&lt;p&gt;I've been spending some quality time with NHibernate 3.0.  Last night I got stuck on an issue with the Criteria query where a collection passed to a constructor was null and the framework was complaining.  After writing a couple of integration tests that tested various parts of my domain object model, I was able to determine that collection types that I was using for the many-side of relationships (ISet&amp;lt;T&amp;gt; and HashSet&amp;lt;T&amp;gt; in this case) where the inappropriate collection types to be using for my collection semantics configuration.  I'm continually amazed at how powerful testing, both unit and integration, can be.  My tests today allowed me to create a sandbox to try things and work out a misunderstanding that I had with NHibernate.  Pretty cool.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5098493075738604550?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5098493075738604550/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2011/01/testing-as-learning-sandbox.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5098493075738604550'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5098493075738604550'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2011/01/testing-as-learning-sandbox.html' title='Testing as a learning sandbox'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1633178860348475629</id><published>2010-12-31T04:07:00.001-06:00</published><updated>2011-01-01T21:31:15.670-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='consulting'/><title type='text'>Anatomy of a successful large agile project</title><content type='html'>&lt;p&gt;I recently had a conversation with a colleague of mine at a company where I’m currently consulting.  We’ve been trying to bootstrap a collection of projects using an agile development process and associated software craftsmanship behaviors.   We have had mixed success to date.  Frustrated with the progress, my colleague asked me to enumerate what I felt were the success factors on the WestlawNext project that I had recently participated on.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;I worked at Thomson Reuters from January 2008 to August 2010, during the initial releases of the WestlawNext project.  I was with the project from the beginning of its software development; the product development group had been working on the inception of the WestlawNext project for a couple of years prior.  WestlawNext was a very large project.  Hundreds of people were involved and millions of dollars were spent to build the next generation legal and regulatory research tool.  A lot was riding on this product.  It had to be a success—there was no option for failure.   The following themes are what I feel made this project a success.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h1&gt;Attitude&lt;/h1&gt;&lt;p&gt;Now that I’ve had time to ponder my WestlawNext experience from afar, I think the number one reason for its success was attitude.  This was an audacious effort to build a new legal research tool in two years time with the number of people involved using an agile software development process.&lt;/p&gt;&lt;p&gt;But from the very beginning, a “can-do” attitude was instilled in the group that we would succeed.  We were going to “knock the ball out of the park” with this product.  There was never a thought that this thing might fail.  Many concerted efforts were made to continually propagate this attitude throughout the participants of the project.  Project tee-shirts, baseball trading cards, raffles, and summer socials were utilized to promote this team spirit.  This infectious attitude allowed us to overcome obstacles that would probably derail other projects.  People were willing to take responsibility for their work and put in the effort over and above the call of duty time and time again.&lt;/p&gt;&lt;h1&gt;&lt;br /&gt;Communication&lt;/h1&gt;&lt;p&gt;Communication is one of the most important functions of a software development project.  Large projects are very susceptible to communication breakdowns as the number of people increase.  We tried to minimize these breakdowns by favoring face-to-face communication as much as possible.  We were encouraged as software developers to pair program.  Designers were encouraged to work directly with developers on styling concerns.  We were encouraged to collaborate together when tough problems arose.  No GoToMeeting.  No conference calls.  Face-to-face conversations.&lt;/p&gt;&lt;p&gt;We were extremely lucky to be able to co-locate almost everyone on the project in three areas of the Thomson Reuters facility in Eagan.  When I mean everyone, I mean business people, vice presidents, directors, testers, designers, managers, coaches, and software developers.  This is one of a few places that I have consulted that have had the luxury of co-locating people in common areas.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h1&gt;Leadership&lt;/h1&gt;&lt;p&gt;WestlawNext benefited from strong leadership that what 100% dedicated to the project.  No other obligations—they were focused solely on the development on the new product.  Our leaders were also quite familiar with agile software development process.  Some of them had come from other agile projects, both within the company and from outside.  They didn’t have to start from square one and many already knew the key behaviors of the process.  A few of them were software developers at one time (or still are). This is refreshing from a developer’s point of view.  They understand what it takes to build software; they’ve been in the trenches.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;There is one moment in particular that I am very fond of.  I was working on a tough networking issue with some .NET code that we had provided another group.  We were throwing spurious socket closed exceptions, but it didn’t happen all the time and it seemed to occur only when the server load increased.  Our senior director, one of our leaders, was helping triage the issue and participating in our root cause analysis.  This senior director had technical chops and was quite proficient at network analysis.  He rolled up his sleeves and got right in and loved being able to help solve the issue.  We did solve the issue; it turned out to be tied to a deprecated thread-local storage API in .NET.  That leader earned a ton of my respect that day.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h1&gt;Testing&lt;/h1&gt;&lt;p&gt;Testing is paramount to building a quality software product.  The WestlawNext project embraced testing like I have never seen before in my career.  We evolved our designs with unit testing.  We used integration testing to ensure that software components were wired together correctly.  Acceptance testing ensured that features did not regress in future iterations of development.  Load and performance testing was continuously run in an effort to tune the overall product.  Beta testers were allowed to play with the software well in advance of its initial release date, ensuring that it satisfied the customer.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;All of this testing allowed us to build tight feedback loops, giving us near-instantaneous data on the health of our growing and evolving product.  The suites of tests infused confidence within the project group; we knew exactly how the software performed at specific load levels.  I cannot fathom working on a software development project that does not fully embrace the aforementioned levels of testing.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;h1&gt;Conclusion&lt;/h1&gt;&lt;p&gt;In conclusion, I’m starting to realize that the WestlawNext project may have been one of those rare moments where everything came together in near perfect harmony to produce a great product.  As I have moved on from Thomson Reuters, I yearn to replicate a similar experience at my other clients.  My current engagement only reinforces the fact that every software development project takes a different path to success, and some may never make it to the end.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1633178860348475629?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1633178860348475629/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/12/anatomy-of-successful-large-agile.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1633178860348475629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1633178860348475629'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/12/anatomy-of-successful-large-agile.html' title='Anatomy of a successful large agile project'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3026735410619626688</id><published>2010-12-02T19:28:00.000-06:00</published><updated>2010-12-02T19:28:33.438-06:00</updated><title type='text'>DevJam Test Driven training December 2-3, 2010</title><content type='html'>Photos and video from today's Test Driven class at DevJam U.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://goo.gl/photos/UzRuqxNRIQ" imageanchor="1" style="clear:right;margin-bottom:1em;margin-left:1em"&gt;&lt;img border="0" src="http://lh4.ggpht.com/_RPAIJEgCpag/TPhGKyG1B4E/AAAAAAABHZo/jpT2_AcdX0g/s160-c/DevJamTestDrivenTrainingDecember232010.jpg"&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3026735410619626688?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3026735410619626688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/12/devjam-test-driven-training-december-2.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3026735410619626688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3026735410619626688'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/12/devjam-test-driven-training-december-2.html' title='DevJam Test Driven training December 2-3, 2010'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_RPAIJEgCpag/TPhGKyG1B4E/AAAAAAABHZo/jpT2_AcdX0g/s72-c/DevJamTestDrivenTrainingDecember232010.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-9066947121975582836</id><published>2010-10-31T20:27:00.001-05:00</published><updated>2010-10-31T20:27:29.874-05:00</updated><title type='text'>Kaleidoscope diff tool for Mac OS X</title><content type='html'>&lt;p&gt;Found a really interesting new diff and merge tool for the Mac: &lt;a href="http://www.kaleidoscopeapp.com/"&gt;Kaleidoscope&lt;/a&gt;.﻿  Native app, integrates with Versions, Cornerstone, and the command line.  Looks promising.&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-9066947121975582836?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/9066947121975582836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/10/kaleidoscope-diff-tool-for-mac-os-x.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/9066947121975582836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/9066947121975582836'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/10/kaleidoscope-diff-tool-for-mac-os-x.html' title='Kaleidoscope diff tool for Mac OS X'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-8951548353982188079</id><published>2010-10-31T08:04:00.001-05:00</published><updated>2010-10-31T08:04:34.377-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><title type='text'>Autofixture: A generic Test Data Builder implementation for .NET</title><content type='html'>&lt;p&gt;Just came across a Test Data Builder implementation for .NET, &lt;a href="http://autofixture.codeplex.com/"&gt;Autofixture&lt;/a&gt;.  The Test Data Builder pattern has become quite popular recently since it was mentioned in &lt;span style="text-decoration: underline;"&gt;Growing Object-Oriented Software, Guided by Tests&lt;/span&gt;.  I've used the pattern before, but I've always built the builder implementations by hand.  This implementation looks really promising.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-8951548353982188079?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/8951548353982188079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/10/autofixture-generic-test-data-builder.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8951548353982188079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8951548353982188079'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/10/autofixture-generic-test-data-builder.html' title='Autofixture: A generic Test Data Builder implementation for .NET'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1979294218925536566</id><published>2010-10-13T21:10:00.001-05:00</published><updated>2010-10-13T21:10:19.142-05:00</updated><title type='text'>Great video on what motivates us</title><content type='html'>&lt;p&gt;Great video on drive and motivation.  Love the whiteboard drawings.  Spend 10 minutes watching this video.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;﻿&lt;br /&gt;&lt;object width="640" height="385"&gt;&lt;param name="movie" value="http://www.youtube.com/v/u6XAPnuFjJc?fs=1&amp;amp;hl=en_US&amp;amp;color1=0x2b405b&amp;amp;color2=0x6b8ab6"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/u6XAPnuFjJc?fs=1&amp;amp;hl=en_US&amp;amp;color1=0x2b405b&amp;amp;color2=0x6b8ab6" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="385"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1979294218925536566?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1979294218925536566/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/10/great-video-on-what-motivates-us.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1979294218925536566'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1979294218925536566'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/10/great-video-on-what-motivates-us.html' title='Great video on what motivates us'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5293857225383900080</id><published>2010-08-31T22:11:00.001-05:00</published><updated>2010-08-31T22:11:55.026-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Loving my new Magic Trackpad</title><content type='html'>&lt;p&gt;Just received my Magic Trackpad from Apple today.  Very impressed after a bit of use with it.  Love all the different gestures that you can map to.  After using this, a mouse is going to seem awfully archaic.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5293857225383900080?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5293857225383900080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/08/loving-my-new-magic-trackpad.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5293857225383900080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5293857225383900080'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/08/loving-my-new-magic-trackpad.html' title='Loving my new Magic Trackpad'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-918378666632362041</id><published>2010-05-17T10:51:00.002-05:00</published><updated>2010-05-17T10:53:18.643-05:00</updated><title type='text'>Brief history of mock objects</title><content type='html'>A brief history of mock objects, a story told by Steve Freeman.  Good read as to the "why" of mock objects and how Hamcrest, jMock, and others came about.  &lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mockobjects.com/2009/09/brief-history-of-mock-objects.html"&gt;http://www.mockobjects.com/2009/09/brief-history-of-mock-objects.html&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-918378666632362041?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/918378666632362041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/05/brief-history-of-mock-objects.html#comment-form' title='28 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/918378666632362041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/918378666632362041'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/05/brief-history-of-mock-objects.html' title='Brief history of mock objects'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>28</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-956609583103648286</id><published>2010-05-10T00:49:00.001-05:00</published><updated>2010-05-10T00:49:32.008-05:00</updated><title type='text'>Steve Freeman on sustainable TDD</title><content type='html'>&lt;p&gt;Excellent presentation by Steve Freeman on sustainable TDD.  Lots of great tips for making your unit tests easier to comprehend and maintain.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.infoq.com/presentations/Sustainable-Test-Driven-Development"&gt;http://www.infoq.com/presentations/Sustainable-Test-Driven-Development&lt;/a&gt;﻿&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-956609583103648286?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/956609583103648286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/05/steve-freeman-on-sustainable-tdd.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/956609583103648286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/956609583103648286'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/05/steve-freeman-on-sustainable-tdd.html' title='Steve Freeman on sustainable TDD'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5072048705602003828</id><published>2010-05-09T17:10:00.001-05:00</published><updated>2010-05-09T17:13:57.309-05:00</updated><title type='text'>Practical styles of pair programming</title><content type='html'>&lt;p&gt;Excellent blog on pair programming.&lt;/p&gt;&lt;p&gt;&lt;a href="http://blog.xebia.com/2010/05/09/practical-styles-of-pair-programming/"&gt;http://blog.xebia.com/2010/05/09/practical-styles-of-pair-programming/﻿&lt;/a&gt;&lt;/p&gt;&lt;p&gt;A quote from the blog entry:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;&lt;span style="font-family: Verdana, Arial, sans-serif; font-size: 12px; line-height: 14px;"&gt;"No you're not faster on your own, you're just creating more crap for your colleagues to puzzle over and eventually delete. The code you write alone sucks. That guy that is getting on your nerves is trying to tell you (clumsily) that your code sucks, try to listen to him and you'll turn into a better programmer." ﻿&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Have you encountered one or more of these styles?  How many developers are pair programming these days?&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5072048705602003828?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5072048705602003828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/05/practical-styles-of-pair-programming.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5072048705602003828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5072048705602003828'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/05/practical-styles-of-pair-programming.html' title='Practical styles of pair programming'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-415447594379060938</id><published>2010-05-03T10:23:00.000-05:00</published><updated>2010-05-03T10:23:18.499-05:00</updated><title type='text'>Tool coming to Xcel Energy Center</title><content type='html'>Tool is coming to the Twin Cities this summer!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.xcelenergycenter.com/events/detail.jsp?month=7&amp;amp;year=2010&amp;amp;day=1&amp;amp;event_id=881"&gt;Tool concert on July 1, 2010&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tickets go on sale this Saturday.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-415447594379060938?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.xcelenergycenter.com/events/detail.jsp?month=7&amp;year=2010&amp;day=1&amp;event_id=881' title='Tool coming to Xcel Energy Center'/><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/415447594379060938/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/05/tool-coming-to-xcel-energy-center.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/415447594379060938'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/415447594379060938'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/05/tool-coming-to-xcel-energy-center.html' title='Tool coming to Xcel Energy Center'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7354149430300104997</id><published>2010-04-29T21:47:00.001-05:00</published><updated>2010-04-29T21:47:14.808-05:00</updated><title type='text'>Uninstalling Mac developer tools</title><content type='html'>If you ever need to uninstall the Mac OS X developer tools, you do it with one command:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;sudo /Developer/Library/uninstall-devtools --mode=all&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Found this advice &lt;a href="http://macdevelopertips.com/xcode/how-to-uninstall-xcode.html"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7354149430300104997?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7354149430300104997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/04/uninstalling-mac-developer-tools.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7354149430300104997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7354149430300104997'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/04/uninstalling-mac-developer-tools.html' title='Uninstalling Mac developer tools'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4091346444049624510</id><published>2010-04-26T00:56:00.001-05:00</published><updated>2010-04-26T00:56:07.122-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><title type='text'>Mac OS X key bindings</title><content type='html'>I'm trying to make my Xcode environment a bit more friendly and thus I'm investigating key bindings.  A good article that summarizes how to change key bindings system-wide.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.erasetotheleft.com/post/mac-os-x-key-bindings/"&gt;http://www.erasetotheleft.com/post/mac-os-x-key-bindings/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, this doesn't seem to work with Xcode.  My original investigation started &lt;a href="http://stackoverflow.com/questions/476953/xcode-delete-line-hot-key"&gt;here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4091346444049624510?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4091346444049624510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/04/mac-os-x-key-bindings.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4091346444049624510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4091346444049624510'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/04/mac-os-x-key-bindings.html' title='Mac OS X key bindings'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5235667631003137563</id><published>2010-04-18T20:43:00.001-05:00</published><updated>2010-04-18T20:44:29.183-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance testing'/><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Test-Driven in Groovy presentation in the bag</title><content type='html'>Joe Muraski and myself did a Test-Driven in Groovy workshop at GR8 in the US conference here in Bloomington, MN this past Friday.  If you're interested in the materials (presentation, demo app), you can get it all right &lt;a href="http://bitbucket.org/joe.muraski/grails_tdd_workshop"&gt;here&lt;/a&gt;.  The demo consists of a Java web app with lots of opportunity for refactoring, Groovy unit tests, and Cucumber (via cuke4duke) acceptance tests.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5235667631003137563?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5235667631003137563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/04/test-driven-in-groovy-presentation-in.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5235667631003137563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5235667631003137563'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/04/test-driven-in-groovy-presentation-in.html' title='Test-Driven in Groovy presentation in the bag'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-8729972079501882103</id><published>2010-04-08T07:16:00.001-05:00</published><updated>2010-04-08T07:16:22.250-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>iPhone presentation</title><content type='html'>What a great turn out for the iPhone presentation last night.  Thanks to everyone that came out.  I've updated the Google Groups page for the presentation with links to blogs and other interesting information pertaining to iPhone platform development.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://groups.google.com/group/jamsessions/web/10-04-07-iphone-os-the-next-killer-platform"&gt;http://groups.google.com/group/jamsessions/web/10-04-07-iphone-os-the-next-killer-platform&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A huge thanks goes out to my co-presenter, Bob McCune.  The SenateJam demo was a big hit.  &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-8729972079501882103?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/8729972079501882103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/04/iphone-presentation.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8729972079501882103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8729972079501882103'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/04/iphone-presentation.html' title='iPhone presentation'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-8608756170617813549</id><published>2010-04-04T00:57:00.001-05:00</published><updated>2010-04-04T00:57:37.536-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>Preparing for DevJam Jam Session iPhone presentation</title><content type='html'>I've been spending some time working on an iPhone development presentation that Bob McCune and I will co-present at DevJam's Jam Session this coming Wednesday.  I was looking at job trends at indeed.com--iPhone is #3 on the list of  top job trends.  Here's the graph:&lt;br /&gt;&lt;br /&gt;&lt;div style="width:540px"&gt;&lt;br /&gt;&lt;a href="http://www.indeed.com/jobtrends?q=iPhone&amp;relative=1&amp;relative=1" title="iPhone Job Trends"&gt;&lt;br /&gt;&lt;img width="540" height="300" src="http://www.indeed.com/trendgraph/jobgraph.png?q=iPhone&amp;relative=1" border="0" alt="iPhone Job Trends graph"&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;table width="100%" cellpadding="6" cellspacing="0" border="0" style="font-size:80%"&gt;&lt;tr&gt;&lt;br /&gt;&lt;td&gt;&lt;a href="http://www.indeed.com/jobtrends?q=iPhone&amp;relative=1&amp;relative=1"&gt;iPhone Job Trends&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;&lt;td align="right"&gt;&lt;a href="http://www.indeed.com/q-iPhone-jobs.html"&gt;iPhone jobs&lt;/a&gt;&lt;/td&gt;&lt;br /&gt;&lt;/tr&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Wow!  Talk about growth.  Looking forward to the presentation.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-8608756170617813549?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/8608756170617813549/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/04/preparing-for-devjam-jam-session-iphone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8608756170617813549'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8608756170617813549'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/04/preparing-for-devjam-jam-session-iphone.html' title='Preparing for DevJam Jam Session iPhone presentation'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7646204542646102091</id><published>2010-04-03T22:03:00.001-05:00</published><updated>2010-04-03T22:03:38.670-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><title type='text'>First impressions of the new iPad</title><content type='html'>What a beautiful device!  A little bit heavy to hold in one hand for an extended period of time.  Smudges from finger taps and swipes are more noticeable on this device, especially when reading text.  I'll have to investigate a protective film and see that makes any difference.  &lt;br /&gt;&lt;br /&gt;The processor in this device is very fast; the device is very snappy with animations, games, and video.  I can see game makers really going after this thing.  EA seems to have a couple of games out for the iPad (I tried Scrabble and Need for Speed).  Game control was very good for Need for Speed.&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7646204542646102091?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7646204542646102091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/04/first-impressions-of-new-ipad.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7646204542646102091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7646204542646102091'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/04/first-impressions-of-new-ipad.html' title='First impressions of the new iPad'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4555061753163088967</id><published>2010-04-03T20:58:00.001-05:00</published><updated>2010-04-03T20:58:56.664-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ipad'/><category scheme='http://www.blogger.com/atom/ns#' term='itunes'/><title type='text'>Transferring .epub files to your iPad</title><content type='html'>Transferring .epub files purchased outside of iTunes seems to be very easy.  Download the .epub file to your computer.  Open up iTunes and select File -&gt; Add to Library... menu item.  From the file chooser, select the .epub file that you want to transfer to your iPad.  Click Choose and the eBook file will be added to your Book Library in iTunes 9.1.  Sync as usual and the book will show up in iBooks.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4555061753163088967?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4555061753163088967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/04/transferring-epub-files-to-your-ipad.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4555061753163088967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4555061753163088967'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/04/transferring-epub-files-to-your-ipad.html' title='Transferring .epub files to your iPad'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7225149718324168388</id><published>2010-03-23T00:11:00.001-05:00</published><updated>2010-03-23T00:11:22.258-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mercurial'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>Nice Mercurial tutorial by Joel Spolsky</title><content type='html'>Joel Spolsky (of Joel on Software) wrote a very entertaining and thorough &lt;a href="http://hginit.com/"&gt;tutorial&lt;/a&gt; on Mercurial, a distributed version control system (DVCS).  The tutorial has a Subversion re-education pre-tutorial for those of us with Subversion brain damage.  Well worth a look.  Sadly, Joel will no longer be blogging, citing the need to focus on his growing software company.  His musings on software development will be missed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7225149718324168388?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7225149718324168388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/03/nice-mercurial-tutorial-by-joel-spolsky.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7225149718324168388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7225149718324168388'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/03/nice-mercurial-tutorial-by-joel-spolsky.html' title='Nice Mercurial tutorial by Joel Spolsky'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-845794343791380228</id><published>2010-03-19T06:50:00.001-05:00</published><updated>2010-03-19T06:50:40.167-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><title type='text'>Mockito's @InjectMocks annotation does reflection-based DI</title><content type='html'>I've been using @InjectMocks heavily lately since it came out in version 1.8.3 of mockito.  The javadocs for this annotation state that it uses setter injection to inject its dependencies.  Being a lazy developer, I was writing a unit test yesterday at work and forgot to write the setter methods for a couple of dependencies on the SUT that I was testing.  Lo and behold, the test passed and all mock verifications were satisfied.  Very confused, I went back to some other unit tests and their SUTs and removed the setter methods.  In all of my cases, the tests continued to pass.  A quick note to the mockito list confirms what I discovered--@InjectMocks actually is using a reflection-based DI scheme, not unlike what Spring does when you annotate collaborator fields in a Spring bean with @Autowired and @Resource.  Very cool feature, as this further reduces code noise.  &lt;a href="http://groups.google.com/group/mockito/browse_thread/thread/95454ad6087e5a36?hl=en"&gt;Here&lt;/a&gt; is the discussion on Google Groups.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-845794343791380228?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/845794343791380228/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/03/mockito-injectmocks-annotation-does.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/845794343791380228'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/845794343791380228'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/03/mockito-injectmocks-annotation-does.html' title='Mockito&amp;#39;s @InjectMocks annotation does reflection-based DI'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6161934769771234282</id><published>2010-03-16T23:42:00.001-05:00</published><updated>2010-03-16T23:42:54.346-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance testing'/><category scheme='http://www.blogger.com/atom/ns#' term='cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Cool features in Cucumber, part 1</title><content type='html'>My Cucumber adventure (via cuke4duke) continues.  I have been busy writing features and building out step definitions in Groovy.  Groovy absolutely rocks for this sort of thing.  I'm doing some more elaborate Cucumber features (at least in my novice head) and came upon this &lt;a href="http://robots.thoughtbot.com/post/189412598/five-ridiculously-awesome-cucumber-and-webrat"&gt;blog posting&lt;/a&gt;.  Very handy stuff.  More related to the Ruby version of Cucumber, but most of the concepts transfer over to cuke4duke.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6161934769771234282?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6161934769771234282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/03/cool-features-in-cucumber-part-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6161934769771234282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6161934769771234282'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/03/cool-features-in-cucumber-part-1.html' title='Cool features in Cucumber, part 1'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4592233230689127291</id><published>2010-03-13T20:54:00.001-06:00</published><updated>2010-03-13T20:54:51.356-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='acceptance testing'/><category scheme='http://www.blogger.com/atom/ns#' term='cucumber'/><category scheme='http://www.blogger.com/atom/ns#' term='behavior-driven development'/><title type='text'>PeepCode screencast: Use the Cucumber</title><content type='html'>I've been interested in acceptance testing tools recently and Cucumber has been at the top of my list.  &lt;a href="http://peepcode.com/"&gt;PeepCode&lt;/a&gt; recently released a screencast on &lt;a href="http://peepcode.com/products/cucumber"&gt;Cucumber&lt;/a&gt;.  I've viewing it right now; the screencast is excellent and a nice introduction to Cucumber.  I'm thinking of using it on a Grails web app.  The screencast is based on a Rails 2 web application, which Cucumber seems to integration seamlessly with.  Supposedly Cucumber is technology agnostic and works against any sort of web application.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4592233230689127291?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4592233230689127291/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/03/peepcode-screencast-use-cucumber.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4592233230689127291'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4592233230689127291'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/03/peepcode-screencast-use-cucumber.html' title='PeepCode screencast: Use the Cucumber'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1656969171593806601</id><published>2010-03-13T14:47:00.001-06:00</published><updated>2010-03-13T14:47:42.441-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><category scheme='http://www.blogger.com/atom/ns#' term='itunes'/><title type='text'>CoverScout for retrieving iTunes album art</title><content type='html'>I recently purchased the &lt;a href="http://www.macheist.com/"&gt;MacHeist&lt;/a&gt; nanoBundle, a collection of Mac OS X applications and utilities.  One of the utilities included in the bundle is &lt;a href="http://www.equinux.com/us/products/coverscout/index.html"&gt;CoverScout&lt;/a&gt;, a utility that will allow you to browse your iTunes library and retrieve hard to find album art.  I have a fairly large collection of music and iTunes has been pretty average in its attempts to find album art.  CoverScout will retrieve album art from many different sources and allow you to select which image to use.  The images are also rated by quality.  Very cool utility.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1656969171593806601?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1656969171593806601/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/03/coverscout-for-retrieving-itunes-album.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1656969171593806601'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1656969171593806601'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/03/coverscout-for-retrieving-itunes-album.html' title='CoverScout for retrieving iTunes album art'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3825459232508710910</id><published>2010-03-08T20:38:00.001-06:00</published><updated>2010-03-08T20:42:07.494-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><title type='text'>New annotations in mockito 1.8.3</title><content type='html'>&lt;a href="http://code.google.com/p/mockito/wiki/ReleaseNotes"&gt;Mockito 1.8.3&lt;/a&gt; was recently released and I got a chance to use it today.  There are a couple of new annotations available in this release: @Captor, @Spy, and @InjectMocks.  I was able to use @Captor and @InjectMocks today.  Even after just a few minutes with these two annotations, I'm sold.  Very cool enhancement.  I spent some quality time with EasyMock last week, and there's nothing easy with EasyMock.  Ugh!!  If you're hip to using mock objects in your Java unit testing efforts, you really should look at mockito these days.  Details about @Captor and @InjectMocks follows.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;@Captor&lt;/h2&gt;&lt;br /&gt;This annotation will automatically create typed argument captors (&lt;a href="http://mockito.googlecode.com/svn/tags/1.8.3/javadoc/org/mockito/ArgumentCaptor.html"&gt;&lt;code&gt;org.mockito.ArgumentCaptor&amp;lt;T&amp;gt;&lt;/code&gt;&lt;/a&gt;) in your unit tests.  Argument captors are essential in verifying indirect outputs to your mocked collaborators.  &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class Test{&lt;br /&gt;    @Captor ArgumentCaptor&amp;lt;Foobar&amp;gt; foobarCaptor;&lt;br /&gt;&lt;br /&gt;    @Before&lt;br /&gt;    public void init(){&lt;br /&gt;       MockitoAnnotations.init(this);&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    @Test &lt;br /&gt;    public void shouldDoSomethingUseful() {&lt;br /&gt;       //...&lt;br /&gt;       verify(mock.doStuff(foorbarCaptor.capture()));&lt;br /&gt;       Foobar capturedFoobar = foobarCaptor.getValue();&lt;br /&gt;       assertEquals("foobar", capturedFoobar.getName());&lt;br /&gt;    }&lt;br /&gt; }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;@InjectMocks&lt;/h2&gt;&lt;br /&gt;Automatically injects mocks by type using setter injection.  Constructor injection is not currently available, but if you want to provide a patch, the mockito team will gladly consider your contribution.  I'm actually more interested in reflection-based injection, similar to what Spring uses when annotating dependency fields using @Autowired.  Having your unit tests inject dependencies via reflection would help me avoid the set* methods on the implementations.  I may have to play with this a bit.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public class FooBarManagerTests  {&lt;br /&gt;&lt;br /&gt;       @Mock private FooDependency mockFoo;&lt;br /&gt;       @Mock private BarDependency mockBar;&lt;br /&gt;       @InjectMocks private FooBarManager manager = new FooBarManagerImpl();&lt;br /&gt;&lt;br /&gt;       @Before &lt;br /&gt;       public void initMocks() {&lt;br /&gt;           // Initializes all mocks and then injects those mocks into the FooManager instance.&lt;br /&gt;           MockitoAnnotations.initMocks(this);&lt;br /&gt;       }&lt;br /&gt;&lt;br /&gt;       @Test &lt;br /&gt;       public void shouldDoSomething() {&lt;br /&gt;           manager.doSomething();&lt;br /&gt;           verify(mockFoo).doSomethingToFoo(any(String.class));&lt;br /&gt;           verify(mockBar).doSomethingToBar(any(Integer.class));&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3825459232508710910?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3825459232508710910/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/03/new-annotations-in-mockito-183.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3825459232508710910'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3825459232508710910'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/03/new-annotations-in-mockito-183.html' title='New annotations in mockito 1.8.3'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5208725131338473765</id><published>2010-02-27T00:34:00.001-06:00</published><updated>2010-02-27T00:34:19.071-06:00</updated><title type='text'>Gerard Meszaros "From Concept to Product Backlog" talk</title><content type='html'>I just finished up an InfoQ presentation by Gerard Meszaros &lt;a href="http://www.infoq.com/presentations/From-Concept-to-Product-Backlog"&gt;discussing&lt;/a&gt; how to go from the conceptualization of a project to the manifestation of a product backlog.  I really enjoyed the presentation and it hits on some gray areas of current agile implementations that I have worked on.  Highly recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5208725131338473765?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5208725131338473765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/02/gerard-meszaros-concept-to-product.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5208725131338473765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5208725131338473765'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/02/gerard-meszaros-concept-to-product.html' title='Gerard Meszaros &amp;quot;From Concept to Product Backlog&amp;quot; talk'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4288110388214487414</id><published>2010-02-26T09:07:00.000-06:00</published><updated>2010-02-26T09:07:59.923-06:00</updated><title type='text'>Adopting Agility with XP, Scrum and Lean Thinking - Powered by RegOnline</title><content type='html'>David Hussman is leading an agile course next week.  Still room for participants to register.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="https://www.regonline.com/devjam-adopting-agility"&gt;Adopting Agility with XP, Scrum and Lean Thinking&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4288110388214487414?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='https://www.regonline.com/devjam-adopting-agility' title='Adopting Agility with XP, Scrum and Lean Thinking - Powered by RegOnline'/><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4288110388214487414/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/02/adopting-agility-with-xp-scrum-and-lean.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4288110388214487414'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4288110388214487414'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/02/adopting-agility-with-xp-scrum-and-lean.html' title='Adopting Agility with XP, Scrum and Lean Thinking - Powered by RegOnline'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3552348034913364068</id><published>2010-02-08T21:35:00.001-06:00</published><updated>2010-02-08T21:35:58.726-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>DevJam course offerings for February-March 2010</title><content type='html'>David Hussman recently posted the new DevJam course offerings for February and March 2010.  I'll be leading the Introduction to Groovy, Introduction to Grails and Test Driven courses.  The Test Driven course is open to Java and .NET developers (.NET examples in C#).  Detailed  information can be found at &lt;a href="http://www.devjam.com/courses-and-training/index.php"&gt;http://www.devjam.com/courses-and-training/index.php&lt;/a&gt;.  Seating is limited to about 12 participants per course.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3552348034913364068?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3552348034913364068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/02/devjam-course-offerings-for-february.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3552348034913364068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3552348034913364068'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/02/devjam-course-offerings-for-february.html' title='DevJam course offerings for February-March 2010'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4966352837965796375</id><published>2010-01-13T22:38:00.001-06:00</published><updated>2010-01-13T22:38:38.613-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='flex'/><category scheme='http://www.blogger.com/atom/ns#' term='intellij'/><title type='text'>IntelliJ IDEA 9 as an Adobe Flex IDE</title><content type='html'>If you're on the fence about paying for a license for IntelliJ IDEA, here is one more reason to justify the cost of the license.  Adobe Flex.  I've spent just a little time with it and the Flex 4 Beta 2 SDK and I must admit, IntelliJ as a Flex IDE rocks.  Much better than Flex Builder 3.  You don't get a Design View with IntelliJ, but I never used it in Flex Builder and it seems of dubious value.  &lt;br /&gt;&lt;br /&gt;I can't comment on how it stacks up against Flash Builder 4, but Flex development in IntelliJ is a joy.  I'll post more as a I get a chance to use it some more. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4966352837965796375?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4966352837965796375/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2010/01/intellij-idea-9-as-adobe-flex-ide.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4966352837965796375'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4966352837965796375'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2010/01/intellij-idea-9-as-adobe-flex-ide.html' title='IntelliJ IDEA 9 as an Adobe Flex IDE'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3776020106495631117</id><published>2009-12-16T23:27:00.001-06:00</published><updated>2009-12-16T23:27:51.236-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>Are you cultivating your software development expert mind?</title><content type='html'>What are you doing to build your proficiency in software development?  It's something I've been interested in lately.  How do you develop an &lt;a href="http://www.scientificamerican.com/article.cfm?id=the-expert-mind"&gt;expert mind&lt;/a&gt; in software development?   I spend my day consulting and I notice that most of the people that I develop software solutions with day-to-day do not spend any time outside of work cultivating their development skills.  I'm somewhat dumbfounded by this phenomenon.  Is this commonplace elsewhere?&lt;br /&gt;&lt;br /&gt;I spend a fair amount of time reading books and then applying the reading to personal coding projects.  Typically I have used these projects to learn a new technology.  Recently I've started working through Dave Thomas's &lt;a href="http://www.codekata.com"&gt;Code Katas&lt;/a&gt;.  From Dave's Code Kata website:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;Code Kata is an attempt to bring this element of practice to software development. A kata is an exercise in karate where you repeat a form many, many times, making little improvements in each. The intent behind code kata is similar. Each is a short exercise (perhaps 30 minutes to an hour long). Some involve programming, and can be coded in many different ways. Some are open ended, and involve thinking about the issues behind programming. These are unlikely to have a single correct answer.  &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;So, again, what are you doing to practice software development?  &lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3776020106495631117?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3776020106495631117/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/12/are-you-cultivating-your-software.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3776020106495631117'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3776020106495631117'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/12/are-you-cultivating-your-software.html' title='Are you cultivating your software development expert mind?'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4888466777101267395</id><published>2009-11-13T16:58:00.001-06:00</published><updated>2009-11-13T16:58:53.854-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='mac'/><category scheme='http://www.blogger.com/atom/ns#' term='hardware'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Not a fan of Apple's new Magic Mouse</title><content type='html'>I recently purchased the new Apple Magic Mouse and after about a week of on and off use, I'm not a fan of it.  For me, the laser tracking is terrible.  I thought it might be the desk so I bought a mouse pad (remember those) and though the mouse pad made tracking a bit better, the Magic Mouse laser tracking performance is irritatingly poor on both the desk and mouse pad surfaces.  It's a  beautiful device, but it's basic performance is just terrible from my experiences with it.  I'm going to hang onto it for a while and see if the driver support gets better over time.  &lt;br /&gt;&lt;br /&gt;Anyone else seeing issues with the basic laser tracking performance?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4888466777101267395?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4888466777101267395/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/11/not-fan-of-apple-new-magic-mouse.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4888466777101267395'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4888466777101267395'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/11/not-fan-of-apple-new-magic-mouse.html' title='Not a fan of Apple&amp;#39;s new Magic Mouse'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2523430024095056925</id><published>2009-11-11T22:18:00.001-06:00</published><updated>2009-11-11T22:33:28.276-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='test driven development'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><title type='text'>Using argument matchers in EasyMock and mockito</title><content type='html'>I spent some quality time with EasyMock today while coaching some developers on building tests around an existing codebase.  We were mocking a dependency of our SUT and the method call that we wanted to mock had two parameters.  When we wrote the expectation, we used the anyObject() matcher for the first parameter and tried to perform an exact match on the second parameter, a Boolean.  Here is an example of what we were trying to do in EasyMock (NOTE: we statically imported EasyMock so we could reduce the amount of code noise by not prefacing our expect, matcher, replay and verify invocations with &lt;strong&gt;EasyMock.&lt;/strong&gt;):&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;em&gt;expect&lt;/em&gt;(mockObject.retrieveSomething((String) &lt;em&gt;anyObject()&lt;/em&gt;, false)).andReturn(someObject);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Unfortunately, EasyMock and mockito do not like this.  They both want you to use matchers for all parameters if you use matchers for any parameters.  However, the two libraries react quite differently when this situation occurs.   EasyMock complains with a somewhat confusing message that at first blush makes it seem like we declared the expectation for multiple invocations.  It really threw us off for a while (at least an hour) trying to figure out what was wrong with our expectations.  Here is how we fixed it in EasyMock:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;&lt;em&gt;expect&lt;/em&gt;(mockObject.retrieveSomething((String) &lt;em&gt;anyObject()&lt;/em&gt;,  &lt;em&gt;eq&lt;/em&gt;(false))).andReturn(someObject);&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Mockito does a much better job of stating that when you use a parameter argument matcher in your expectation, you have to use parameter argument matchers for &lt;em&gt;all&lt;/em&gt; of the parameters of the method call participating in the expectation.  I find it interesting that mockito retains the behavior of EasyMock (mockito is a fork of EasyMock) with regards to argument matching, but mockito improves on the error messaging when something goes wrong with the mock object setup.  Further reinforces my decision to forego EasyMock in favor of mockito.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2523430024095056925?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2523430024095056925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/11/using-argument-matchers-in-easymock-and.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2523430024095056925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2523430024095056925'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/11/using-argument-matchers-in-easymock-and.html' title='Using argument matchers in EasyMock and mockito'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1215124687285934225</id><published>2009-11-11T16:50:00.001-06:00</published><updated>2009-11-11T22:35:49.544-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>Getting a handle on code quality with Sonar</title><content type='html'>I've been working with a client recently who uses &lt;a href="http://sonar.codehaus.org/"&gt;Sonar&lt;/a&gt;, an open source code quality management platform hosted at Codehaus.  I'm thoroughly impressed with this tool.  If you want to see what the tool can do without investing the time in installing it, take a look at the various &lt;a href="http://sonar.codehaus.org/screencasts/"&gt;screencasts&lt;/a&gt;.  They also have a &lt;a href="http://nemo.sonarsource.org/"&gt;live version of Sonar&lt;/a&gt; up so you can play with it without installation.&lt;br /&gt;&lt;br /&gt;We've been working on getting unit tests built around a legacy code base and Sonar has been a big help in identifying classes that are the biggest code coverage offenders.  We used the Clouds feature, a &lt;a href="http://en.wikipedia.org/wiki/Word_cloud"&gt;word cloud&lt;/a&gt; that weights the class names in the cloud based on code coverage and complexity.  The less test coverage on the class and/or the more complex the class, the larger the weight of that class name word in the word cloud.  It really helped us focus on where to direct our testing efforts.  &lt;br /&gt;&lt;br /&gt;I have yet to get this tool up and running in one of my own projects, but things are finally starting to simmer down now with consulting and training activities that I hope to focus on building out a CI environment using Hudson and hooking in Sonar to that environment.  Stay tuned.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1215124687285934225?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1215124687285934225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/11/getting-handle-on-code-quality-with.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1215124687285934225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1215124687285934225'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/11/getting-handle-on-code-quality-with.html' title='Getting a handle on code quality with Sonar'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-670235228309743643</id><published>2009-11-10T19:41:00.001-06:00</published><updated>2009-11-10T19:41:57.436-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><title type='text'>Promoting keystroke use in Eclipse</title><content type='html'>If you want to promote key mappings use in Eclipse, &lt;a href="http://www.mousefeed.com/"&gt;MouseFeed&lt;/a&gt; might be your ticket.  This Eclipse plugin monitors your mouse usage, and when you click on a UI component (button, menu, etc.) that can be invoked by key stroke, the MouseFeed plugin will pop up a small notification window stating that the action has a key mapping.  The notification window disappears after a few seconds, but it's power is obvious.  Very similar to the Key Promoter plugin in IntelliJ IDEA.  Very cool Eclipse plugin.  &lt;br /&gt;&lt;br /&gt;Here is a screencast of the MouseFeed plugin in action:&lt;br /&gt;&lt;br /&gt;&lt;object width="948" height="347"&gt; &lt;param name="movie" value="http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/jingswfplayer.swf"&gt;&lt;/param&gt; &lt;param name="quality" value="high"&gt;&lt;/param&gt; &lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt; &lt;param name="flashVars" value="thumb=http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/FirstFrame.jpg&amp;containerwidth=948&amp;containerheight=347&amp;content=http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/00000002.swf"&gt;&lt;/param&gt; &lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt; &lt;param name="scale" value="showall"&gt;&lt;/param&gt; &lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt; &lt;param name="base" value="http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/"&gt;&lt;/param&gt;  &lt;embed src="http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/jingswfplayer.swf" quality="high" bgcolor="#FFFFFF" width="948" height="347" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/FirstFrame.jpg&amp;containerwidth=948&amp;containerheight=347&amp;content=http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/00000002.swf" allowFullScreen="true" base="http://content.screencast.com/users/cebartling/folders/Jing/media/99d60d30-6661-4ec3-9b5a-8f5ce464cd3b/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-670235228309743643?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/670235228309743643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/11/promoting-keystroke-use-in-eclipse.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/670235228309743643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/670235228309743643'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/11/promoting-keystroke-use-in-eclipse.html' title='Promoting keystroke use in Eclipse'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-8658594530622088021</id><published>2009-11-05T22:15:00.001-06:00</published><updated>2009-11-05T22:15:17.595-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><title type='text'>Completed another Test Driven and Refactoring course for DevJam</title><content type='html'>This time using C# and the .NET platform.  The course went over really well, though we did have some small snafus with the training area in the DevJam office.  Nothing that can't be tweaked.  I had 15 participants in this class.  All participants pair programmed when completing the hand-on exercises and again, I'm totally amazed at how well pair programming goes over when you get people away from their normal work environment.  Everyone really grooved on the pair programming thing.&lt;br /&gt;&lt;br /&gt;One area that we will need to work on is the mock objects content.  We don't have any hands-on exercises for using mock objects and we heard about it in the reviews of the course.   I did walk everyone through a demonstration of using mock objects in your unit tests, but I mis-gauged how much interest the participants had in mock objects and the desire to get their feet wet with mock objects.  Some of the class participants stay after the course ended and we did another 40 minutes of live coding demos on the use and features of mock objects (using &lt;a href="http://code.google.com/p/moq/"&gt;moq&lt;/a&gt; for the mocking framework in .NET).&lt;br /&gt;&lt;br /&gt;All in all, an awesome two days for me and hopefully for the course participants.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-8658594530622088021?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/8658594530622088021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/11/completed-another-test-driven-and.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8658594530622088021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8658594530622088021'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/11/completed-another-test-driven-and.html' title='Completed another Test Driven and Refactoring course for DevJam'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7181717602968781709</id><published>2009-10-27T22:18:00.001-05:00</published><updated>2009-10-27T22:18:08.907-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile &quot;unit testing&quot; tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='training'/><title type='text'>Test Driven and Refactoring class in Chicago</title><content type='html'>Completed a two day Test Driven and Refactoring class in Chicago today.  The class went really well and I think I really was able to get a few developers to come down off the TDD fence and really buy into it.  That is always satisfying.  The class was again offered by DevJam.&lt;br /&gt;&lt;br /&gt;I did have a few participants that actually bowed out after the first day of training.  One in particular was very abstinent about not writing tests and really does not believe unit testing and TDD in particular are useful in software development.  This person was very much in favor of big design up front.  This person's views really threw me for a loop.  The group that I gave the training to has significant issues with quality, so the view of testing not worth the effort seemed very ironic in this situation.  Needless to say, I was not able to get this person to realize how unit testing and TDD help you in the design process.  Oh well, you can't win them all over.  &lt;br /&gt;&lt;br /&gt;I heard a lot of good feedback around the mock objects example that I demonstrated.  In this example, I demonstrated not only behavior verification with the mock objects, but also was able to demonstrate capturing indirect outputs on the mock objects and then verifying the state of these indirect outputs.  I used mockito 1.8 for the demo.  All in all a great class.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7181717602968781709?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7181717602968781709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/10/test-driven-and-refactoring-class-in_27.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7181717602968781709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7181717602968781709'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/10/test-driven-and-refactoring-class-in_27.html' title='Test Driven and Refactoring class in Chicago'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1966627736023945387</id><published>2009-10-27T19:06:00.001-05:00</published><updated>2009-10-27T19:06:55.250-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='training'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Second Groovy and Grails training in the bag</title><content type='html'>Completed my second Groovy and Grails training for DevJam this past Saturday.  This training session was much smoother than the first training.  Still too much material and exercises to be taught in just one day.  Received a lot of good feedback from the participants and hopefully this feedback helps solidify the training.  I'm always amazed at how much stuff I could focus in on for the Groovy training.  Really need to beef up the meata-object protocol stuff in the Groovy training.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1966627736023945387?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1966627736023945387/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/10/second-groovy-and-grails-training-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1966627736023945387'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1966627736023945387'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/10/second-groovy-and-grails-training-in.html' title='Second Groovy and Grails training in the bag'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-471218309271876859</id><published>2009-10-07T21:24:00.001-05:00</published><updated>2009-10-07T21:24:14.268-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Using the new Groovy-Eclipse V2 plugin</title><content type='html'>Started using the new &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin"&gt;Groovy-Eclipse V2 plugin&lt;/a&gt;.  I'm continuing to fine tune some Groovy training that I've come up with in collaboration with DevJam.  So far so good.  Seems to work pretty well.  I'm not expecting much at the moment, but the alpha seems pretty stable.  We need an open source Groovy IDE for the training, and I would love to use Eclipse and this plugin to fulfill that role.  I think I still prefer IntelliJ for Groovy stuff (it seems more mature), but it costs some money and most people are using Eclipse these days.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-471218309271876859?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/471218309271876859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/10/using-new-groovy-eclipse-v2-plugin.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/471218309271876859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/471218309271876859'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/10/using-new-groovy-eclipse-v2-plugin.html' title='Using the new Groovy-Eclipse V2 plugin'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-714421454479195240</id><published>2009-10-05T01:30:00.001-05:00</published><updated>2009-10-05T01:30:22.697-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>First Groovy and Grails training is in the bag</title><content type='html'>I made it through my first test run of &lt;a href="http://devjam.com/courses-and-training/groovy.php"&gt;Groovy&lt;/a&gt; and &lt;a href="http://devjam.com/courses-and-training/grails.php"&gt;Grails&lt;/a&gt; training for &lt;a href="http://devjam.com/"&gt;DevJam&lt;/a&gt; this past Saturday.  Had a couple of snafus occur.  Nothing major and easily fixed.  Did learn a couple of things though:&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Don't put developers on an operating system that they don't know for training&lt;/h2&gt;  The DevJam training has Mac minis which boot either Mac OS X Snow Leopard or Windows Vista (via Bootcamp).  I had the systems booted to Mac OS X for the training.  Unfortunately all of the developers that came to this training were unfamiliar with Mac OS X, but willing to try it.  Bad move on my part.  I ended up answering far too many questions on the operating system and which tools were were going to use.  Oracle SQL Developer also gave me problems in the Mac OS X environment when trying to update the tool with the MySQL drivers through its software updating system.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;If you think you have enough code examples, you don't!&lt;/h2&gt;&lt;br /&gt;I had about 10-12 Groovy code examples to demonstrate various features of the language.  Far too few for the questions that cropped up.  Luckily, it was Groovy and writing new code examples or changing existing code examples was pretty straightforward.  Kudos to Groovy for being very easy to explore and play with.  The participants thought very highly of the interactiveness of the coding during the session.   &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Don't try to do both Groovy and Grails in a single day.&lt;/h2&gt;&lt;br /&gt;I knew going in that doing both was going to be very difficult.  I just didn't realize how difficult it would be.  Again, due to operating system and tool snafus, I didn't finish up the Groovy stuff until well into the afternoon.  Not much time for Grails.  I was looking forward to the exercise in Grails and we didn't get very far with it.  &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Automate the packaging of the student materials in electronic format.&lt;/h2&gt;&lt;br /&gt;We decided to put all the training handouts, examples, and anything else helpful for the students on 4 GB flash drives and give the flash drives to the students to keep.  That's good.  What's not good is missing some things on the flash drive and updating flash drives during the course.  Next time I'll use an Ant build script to build a distribution and clean out any Subversion metadata from the student materials.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;The Groovy Eclipse plugin seems to be making headway.&lt;/h2&gt;&lt;br /&gt;One of the participants in the group, Nick Spilman, had his laptop along and was using Eclipse Galileo and the &lt;a href="http://groovy.codehaus.org/Eclipse+Plugin"&gt;new Groovy Eclipse plugin&lt;/a&gt; during the Groovy portion of the training.  He thought it worked well with Groovy.  I used IntelliJ 9.0 EAP (Maia) and that also works well.  Looks like SpringSource (or shall I say VMware now) is getting serious on the tooling for Groovy and Grails.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Need to spend more time on understanding Groovy's meta-programming facilities.&lt;/h2&gt;&lt;br /&gt;It's one thing to use Groovy and use its meta-programming faclities (aka MOP) successfully in your own work.  It is a far different thing to try and teach others about Groovy's meta-programming facilities.  Teaching a concept, especially a concept as complicated as meta-programming, is extremely difficult. &lt;br /&gt;&lt;br /&gt;&lt;h2&gt;Performing test runs of presentations and trainings is essential.&lt;/h2&gt;&lt;br /&gt;I'm very pleased that I was afforded the opportunity to be able to offer a couple of test runs of this training to some developers before offering it to the public.  Like anything else, it takes practice and feedback to get good at something.  I have another test run of this training later this month and I'm sure it will be much better than it was the first time out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-714421454479195240?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/714421454479195240/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/10/first-groovy-and-grails-training-is-in.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/714421454479195240'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/714421454479195240'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/10/first-groovy-and-grails-training-is-in.html' title='First Groovy and Grails training is in the bag'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5637364688588695774</id><published>2009-09-26T23:25:00.001-05:00</published><updated>2009-09-26T23:26:29.806-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><title type='text'>ColorSchemeDesigner.com</title><content type='html'>If you're developing a website and need to pick out a color scheme, take a look at &lt;a href="http://www.colorschemedesigner.com/"&gt;ColorSchemeDesigner.com&lt;/a&gt;.  Great webapp for picking color scheme.  Liked it so much I donated some money to the developer.  Highly recommended.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5637364688588695774?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5637364688588695774/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/09/colorschemedesignercom.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5637364688588695774'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5637364688588695774'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/09/colorschemedesignercom.html' title='ColorSchemeDesigner.com'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6677248783456940161</id><published>2009-09-21T21:26:00.001-05:00</published><updated>2009-09-21T21:26:43.004-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><title type='text'>Video conversion with HandBrake</title><content type='html'>I have a JVC Everio HDD camcorder that I haven't used very much until just recently.  Looking for some software to convert the MOD formatted video files on the Everio to a different format, I happened upon HandBrake.  HandBrake did a nice job of converting the video to something I can use in QuickTime.  Very impressed with this piece of open source software.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6677248783456940161?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6677248783456940161/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/09/video-conversion-with-handbrake.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6677248783456940161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6677248783456940161'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/09/video-conversion-with-handbrake.html' title='Video conversion with HandBrake'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5785879142242557138</id><published>2009-09-17T00:37:00.001-05:00</published><updated>2009-09-17T00:37:07.839-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy development'/><title type='text'>Is Spring Framework becoming a configuration nightmare?</title><content type='html'>I had a crappy day dealing with Spring Framework 3.0 M4.  I've been using Spring since 2004 and I've been a big fan of its use.  Lately however, I've become concerned that Spring Framework is turning into another EJB, a configuration monster.  I've been using Spring 3.0 M1 for a while now and recently upgraded to M4 to get access to some new Spring MVC annotations, &lt;em&gt;@RequestBody&lt;/em&gt; and &lt;em&gt;@ResponseBody&lt;/em&gt;.  These annotations allow you to bind directly to the request body and response body, respectively.  They're very helpful if you are using Spring MVC for ReSTful web services.  They seemed relatively innocuous, but after some time with them, they are much more complicated to configure than one might expect from Spring.  Still don't have a working solution with these new annotations.  Part of it is the documentation isn't where it needs to be, but that will hopefully be remedied by the time 3.0 is GA.   In the meantime, I'm stuck on the damn configuration of view resolvers, mapping adapters, and what not.  Configuration kills!  I've had the chance to work on Grails and I must say, I am very much longing for another opportunity to work on that platform.  I realize that Grails uses Spring, but Grails also keeps Spring away from, behind the covers for the most part, so I can build solutions for my client instead of muddling through configuration acrobatics.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5785879142242557138?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5785879142242557138/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/09/is-spring-framework-becoming.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5785879142242557138'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5785879142242557138'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/09/is-spring-framework-becoming.html' title='Is Spring Framework becoming a configuration nightmare?'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1705002403238449639</id><published>2009-09-15T19:22:00.001-05:00</published><updated>2009-09-17T00:38:17.611-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='networking'/><title type='text'>Keeping traceroute/tracepath by my side these days</title><content type='html'>Ugh!  All sorts of networking issues lately at work.  Each environment is set up differently from a networking standpoint.  Makes promoting code a pain in the butt.  I've been giving traceroute and tracepath both a workout these past couple of days.  Who says learning Unix utilities is a waste of time in this day and age of graphical desktops and networking utilities.  One tip from today: Make sure you specify the port that you want to route to in the traceroute/tracepath invocation.  In our case it did make a difference ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1705002403238449639?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1705002403238449639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/09/keeping-traceroutetracepath-by-my-side.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1705002403238449639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1705002403238449639'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/09/keeping-traceroutetracepath-by-my-side.html' title='Keeping traceroute/tracepath by my side these days'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-842314961816221006</id><published>2009-09-07T10:09:00.001-05:00</published><updated>2009-09-07T10:09:09.527-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><title type='text'>Snow Leopard ships with Subversion 1.6.5 support</title><content type='html'>Just upgraded to Versions 1.0.5 and noticed that Snow Leopard ships with Subversion 1.6.5 libraries and command line tools.  Very cool.  I'm assuming Xcode 3.2 also uses Subversion 1.6.5.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-842314961816221006?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/842314961816221006/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/09/snow-leopard-ships-with-subversion-165.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/842314961816221006'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/842314961816221006'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/09/snow-leopard-ships-with-subversion-165.html' title='Snow Leopard ships with Subversion 1.6.5 support'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6132833434670465710</id><published>2009-09-03T23:55:00.001-05:00</published><updated>2009-09-03T23:56:27.857-05:00</updated><title type='text'>Snow Leopard installation frees up a ton of disk space</title><content type='html'>Approximately 17 GB in my case.  Not too shabby.  Now I have to get Xcode 3.2 and the iPhone SDK add-on installed.  BTW, the iPhone SDK installation now expects Xcode 3.2 to be previously installed, so make sure you've installed it off the Snow Leopard distribution.  The 404 MB file size of the iPhone 3.0 SDK for Snow Leopard should be tip off if you've installed previous iPhone SDKs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6132833434670465710?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6132833434670465710/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/09/snow-leopard-installation-frees-up-ton.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6132833434670465710'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6132833434670465710'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/09/snow-leopard-installation-frees-up-ton.html' title='Snow Leopard installation frees up a ton of disk space'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4781597191872737184</id><published>2009-09-03T23:42:00.001-05:00</published><updated>2009-09-03T23:42:52.218-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.net'/><category scheme='http://www.blogger.com/atom/ns#' term='performance tuning'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><title type='text'>.NET thread local storage implementation kicks my butt</title><content type='html'>I got skooled today in .NET.  I wrote a thread-local storage abstraction using named data slots some time ago.  Avoid named data slots at all costs!  Use the &lt;strong&gt;ThreadStaticAttribute&lt;/strong&gt; instead.  Not only is the ThreadStaticAttribute much easier to implement, but it performs better also.  I had to wait till my code was in a near-prod environment before enough load could be generated to cause the race condition to occur.  It took me about 2 days of debugging to find the issue.  Most importantly, read the damn documentation before you attempt to write some threading code.  There are some subtle issues in the .NET Base Class Library that I would have avoided if I had read the MSDN site.   Very embarrassing.&lt;br /&gt;&lt;br /&gt;From Microsoft:&lt;br /&gt;&lt;br /&gt;&lt;em&gt;The .NET Framework provides two mechanisms for using thread local storage (TLS): thread-relative static fields (that is, fields that are marked with the ThreadStaticAttribute attribute) and data slots. Thread-relative static fields provide much better performance than data slots, and enable compile-time type checking. For more information about using TLS, see Thread Local Storage: Thread-Relative Static Fields and Data Slots.&lt;/em&gt; (&lt;a href="http://msdn.microsoft.com/en-us/library/system.threading.thread.allocatenameddataslot.aspx"&gt;http://msdn.microsoft.com/en-us/library/system.threading.thread.allocatenameddataslot.aspx&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4781597191872737184?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4781597191872737184/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/09/net-thread-local-storage-implementation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4781597191872737184'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4781597191872737184'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/09/net-thread-local-storage-implementation.html' title='.NET thread local storage implementation kicks my butt'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4529514776696733119</id><published>2009-08-31T22:24:00.001-05:00</published><updated>2009-08-31T22:24:43.198-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><title type='text'>Mac Pro upgraded to Snow Leopard</title><content type='html'>Painless install of Snow Leopard on my early 2009 Mac Pro.  I don't really notice much new.  System seems a bit snappier, but that purely qualitative observation on my part.  No numbers to back that up.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4529514776696733119?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4529514776696733119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/08/mac-pro-upgraded-to-snow-leopard.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4529514776696733119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4529514776696733119'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/08/mac-pro-upgraded-to-snow-leopard.html' title='Mac Pro upgraded to Snow Leopard'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3256052691178782655</id><published>2009-08-18T23:25:00.001-05:00</published><updated>2009-08-18T23:27:11.277-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile tdd'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><title type='text'>Know your SUT and your mocks</title><content type='html'>I was working with a colleague of mine tonight and he became confused with his unit test.  It was an interesting exchange, so I thought I would write it up.  He had a system under test (SUT), a service, that had a number of dependencies.  The dependencies were mocked using a mocking framework (mockito in this instance).  He was writing a test to get better code coverage in preparation for some refactoring and he started to add an expectation to the SUT.  When he ran his test, the test failed, but the error lead you to believe that it was the improper use of matchers within mockito.  It took him and I awhile to realize that he was trying to add expectations to a non-mock class.  In hindsight, he should have picked up on this right away, as we have a coding convention of naming our mock object instances as &lt;strong&gt;mock*&lt;/strong&gt;.   The SUT does not follow this naming convention and hence you should see the problem right away.  A little concerned that mockito didn't alert us to the fact that we were trying to add expectations to a non-mock instance.  Moral of the story: Make your mock object instances stand out--name them appropriately so everyone knows that it's a mock.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3256052691178782655?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3256052691178782655/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/08/know-your-sut-and-your-mocks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3256052691178782655'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3256052691178782655'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/08/know-your-sut-and-your-mocks.html' title='Know your SUT and your mocks'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4449748869155127838</id><published>2009-08-12T23:24:00.001-05:00</published><updated>2009-08-12T23:24:24.070-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><title type='text'>My top 5 favorite Mac OS X apps/tools/utilities</title><content type='html'>One of my friends is buying his first Mac (a Mac mini) and I told him I would compile a list of tools and utilities that I use on my Mac systems.  Here are my top 5 that I absolutely must have:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/qsb-mac/"&gt;Google Quick Search Box&lt;/a&gt;/Quicksilver:  I was a big fan of Quicksilver, but it seems to be dead.  Sounds like the Quicksilver developer is now working with/for Google on something similar: Google Quick Search Box (QSB).  Love QSB and it seems to be in active development too.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://iterm.sourceforge.net/"&gt;iTerm&lt;/a&gt;: Gotta have a command line.  This one does tabbed terminal consoles.&lt;/li&gt; &lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://macromates.com/"&gt;TextMate&lt;/a&gt;: Great programmer's editor.  &lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://versionsapp.com/"&gt;Versions&lt;/a&gt;: A good Subversion client for OS X.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://growl.info/"&gt;Growl&lt;/a&gt;: Notification system.  Extremely helpful.&lt;/li&gt;&lt;br /&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4449748869155127838?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4449748869155127838/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/08/my-top-5-favorite-mac-os-x.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4449748869155127838'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4449748869155127838'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/08/my-top-5-favorite-mac-os-x.html' title='My top 5 favorite Mac OS X apps/tools/utilities'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2118300502276761547</id><published>2009-06-21T22:02:00.001-05:00</published><updated>2009-06-21T22:02:53.152-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>First reactions to Xcode 3.1.3</title><content type='html'>Code Sense seems to be much better.  Acts intelligently and pressing Return on the suggestion selects the suggestion.  It's been a while since I've been in Xcode, but I remember the Code Sense being somewhat odd.  That doesn't seem to be the case now.  BTW, I'm using Xcode from the iPhone SDK released last week.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2118300502276761547?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2118300502276761547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/06/first-reactions-to-xcode-313.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2118300502276761547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2118300502276761547'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/06/first-reactions-to-xcode-313.html' title='First reactions to Xcode 3.1.3'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2277296168052243041</id><published>2009-05-14T10:51:00.001-05:00</published><updated>2009-05-14T10:51:07.340-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><title type='text'>Learn IDE key mappings while pair programming</title><content type='html'>I'm a big believer in keeping the hands on the keyboard and minimizing the amount of mouse use when coding.  Therefore, I tend to spend some time learning the keymappings for the IDE I am using.  I'm most proficient with IntelliJ IDEA but I've also learned a good portion of the keymappings in Eclipse and Visual Studio+ReSharper.  &lt;br /&gt;&lt;br /&gt;I've been doing a fair amount of pair programming lately on my current gig, a &lt;strong&gt;good thing&lt;/strong&gt;.  One behavior that we have been practicing while pair programming is &lt;em&gt;gently&lt;/em&gt; forcing the driver of the pair to use keymappings to activate various actions within the IDE.  Neal Ford describes this in his book &lt;u&gt;The Productive Programmer&lt;/u&gt;.  Practicing this behavior while pair programming has proven very valuable to increasing our productivity while in the code base.  Neal mentions the KeyPromoter plugin for IntelliJ; I've tried this plugin and I haven't become a big fan of it.  Much easier if your navigator keeps you honest.  &lt;br /&gt;&lt;br /&gt;I've done this before with pair programming while working at Identix in 2004 with Hans Loedolff.  Hans knew all the IntelliJ keymappings and could type at about 90 words per minute.  He was an excellent &lt;em&gt;pair programmmer&lt;/em&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2277296168052243041?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2277296168052243041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/05/learn-ide-key-mappings-while-pair.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2277296168052243041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2277296168052243041'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/05/learn-ide-key-mappings-while-pair.html' title='Learn IDE key mappings while pair programming'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6729769176627290444</id><published>2009-05-14T08:50:00.001-05:00</published><updated>2009-05-14T08:55:53.545-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linux'/><category scheme='http://www.blogger.com/atom/ns#' term='performance tuning'/><title type='text'>nmon performance monitoring tool</title><content type='html'>One of the takeaways from yesterday's Tomcat Expert Series seminar was the use of &lt;strong&gt;nmon&lt;/strong&gt; (Nigel's monitor), a curses-based performance monitoring tool.  I had never heard of nmon before yesterday, so I was curious why I missed this tool in my IT travels.  Seems the tool has originated out of IBM, originally on IBM's AIX Unix variant.  The tool has been ported to Linux.  More information &lt;a href="http://www.ibm.com/developerworks/wikis/display/WikiPtype/nmon"&gt;here&lt;/a&gt;.  If you're deploying onto Linux or AIX, it might be worthwhile to take a look at this tool and add it to your systems.  Unfortunately it does not look like there's a version for Mac OS X yet.  Hey, OS X is Unix too ;-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6729769176627290444?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6729769176627290444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/05/nmon-performance-monitoring-tool.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6729769176627290444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6729769176627290444'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/05/nmon-performance-monitoring-tool.html' title='nmon performance monitoring tool'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5533545874754727914</id><published>2009-05-13T21:25:00.001-05:00</published><updated>2009-05-13T21:25:44.561-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='tomcat'/><title type='text'>Tomcat Expert Series here in Minneapolis</title><content type='html'>Attended the SpringSource Tomcat Expert Series seminar here in Minneapolis this morning at the Hyatt Regency.  Filip Hanik of SpringSource presented.  Filip is a major committer to the Apache Tomcat project.  Excellent technical presentations on Tomcat and JVM performance tuning tips and debugging JVM memory and thread issues.  Lots of good information around Sun's generational heap and garbage collecting the heap,  If you get a chance to take this presentation in, you won't regret it.  $75 USD for 3.5 hours and a nice lunch. Seemed like a nice turn out, probably 120 or so attendees.  SpringSource seems to be picking up momentum in the JVM space with recent acquisitions of G2One (Groovy and Grails consulting and development) and Hyperic (web application monitoring and management tooling).  Could be well positioned when the economy comes out of this funk it's currently in.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5533545874754727914?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5533545874754727914/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/05/tomcat-expert-series-here-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5533545874754727914'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5533545874754727914'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/05/tomcat-expert-series-here-in.html' title='Tomcat Expert Series here in Minneapolis'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7456884304101097073</id><published>2009-04-24T06:28:00.001-05:00</published><updated>2009-04-24T06:28:53.866-05:00</updated><title type='text'>Adding GNOME to Ubuntu Server</title><content type='html'>I needed to add in an Xserver to my Ubuntu Server--Oracle 11g installer is graphical.  I didn't want to play the redirecting of the X display back to OS X, so I did some searching and &lt;a href="http://ubuntuforums.org/archive/index.php/t-186298.html"&gt;found this discussion&lt;/a&gt;.  I'll reproduce the steps that I took.  The forum posting has many different solutions.&lt;br /&gt;&lt;br /&gt;Update your package system.&lt;br /&gt;&lt;pre&gt;sudo apt-get update&lt;/pre&gt; &lt;br /&gt;&lt;br /&gt;Install the Ubuntu desktop package. This package seems to be a super package containing many package dependencies.  It literally downloaded about 1.7 GB of software.  Gdm is part of this install, so you don't have to do an individual install of that after the fact.&lt;br /&gt;&lt;pre&gt;sudo apt-get install ubuntu-desktop&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gdm automatically starts the X system during bootup.  To configure it to start, do the following:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;sudo /etc/init.d/gdm start&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You may need to reconfigure your video card, keyboard, etc.  To do so, do the following:&lt;br /&gt;&lt;pre&gt;sudo dpkg-reconfigure xserver-xorg&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7456884304101097073?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7456884304101097073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/04/adding-gnome-to-ubuntu-server.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7456884304101097073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7456884304101097073'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/04/adding-gnome-to-ubuntu-server.html' title='Adding GNOME to Ubuntu Server'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4720248141087102837</id><published>2009-04-23T20:08:00.001-05:00</published><updated>2009-04-23T20:10:58.673-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><category scheme='http://www.blogger.com/atom/ns#' term='virtualization'/><category scheme='http://www.blogger.com/atom/ns#' term='ubuntu'/><category scheme='http://www.blogger.com/atom/ns#' term='oracle'/><title type='text'>Installing VMware Tools on Ubuntu Server</title><content type='html'>I'm brining up an Oracle 11g install on Ubuntu Server here at home, and I had a need to install VMware Tools on the server installation before I got hot and heavy into the Oracle installation.  &lt;a href="http://www.gorillapond.com/2009/03/09/install-vmware-tools-on-ubuntu-linux-reborn/"&gt;Here are some great instructions&lt;/a&gt; on how to do just that.  I'm using VMware Fusion 2.0.4 on a Mac OS X 10.5.6 host system.  Seems VMware has released the source for VMware Tools and you can now get it from an Ubuntu apt repository.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4720248141087102837?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4720248141087102837/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/04/installing-vmware-tools-on-ubuntu.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4720248141087102837'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4720248141087102837'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/04/installing-vmware-tools-on-ubuntu.html' title='Installing VMware Tools on Ubuntu Server'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7254242455405243477</id><published>2009-04-11T10:02:00.001-05:00</published><updated>2009-04-11T10:04:08.132-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='music'/><title type='text'>Excellent Digg Dialogg with Trent Reznor</title><content type='html'>&lt;a href="http://digg.com/dialogg/Trent_Reznor?FC=UABDBR3"&gt;Excellent video with Trent Reznor of Nine Inch Nails.&lt;/a&gt;  Kevin Rose of Digg hosts and the questions are from the community, voted up on Digg.  Excellent content around Trent's efforts on alternative music distributions and business models.  He also mentions his interactions with id Software and John Carmack.  Has some nice comments about the programming profession.  Well worth watching.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7254242455405243477?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7254242455405243477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/04/excellent-digg-dialogg-with-trent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7254242455405243477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7254242455405243477'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/04/excellent-digg-dialogg-with-trent.html' title='Excellent Digg Dialogg with Trent Reznor'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-1717670048459521610</id><published>2009-04-05T14:27:00.001-05:00</published><updated>2009-04-05T15:57:12.236-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy development'/><title type='text'>Embedded domain components in Grails</title><content type='html'>&lt;p&gt;The embedded component feature of Grails is not documented very well, in my opinion. Therefore, I thought I would create a blog entry so others don't have to spend the time trying to experiment with it to get it to work.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I recently spent some time working on a home project that I have implemented in Grails 1.1. Grails has a feature for embedding domain components into other domain classes. An embedded component participates in the domain class mapping to a database table; there is no join to an child embedded component table. In my domain object model, a TimeRecord is a domain component suitable for embedding. It doesn't live on its own, but is meant to be embedded as a reusable component throughout my domain object model. Grails has first-class support for embedded components, though it took me a bit of time to figure out how to get it to work. First the definition of the TimeRecord class:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class TimeRecord {&lt;br /&gt;  TimeRecordUnits units&lt;br /&gt;  BigDecimal value&lt;br /&gt; &lt;br /&gt;  static constraints = {&lt;br /&gt;    units(nullable: false)&lt;br /&gt;    value(nullable: false)&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Nothing earth-shattering here. The reference to TimeRecordUnits is a Groovy enum. The TimeRecord class is not meant to be mapped to its own table in the database; it will become part of any domain object's table mapping whenever it is embedded in that domain object class. Thus, the TimeRecord class definition needs to reside inside some other domain object's Groovy file. Strange behavior, even for convention over configuration, but it does work.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Now embed the TimeRecord in another domain object class and that domain object's table mapping will also have TimeRecord properties mapped to it. Here is my Story class that has a TimeRecord contained in it:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Story {&lt;br /&gt;&lt;br /&gt;  TimeRecord estimate&lt;br /&gt;&lt;br /&gt;  static embedded = ['estimate']&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;p&gt;I've removed other Story properties to focus on the embedded component mapping. Grails has a static property named &lt;em&gt;&lt;strong&gt;embedded&lt;/strong&gt;&lt;/em&gt; that specifies the component object property that should participate as an embedded association. That's it. I put the TimeRecord definition in the Story.groovy file, directly after the Story definition. Everything maps correctly to the database and I don't get an extraneous time_record table being generated by GORM. Pretty cool.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I must say that domain object modeling in Grails is much, MUCH faster than it is in Java with Hibernate. I'm at least an order of magnitude faster with GORM in Grails than I was in Java and Hibernate. I'm hooked on Grails &lt;em&gt;convention over configuration&lt;/em&gt; theme.&lt;/p&gt;&lt;br /&gt;&lt;p xmlns="" class="poweredbyzoundry"&gt;Powered by &lt;a href="http://www.zoundryraven.com" class="poweredbyzoundry_link" rel="nofollow"&gt;Zoundry Raven&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-1717670048459521610?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/1717670048459521610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/04/embedded-domain-components-in-grails.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1717670048459521610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/1717670048459521610'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/04/embedded-domain-components-in-grails.html' title='Embedded domain components in Grails'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6208504365837391830</id><published>2009-03-22T19:49:00.001-05:00</published><updated>2009-03-22T19:49:36.700-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Grails domain object modeling with Groovy enums</title><content type='html'>I had a need to use enumerations within my object model in my Grails app today.  I wrote up a Google Sites page about &lt;a href="http://sites.google.com/a/pintailconsultingllc.com/groovy-and-grails/Home/gorm-and-domain-object-modeling/domain-object-modeling-with-groovy-enums"&gt;my solution&lt;/a&gt;.  I am using Grails 1.1 for this solution. &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6208504365837391830?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6208504365837391830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/03/grails-domain-object-modeling-with.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6208504365837391830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6208504365837391830'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/03/grails-domain-object-modeling-with.html' title='Grails domain object modeling with Groovy enums'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-8198387776960363002</id><published>2009-03-08T23:41:00.001-05:00</published><updated>2009-03-08T23:41:03.394-05:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web development'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Having another look at Grails</title><content type='html'>It's been a while since I've really worked with Grails.  I used it in 2007 for about 7 months, but we really didn't use it in a typical fashion, as the front end was done in Adobe Flex.  2007 was also fairly early in the life of Grails; I remember using version 0.5.6 when I started at the client.   &lt;br /&gt;&lt;br /&gt;I'm now building a sample application in Grails 1.0.4 and doing all the AJAX stuff in jQuery.  I'm really impressed with Grails now!  It's so much more productive than I remember it.  Also, I have a couple of books that have been absolutely essential to getting me going with Grails again: &lt;strong&gt;The Definitive Guide to Grails, Second Edition&lt;/strong&gt; and &lt;strong&gt;Groovy and Grails Recipes&lt;/strong&gt;.  I'm using IntelliJ IDEA 8.1 for all my development and its Groovy and Grails support is much better than I remember it.  JetBrains really makes it easy to give them money every year for a personal license upgrade for IntelliJ.  &lt;br /&gt;&lt;br /&gt;I haven't been super pleased with the Grails documentation on the Grails site and hopefully SpringSource has a positive effect on this issue in the near future.  My development has been plowing ahead very nicely.  I really like that I don't have to restart the application server for every little change.  That saves a ton of time and has a positive effect on your ability to stay focused on job at hand.  Very impressed with Grails this time around.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-8198387776960363002?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/8198387776960363002/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/03/having-another-look-at-grails.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8198387776960363002'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/8198387776960363002'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/03/having-another-look-at-grails.html' title='Having another look at Grails'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4655381986537811748</id><published>2009-03-05T07:03:00.001-06:00</published><updated>2009-03-05T07:03:20.759-06:00</updated><title type='text'>The amazing effect of Apple's iPhone platform and the App Store</title><content type='html'>Michael Tyson has a very relevant post about the &lt;a href="http://michael.tyson.id.au/2009/02/17/happy-birthday-loopy-thanks-apple/"&gt;amazing effect that Apple's App Store&lt;/a&gt; has been having on creative individuals who are driven enough to build applications for the iPhone platform.  I'm around quite a few people who have iPhones.  It's amazing to see and hear their enthusiasm for this great platform.  Michael's post is a great testament that software development can be very rewarding.   Great encouragement for those interested in looking at Objective-C and Cocoa Touch.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4655381986537811748?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4655381986537811748/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/03/amazing-effect-of-apple-iphone-platform.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4655381986537811748'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4655381986537811748'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/03/amazing-effect-of-apple-iphone-platform.html' title='The amazing effect of Apple&amp;#39;s iPhone platform and the App Store'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5150659706811891645</id><published>2009-03-03T21:57:00.001-06:00</published><updated>2009-03-03T22:07:47.844-06:00</updated><title type='text'>IntelliJ's support for @AspectJ pointcuts in Spring 2.x AOP</title><content type='html'>I came across a really nice feature in IntelliJ IDEA 8.1 (it may be in earlier versions, but I'm using 8.1).  I've been doing some AOP work within Spring Framework 2.5.6, using the excellent @AspectJ pointcut annotations.  Once you have everything configured in your Spring application context, IntelliJ will start to annotate where pointcuts are being applied within your code.  The annotation/emblem shows up in the left hand gutter of the editor window, right next to the line numbers.  Clicking on the emblem will cause a popup listing of all the advices that are applied at that particular join point.  You can even navigate directly to the advice from the popup.  Very cool.  Eclipse has something similar with their AspectJ development tools (AJDT), but this is the first time I've seen something like this in IntelliJ, my preferred Java editor.&lt;br /&gt;&lt;br /&gt;&lt;object width="891" height="162"&gt; &lt;param name="movie" value="http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/bootstrap.swf"&gt;&lt;/param&gt; &lt;param name="quality" value="high"&gt;&lt;/param&gt; &lt;param name="bgcolor" value="#FFFFFF"&gt;&lt;/param&gt; &lt;param name="flashVars" value="thumb=http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/FirstFrame.jpg&amp;containerwidth=891&amp;containerheight=162&amp;content=http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/intellij-aspectj-support.swf"&gt;&lt;/param&gt; &lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt; &lt;param name="scale" value="showall"&gt;&lt;/param&gt; &lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt; &lt;param name="base" value="http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/"&gt;&lt;/param&gt;  &lt;embed src="http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/bootstrap.swf" quality="high" bgcolor="#FFFFFF" width="891" height="162" type="application/x-shockwave-flash" allowScriptAccess="always" flashVars="thumb=http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/FirstFrame.jpg&amp;containerwidth=891&amp;containerheight=162&amp;content=http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/intellij-aspectj-support.swf" allowFullScreen="true" base="http://content.screencast.com/users/cebartling/folders/Default/media/21b8dcb6-4824-4673-b579-a207b12cfbc4/" scale="showall"&gt;&lt;/embed&gt; &lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5150659706811891645?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5150659706811891645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/03/intellij-support-for-aspectj-pointcuts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5150659706811891645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5150659706811891645'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/03/intellij-support-for-aspectj-pointcuts.html' title='IntelliJ&amp;#39;s support for @AspectJ pointcuts in Spring 2.x AOP'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2012617287790499624</id><published>2009-02-26T12:18:00.001-06:00</published><updated>2009-02-26T12:18:14.918-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='version control'/><category scheme='http://www.blogger.com/atom/ns#' term='os x'/><title type='text'>Versions, a native Mac OS X Subversion client</title><content type='html'>Just bought a license for &lt;a href="http://www.versionsapp.com/" target="_blank"&gt;Versions, a native Mac OS X Subversion client&lt;/a&gt;.  I've been playing around with Versions in pre-release form and really liked it.  I did have some troubles with previous releases reading my 1.5-based working copy, but that seems to be fixed in the 1.0.3 version of the Versions client.  I really like the responsiveness of Versions and they have a very clean and uncluttered UI.  Previously, I was using SmartSVN.  Check it out, I think you'll like what you see.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2012617287790499624?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2012617287790499624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/02/versions-native-mac-os-x-subversion.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2012617287790499624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2012617287790499624'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/02/versions-native-mac-os-x-subversion.html' title='Versions, a native Mac OS X Subversion client'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6462641481495151169</id><published>2009-02-17T21:18:00.001-06:00</published><updated>2009-02-17T21:20:15.358-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><title type='text'>Google Sync for the iPhone</title><content type='html'>Just came across a new feature of Google Calendar today, Google Sync for your iPhone...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.google.com/mobile/apple/sync.html"&gt;http://www.google.com/mobile/apple/sync.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I immediately set this up on my iPhone and it works great.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6462641481495151169?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6462641481495151169/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/02/google-sync-for-iphone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6462641481495151169'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6462641481495151169'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/02/google-sync-for-iphone.html' title='Google Sync for the iPhone'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6809258287151624581</id><published>2009-02-16T00:34:00.000-06:00</published><updated>2009-02-16T11:06:01.382-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile tdd'/><title type='text'>Interesting Microsoft Research paper on the efficiency and effectiveness of TDD</title><content type='html'>&lt;p&gt;From &lt;a href="http://clabs.org/blogki/blogki.cgi?page=/ComputersAndTechnology/TddEfficiency" target="_blank"&gt;cLabs Blogki&lt;/a&gt;:&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://research.microsoft.com/en-us/projects/esm/nagappan_tdd.pdf"&gt;http://research.microsoft.com/en-us/projects/esm/nagappan_tdd.pdf&lt;/a&gt;&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Case studies done on 4 development teams (three at Microsoft, one at IBM) that have adopted TDD. Results of the case studies indicate that the pre-release defect density of the four products decreased between 40% and 90% relative to similar projects tha tdid not use the TDD practice. The teams subjectively said that they experienced a 15-35% increase in initial development time after adopting TDD. Very interesting paper.&lt;/p&gt;&lt;br /&gt;&lt;p xmlns="" class="poweredbyzoundry"&gt;Powered by &lt;a href="http://www.zoundryraven.com" class="poweredbyzoundry_link" rel="nofollow"&gt;Zoundry Raven&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6809258287151624581?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6809258287151624581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/02/interesting-microsoft-research-paper-on.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6809258287151624581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6809258287151624581'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/02/interesting-microsoft-research-paper-on.html' title='Interesting Microsoft Research paper on the efficiency and effectiveness of TDD'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2917282949328030577</id><published>2009-02-08T21:41:00.000-06:00</published><updated>2009-02-08T21:42:01.710-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><title type='text'>TED iPhone app is very cool</title><content type='html'>&lt;p&gt;I seemed to have missed the &lt;a href="http://www.appleinsider.com/blogs/iphone/08/12/09/ted_talk_videos_available_through_free_iphone_app.html" target="_blank"&gt;release of the TED iPhone application&lt;/a&gt;. If you're into TED, the iPhone app is done very well and the video quality is great. You can download it from the &lt;a href="http://itunes.apple.com/WebObjects/MZStore.woa/wa/viewSoftware?id=298728479&amp;amp;mt=8"&gt;App Store&lt;/a&gt;.&lt;/p&gt;&lt;br /&gt;&lt;p xmlns="" class="poweredbyzoundry"&gt;Powered by &lt;a href="http://www.zoundryraven.com" class="poweredbyzoundry_link" rel="nofollow"&gt;Zoundry Raven&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2917282949328030577?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2917282949328030577/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/02/ted-iphone-app-is-very-cool.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2917282949328030577'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2917282949328030577'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/02/ted-iphone-app-is-very-cool.html' title='TED iPhone app is very cool'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3997968458252957241</id><published>2009-02-08T18:24:00.000-06:00</published><updated>2009-02-08T18:25:14.234-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jquery javascript ajax ria'/><title type='text'>jQuery resources, tutorials, tips</title><content type='html'>&lt;p&gt;If you're into jQuery, &lt;a href="http://www.moralfibre.co.za/2009/02/05/jquery-tips-tricks-resources/?goback=.hom" target="_blank"&gt;this blog entry&lt;/a&gt; has a plethora of jQuery resources, tips, tricks, and tutorials.&lt;/p&gt;&lt;br /&gt;&lt;p xmlns="" class="poweredbyzoundry"&gt;Powered by &lt;a href="http://www.zoundryraven.com" class="poweredbyzoundry_link" rel="nofollow"&gt;Zoundry Raven&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3997968458252957241?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3997968458252957241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/02/jquery-resources-tutorials-tips.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3997968458252957241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3997968458252957241'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/02/jquery-resources-tutorials-tips.html' title='jQuery resources, tutorials, tips'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6648000903119283334</id><published>2009-01-31T17:51:00.001-06:00</published><updated>2009-01-31T17:51:12.469-06:00</updated><title type='text'>Great jQuery documentation site</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;If you're using jQuery, check out &lt;a href='http://www.visualjquery.com/' target='_blank'&gt;Visual jQuery&lt;/a&gt;.  Nicely done.  &lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6648000903119283334?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6648000903119283334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/great-jquery-documentation-site.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6648000903119283334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6648000903119283334'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/great-jquery-documentation-site.html' title='Great jQuery documentation site'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4371270295572477968</id><published>2009-01-29T22:00:00.001-06:00</published><updated>2009-01-29T22:00:39.640-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Managing stories electronically</title><content type='html'>&lt;p&gt;I've been involved in this agile project at my client for some time and for the past three months or so I've been working in a group that favors a low fidelity mechanism for managing their stories--Post-It notes on a board. The stories, tasks, and acceptance tests are all written on Post-It notes. We are required to keep the stories and tasks in Team Foundation Server (TFS) also, but the group manages the iteration's work from the Post-It notes. The TFS eScrum template is not a particular good system for managing stories and tasks, so we tend to stick to the low fidelity method.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I really dislike this behavior. The Post-It notes are difficult to keep stuck to anything for the entire iteration. They drop off the board and mysteriously get lost. The Post-It notes are typically written in many different handwritings. There's no consistency in display of stories and tasks. Some of the Post-It notes are almost unreadable. The format of the Post-It notes is not consistent. It's difficult to write much on a single Post-It note. Reporting, well...&lt;/p&gt;&lt;br /&gt;&lt;p&gt;I'm a big believer in managing your stories and tasks electronically. Use the Post-It notes during iteration planning to facilitate teamwork and collaboration, but don't leave the stories, acceptance tests and tasks in that form for any amount of time. Get them into a tracking system that allows you to easily manage the stories and tasks for the iteration. I'm a big believer of a dashboard view that gives you a high level overview of all the iterations stories and their progress in a single view.&lt;/p&gt;&lt;br /&gt;&lt;p xmlns="" class="poweredbyzoundry"&gt;Powered by &lt;a href="http://www.zoundryraven.com" class="poweredbyzoundry_link" rel="nofollow"&gt;Zoundry Raven&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4371270295572477968?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4371270295572477968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/managing-stories-electronically.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4371270295572477968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4371270295572477968'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/managing-stories-electronically.html' title='Managing stories electronically'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-6540083727658664660</id><published>2009-01-25T20:35:00.001-06:00</published><updated>2009-01-25T20:35:28.954-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile &quot;unit testing&quot; tdd'/><title type='text'>Follow up on keeping fake objects simple</title><content type='html'>&lt;p&gt;The Google Testing Blog has an a very timely article about &lt;a href="http://googletesting.blogspot.com/2009/01/tott-keep-your-fakes-simple.html" target="_blank"&gt;keeping your fake object implemenations simple&lt;/a&gt;. I previously blogged about this issue. It's nice to see others have seen similar issues with the fake object test double.&lt;/p&gt;&lt;br /&gt;&lt;p xmlns="" class="poweredbyzoundry"&gt;Powered by &lt;a href="http://www.zoundryraven.com" class="poweredbyzoundry_link" rel="nofollow"&gt;Zoundry Raven&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-6540083727658664660?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/6540083727658664660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/follow-up-on-keeping-fake-objects.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6540083727658664660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/6540083727658664660'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/follow-up-on-keeping-fake-objects.html' title='Follow up on keeping fake objects simple'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5277105167556819704</id><published>2009-01-24T15:18:00.001-06:00</published><updated>2009-01-24T15:18:27.372-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>Programming vibration on the iPhone</title><content type='html'>Erica Sadun has a timely &lt;a href="http://blogs.oreilly.com/iphone/2009/01/on-vibration.html" target="_blank"&gt;blog posting&lt;/a&gt; about how to get your iPhone to vibrate from within your iPhone applications.  I've been working on an educational app for the iPhone and wanted to use vibration for user feedback.  And now I know how to.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5277105167556819704?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5277105167556819704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/programming-vibration-on-iphone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5277105167556819704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5277105167556819704'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/programming-vibration-on-iphone.html' title='Programming vibration on the iPhone'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7726069124625633982</id><published>2009-01-24T15:12:00.001-06:00</published><updated>2009-01-24T15:14:40.118-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><title type='text'>Measuring value during an iteration</title><content type='html'>I'm currently working on a large agile project where we measure task burn-up.  Our user stories are decomposed into individual tasks and the tasks are estimated.  When a developer or a development pair completes a task, they mark that task complete in the tracking system.  A daily chart is then generated by the tracking system that displays a line graph of units of tasks completed in the current iteration.  The cumulative total task units from the estimates is another line on the graph, and it typically stays horizontal across the entire iteration.   Up until recently I hadn't given much thought to these generated charts.&lt;br /&gt;&lt;br /&gt;Now I'm wondering what value these charts actually provide.  If management is interested in seeing that people are busy working and completing tasks, then these charts are spot on.  They definitely will show the amount of work completed during the iteration and when it's completed.  But really, is that metric all that important?  I tend to say no.  One issue off the top of my head that I have seen happen in our group is the completion of tasks on stories, but not fully completing the stories.  For whatever reason, our user stories are drifting from one iteration to the next, never reaching the point of completion.  Therefore, I conclude that we're keeping ourselves busy, but not adding any value to the overall product.  &lt;br /&gt;&lt;br /&gt;I want to know how much value I have built into the product.  To measure that quantitatively, you need to measure user story burn-up.  If you measure user story burn-up, you will focus the development team on completing stories.  I think the emphasis needs to be on the user story; the task is a planning construct that just helps us decompose the story into units of development that can be worked on concurrently by a number of developer pairs.  I don't know if I really care about task estimates anymore either.  I'm drifting towards estimating at the user story level only.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7726069124625633982?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7726069124625633982/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/measuring-value-during-iteration.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7726069124625633982'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7726069124625633982'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/measuring-value-during-iteration.html' title='Measuring value during an iteration'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-3737303590725038563</id><published>2009-01-23T22:16:00.001-06:00</published><updated>2009-01-24T16:28:32.223-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='agile'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='development'/><category scheme='http://www.blogger.com/atom/ns#' term='mocking'/><category scheme='http://www.blogger.com/atom/ns#' term='test-driven design'/><title type='text'>Using ArgumentMatcher to capture indirect output arguments</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;Yesterday, I posted a blog entry about performing assertions directly in your ArgumentMatcher implementations.  I wanted to close the loop on my previous usage of the ArgumentMatcher.  After some discussion with the main committer to mockito, Szczepan Faber, it seems that ArgumentMatcher should only be used to capture the indirect output argument, making it accessible to the test code.  Once the test code has the indirect output argument available to it, you can then assert on it to your heart's delight.  Szczepan recommended not embedding the assertions directly in the ArgumentMatcher implementation.  More information can be found &lt;a href='http://groups.google.com/group/mockito/browse_thread/thread/ce196f0460aa27cb' target='_blank'&gt;here&lt;/a&gt;.  Seems like a good approach.  &lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-3737303590725038563?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/3737303590725038563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/using-argumentmatcher-to-capture.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3737303590725038563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/3737303590725038563'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/using-argumentmatcher-to-capture.html' title='Using ArgumentMatcher to capture indirect output arguments'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-2360369579475227380</id><published>2009-01-23T00:00:00.001-06:00</published><updated>2009-01-23T00:00:24.734-06:00</updated><title type='text'>The importance of grooming the story backlog</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I'm currently on an agile project in primarily a developer role.  Our iteration planning has been a sore spot with me since I joined the group.  We've made some tweaks and improvements, but our stories and their acceptance tests are poor quality.  We aren't doing much of any pre-planning, harvesting of stories, or grooming of the backlog.  It really hurts when we get to the iteration planning day.  I dread iteration planning.  &lt;br/&gt;&lt;br/&gt;I'm a big believer in grooming the backlog while developers are working on the current iteration's stories; streamline your process by getting more things completed concurrently.  The coach and one or more of the testers get together with the customer and determine which features the customer would like to focus on in the next iteration.  If you need technical expertise, add the tech lead to this group.  Use the release backlog to jumpstart this conversation with candidate stories.  Fill out the details of this group of candidate stories for the next iteration.  This meeting between coach, testers, and customer focus on the feature details and the acceptance tests.  When you try to do this during iteration planning, there tends to be too many people and the conversation becomes chaotic. &lt;br/&gt;&lt;br/&gt;Try to solidify your stories and acceptance tests well ahead of the iteration planning meeting.  Send out the stories and the accompanying acceptance tests to the rest of group before the iteration planning meeting.  Now the participants of the upcoming iteration planning can prepare off-line before the meeting.  &lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-2360369579475227380?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/2360369579475227380/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/importance-of-grooming-story-backlog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2360369579475227380'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/2360369579475227380'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/importance-of-grooming-story-backlog.html' title='The importance of grooming the story backlog'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4689691790104388880</id><published>2009-01-22T22:43:00.001-06:00</published><updated>2009-01-22T22:43:13.364-06:00</updated><title type='text'>Using assertions within your mockito ArgumentMatcher implementations</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I've been using mockito in my Java work recently and have really enjoyed its functionality and ease of use.  Lately I've been trying to do a better job of verifying my SUT's indirect outputs, both behavior and state.  Behavior is easy to verify with mocking frameworks and mockito is no different.  State verification of indirect outputs is bit trickier, but still pretty easy to do once you know what matcher combination you need to use.  For mockito, you use the &lt;a href='http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/ArgumentMatcher.html' target='_blank'&gt;org.mockito.ArgumentMatcher&amp;lt;T&amp;gt;&lt;/a&gt; class and its subclasses (all implement the &lt;a href='http://code.google.com/p/hamcrest/source/browse/trunk/hamcrest-java/hamcrest-core/src/main/java/org/hamcrest/Matcher.java' target='_blank'&gt;org.hamcrest.Matcher&lt;/a&gt; interface).  There is a single abstract method that you should implement, the &lt;a href='http://mockito.googlecode.com/svn/branches/1.6/javadoc/org/mockito/ArgumentMatcher.html#matches%28java.lang.Object%29' target='_blank'&gt;matches(Object argument)&lt;/a&gt; method.  This method returns a boolean result.  &lt;br/&gt;&lt;br/&gt;Today, I was having a conversation with a co-worker of mine, Ryan Anderson, about the use of the ArgumentMatcher.  Ryan wondered if one could use JUnit assertions within the matches method implementation and just return true if all of the assertions passed; failed assertions will not reach the return statement.  Indeed, you can use assertions in the ArgumentMatcher implementation.  JUnit assertions actually throw an instance of &lt;a href='http://java.sun.com/javase/6/docs/api/java/lang/AssertionError.html' target='_blank'&gt;java.lang.AssertionError&lt;/a&gt;, thus your stack trace will show exactly which assertion within the ArgumentMatcher failed.  Much better using the assertions than testing and returning a boolean value.  Might be helpful for your testing efforts.&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4689691790104388880?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4689691790104388880/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/using-assertions-within-your-mockito.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4689691790104388880'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4689691790104388880'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/using-assertions-within-your-mockito.html' title='Using assertions within your mockito ArgumentMatcher implementations'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-4518801110978008813</id><published>2009-01-21T23:08:00.001-06:00</published><updated>2009-01-21T23:08:25.518-06:00</updated><title type='text'>Taking fake objects too far</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I recently worked on a Java project where we utilized the &lt;a href='http://xunitpatterns.com/Fake%20Object.html' target='_blank'&gt;Fake Object pattern&lt;/a&gt; &lt;em&gt;ad nauseum&lt;/em&gt;.  We used this pattern to provide a test double layer of our data access objects, but in doing so, we tried to implement too much of a fake repository for our domain objects.  The fake data access objects became a hindrance to writing unit tests and thus dissuaded people from writing unit tests.  Well, a friend of mine still on the project told me today that they are ripping out all the fake object implementations and putting in mocks and stubs using the excellent &lt;a href='http://code.google.com/p/mockito/' target='_blank'&gt;mockito&lt;/a&gt; library.  They hope to get back to easy test double usage and thus promote the use of unit testing and TDD.  Moral of the story: Your tests can accumulate technical debt.  Constantly ensure that test double usage is healthy in your unit tests.&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-4518801110978008813?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/4518801110978008813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/taking-fake-objects-too-far.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4518801110978008813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/4518801110978008813'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/taking-fake-objects-too-far.html' title='Taking fake objects too far'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-5562621395913191346</id><published>2009-01-19T16:47:00.001-06:00</published><updated>2009-02-03T22:19:45.779-06:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='cocoa'/><category scheme='http://www.blogger.com/atom/ns#' term='iphone'/><category scheme='http://www.blogger.com/atom/ns#' term='objective-c'/><title type='text'>Interface Builder: Remember to hook up the view to the ViewController's FileOwner view outlet</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;I don't know if I like or despise Interface Builder.  Most of the time it's an effective tool to building UI for the Mac and the iPhone.  Every so often, I'm completely confounded by it's tediousness.  Case in point: The ViewController's File Owner has an outlet for the view.  If you have one single view in your XIB, you still need to make a connection between the File Owner's view and the View object in the XIB file.  I spent significant time today trying to figure out why a multi-view iPhone example that I was working on kept throwing exceptions after I started adding the subviews to the codebase.  To me, Interface Builder seems a bit opaque; you never really know if everything is wired together properly.  I'm sure experience will help alleviate this type of issue cropping up in the future, but from my very limited exposure to the Xcode/Interface Builder tooling, it seems like the tooling could use a revamp to make things much more user friendly.  I believe the precursor to Eclipse, Visual Age for Java|Smalltalk had a similar UI wiring scheme, but with a much easier view of all the existing wirings.  Something similar would be helpful in Interface Builder.   &lt;br/&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;UPDATE on February 3, 2009: Bill Dudney has seen this phenomenon in his trainings and blogs about it &lt;a href="http://bill.dudney.net/roller/objc/entry/demystifying_view_controllers_and_views"&gt;here&lt;/a&gt;, with screenshots.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-5562621395913191346?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/5562621395913191346/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/interface-builder-remember-to-hook-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5562621395913191346'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/5562621395913191346'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/interface-builder-remember-to-hook-up.html' title='Interface Builder: Remember to hook up the view to the ViewController&amp;#39;s FileOwner view outlet'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-11388923.post-7605955715727673830</id><published>2009-01-14T23:32:00.001-06:00</published><updated>2009-01-14T23:32:37.936-06:00</updated><title type='text'>Google's Quick Search Box for the Mac</title><content type='html'>&lt;div xmlns='http://www.w3.org/1999/xhtml'&gt;If you like Quicksilver for the Mac, you may want to look at &lt;a href='http://code.google.com/p/qsb-mac/' target='_blank'&gt;Quick Search Box for the Mac&lt;/a&gt;.  One of the developers of qsb-mac is the Quicksilver creator, Nicholas Jitkoff.  Google is hosting it at googlecode as an open source project.  I like what I see of it already.&lt;br/&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/11388923-7605955715727673830?l=bartling.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://bartling.blogspot.com/feeds/7605955715727673830/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://bartling.blogspot.com/2009/01/google-quick-search-box-for-mac.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7605955715727673830'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/11388923/posts/default/7605955715727673830'/><link rel='alternate' type='text/html' href='http://bartling.blogspot.com/2009/01/google-quick-search-box-for-mac.html' title='Google&amp;#39;s Quick Search Box for the Mac'/><author><name>Chris Bartling</name><uri>https://profiles.google.com/113609952088679172610</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='//lh5.googleusercontent.com/-wViWlXXmFbM/AAAAAAAAAAI/AAAAAAABbqw/tZx_bPjSxSY/s512-c/photo.jpg'/></author><thr:total>1</thr:total></entry></feed>
