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

<channel>
	<title>Jworks.nl - Agile Software Development using Groovy and Grails</title>
	<atom:link href="http://www.jworks.nl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.jworks.nl</link>
	<description>Effective Software Development using Effective Tools, People and Process</description>
	<lastBuildDate>Fri, 02 Dec 2011 20:37:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>This week in Discobot (45.2011)</title>
		<link>http://www.jworks.nl/2011/11/11/this-week-in-discobot-45-2011/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=this-week-in-discobot-45-2011</link>
		<comments>http://www.jworks.nl/2011/11/11/this-week-in-discobot-45-2011/#comments</comments>
		<pubDate>Fri, 11 Nov 2011 08:07:42 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Discobot]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=359</guid>
		<description><![CDATA[Another night of coding, another update on the Discobot project! For those unfamiliar with the Discobot project: it&#8217;s the project name for running Groovy on Android. We (Marcin Erdmann and Erik Pragt) are working towards an easy to use framework to run the newest version of Groovy on the newest version of Android. Currently, we&#8217;re [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F11%2F11%2Fthis-week-in-discobot-45-2011%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F11%2F11%2Fthis-week-in-discobot-45-2011%2F&amp;style=normal&amp;hashtags=jworks&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Another night of coding, another update on the Discobot project! For those unfamiliar with the Discobot project: it&#8217;s the project name for running Groovy on Android. We (Marcin Erdmann and Erik Pragt) are working towards an easy to use framework to run the newest version of Groovy on the newest version of Android. Currently, we&#8217;re not there yet, but we will demonstrate our progress at the next <a href="http://skillsmatter.com/event/groovy-grails/groovy-grails-exchange-2011" target="_blank">Groovy and Grails Exchange</a> in London.</p>
<p>A small update though on our current progress, since it has been a while since our last update, and we&#8217;ve gotten a few requests to update you all. To start with: the project is still very alive, and we are working hard to create a streamlined environment for developing Groovy Android applications, including <a href="http://www.gradle.org">Gradle</a> support, with some tasks to easily deploy your Groovy application on the Android emulator.</p>
<p>The last couple of weeks we&#8217;ve been struggling to work with the dynamics provided by Groovy. Groovy works a bit different compared to the standard Java runtime in Android. A small example:</p>
<pre class="brush: groovy">
class B {
  def pub() {'a'}
} 

def x = [pub: {'b'}] as B
</pre>
<p>This code dynamically creates a class at runtime. We have to make the Android environment aware of these classes, which is done by the DiscobotClassloader. This is quite tricky to accomplish, but the good news is, that after some days and nights of coding, it works now. Basic Groovy code, like </p>
<pre class='brush: groovy'>[1,2,3].each { println it }</pre>
<p> was already working for quite some time, but now we support a great deal of the features provided by Groovy already at the moment. Even though we haven&#8217;t measured yet how far we are exactly in terms of features, but we&#8217;re on the right way.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/NRiISubrnQg?hd=1" frameborder="0" allowfullscreen></iframe></p>
<p>What we&#8217;ll do now though, is to create an Android application which will run all Groovy unit tests. We&#8217;ve done it before, and around 30% of the unit tests worked on the Android emulator. Now, with the support for dynamically generating classes, which was one of the biggest problem, we should get far above this 30%. So, please bear with us and we&#8217;ll keep update you on the progress we&#8217;ll make. In the meantime, you can follow the progress we&#8217;re making in our <a href="https://github.com/disco-bot/disco-bot/tree/discobot-patches" target="_blank">Git repository</a>!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/11/11/this-week-in-discobot-45-2011/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>This week in Discobot (40.2011)</title>
		<link>http://www.jworks.nl/2011/10/14/this-week-in-discobot-40-2011/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=this-week-in-discobot-40-2011</link>
		<comments>http://www.jworks.nl/2011/10/14/this-week-in-discobot-40-2011/#comments</comments>
		<pubDate>Fri, 14 Oct 2011 19:41:24 +0000</pubDate>
		<dc:creator>Marcin Erdmann</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Discobot]]></category>
		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=352</guid>
		<description><![CDATA[After some hectic times at work caused by very tight deadlines and me getting married in the beginning of September we finally managed with Erik to get back to working on Discobot last week. Some of you have probably already noticed that we have a talk on Discobot scheduled at Groovy &#038; Grails Exchange 2011 [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F10%2F14%2Fthis-week-in-discobot-40-2011%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F10%2F14%2Fthis-week-in-discobot-40-2011%2F&amp;style=normal&amp;hashtags=jworks&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>After some hectic times at work caused by very tight deadlines and me getting married in the beginning of September we finally managed with Erik to get back to working on Discobot last week.</p>
<p>Some of you have probably already noticed that we have a <a href="http://skillsmatter.com/podcast/groovy-grails/groovy-android" target="_blank">talk</a> on Discobot scheduled at Groovy &#038; Grails Exchange 2011 in London which takes place in early December. Although the progress is good there is still quite a lot of work to be done on Discobot and we decided that probably one evening a week will not be enough. On the other hand knowing about the talk gives us an even stronger motivation to succeed!</p>
<p>Last week Erik continued his work on getting all Groovy tests running in the emulator. We found out that &#8216;on the fly generated&#8217; classes which are created by Groovy when you for example cast a map of closure into a class using &#8216;as&#8217; keyword cannot be loaded by the classloader. The reason is simple &#8211; classloader looks for class files but it should be looking for dex files. This is our main concern at the moment as it causes exceptions all over the place and breaks anything more complex than a &#8216;hello world&#8217;. From the code written by Hjalmar we&#8217;ve noticed that he also encountered the problem and we&#8217;re trying to apply his solution to see if it will work. So, it looks like there&#8217;s a lot of class loading fun ahead of us!</p>
<p>We&#8217;ve also got a response from guys behind Gradle plugin for Android about our pull request. They had several small remarks which I managed include in my second pull request. From what they said it looks like they should accept it in the coming days.</p>
<p>I&#8217;ve also looked for options regarding a repository in which to put our artefacts (Gradle plugin and the modyfied version of Groovy). I&#8217;ve found a nice blog about creating a a github based Maven repository and using it with Gradle. It seems easy and straightforward so probably we will go for this solution for now.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/10/14/this-week-in-discobot-40-2011/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Maximizing browser window for all Geb tests</title>
		<link>http://www.jworks.nl/2011/10/06/maximizing-browser-window-for-all-geb-tests/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=maximizing-browser-window-for-all-geb-tests</link>
		<comments>http://www.jworks.nl/2011/10/06/maximizing-browser-window-for-all-geb-tests/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 12:10:00 +0000</pubDate>
		<dc:creator>Marcin Erdmann</dc:creator>
				<category><![CDATA[Geb]]></category>
		<category><![CDATA[geb]]></category>
		<category><![CDATA[geb config]]></category>
		<category><![CDATA[maximizing browser]]></category>
		<category><![CDATA[webdriver]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=341</guid>
		<description><![CDATA[There might be different reasons for setting a browser window size for your Geb tests. For us it was simply the fact that some floating elements where overlapping with other elements rendering them unclickable when the browser window was set to occupy only the half of the screen and that&#8217;s the default size of a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F10%2F06%2Fmaximizing-browser-window-for-all-geb-tests%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F10%2F06%2Fmaximizing-browser-window-for-all-geb-tests%2F&amp;style=normal&amp;hashtags=geb,geb+config,maximizing+browser,webdriver&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>There might be different reasons for setting a browser window size for your Geb tests. For us it was simply the fact that some floating elements where overlapping with other elements rendering them unclickable when the browser window was set to occupy only the half of the screen and that&#8217;s the default size of a Firefox window started by Webdriver.</p>
<p>There were two requirements for the solution &#8211; it had to work on every machine the tests were run without any configuration (so we had to discard all of the solutions involving changing the Firefox profile) and also the window had to be maximized for each of our tests. Unfortunately WebDriver doesn&#8217;t allow to easily control browser window size, at least as long as <a href="http://code.google.com/p/selenium/issues/detail?id=174" target="_blank">this issue</a> isn&#8217;t solved. Therefore we had to revert to resizing the window via Javascript which we don&#8217;t like, but it seems to be the only solution for now. Thanks to putting the code into our GebConfig.groovy we got the window maximized for every test. Following is the driver closure we needed to put in our Geb config:</p>
<pre class="brush: groovy">driver = {
    def driver = new FirefoxDriver()
    driver.executeScript("window.resizeTo(screen.width, screen.height)")
    return driver
}</pre>
<p>Note that you can use a similar technique to not only maximize but also set the window to a certain size and to do it on a per test basis if you put the resizing code into your test instead of the GebConfig.groovy.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/10/06/maximizing-browser-window-for-all-geb-tests/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friday Repost: Grails and Bamboo</title>
		<link>http://www.jworks.nl/2011/09/30/friday-repost-grails-and-bamboo/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=friday-repost-grails-and-bamboo</link>
		<comments>http://www.jworks.nl/2011/09/30/friday-repost-grails-and-bamboo/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 08:00:34 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[atlassian]]></category>
		<category><![CDATA[bamboo]]></category>
		<category><![CDATA[friday repost]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=214</guid>
		<description><![CDATA[The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog In our development environment, we use the complete Atlassian suite. We (or actually I) choose this environment because the products integrates so well together, but [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F30%2Ffriday-repost-grails-and-bamboo%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F30%2Ffriday-repost-grails-and-bamboo%2F&amp;style=normal&amp;hashtags=atlassian,bamboo,friday+repost,grails,groovy&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><i>The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog</i></p>
<p>In our development environment, we use the complete <a href="http://www.atlassian.com">Atlassian</a> suite. We (or actually I) choose this environment because the products integrates so well together, but also because it integrates good with other products, like SpringSource Tool Suite, or, in our case, <a href="http://www.jetbrains.com">IntelliJ IDEA</a>. And finally, the Atlassian suite has excellent support for building Grails projects, which, at the moment, is all we do. Simply put, we choose Atlassian because it rocks!</p>
<p>To integrate even better with the Atlassian Build Server (Bamboo), I&#8217;ve created a small script which will update the version number of the application with the Build Number. This way, we always know which build is running where. To do so, I created the following script.</p>
<pre class="brush: groovy">
includeTargets << grailsScript("_GrailsEvents")

target('default': "Sets the current application version") {
    def buildNumberFile = new File('build-number.txt')
    if (buildNumberFile.exists()) {
        def props = new Properties()
        buildNumberFile.withInputStream { stream ->
            props.load(stream)
        }

        def buildNumber = props["build.number"]

        metadata.'app.version' = metadata.'app.version' + ".${buildNumber}"
        metadata.persist()
        event("StatusFinal", ["Application build number updated to ${buildNumber}"])
    }
}
</pre>
<p>This script will look for a file called &#8216;build-number.txt&#8217;, which is produced by the <a href="http://confluence.atlassian.com/display/BAMBOO/Bamboo+Development+Hub">Build Number Stamper Plugin</a>, and put in the working directory. This file is read by the script, and it updates the version number in application.properties, which will result in a war file produced by the build in the following format &#8216;<name>-<version>.<buildnumber>.war&#8217;, for example &#8216;todolist.0.1.34.war&#8217;. This way you can easily relate each build which bugs you might find, and avoids confusion, for example between testers and developers.</p>
<p>As an extra, we&#8217;ve show the current version of the application in the source of our HTML. We do this by reading the version number from the application.properties with the following tag:</p>
<pre class="brush: groovy">
<g:meta name="app.version"/>
</pre>
<p>This will display the version number of the application, and will allow you to relate issues to a build number, to avoid miscommunication about the deployed application!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/09/30/friday-repost-grails-and-bamboo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friday Repost: Making Grails work behind an proxy server</title>
		<link>http://www.jworks.nl/2011/09/23/friday-repost-making-grails-work-behind-an-proxy-server/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=friday-repost-making-grails-work-behind-an-proxy-server</link>
		<comments>http://www.jworks.nl/2011/09/23/friday-repost-making-grails-work-behind-an-proxy-server/#comments</comments>
		<pubDate>Fri, 23 Sep 2011 08:00:24 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[friday repost]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[nexus]]></category>
		<category><![CDATA[proxy server]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=218</guid>
		<description><![CDATA[The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog. Making Grails work behind an NTLM firewall (or using Grails without Internet) Currently, I&#8217;m in the process of taking over an existing Grails project and [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F23%2Ffriday-repost-making-grails-work-behind-an-proxy-server%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F23%2Ffriday-repost-making-grails-work-behind-an-proxy-server%2F&amp;style=normal&amp;hashtags=friday+repost,grails,nexus,proxy+server&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><i>The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog.</i></p>
<p>Making Grails work behind an NTLM firewall (or using Grails without Internet)</p>
<p>Currently, I&#8217;m in the process of taking over an existing Grails project and migrating it to a different location. This location has been setup by me, so I have full control over it, except for one tiny detail: the Proxy Server.</p>
<p>The application used to work great, and installing plugins was a breeze: just do a good old &#8216;grails install-plugin fitnesse&#8217;, and the plugin would be installed. However, since this Proxy Server is not just any Proxy Server, but a Microsoft NTLM Proxy Server, we tried quite hard to make Java work with it, but at the moment the score is 1-0 for the Proxy Server. This gives us the following problems:</p>
<p>
1) Our dependencies cannot be downloaded<br />
2) Our plugins cannot be be downloaded<br />
3) Some plugins cannot be installed anymore
</p>
<p>
<b>Downloading dependencies</b><br />
In our BuildConfig.groovy, we specified some dependencies like joda time and xstream. These dependencies are normally downloaded, but due to our Proxy issue, that doesn&#8217;t work.</p>
<p>Our solution to this is to use Nexus. Nexus is able to pass the firewall, and can download our dependencies. It serves as a transparent Maven proxy, which can also be used by Ivy, and solves our problem nicely. Besides, it&#8217;s a good idea to install a local Maven proxy anyway, mostly because of reliability, but also because of speed and making sure everyone uses the same dependencies.</p>
<p>
<b>Downloading plugins</b><br />
Unfortunately, the Grails plugins are not in a Maven repository. However, a solution to this is to download the plugin zip (eg grails-fitnesse-0.2.zip), rename it (to fitnesse-0.2.zip), put it in the lib directory (even though I&#8217;m really not a fan of putting binaries in version control systems), and register it in the application.properties and BuildConfig.groovy.
</p>
<p>The BuildConfig.groovy should look like this:</p>
<pre class="brush: groovy">
grails.project.dependency.resolution = {
    inherits "global" // inherit Grails' default dependencies
    log "warn" // log level of Ivy resolver, either 'error', 'warn', 'info', 'debug' or 'verbose'
    repositories {
        mavenRepo "http://172.30.60.106:8081/nexus/content/repositories/central" // nexus repo
    }
    dependencies {
        compile ('com.thoughtworks.xstream:xstream:1.3.1') {
            excludes "stax","stax-api"
        }
    }

    plugins {
        runtime ':hibernate:1.3.2'
        runtime ':tomcat:1.3.2'
        runtime ':fitnesse:0.2'
    }
</pre>
<p>As you can see, everything is configured here: the dependencies are here, the location to nexus is configured, and there&#8217;s a plugin closure. This &#8220;plugins&#8221; closure defines the plugins, and allows you to place them in the &#8216;lib&#8217; directory. Be sure to rename the plugin zip to remove the &#8216;grails&#8217; part, else it doesn&#8217;t work. Maybe these zips are also available from a Maven repository, which would solve the issue of putting binaries in our source control system, but I haven&#8217;t been able to find them yet. </p>
<p><b>Plugin installation</b><br />
Some plugins, like the jQuery plugin, but also like my own plugin, the <a href="http://www.grails.org/plugin/syntax-highlighter">syntax-highlighter</a>, download resources from the Internet when installing them. I haven&#8217;t been able to work around that yet, but my current solution is to just not use those plugins. I downloaded the jQuery javascript libraries and attached them to the project myself, and since we only use jQuery which does that, this solution is also an adequate fix.</p>
<p><b>Conclusion</b><br />
So, as you can see, with some effort, it&#8217;s possible to make Grails work behind a Proxy Server, or without internet at all. This is a good solution for build servers, so you can have reproducible builds without the need for an Internet connection.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/09/23/friday-repost-making-grails-work-behind-an-proxy-server/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Friday Repost: Groovy Test Data Builder Pattern</title>
		<link>http://www.jworks.nl/2011/09/16/friday-repost-groovy-object-mother-pattern/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=friday-repost-groovy-object-mother-pattern</link>
		<comments>http://www.jworks.nl/2011/09/16/friday-repost-groovy-object-mother-pattern/#comments</comments>
		<pubDate>Fri, 16 Sep 2011 08:00:01 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[friday repost]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=202</guid>
		<description><![CDATA[The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog Most of us value the quality of our code highly. I do, and I expect you, as a reader, also to care for the quality [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F16%2Ffriday-repost-groovy-object-mother-pattern%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F16%2Ffriday-repost-groovy-object-mother-pattern%2F&amp;style=normal&amp;hashtags=friday+repost,groovy,testing&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><i>The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog</i></p>
<p>Most of us value the quality of our code highly. I do, and I expect you, as a reader, also to care for the quality of your code. Because of that, we write tests. Test which usually contain of 3 parts: the setup, the execution and the verification. And sometimes some cleanup. In this blog, I&#8217;d like to focus on the setup part, and try to get rid of some boilerplate code which can easily clutter our tests!</p>
<p>As I mentioned before, we  usually write some setup code which serves as input for our test. This code can look like this:</p>
<pre class="brush: groovy">
def person = new Person(firstName:'Erik', lastName:'Pragt', age:30, married:true, hobby:"programming")
</pre>
<p>Writing this code can be time consuming, plus the code doesn&#8217;t reveal the intention of the test. What are the significant bits in this setup code? Is it the age? Is it my name? Or a combination?</p>
<p>To solve the creation of testdata, there are multiple patterns. On of those patterns is the Test Data Builder pattern. The idea behind the Test Data Builder pattern is that test data should be easily to construct, which is usually accomplished by chaining method calls (also called a Fluent Interface, or a Builder).</p>
<p>I&#8217;ve taken the concept to Groovy and made an TestDataBuilder Category. A Groovy Category adds functionality to your code within a limited scope (defined by the &#8216;use&#8217; keyword). This enables the object which is used in the setup of the test to &#8216;borrow&#8217; the method of the TestDataBuilder Groovy class, which allows it to construct itself with testdata. This is best demonstrated by the use of an example:</p>
<pre class="brush: groovy">
use(TestDataBuilder) {
    def person = Person.build()
}
</pre>
<p>By placing the creation of the data in the scope of the Category, the .build() method becomes available in for the Person class. Calling the build method will instantiate the Person class and populate all the fields with values which all equal true. So numbers will become 1, booleans true, Strings will get the name of the variable as a value, etc.</p>
<p>To use this in tests, and make the code more intention revealing, we can choose to populate some fields with our own values, and have the rest be generated.</p>
<pre class="brush: groovy">
use(TestDataBuilder) {
    def person = Person.build(name:'Erik')

    assert person.name == "Erik"
    assert age == 1
    assert married == true
}
</pre>
<p>The benefits of this is that you save a lot of setup code, and make the code a lot more clear and maintainable. If you want to use this, the code can be found on <a href="http://github.com/bodiam/objectmother/blob/master/src/nl/jworks/util/objectmother/ObjectMother.groovy">GitHub.com</a>. (This class was previously called the ObjectMother, an error on my side. The change in name isn&#8217;t reflected yet in GitHub). Yes, there are some limitations, like it doesn&#8217;t handly all standard datatypes yet (like dates), nor does it populate associations (list with other objects) yet. Have fun, and any feedback on the code would be highly valued!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/09/16/friday-repost-groovy-object-mother-pattern/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friday Repost: Preventing spam with Groovy and Grails</title>
		<link>http://www.jworks.nl/2011/09/09/friday-repost-preventing-spam-with-groovy-and-grails/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=friday-repost-preventing-spam-with-groovy-and-grails</link>
		<comments>http://www.jworks.nl/2011/09/09/friday-repost-preventing-spam-with-groovy-and-grails/#comments</comments>
		<pubDate>Fri, 09 Sep 2011 08:00:36 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[akismet]]></category>
		<category><![CDATA[friday repost]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[spam]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=209</guid>
		<description><![CDATA[The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog When I created the jworks.nl website in Grails, one of my requirements was to have a blog. Since the website is created in Grails, and [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F09%2Ffriday-repost-preventing-spam-with-groovy-and-grails%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F09%2Ffriday-repost-preventing-spam-with-groovy-and-grails%2F&amp;style=normal&amp;hashtags=akismet,friday+repost,grails,groovy,spam&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><i>The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog</i></p>
<p>When I created the <a href="http://www.jworks.nl">jworks.nl</a> website in Grails, one of my requirements was to have a blog. Since the website is created in Grails, and the Grails application doesn&#8217;t integrate easily with a standard blogging solution like WordPress, I decided to create my own blogging solution. But, since this proved to be much more painful than initially anticipated, I migrated the website to a new design and decided to use WordPress instead. However, the plugin creation was fun to do, so I&#8217;m sharing my experiences here.</p>
<p>The current blog consists of little more than just a BlogPost class, and a Comment class. This worked pretty well, and I got the blog up in no time. However, my blog was found by the spam bots, and it got spammed a little. In the first couple of days, I got 3 spam messages a day, which could be easily managed by hand (however still quite annoying). Then, the spam load increased to 10, 100 and then a 1000 per day. Then I got really annoyed, and decided it was time for a solution!</p>
<p>My solution was not to choose a Captcha. Captcha&#8217;s tend to bother the user, making it harder to post feedback. That&#8217;s not something I&#8217;d look forward to. So I created my own solution, based on how WordPress does it.</p>
<p>WordPress has their own spam blocking service, which is called Akismet. The nice thing about Akismet is that their service isn&#8217;t exclusive for WordPress, but they provide an API so others can also use it! Which is exactly what I did: I created a Grails plugin for Akismet, called (surprise surpise!): Grails Akismet! I&#8217;m sure you didn&#8217;t see that coming!</p>
<p>It&#8217;s very simple to use. Just do a &#8216;grails install akismet&#8217;, add your site plus the Aksimet key to your Grails configuration, and you&#8217;re good to go! The plugin provides a Grails Service, which can be injected into most Grails artifacts (like services, domains, and controllers). By using the &#8216;check for spam&#8217; method in the AkismetService, a call to the online Akismet service is done, which determines if the comment is spam or not. Very easy, and very non-intrusive!</p>
<p>So, if you want to get started with the plugin, please check out the <a href="http://www.grails.org/plugin/akismet">documentation</a> and let me know what you think!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/09/09/friday-repost-preventing-spam-with-groovy-and-grails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Friday Repost: Indexing documents with Tika and Grails</title>
		<link>http://www.jworks.nl/2011/09/02/friday-repost-indexing-documents-with-tika-and-grails/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=friday-repost-indexing-documents-with-tika-and-grails</link>
		<comments>http://www.jworks.nl/2011/09/02/friday-repost-indexing-documents-with-tika-and-grails/#comments</comments>
		<pubDate>Fri, 02 Sep 2011 08:00:46 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[friday repost]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[indexing]]></category>
		<category><![CDATA[tika]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=205</guid>
		<description><![CDATA[The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog In one of the previous blogposts, I described a way to easily upload images by using Grails commands. This blogpost further builds on that, by [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F02%2Ffriday-repost-indexing-documents-with-tika-and-grails%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F09%2F02%2Ffriday-repost-indexing-documents-with-tika-and-grails%2F&amp;style=normal&amp;hashtags=friday+repost,grails,groovy,indexing,tika&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><i>The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog</i></p>
<p>In <a href="http://www.jworks.nl/2011/08/05/friday-repost-easy-file-uploading-in-grails/">one of the previous blogposts</a>, I described a way to easily upload images by using Grails commands. This blogpost further builds on that, by providing a generic way to index uploaded documents. These documents can later be retrieved by using the search option provided by the Grails Search plugin.</p>
<p>To index documents, we&#8217;re going to need two components: one of these components is the Grails Search plugin, as described above. The other component is Tika. Tika is a document indexer library which can index many kinds of documents like Text, Word, Excel, Powerpoint, but also more exotic document formats, like MP3 and FLV. Combined with Lucene, this provides a powerful combo.</p>
<p>So, how do we get this to work? Well, first we need the application from the previous blogpost. I refactored it a little to represent the new generic format better. I renamed all references from image to document (so now we have a CreateDocumentCommand instead of a CreateImageCommand, as well as all other references), and I moved the upload.gsp to the views directory, since redirection and forwarding works better that way. After the refactoring was done, I first installed the searchable plugin by typing:</p>
<blockquote><p>
grails install searchable
</p></blockquote>
<p>I also needed Tika, so I added it to the BuildConfig.groovy in the grails-app/conf directory, like this:</p>
<pre class="brush:groovy">
        compile('org.apache.tika:tika-core:0.7')
        compile('org.apache.tika:tika-parsers:0.7') { excludes "xercesImpl", "xmlParserAPIs", "xml-apis", "log4j" }
</pre>
<p>Grails and extra XML libraries really don&#8217;t mix well, so to prevent some nasty class loading issues, better exclude them here. What we need to do now is to tell searchable to index our documents when we upload them. This is quite trivial really, we can just annotate the Document class (which in the previous application was called &#8216;Image&#8217;) with a Tika converter. Then we have to create the converter, register it in Spring, and we should be done. So, first things first: let&#8217;s annotate the Document class.</p>
<p>In the Document class, add a searchable closure with a converter for the byte array, like this:</p>
<pre class="brush:groovy">
package com.example.domain

class Document {
    byte[] bytes

    static searchable = {
        bytes converter: 'tikaConverter'
    }
}
</pre>
<p>We now need to create the TikaConverter. We&#8217;ll create a TikaConverter.groovy in the src/groovy/com/example/converter directory. The class should look like this:</p>
<pre class="brush:groovy">
package com.example.converter

import org.apache.tika.Tika;
import org.compass.core.converter.ConversionException;
import org.compass.core.converter.basic.AbstractBasicConverter
import org.compass.core.mapping.ResourcePropertyMapping
import org.compass.core.marshall.MarshallingContext

class TikaConverter extends AbstractBasicConverter {

    private Tika tika

    TikaConverter() {
        tika = new Tika()
        tika.maxStringLength = -1 // unlimited document length
    }

    @Override
    protected Object doFromString(String str, ResourcePropertyMapping resourcePropertyMapping, MarshallingContext context) throws ConversionException {
        return null // we don't need this
    }

    @Override
    protected String doToString(Object o, ResourcePropertyMapping resourcePropertyMapping, MarshallingContext context) {
        return tika.parseToString(new ByteArrayInputStream(o))
    }

}
</pre>
<p>This class is responsible for extracting text from any kind of document uploaded to the system. To make this converter available, we have to register it in the Spring context, and then we&#8217;re ready to go. To register the Converter in the Spring context, add the following lines to grails-app/conf/spring/resources.groovy:</p>
<pre class="brush:groovy">
import com.example.converter.TikaConverter

beans = {
    tikaConverter(TikaConverter)
}
</pre>
<p>Now everything should be set in place. Browse to: <a href="http://localhost:8080/document-indexing/upload/show">http://localhost:8080/document-indexing/upload/show</a> to upload a document. Any kind of document will do, as long as it contains some text. When the uploading went alright, the document will be available in the Lucene index. You can test this by going to <a href="http://localhost:8080/document-indexing/searchable">http://localhost:8080/document-indexing/searchable</a> and type in some text from the document you have just uploaded. The result should be a result page similar to Google.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/09/02/friday-repost-indexing-documents-with-tika-and-grails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>GStringImpl cannot be cast to java.lang.String</title>
		<link>http://www.jworks.nl/2011/08/29/gstringimpl-cannot-be-cast-to-java-lang-string/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=gstringimpl-cannot-be-cast-to-java-lang-string</link>
		<comments>http://www.jworks.nl/2011/08/29/gstringimpl-cannot-be-cast-to-java-lang-string/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 08:00:00 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=303</guid>
		<description><![CDATA[Last week, we got a nasty error in our application: java.lang.ClassCastException: org.codehaus.groovy.runtime.GStringImpl cannot be cast to java.lang.String The stacktrace was not helpful at all, and showed that the error was caused by a NullPointerException in Melody, which was a false message. After some searching around, we found the following code to be the culprit: render(view: [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F08%2F29%2Fgstringimpl-cannot-be-cast-to-java-lang-string%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F08%2F29%2Fgstringimpl-cannot-be-cast-to-java-lang-string%2F&amp;style=normal&amp;hashtags=jworks&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p>Last week, we got a nasty error in our application:</p>
<blockquote><p>
java.lang.ClassCastException: org.codehaus.groovy.runtime.GStringImpl cannot be cast to java.lang.String
</p></blockquote>
<p>The stacktrace was not helpful at all, and showed that the error was caused by a NullPointerException in Melody, which was a false message. After some searching around, we found the following code to be the culprit:</p>
<pre class="brush:groovy">
render(view: 'index', model: ["${command.class.simpleName}": command)
</pre>
<p>What happens here, is that a GString is used as a map key for rendering the model in the view. It&#8217;s never a good idea to use <a href="http://codenarc.sourceforge.net/codenarc-rules-basic.html" title="CodeNarc Basic Rules" target="_blank">GStrings as a Map key</a>, since the hashCode of GStrings are not guaranteed to be stable. A better approach is to use a String instead, which can be done using the following code:</p>
<pre class="brush:groovy">
render(view: 'index', model: [(command.class.simpleName): command)
</pre>
<p>The above is our current fix, and we changed our <a href="http://codenarc.sourceforge.net" title="CodeNarc" target="_blank">CodeNarc</a> GString as Map key to a prio 1 rule. Whenever a prio 1 error occurs, our build will fail, preventing future errors like this.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/08/29/gstringimpl-cannot-be-cast-to-java-lang-string/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Friday Repost: Groovy&#8217;s @Immutable pitfalls</title>
		<link>http://www.jworks.nl/2011/08/26/friday-repost-groovys-immutable-pitfalls/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=friday-repost-groovys-immutable-pitfalls</link>
		<comments>http://www.jworks.nl/2011/08/26/friday-repost-groovys-immutable-pitfalls/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 08:00:59 +0000</pubDate>
		<dc:creator>Erik Pragt</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[friday repost]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[immutable]]></category>

		<guid isPermaLink="false">http://www.jworks.nl/?p=207</guid>
		<description><![CDATA[The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog. Groovy 1.6 introduced some Groovy AST transformations like @Lazy, @Delegate and @Immutable, and there are more. This blog describes some pitfalls of using @Immutable, but [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="float: right; margin-left: 10px;">
			<a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F08%2F26%2Ffriday-repost-groovys-immutable-pitfalls%2F"><br />
				<img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.jworks.nl%2F2011%2F08%2F26%2Ffriday-repost-groovys-immutable-pitfalls%2F&amp;style=normal&amp;hashtags=friday+repost,groovy,immutable&amp;b=2" height="61" width="50" /><br />
			</a>
		</div>
<p><i>The Friday Repost series are copies from my earlier writings. Since I don&#8217;t want to loose them, and they might prove useful to others, I&#8217;m reposting them on this blog.</i></p>
<p>Groovy 1.6 introduced some Groovy AST transformations like @Lazy, @Delegate and @Immutable, and there are more. This blog describes some pitfalls of using  @Immutable, but to do that, a proper example of @Immutable seems well deserved.
</p>
<p><h3>A first introduction</h3>
<p> @Immutable, like the name suggests, makes your classes immutable. This means that state changes from the outside, for example by the use of setters, are no longer possible. A good use case for this is when building Commands or DTO&#8217;s (also known as Command Query Separation). See for example the following code:
</p>
<pre class="brush: groovy">
class CreateCustomerCommand {
  String name
  Date birthDate
  boolean married
}
</pre>
<p>The state of this class should not change. However, in Groovy, this is a bit harder to do than in Java, since Groovy uses a lot of reflection to invoke properties. So the following is quite valid in Groovy:</p>
<pre class="brush: groovy">
def command = new CreateCustomerCommand(name:'Erik Pragt', married:false)
command.married = true
</pre>
<p>Being able to do so could cause a lot of unexpected things, and a lot of unwanted behavior! To make sure this doesn&#8217;t happen, we can use the @Immutable annotation:</p>
<pre class="brush: groovy">
@Immutable
final class CreateCustomerCommand {
  String name
  Date birthDate
  boolean married
}
</pre>
<p>As you can see, two things have changed: </p>
<ol>
<li>The class is now annotated with @Immutable
<li>The class has been made final, which is a requirement for @Immutable
<ol>
<p>When executing the above code again, an exception will be thrown:</p>
<blockquote><p>
groovy.lang.ReadOnlyPropertyException: Cannot set readonly property: married for class: CreateCustomerCommand
</p></blockquote>
<p>Seems all pretty and cute, right? However, what would happen when someone with evil intentions (or maybe someone with an old Java habbit), decides to create a setter for this class?</p>
<pre class="brush: groovy">
@Immutable
final class CreateCustomerCommand {
  String name
  Date birthDate
  boolean married

  void setMarried(boolean married) {
     this.married = married
  }
}
</pre>
<p>Now, the code does execute without throwing an exception, and suddenly the code is mutable again. Unfortunately, there&#8217;s not much we can do about this, but it breaks the @Immutable contract. There is a small note on this on the <a href="http://groovy.codehaus.org/Immutable+AST+Macro" target="_blank">@Immutable documentation page</a>: </p>
<p><i>&#8220;You don&#8217;t have to follow Groovy&#8217;s normal property conventions, e.g. you can create an explicit private field and then you can write explicit get and set methods. Such an approach, isn&#8217;t currently prohibited (to give you some wiggle room to get around these conventions) but any fields created in this way are deemed not to be part of the significant state of the object and aren&#8217;t factored into the equals or hashCode methods. Use at your own risk!&#8221;</i></p>
<p>
This text describes the other features of @Immutable: an automatic equals and hashCode method. Since the setter breaks the @Immutable behavior, this is excluded from the equals / hashCode generation. However, <b>this only applies</b> when the fields are private! So be aware of that!
</p>
<p><h3>Conclusion</h3>
<p>My conclusion in this is quite simple: don&#8217;t expose state changes to the outside world whenever your intention is to be @Immutable! </p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.jworks.nl/2011/08/26/friday-repost-groovys-immutable-pitfalls/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

