<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0">
  <category />
  <title>Grey-Bearded Geek</title>
  <id>http://greybeardedgeek.net</id>
  <updated>2008-04-19T00:00:00Z</updated>
  <author>
    <name>Rich Freedman</name>
  </author>
  <atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/GreyBeardedGeek" /><feedburner:info uri="greybeardedgeek" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry>
    <title>Java Dates</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/4YRXcFOrhag/" rel="alternate" />
    <id>http://greybeardedgeek.net/2012/11/24/java-dates/</id>
    <published>2012-11-24T00:00:00Z</published>
    <updated>2012-11-24T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="Java" />
    <summary type="html">&lt;p&gt;I often see questions about why a date fetched from a database via JDBC has the &amp;lsquo;wrong&amp;rsquo; timezone, or the &amp;lsquo;wrong&amp;rsquo; time.&lt;/p&gt;

&lt;p&gt;The basic thing that all Java programmers must understand when working with dates is that Java &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Date.html" target="_blank"&gt;Date&lt;/a&gt; objects do not have a &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html" target="_blank"&gt;TimeZone&lt;/a&gt;. A Date represents its point in time as the number of milliseconds elapsed since the &amp;ldquo;Java Epoch&amp;rdquo;, January 1, 1970, 00:00:00 GMT.&lt;/p&gt;

&lt;p&gt;So, a Java Date is essentially a Long. It embodies no concept of a TimeZone.&lt;/p&gt;

&lt;p&gt;Every SQL database that I&amp;rsquo;m aware of does essentially the same thing. The epoch used may be different, but virtually all databases store dates in a similar timezone-free format. Your JDBC driver is responsible for doing the conversion when you insert or select a date. When you select a date from a database, you get a timezone-free representation of that date, just as if you had created that date in Java&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I often see questions about why a date fetched from a database via JDBC has the &amp;lsquo;wrong&amp;rsquo; timezone, or the &amp;lsquo;wrong&amp;rsquo; time.&lt;/p&gt;

&lt;p&gt;The basic thing that all Java programmers must understand when working with dates is that Java &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Date.html" target="_blank"&gt;Date&lt;/a&gt; objects do not have a &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html" target="_blank"&gt;TimeZone&lt;/a&gt;. A Date represents its point in time as the number of milliseconds elapsed since the &amp;ldquo;Java Epoch&amp;rdquo;, January 1, 1970, 00:00:00 GMT.&lt;/p&gt;

&lt;p&gt;So, a Java Date is essentially a Long. It embodies no concept of a TimeZone.&lt;/p&gt;

&lt;p&gt;Every SQL database that I&amp;rsquo;m aware of does essentially the same thing. The epoch used may be different, but virtually all databases store dates in a similar timezone-free format. Your JDBC driver is responsible for doing the conversion when you insert or select a date. When you select a date from a database, you get a timezone-free representation of that date, just as if you had created that date in Java.&lt;/p&gt;

&lt;p&gt;The part that confuses people is that they typically print the date, to the console, to a log file, or a web page, to see its value. And whether you are doing this in your sql console, or in a Java application, printing a date means formatting the date. Formatting the date necessarily introduces a TimeZone.&lt;/p&gt;

&lt;p&gt;The really confusing part is that the most naive way of printing / formatting a date uses the &amp;lsquo;default&amp;rsquo; TimeZone, and does not make this fact obvious. So the novice prints the date, sees an unexpected time zone, and assumes that the Date has the &amp;lsquo;wrong&amp;rsquo; time zone. What has really happened is that the default timezone isn&amp;rsquo;t what they expected it to be.&lt;/p&gt;

&lt;p&gt;We also see folks formatting the date, with an explicit TimeZone, and then re-parsing that string back into a Date object, thinking that they have somehow changed the Date&amp;rsquo;s TimeZone. But, as I mentioned, the Date doesn&amp;rsquo;t have a TimeZone. So then they wonder why the TimeZone hasn&amp;rsquo;t changed.&lt;/p&gt;

&lt;p&gt;The bottom line: Remember that Dates don&amp;rsquo;t have TimeZones. Producing a String from a Date (including implicit or explicit use of toString()) without specifying a TimeZone always formats that date string using the local default TimeZone. The TimeZone does not come from the Date. It comes from the local system. What is your default TimeZone? See &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/TimeZone.html#getDefault()" target="_blank"&gt;TimeZone.getDefault()&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here is a small example that illustrates formatting of a Date with TimeZone:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::java
import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;

public class DateFormatExample {
  public static void main(String[] args) {

     SimpleDateFormat formatNY = new SimpleDateFormat();
     formatNY.setTimeZone(TimeZone.getTimeZone("America/New_York"));

     SimpleDateFormat formatLA = new SimpleDateFormat();
     formatLA.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));

     Date now = new Date();

     System.out.println("The current date and time in NY is " + formatNY.format(now));
     System.out.println("The current date and time in LA is " + formatLA.format(now));
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For extra points, replace &amp;lsquo;new Date();&amp;rsquo; with &amp;lsquo;new Date(0)&amp;rsquo;, and see what the moment of the Java Epoch looks like in these time zones.
For even more extra points, store a date in your favorite database, select it back, and format it as above. Convince yourself that Dates are TimeZone-free.&lt;/p&gt;

&lt;br/&gt;


&lt;h3&gt;An Improvement - the Calendar class&lt;/h3&gt;


&lt;p&gt;If you look at the &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Date.html" target="_blank"&gt;JavaDocs for the Date class&lt;/a&gt;, you&amp;rsquo;ll see that most of its
methods have been deprecated, with the notable exceptions being the constructor and the toString() method. This is because those now-deprecated methods lacked support for localization.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html" target="_blank"&gt;java.util.Calendar&lt;/a&gt; class was an attempt to replace the Date class with a better implementation. The methods in the Date class that were deprecated have been re-implemented in the Calendar class.&lt;/p&gt;

&lt;p&gt;To make up for Date&amp;rsquo;s lack of a &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Locale.html" target="_blank"&gt;Locale&lt;/a&gt;, Calender has a locale property, and setLocale and getLocal methods. This allows Calendars to localized.&lt;/p&gt;

&lt;p&gt;Calendar also has a timeZone property and associated mutator methods &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#setTimeZone()"&gt;setTimeZone&lt;/a&gt;
and &lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#getTimeZone()"&gt;getTimezone&lt;/a&gt;. It has two constructors &amp;ndash;
&lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#Calendar(java.util.TimeZone, java.util.Locale)"&gt;
one that takes a TimeZone and a Locale&lt;/a&gt;, and
&lt;a href="http://docs.oracle.com/javase/7/docs/api/java/util/Calendar.html#Calendar()"&gt;one that takes no arguments&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The no-arg constructor initializes the calendar with the default time zone and the default locale. As with the use of the Date class, Calendar&amp;rsquo;s
no-arg constructor using default values is the one that is most likely to be used, and the one most likely to cause confusion.&lt;/p&gt;

&lt;p&gt;Calendar has some other improvements over Date, including a number of additional date manipulation and comparison methods.
Finally, you can set the date of a Calendar with the setTime() method, and retrieve the date of a Calendar with the getTime() method.&lt;/p&gt;

&lt;p&gt;Calendar is now the preferred class to use, and Date should only be used when interfacing with &amp;ldquo;legacy&amp;rdquo; code, such as JDBC.&lt;/p&gt;

&lt;br/&gt;


&lt;h3&gt;An Alternative - Joda Time&lt;/h3&gt;


&lt;p&gt;Early on, it became apparent that Java&amp;rsquo;s Date class just doesn&amp;rsquo;t have a lot of the functionality that programmers commonly need when dealing with dates.
One of the most wished-for features was (and still is) a Time class that is independent from Date. One might, for instance, wish to represent &amp;ldquo;4:00 PM&amp;rdquo;, and perhaps
compare it to &amp;ldquo;2:00 AM&amp;rdquo; to see which is earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://joda-time.sourceforge.net"&gt;Joda Time&lt;/a&gt; appeared around 2003 to solve this and many of the other problems with java.util.Date.
(Joda provides times irrespective of dates with the &lt;a href="http://joda-time.sourceforge.net/apidocs/org/joda/time/Instant.html"&gt;Instant&lt;/a&gt; class.)
When Calendar arrived on the scene, it improved things a bit, but Joda was still needed. Joda is still actively maintained, and as of the end of 2012, is still
arguably the best way to handle dates in Java. Notably, Joda even &lt;a href="http://joda-time.sourceforge.net/contrib/hibernate/index.html"&gt;includes support for Hibernate&lt;/a&gt;.&lt;/p&gt;

&lt;br/&gt;


&lt;h3&gt;Coming Improvements - JSR-310&lt;/h3&gt;


&lt;p&gt;In 2007, folks from Google, Sun, Red Hat, and others got together with &lt;a href="http://blog.joda.org/"&gt;Stephen Colebourne&lt;/a&gt;, founder and leader of the Joda project, and produced
&lt;a href="http://jcp.org/en/jsr/detail?id=310"&gt;JSR-310&lt;/a&gt;, a Java Specification for a new Date and Time API. JSR-310 is heavily influenced by
the Joda Time library, &lt;a href="http://blog.joda.org/2009/11/why-jsr-310-isn-joda-time_4941.html"&gt;but is not exactly the same&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;JSR-310 was initially slated for implementation in Java 7, and &lt;a href="http://sourceforge.net/apps/mediawiki/threeten/index.php?title=ThreeTen"&gt;now is a candidate for inclusion in Java 8&lt;/a&gt;. This is sorely needed in Java &amp;ndash; let&amp;rsquo;s hope that JSR-310 makes it in the Java 8 release!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/4YRXcFOrhag" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2012/11/24/java-dates/</feedburner:origLink></entry>
  <entry>
    <title>Dell Vostro 200 Ethernet Card Replacement</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/TI9bWabypls/" rel="alternate" />
    <id>http://greybeardedgeek.net/2012/09/29/dell-vostro-200-ethernet-card-replacement/</id>
    <published>2012-09-29T00:00:00Z</published>
    <updated>2012-09-29T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Hardware" />
    <category term="Linux" />
    <summary type="html">&lt;p&gt;I&amp;rsquo;ve been experiencing intermittently high rates of packet loss on my home network for a while now.&lt;/p&gt;

&lt;p&gt;After much troubleshooting and swapping of spare routers, I eventually figured out that the problem was with my &amp;lsquo;house server&amp;rsquo;,
a &lt;a href="http://www.pcworld.com/product/30274/vostro-200.html"&gt;Dell Vostro 200&lt;/a&gt; running &lt;a href="http://www.ubuntu.com"&gt;Ubuntu Linux&lt;/a&gt;. Apparently, the
on-board ethernet interface was defective. While it still worked, it was the source of the packet loss. I unplugged the the
cable between it and the router, and the packet-loss problem instantly went away.&lt;/p&gt;

&lt;p&gt;After determining that the cable itself was not the problem, I ordered a new ethernet card,
an &lt;a href="http://goo.gl/MIi6l"&gt;Intel PWLA8391GT PRO/1000 GT PCI Network Adapter&lt;/a&gt; from Amazon for a little under $40 USD. I&amp;rsquo;m happy to report that I installed it,
turned the server back on, and it just worked. &lt;a href="http://www.ubuntu.com"&gt;Ubuntu 12.04.1 LTS (Precise Pangolin)&lt;/a&gt; required no configuration, and no additional&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I&amp;rsquo;ve been experiencing intermittently high rates of packet loss on my home network for a while now.&lt;/p&gt;

&lt;p&gt;After much troubleshooting and swapping of spare routers, I eventually figured out that the problem was with my &amp;lsquo;house server&amp;rsquo;,
a &lt;a href="http://www.pcworld.com/product/30274/vostro-200.html"&gt;Dell Vostro 200&lt;/a&gt; running &lt;a href="http://www.ubuntu.com"&gt;Ubuntu Linux&lt;/a&gt;. Apparently, the
on-board ethernet interface was defective. While it still worked, it was the source of the packet loss. I unplugged the the
cable between it and the router, and the packet-loss problem instantly went away.&lt;/p&gt;

&lt;p&gt;After determining that the cable itself was not the problem, I ordered a new ethernet card,
an &lt;a href="http://goo.gl/MIi6l"&gt;Intel PWLA8391GT PRO/1000 GT PCI Network Adapter&lt;/a&gt; from Amazon for a little under $40 USD. I&amp;rsquo;m happy to report that I installed it,
turned the server back on, and it just worked. &lt;a href="http://www.ubuntu.com"&gt;Ubuntu 12.04.1 LTS (Precise Pangolin)&lt;/a&gt; required no configuration, and no additional
driver installation.&lt;/p&gt;

&lt;p&gt;So, if you need a new or additional network card for Dell Vostro 200, I highly recommend the Intel Pro/100 GT.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/TI9bWabypls" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2012/09/29/dell-vostro-200-ethernet-card-replacement/</feedburner:origLink></entry>
  <entry>
    <title>Command-Line Android Screen Capture with Groovy</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/aRWvpWk8FYg/" rel="alternate" />
    <id>http://greybeardedgeek.net/2012/05/30/command-line-android-screen-capture-with-groovy/</id>
    <published>2012-05-30T00:00:00Z</published>
    <updated>2012-05-30T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="Groovy" />
    <category term="Android" />
    <summary type="html">&lt;p&gt;I&amp;rsquo;m writing a chapter about &lt;a href="http://jquerymobile.com/" target="_new"&gt;jQuery Mobile&lt;/a&gt; for a &lt;a href="http://www.manning.com/" target='_new'&gt;Manning&lt;/a&gt; book, tentatively titled &amp;ldquo;Mobile Web Apps In Practice&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;I need to get some good, high-quality screen captures for illustrations for the chapter. I read a few articles about how to do a screen capture on an Android device using the ddms tool from the Android sdk,
and that worked fine (see, for example, http://forum.gtvhacker.com/gtv-guides/topic59.html if you&amp;rsquo;re interested). But I figured that there had to be an easier way.&lt;/p&gt;

&lt;p&gt;I found Java code for use of the &lt;a href="http://mvnrepository.com/artifact/com.google.android.tools/ddmlib" target="_new"&gt;ddmlib&lt;/a&gt; library for working with the Android SDK to do a screen capture at
&lt;a href="https://github.com/roman10/roman10-android-tutorial/blob/master/screenshot/src/com/android/screenshot/Screenshot.java" target="_new"&gt;https://github.com/roman10/roman10-android-tutorial/blob/master/screenshot/src/com/android/screenshot/Screenshot.java&lt;/a&gt;&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;I&amp;rsquo;m writing a chapter about &lt;a href="http://jquerymobile.com/" target="_new"&gt;jQuery Mobile&lt;/a&gt; for a &lt;a href="http://www.manning.com/" target='_new'&gt;Manning&lt;/a&gt; book, tentatively titled &amp;ldquo;Mobile Web Apps In Practice&amp;rdquo;.&lt;/p&gt;

&lt;p&gt;I need to get some good, high-quality screen captures for illustrations for the chapter. I read a few articles about how to do a screen capture on an Android device using the ddms tool from the Android sdk,
and that worked fine (see, for example, http://forum.gtvhacker.com/gtv-guides/topic59.html if you&amp;rsquo;re interested). But I figured that there had to be an easier way.&lt;/p&gt;

&lt;p&gt;I found Java code for use of the &lt;a href="http://mvnrepository.com/artifact/com.google.android.tools/ddmlib" target="_new"&gt;ddmlib&lt;/a&gt; library for working with the Android SDK to do a screen capture at
&lt;a href="https://github.com/roman10/roman10-android-tutorial/blob/master/screenshot/src/com/android/screenshot/Screenshot.java" target="_new"&gt;https://github.com/roman10/roman10-android-tutorial/blob/master/screenshot/src/com/android/screenshot/Screenshot.java&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This was good, but I both wanted an easy one-liner shell script, and to be able to customize the operation easily.
So, being a fan of Groovy, I turned the Java code into a Groovy script, and dumped the source code for ddmlib in favor of a Grapes reference to the library in the central Maven repo.&lt;/p&gt;

&lt;p&gt;I set up the groovy script to run as a shell script, and got rid of the .groovy extension.&lt;/p&gt;

&lt;p&gt;Now I have a nice command-line way to do Android hardware screen captures.&lt;/p&gt;

&lt;p&gt;The script is at &lt;a href="https://github.com/rfreedman/android-screencapture" target="github"&gt;https://github.com/rfreedman/android-screencapture&lt;/a&gt;. Feel free to fork and hack!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/aRWvpWk8FYg" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2012/05/30/command-line-android-screen-capture-with-groovy/</feedburner:origLink></entry>
  <entry>
    <title>Inflection (Pluralization) in Java</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/T0bot0JEkVE/" rel="alternate" />
    <id>http://greybeardedgeek.net/2012/04/26/inflection-pluralization-in-java/</id>
    <published>2012-04-26T00:00:00Z</published>
    <updated>2012-04-26T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="Java" />
    <summary type="html">&lt;p&gt;Most non-trivial, user-facing software eventually needs to do
&lt;a href="http://en.wikipedia.org/wiki/Declension" target="_new"&gt;declension&lt;/a&gt; to offer reasonable feedback.
Often, simple &lt;a href="http://en.wikipedia.org/wiki/Inflection" target="_new"&gt;inflection&lt;/a&gt; of nouns is sufficient.&lt;/p&gt;

&lt;p&gt;There are some good inflection libraries in other languages, perhaps most notably
&lt;a href="http://search.cpan.org/~dconway/Lingua-EN-Inflect" target="_new"&gt;Damian Conway&amp;rsquo;s Lingua::EN::Inflect&lt;/a&gt;
for Perl, and Rails' ActiveSupport::Inflector, but there are surprisingly few good stand-alone implementations for Java.&lt;/p&gt;

&lt;p&gt;A search on the web for &amp;lsquo;Java Inflector Library&amp;rsquo; will find you references to &lt;a href="http://www.jboss.org/modeshape" target="_new"&gt;ModeShape&lt;/a&gt; (formerly JBoss DNA),
&lt;a href="http://code.google.com/p/activejdbc" target="_new"&gt;ActiveJDBC&lt;/a&gt;, &lt;a href="http://cxf.apache.org" target="_new"&gt;Apache CXF&lt;/a&gt;,
&lt;a href="http://www.netbeans.org" target="_new"&gt;NetBeans&lt;/a&gt;, and other projects, all of which are larger projects that include an inflection class or sub-library&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;Most non-trivial, user-facing software eventually needs to do
&lt;a href="http://en.wikipedia.org/wiki/Declension" target="_new"&gt;declension&lt;/a&gt; to offer reasonable feedback.
Often, simple &lt;a href="http://en.wikipedia.org/wiki/Inflection" target="_new"&gt;inflection&lt;/a&gt; of nouns is sufficient.&lt;/p&gt;

&lt;p&gt;There are some good inflection libraries in other languages, perhaps most notably
&lt;a href="http://search.cpan.org/~dconway/Lingua-EN-Inflect" target="_new"&gt;Damian Conway&amp;rsquo;s Lingua::EN::Inflect&lt;/a&gt;
for Perl, and Rails' ActiveSupport::Inflector, but there are surprisingly few good stand-alone implementations for Java.&lt;/p&gt;

&lt;p&gt;A search on the web for &amp;lsquo;Java Inflector Library&amp;rsquo; will find you references to &lt;a href="http://www.jboss.org/modeshape" target="_new"&gt;ModeShape&lt;/a&gt; (formerly JBoss DNA),
&lt;a href="http://code.google.com/p/activejdbc" target="_new"&gt;ActiveJDBC&lt;/a&gt;, &lt;a href="http://cxf.apache.org" target="_new"&gt;Apache CXF&lt;/a&gt;,
&lt;a href="http://www.netbeans.org" target="_new"&gt;NetBeans&lt;/a&gt;, and other projects, all of which are larger projects that include an inflection class or sub-library.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://www.atteo.org/blog/evo-inflector" target="_new"&gt;Evo Inflector library&lt;/a&gt; is a stand-alone library that looks to be very full-featured,
and is in the maven repos, so would appear to be open-source, but I wasn&amp;rsquo;t able to find a license or a source code repository for it. It is also more of a
&amp;lsquo;kitchen-sink&amp;rsquo; library, and not dedicated to inflection.&lt;/p&gt;

&lt;p&gt;The one stand-alone library that I was able to find that has an open-source (Apache 2.0) license is the simply-named
&lt;a href="http://weblogs.java.net/blog/tomwhite/archive/2006/07/pluralization.html" target="_new"&gt;&amp;ldquo;Inflector&amp;rdquo;&lt;/a&gt; library.
It&amp;rsquo;s simple &amp;ndash; English nouns only &amp;ndash; and I&amp;rsquo;m using it in my current project. However, after an extensive search, I&amp;rsquo;ve been unable to find
a source repo for it. It appears that it used to live at https://inflector.dev.java.net, but that does not seem to exist any more.&lt;/p&gt;

&lt;p&gt;I think that it would be really useful to a stand-alone, open-source library dedicated to inflection, and able to handle adjectives and pronouns
in addition to nouns. It would also be really nice if it handled more languages than just English.&lt;/p&gt;

&lt;p&gt;Anyone up for the challenge?&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/T0bot0JEkVE" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2012/04/26/inflection-pluralization-in-java/</feedburner:origLink></entry>
  <entry>
    <title>Java Desktop Integration with Java 6</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/s_BCJj1AefI/" rel="alternate" />
    <id>http://greybeardedgeek.net/2012/03/19/java-desktop-integration-with-java-6/</id>
    <published>2012-03-19T00:00:00Z</published>
    <updated>2012-03-19T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="Java" />
    <summary type="html">&lt;p&gt;Integrate Your Java Application With The Desktop&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s been a number of years since I attempted to do Java desktop integration, and back then
I depended on the &lt;a href="http://java.net/projects/jdic"&gt;JDesktop Integration Components (JDIC) project&lt;/a&gt;
to provide a platform-independent interface to native web browser.&lt;/p&gt;

&lt;p&gt;I needed this functionality again recently, and checked back in on JDIC, only to find that the project
never made it to 1.0 release status, and hasn&amp;rsquo;t been updated in over two years.&lt;/p&gt;

&lt;p&gt;Fortunately, with a bit more research, I found that as of Java SE 6, most of the JDIC functionality has been
built into the new &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html"&gt;java.awt.Desktop&lt;/a&gt; class.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/desktop_api/"&gt;documentation&lt;/a&gt;
is pretty good, so here just a couple small examples to whet your appetite.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::java
Desktop desktop = null;
if(Desktop.isDesktopSupported()) {
&lt;/code&gt;&lt;/pre&gt;
</summary>
    <content type="html">&lt;p&gt;Integrate Your Java Application With The Desktop&lt;/p&gt;

&lt;p&gt;It&amp;rsquo;s been a number of years since I attempted to do Java desktop integration, and back then
I depended on the &lt;a href="http://java.net/projects/jdic"&gt;JDesktop Integration Components (JDIC) project&lt;/a&gt;
to provide a platform-independent interface to native web browser.&lt;/p&gt;

&lt;p&gt;I needed this functionality again recently, and checked back in on JDIC, only to find that the project
never made it to 1.0 release status, and hasn&amp;rsquo;t been updated in over two years.&lt;/p&gt;

&lt;p&gt;Fortunately, with a bit more research, I found that as of Java SE 6, most of the JDIC functionality has been
built into the new &lt;a href="http://docs.oracle.com/javase/6/docs/api/java/awt/Desktop.html"&gt;java.awt.Desktop&lt;/a&gt; class.&lt;/p&gt;

&lt;p&gt;The &lt;a href="http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/desktop_api/"&gt;documentation&lt;/a&gt;
is pretty good, so here just a couple small examples to whet your appetite.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::java
Desktop desktop = null;
if(Desktop.isDesktopSupported()) {
   desktop = Desktop.getDesktop();
   desktop.browse(new URI("http://greybeardedgeek.net"));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::java
Desktop desktop = null;
if(Desktop.isDesktopSupported()) {
   desktop = Desktop.getDesktop();
   desktop.edit(new File("someFile.txt"));
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Desktop class supports browsing and editing as shown above, as well as printing, opening a file with its associated application,
ane creating a new email in the native email client.
If you&amp;rsquo;re looking for JDIC&amp;rsquo;s old System Tray functionality, that&amp;rsquo;s in the &lt;a href="http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/systemtray/"&gt;java.awt.SystemTray&lt;/a&gt; class.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/s_BCJj1AefI" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2012/03/19/java-desktop-integration-with-java-6/</feedburner:origLink></entry>
  <entry>
    <title>Apache mod_jk and OS X Lion</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/wUVOOqCqpRU/" rel="alternate" />
    <id>http://greybeardedgeek.net/2011/10/25/apache-modjk-and-os-x-lion/</id>
    <published>2011-10-25T00:00:00Z</published>
    <updated>2011-10-25T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="OS X" />
    <category term="Apache" />
    <category term="Tomcat" />
    <summary type="html">&lt;p&gt;I just upgraded my MacBook Pro to OS X Lion, and then had to spend a little while getting my development environment working again.
There wasn&amp;rsquo;t too much to fix, but I didn&amp;rsquo;t find resolutions to all of my issues in one place.&lt;/p&gt;

&lt;p&gt;So, here&amp;rsquo;s what I had to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;
The Java environment is not installed by default - run 'java' from the command-line, and Lion will automagically install it.&lt;/li&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
The (legacy) project on which I'm currently working fronts Tomcat with Apache2 using the mod_jk module. After the upgrade, this module is missing.
There's nowhere that I could find to download a binary - you have to build it yourself from source.
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;
The download of the source can be found at &lt;a href="http://tomcat.apache.org/download-connectors.cgi"&gt;http://tomcat.apache.org/download-connectors.cgi&lt;/a&gt;.
Instructions for building it on Lion are at &lt;a href="http://www.malisphoto.com/tips/tomcatonosx.html"&gt;http://www.malisphoto.com/tips/tomcatonosx.html&lt;/a&gt;.
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;

</summary>
    <content type="html">&lt;p&gt;I just upgraded my MacBook Pro to OS X Lion, and then had to spend a little while getting my development environment working again.
There wasn&amp;rsquo;t too much to fix, but I didn&amp;rsquo;t find resolutions to all of my issues in one place.&lt;/p&gt;

&lt;p&gt;So, here&amp;rsquo;s what I had to do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;
The Java environment is not installed by default - run 'java' from the command-line, and Lion will automagically install it.&lt;/li&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
The (legacy) project on which I'm currently working fronts Tomcat with Apache2 using the mod_jk module. After the upgrade, this module is missing.
There's nowhere that I could find to download a binary - you have to build it yourself from source.
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;
The download of the source can be found at &lt;a href="http://tomcat.apache.org/download-connectors.cgi"&gt;http://tomcat.apache.org/download-connectors.cgi&lt;/a&gt;.
Instructions for building it on Lion are at &lt;a href="http://www.malisphoto.com/tips/tomcatonosx.html"&gt;http://www.malisphoto.com/tips/tomcatonosx.html&lt;/a&gt;.
&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;
To be able to build the source, you have to install XCode from the App Store. Note that the App Store only installs the XCode installer, not XCode itself.
You still have to run the XCode installer. 
Then (and this is the part that took me a while to figure out), you have to reboot. Otherwise you get errors when running the configure script.
&lt;p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;
Finally, Apache was up and running, (I could see it by running netstat), but I couldn't connect to it.
Further investigation revealed that I could connect to it using my '.local' machine name, but not 'localhost' or any of the other aliases that I had in /etc/hosts.
The answer, which I found at &lt;a href="http://www.justincarmony.com/blog/2011/07/27/mac-os-x-lion-etc-hosts-bugs-and-dns-resolution/"&gt;http://www.justincarmony.com/blog/2011/07/27/mac-os-x-lion-etc-hosts-bugs-and-dns-resolution/&lt;/a&gt;,
is that Lion does not allow (or rather, does not work properly with) multiple host names per line in /etc/hosts. Putting one per line fixed the problem.
&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Now, all seems to be well with my development environment (we&amp;rsquo;ll see&amp;hellip;.)&lt;/p&gt;

&lt;p&gt;Hopefully, this has helped you to get yours running smoothly as well.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/wUVOOqCqpRU" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2011/10/25/apache-modjk-and-os-x-lion/</feedburner:origLink></entry>
  <entry>
    <title>Notational Velocity on Android</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/ve0QzDNlkd4/" rel="alternate" />
    <id>http://greybeardedgeek.net/2011/08/10/notational-velocity-on-android/</id>
    <published>2011-08-10T00:00:00Z</published>
    <updated>2011-08-10T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Android" />
    <summary type="html">&lt;p&gt;&lt;img src="http://cdn2.staztic.com/logos/notational-acceleration-04.png" style="float:left;"/&gt;
I&amp;rsquo;ve been using &lt;a href="http://notational.net/"&gt;Notational Velocity&lt;/a&gt; for note-taking on my Mac for a while now, and can highly recommend it. It&amp;rsquo;s a wonderfully minimalistic interface, and &amp;ldquo;just works&amp;rdquo; for text.
I used to use Evernote, but found that I don&amp;rsquo;t really need all of the features and multiple media types &amp;ndash; NV feels like the right fit.&lt;/p&gt;

&lt;p&gt;Notational Velocity syncs with &lt;a href="http://simplenoteapp.com/"&gt;SimpleNote&lt;/a&gt;, but until recently, I hadn&amp;rsquo;t seen a decent way to access my NV notes from my Android phone. A couple of months ago however, &lt;a href="https://market.android.com/details?id=com.kludgenics.android.notes"&gt;Notational Acceleration&lt;a/&gt; appeared on the scene. It syncs NV notes through SimpleNote. It&amp;rsquo;s not quite feature-complete yet, but for basic syncing, reading, and writing of notes, it has the same minimalistic feel as Notational Velocity, and &amp;ldquo;just works&amp;rdquo;. I highly recommend it&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;&lt;img src="http://cdn2.staztic.com/logos/notational-acceleration-04.png" style="float:left;"/&gt;
I&amp;rsquo;ve been using &lt;a href="http://notational.net/"&gt;Notational Velocity&lt;/a&gt; for note-taking on my Mac for a while now, and can highly recommend it. It&amp;rsquo;s a wonderfully minimalistic interface, and &amp;ldquo;just works&amp;rdquo; for text.
I used to use Evernote, but found that I don&amp;rsquo;t really need all of the features and multiple media types &amp;ndash; NV feels like the right fit.&lt;/p&gt;

&lt;p&gt;Notational Velocity syncs with &lt;a href="http://simplenoteapp.com/"&gt;SimpleNote&lt;/a&gt;, but until recently, I hadn&amp;rsquo;t seen a decent way to access my NV notes from my Android phone. A couple of months ago however, &lt;a href="https://market.android.com/details?id=com.kludgenics.android.notes"&gt;Notational Acceleration&lt;a/&gt; appeared on the scene. It syncs NV notes through SimpleNote. It&amp;rsquo;s not quite feature-complete yet, but for basic syncing, reading, and writing of notes, it has the same minimalistic feel as Notational Velocity, and &amp;ldquo;just works&amp;rdquo;. I highly recommend it.&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/ve0QzDNlkd4" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2011/08/10/notational-velocity-on-android/</feedburner:origLink></entry>
  <entry>
    <title>A Beginner's Take On Git</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/n-kqMf3kfIM/" rel="alternate" />
    <id>http://greybeardedgeek.net/2011/07/29/a-beginners-take-on-git/</id>
    <published>2011-07-29T00:00:00Z</published>
    <updated>2011-07-29T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="Git" />
    <summary type="html">&lt;p&gt;&lt;a href="http://git-scm.com/" target="_new"&gt;Git&lt;/a&gt;, for those of you who have been living under a rock, is a
&lt;a href="http://www.infoworld.com/d/application-development/torvaldss-git-the-it-technology-software-version-control-167799" target="_new"&gt;
a very popular&lt;/a&gt;
&lt;a href="http://en.wikipedia.org/wiki/Distributed_revision_controldistributed"&gt;distributed software revision control system&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It has been around since 2005, and has been gaining quite a bit of traction over the last several years.
Git is one of those things that I&amp;rsquo;ve been meaning to try on my own time for a while, but a few months ago, I started a new project, and decided to dive in.&lt;/p&gt;

&lt;p&gt;Even after reading all of the Git tutorials and watching the videos, it took the team a while to find a Git workflow that made day-to-day development go smoothly.
The workflow that we eventually adopted works very well for us, and I haven&amp;rsquo;t seen this exact workflow explained anywhere else, so I thought I&amp;rsquo;d document it here
in the hope that it well help someone else&amp;hellip;&lt;/p&gt;
</summary>
    <content type="html">&lt;p&gt;&lt;a href="http://git-scm.com/" target="_new"&gt;Git&lt;/a&gt;, for those of you who have been living under a rock, is a
&lt;a href="http://www.infoworld.com/d/application-development/torvaldss-git-the-it-technology-software-version-control-167799" target="_new"&gt;
a very popular&lt;/a&gt;
&lt;a href="http://en.wikipedia.org/wiki/Distributed_revision_controldistributed"&gt;distributed software revision control system&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It has been around since 2005, and has been gaining quite a bit of traction over the last several years.
Git is one of those things that I&amp;rsquo;ve been meaning to try on my own time for a while, but a few months ago, I started a new project, and decided to dive in.&lt;/p&gt;

&lt;p&gt;Even after reading all of the Git tutorials and watching the videos, it took the team a while to find a Git workflow that made day-to-day development go smoothly.
The workflow that we eventually adopted works very well for us, and I haven&amp;rsquo;t seen this exact workflow explained anywhere else, so I thought I&amp;rsquo;d document it here
in the hope that it well help someone else.&lt;/p&gt;

&lt;p&gt;If you are an experienced Git user, and you see danger lurking in this workflow, or just know of a better way, please let me know in the comments.&lt;/p&gt;

&lt;p&gt;If you have not tried Git or any other distributed revision control system, I urge you to try one.
For a long time, I questioned the need for a distributed revision control system, and was relatively happy with Subversion. Now that I&amp;rsquo;ve used Git,
I understand what all of the noise was about. There are many advantages to this type of system that do not have anything directly to do with whether your team
is distributed or not. Now, I&amp;rsquo;d never go back to Subversion if I didn&amp;rsquo;t have to. And if I did, I&amp;rsquo;d use
&lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-svn.html"&gt;git-svn&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;My basic goal when working out this workflow was to minimize Merge Hell.
We&amp;rsquo;ve all experienced &lt;a href="http://guru.chrismaynard.net/?p=14" target="_new"&gt;Merge Hell&lt;/a&gt;, especially when using either CVS or Subversion.
All of the Git documentation that I read made it seem like Git could help considerably with staying out of this situation. However, as soon as a second developer
joined the team, I found myself in Git merge hell. That event was the genesis for this workflow.&lt;/p&gt;

&lt;p&gt;Before I explain the details of the workflow, let me set out a few basic suggestions that I think are a good idea no matter what kind of revision control system
you are using:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Do all development on a branch, not on the trunk (or in Git terms, on a 'feature' branch, not on the 'master' branch)&lt;/li&gt;
  &lt;li&gt;Commit (and in the case of a distributed RCS, 'push') small changes frequently&lt;/li&gt;
  &lt;li&gt;Endeavor to make difficult merges a local problem - try not to let them affect the rest of the team&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;The following workflow assumes that you are following the three suggestions above.
So, from start to finish on a feature, here&amp;rsquo;s the basic ten-step workflow:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;make sure that your master branch is up to date with the remote repository (git pull master)&lt;/li&gt;

  &lt;li&gt;
      either create a feature branch (git checkout -b feature_branch) 
      or switch to an existing feature branch that has been fully merged with the master branch (git checkout feature_branch)
  &lt;/li&gt;

  &lt;li&gt;do your work on the feature branch, add the changes to git (git add .), and commit them to the feature branch (git commit)&lt;/li&gt;

  &lt;li&gt;switch back to the master branch (git checkout master)&lt;/li&gt;

  &lt;li&gt;make sure that your master branch is up to date by pulling any new changes from the remote repo (git pull)&lt;/li&gt;

  &lt;li&gt;switch back to the feature branch (git checkout feature_branch)&lt;/li&gt;

  &lt;li&gt;merge any new changes from the remote master into your feature branch with 'rebase' - this is the 'magic' part (git rebase master)&lt;/li&gt;

  &lt;li&gt;switch back to the master branch (git checkout master)&lt;/li&gt;

  &lt;li&gt;merge the feature branch into the master branch (git merge feature_branch)&lt;/li&gt;

  &lt;li&gt;push your changes to the remote repo (git push origin master)&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Ok, so that sounds a bit complicated. Fortunately, some of the steps can be skipped some of the time, and even when you have to do them all,
I&amp;rsquo;ve found that it becomes second nature once you understand the reason for each of the steps, and what each does.&lt;/p&gt;

&lt;p&gt;So, here&amp;rsquo;s a step-by-step explanation:&lt;/p&gt;

&lt;p&gt;Step 1 is to simply make sure that you have a current copy of the remote codebase before you start work on a new feature. A no-brainer.&lt;/p&gt;

&lt;p&gt;Step 2 is set up the branch on which you are going to do your work. If it already exists, make sure that it&amp;rsquo;s fully merged into master to
make sure that you don&amp;rsquo;t have to merge it later while you are merging your new changes&lt;/p&gt;

&lt;p&gt;Step 3 &amp;ndash; do your work&lt;/p&gt;

&lt;p&gt;Steps 4 and 5 ensure that your master branch is up to date with the remote repo &amp;ndash; this pulls in any changes that have been pushed to the
remote master branch while you were doing your work. If there are changes pulled, they will merge cleanly, as you haven&amp;rsquo;t made any changes
directly on your local master (this is why we work on a feature branch).
If there were no changes on the remote master (&amp;lsquo;git pull&amp;rsquo; reported no changes), you
can skip steps 7 and 8.&lt;/p&gt;

&lt;p&gt;Step 7 merges new changes from the remote master with your work on the feature branch.
The magic here is the &amp;lsquo;git rebase&amp;rsquo; command. Rebase effectively shelves (temporarily rolls back) the commits that you have made on your feature branch,
applies the updates from the master branch to the feature branch, and then &amp;lsquo;replays&amp;rsquo; your commits back on top of the feature branch.&lt;/p&gt;

&lt;p&gt;The first part, shelving your feature commits and updating the feature branch with the updates on master, when used this way, will always happen cleanly.
The second part, replaying your commits, is where you will potentially encounter one or more merge scenarios.&lt;/p&gt;

&lt;p&gt;There are some very advantageous things about this step. First, because your local commits are put &amp;lsquo;on top of&amp;rsquo; the merged commits from the remote master,
it is a &amp;lsquo;cleaner&amp;rsquo; merge. Generally, it effectively results in a two-way merge instead of a three-way merge &amp;ndash; i.e. merges tend to be easier to do.
Second, once you are done, the timeline is easier for everyone to understand. Even though two or more developers may have interleaved commits, it comes out
looking one developer committed all of their changes, and then the other developer committed all of theirs. To me this is both magical and invaluable.&lt;/p&gt;

&lt;p&gt;Step 8 simply puts you back on the master branch&lt;/p&gt;

&lt;p&gt;Step 9 merges your local feature branch into your local master branch. Again, if you have followed the plan, this will be a clean, &amp;lsquo;fast-forward&amp;rsquo; merge.
Your feature branch and your local master branch are now identical.&lt;/p&gt;

&lt;p&gt;Step 10 pushes your local master branch to the remote master branch. Also a fast-forward merge, unless someone else has pushed to the remote master after
you did step 5. Unlikely, but possible. Solution left as an exercise for the reader.&lt;/p&gt;

&lt;p&gt;Rinse and repeat.&lt;/p&gt;

&lt;p&gt;There has been much discussion on websites everywhere about how &amp;lsquo;rebase&amp;rsquo; is evil because it rewrites history.
I think that it&amp;rsquo;s important to note that using rebase on commits that have already been pushed to the remote repo &lt;em&gt;is&lt;/em&gt; evil.
Here, however, we&amp;rsquo;re rewriting local history, because that&amp;rsquo;s what makes the ultimate timeline make sense, and we&amp;rsquo;re not altering
any history in the remote repo.&lt;/p&gt;

&lt;p&gt;Ok, that&amp;rsquo;s it. Let the discussion ensue!&lt;/p&gt;
&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/n-kqMf3kfIM" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2011/07/29/a-beginners-take-on-git/</feedburner:origLink></entry>
  <entry>
    <title>Testing Grails Controllers with Spock Part 2</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/6kzXw2OF37A/" rel="alternate" />
    <id>http://greybeardedgeek.net/2011/05/19/testing-grails-controllers-with-spock-part-2/</id>
    <published>2011-05-19T00:00:00Z</published>
    <updated>2011-05-19T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="Java" />
    <category term="Groovy" />
    <category term="Grails" />
    <summary type="html">&lt;p&gt;My &lt;a href="http://greybeardedgeek.net/2011/05/13/testing-grails-controllers-with-spock/"&gt;previous post&lt;/a&gt; showed how to get around some of the shortcomings of testing Grails Controllers with the ControllerSpec provided by the Spock testing framework.&lt;/p&gt;

&lt;p&gt;I also found that ControllerSpec is a subclass of UnitSpec, so it does not provide transactional rollback. This makes ControllerSpec somewhat undesirable for an integration test.&lt;/p&gt;

&lt;p&gt;So, I merged the code for ControllerSpec and IntegrationSpec to create ControllerIntegrationSpec.
It works just like ControllerSpec, but executes each test method in a transaction, and rolls the transaction back at the end of the method.&lt;/p&gt;

&lt;p&gt;Here is the Groovy source, which can also be found at &lt;a href="https://github.com/rfreedman/spock-integration-controller-spec/"&gt;https://github.com/rfreedman/spock-integration-controller-spec/&lt;/a&gt;&lt;/p&gt;

&lt;script src="https://gist.github.com/980779.js"&gt; &lt;/script&gt;

</summary>
    <content type="html">&lt;p&gt;My &lt;a href="http://greybeardedgeek.net/2011/05/13/testing-grails-controllers-with-spock/"&gt;previous post&lt;/a&gt; showed how to get around some of the shortcomings of testing Grails Controllers with the ControllerSpec provided by the Spock testing framework.&lt;/p&gt;

&lt;p&gt;I also found that ControllerSpec is a subclass of UnitSpec, so it does not provide transactional rollback. This makes ControllerSpec somewhat undesirable for an integration test.&lt;/p&gt;

&lt;p&gt;So, I merged the code for ControllerSpec and IntegrationSpec to create ControllerIntegrationSpec.
It works just like ControllerSpec, but executes each test method in a transaction, and rolls the transaction back at the end of the method.&lt;/p&gt;

&lt;p&gt;Here is the Groovy source, which can also be found at &lt;a href="https://github.com/rfreedman/spock-integration-controller-spec/"&gt;https://github.com/rfreedman/spock-integration-controller-spec/&lt;/a&gt;&lt;/p&gt;

&lt;script src="https://gist.github.com/980779.js"&gt; &lt;/script&gt;

&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/6kzXw2OF37A" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2011/05/19/testing-grails-controllers-with-spock-part-2/</feedburner:origLink></entry>
  <entry>
    <title>Testing Grails Controllers with Spock</title>
    <link href="http://feedproxy.google.com/~r/GreyBeardedGeek/~3/i4sSGViVBQQ/" rel="alternate" />
    <id>http://greybeardedgeek.net/2011/05/13/testing-grails-controllers-with-spock/</id>
    <published>2011-05-13T00:00:00Z</published>
    <updated>2011-05-13T00:00:00Z</updated>
    <author>
      <name>Rich Freedman</name>
    </author>
    <category term="Chariot" />
    <category term="Java" />
    <category term="Groovy" />
    <category term="Grails" />
    <summary type="html">&lt;p&gt;I&amp;rsquo;m starting a Grails project, and decided to use the Spock testing framework.
Spock is a very nice way to write tests, and I recommend it highly.&lt;/p&gt;

&lt;p&gt;Unit tests with Spock are very easy to write, and Spock&amp;rsquo;s UnitSpec class provides all of the mocking methods that
you would expect to find in a Grails-centric testing framework, including mockDomain, mockForConstraintsTests, and friends.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s one of my simple Spock unit tests for a domain object:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::groovy
class CompoundInstanceSpec extends UnitSpec {

    def "finding the compound instance's primary name"() {
        setup:
        mockDomain(CompoundInstance.class)

        expect:
        !compoundInstance.primaryName
        compoundInstance.setupPrimaryName()
        compoundInstance.primaryName == name2.name
        compoundInstance.compoundNames.remove(name2)
        compoundInstance.setupPrimaryName()
        !compoundInstance.primaryName

        where:
        name1 = [name: 'name1', primary: false]
        name2 = [name: 'name2', primary: true]
&lt;/code&gt;&lt;/pre&gt;
</summary>
    <content type="html">&lt;p&gt;I&amp;rsquo;m starting a Grails project, and decided to use the Spock testing framework.
Spock is a very nice way to write tests, and I recommend it highly.&lt;/p&gt;

&lt;p&gt;Unit tests with Spock are very easy to write, and Spock&amp;rsquo;s UnitSpec class provides all of the mocking methods that
you would expect to find in a Grails-centric testing framework, including mockDomain, mockForConstraintsTests, and friends.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s one of my simple Spock unit tests for a domain object:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::groovy
class CompoundInstanceSpec extends UnitSpec {

    def "finding the compound instance's primary name"() {
        setup:
        mockDomain(CompoundInstance.class)

        expect:
        !compoundInstance.primaryName
        compoundInstance.setupPrimaryName()
        compoundInstance.primaryName == name2.name
        compoundInstance.compoundNames.remove(name2)
        compoundInstance.setupPrimaryName()
        !compoundInstance.primaryName

        where:
        name1 = [name: 'name1', primary: false]
        name2 = [name: 'name2', primary: true]
        name3 = [name: 'name3', primary: false]
        compoundInstance = new CompoundInstance(compoundNames: [name1, name2, name3])
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When it came to integration-testing a Grails Controller, however, I ran into some problems.
The first problem was that my Grails-generated controller code used the ValidationTagLib&amp;rsquo;s message() closure to place internationalized messages into flash scope.
Unfortunately, neither Grail&amp;rsquo;s integration test environment nor Spock&amp;rsquo;s ControllerSpec class wire the messageSource object into the application context, so the
test failed when the controller tried to place a &amp;lsquo;success&amp;rsquo; message into flash scope:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::groovy
flash.message = "${message(code: 'default.created.message',
    args: [message(code: 'compound.label', default: 'Compound'), 
        results.compoundInstance.primaryName])}"
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The simple solution (assuming that you don&amp;rsquo;t need to test the content of the message) is to use MOP programming to override the controller&amp;rsquo;s
message() closure in the test&amp;rsquo;s setup. The following example always returns &amp;ldquo;mockMessage&amp;rdquo; for the value of the message, and allows the test to
proceed normally:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::groovy
setup:
controller.metaClass.message = {args -&amp;gt; "mockMessage"}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A more complete solution would actually wire up the messageSource.&lt;/p&gt;

&lt;br/&gt;


&lt;hr width='50%'/&gt;


&lt;br/&gt;


&lt;p&gt;The second problem that I ran into was that the service called by my controller needed to access the currently logged-in user (I&amp;rsquo;m using the spring-security plugin).
When this is being done in the scope of a test, there is, of course, no currently logged-in user, and of course, the test would fail.&lt;/p&gt;

&lt;p&gt;The simple solution for this problem is to wrap the body of the test with the SpringSecurityUtils' doWithAuth closure, specifying the username of the user
under whose authorization you wish to run the test. Of course, you&amp;rsquo;ll have to make sure that you either create the user and authorizations (roles) in BootStrap.groovy,
or in the test setup.&lt;/p&gt;

&lt;br/&gt;


&lt;hr width='50%'/&gt;


&lt;br/&gt;


&lt;p&gt;Here, then, is my integration test with both issues handled:&lt;/p&gt;

&lt;script src="https://gist.github.com/970650.js?file=spock-integration-grails-controller.groovy"&gt;&lt;/script&gt;


&lt;p&gt;Notice the &amp;lsquo;message&amp;rsquo; fix at line 8, and the &amp;lsquo;security&amp;rsquo; fix beginning at line 15&lt;/p&gt;

&lt;br/&gt;




&lt;script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"&gt;&lt;/script&gt;


&lt;script src="http://gist.github.com/raw/454771/gist-line-number-hack.js"&gt;&lt;/script&gt;


&lt;script type="text/javascript"&gt;addLineNumbersToAllGists()&lt;/script&gt;

&lt;img src="http://feeds.feedburner.com/~r/GreyBeardedGeek/~4/i4sSGViVBQQ" height="1" width="1"/&gt;</content>
  <feedburner:origLink>http://greybeardedgeek.net/2011/05/13/testing-grails-controllers-with-spock/</feedburner:origLink></entry>
</feed>
