<?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>The Kaptain on ... stuff &#187; Source code</title>
	<atom:link href="http://www.kellyrob99.com/blog/tag/source-code/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kellyrob99.com/blog</link>
	<description>Tales of development, life and the folly that goes along with both</description>
	<lastBuildDate>Thu, 01 Jul 2010 21:07:35 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=abc</generator>
		<item>
		<title>A Grails App Demoing the StackExchange API</title>
		<link>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-grails-app-demoing-the-stackexchange-api</link>
		<comments>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/#comments</comments>
		<pubDate>Thu, 03 Jun 2010 07:12:17 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[Application programming interface]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google Reader]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[HTTP]]></category>
		<category><![CDATA[JSON]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[Representational State Transfer]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Stack Overflow]]></category>
		<category><![CDATA[StackApps]]></category>
		<category><![CDATA[StackExchange]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1367</guid>
		<description><![CDATA[So I was making an attempt to catch up on my Google Reader&#8216;ing this weekend and I came across this post on StackOverflow regarding the shiny new StackExchange API. That and a fresh 1.3.1 drop of Grails seemed like as good a reason as any to hack together a little app suitable for seeing what [...]


Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Permanent Link: Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Permanent Link: Jira Grails Plugin'>Jira Grails Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Permanent Link: Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>So I was making an attempt to catch up on my <a class="zem_slink" href="http://www.google.com/reader" title="Google Reader" rel="homepage">Google Reader</a>&#8216;ing this weekend and I came across <a href="http://blog.stackoverflow.com/2010/05/stack-exchange-api-contest/">this post on StackOverflow</a> regarding the shiny new <a class="zem_slink" href="http://www.stackexchange.com" title="StackExchange" rel="homepage">StackExchange</a> <a class="zem_slink" href="http://en.wikipedia.org/wiki/Application_programming_interface" title="Application programming interface" rel="wikipedia">API</a>. That and a fresh 1.3.1 drop of <a class="zem_slink" href="http://grails.org" title="Grails (framework)" rel="homepage">Grails</a> seemed like as good a reason as any to hack together a little app suitable for seeing what you can do with said API.<br />
Turns out it&#8217;s not a whole lot, at least not yet. The minor detraction of having  read-only access and limited connects without an API key are more than offset by seeing such a minimal, clean and easy to use interface. According to the grails stats script, it took about this much effort to implement calls to each and every one of the API endpoints for all of the supported domains:</p>
<pre class="brush: xml;">
    +----------------------+-------+-------+
    | Name                 | Files |  LOC  |
    +----------------------+-------+-------+
    | Controllers          |     1 |    42 |
    | Groovy Helpers       |     1 |    47 |
    +----------------------+-------+-------+
    | Totals               |     2 |    89 |
    +----------------------+-------+-------+
</pre>
<p>
Please note that this is about as minimal as you could reasonably get away with(and kinda ugly to boot), but nevertheless it does manage to implement a UI and backend for exercising the entire API in a total of 2 gsp files and 1 controller action.  What&#8217;s noticeably missing are some tailored views for each of the different <a class="zem_slink" href="http://json.org/" title="JSON" rel="homepage">JSON</a> responses and the implementation of additional query parameters on the calls.</p>
<p></p>
<h2>StackExchange API</h2>
<p>This is really <a href="http://api.stackoverflow.com/0.8/help">pretty well documented</a> and &#8220;consistent&#8221;. Calls in some cases require an {id} in the url and that&#8217;s about it. Each of the individual calls has its own help page that describes the options, like the <a href="http://api.stackoverflow.com/0.8/help/method?method=badges">badges page</a> for instance. To make things a little more helpful while exploring the API, each of the implemented endpoints in this app are also hyper-linked to the corresponding manual page on api.stackoverflow.com.</p>
<p></p>
<h2><a class="zem_slink" href="http://en.wikipedia.org/wiki/Representational_State_Transfer" title="Representational State Transfer" rel="wikipedia">RESTful</a> Access</h2>
<p>Couldn&#8217;t be a whole lot easier than using <a href="http://groovy.codehaus.org/modules/http-builder/">HttpBuilder</a>, which provides nice and concise ways to execute the GET request, inspect the response and deal with success/failure of the request. Aside from assigning the root domain and method using variables, this is little different from the <a href="http://groovy.codehaus.org/HTTP+Builder">canonical example on codehaus</a>.</p>
<pre class="brush: groovy;">
def http = new HTTPBuilder(&quot;http://api.$domain&quot;)
http.request(GET, JSON) {
    uri.path = &quot;/${VERSION}$method&quot;
    headers.'User-Agent' = 'Mozilla/5.0 Ubuntu/8.10 Firefox/3.0.4'
     response.success = { resp, json -&gt;
        answer = json
    }
     response.failure = { resp -&gt;
        answer = &quot;Unexpected error: ${resp.statusLine.statusCode} : ${resp.statusLine.reasonPhrase}&quot;
    }
}
</pre>
<p>The syntax here could probably get even Groovier using the <a href="http://www.grails.org/plugin/rest">Grails REST client plugin</a> wrappers, and indeed incorporating that plugin is how the HttpBuilder dependency is being provided in this app, but I hit on a working implementation first time out so we&#8217;ll leave that for another day, shall we?</p>
<p></p>
<h2>What&#8217;s it Look Like?</h2>
<p><img src='http://www.kellyrob99.com/blog/wp-content/gallery/stackoverflow-api-grails/stackapps-demo_1275451039026.png' alt='stackapps-demo' class='ngg-singlepic ngg-none'  width='860' height='480'/><br />
Did I mention it was ugly?  Where the API call requires a parameter, you get a text field. Each domain gets its own submit button, officially representing my first attempted usage of g:actionSubmit in Grails. Doesn&#8217;t work quite the way I expected, but it does certainly work. Click a button and you&#8217;re shown the raw JSON result, along with the call you made. In an ugly fashion, or did I say that already? Still, for a couple of hours of hacking, I&#8217;m not unhappy with the result.</p>
<p></p>
<h2>StackApps</h2>
<p>This is where the apps in the contest get shown off and, in a wonderful display of <a href="http://en.wikipedia.org/wiki/Eating_your_own_dog_food">dogfooding</a>, it&#8217;s guess what &#8211; another StackOverflow clone! The page for this application <a href="http://stackapps.com/questions/491/a-grails-app-demoing-the-stackexchange-api">can be found here</a>. And the <a href="http://github.com/kellyrob99/stackoverflow-api-grails">source code is up on github</a> if you&#8217;d like to take a look.</p>
<p></p>
<h2>Next Steps?</h2>
<p>Toying with the idea of porting this to appengine, which would unfortunately mean replacing HttpBuilder and the underlying Apache HttpClient in favor of something that didn&#8217;t use a threaded approach, most likely using <a href="http://code.google.com/appengine/docs/java/urlfetch/">URL fetch</a>. That and some slightly less ugly tabular and/or tree views of the JSON responses would be kinda nice to have.<br />
 <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<!-- AdSense Now! V1.95 -->
<!-- Post[count: 3] -->
<div class="adsense adsense-leadout" style="float:right;margin: 12px;"><script type="text/javascript"><!--
google_ad_client = "pub-6955914197200080";
/* 728x90, created 8/3/09 */
google_ad_slot = "4051815125";
google_ad_width = 728;
google_ad_height = 90;
//-->
</script>
<script type="text/javascript"
src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script></div><p align="left"><a class="tt" href="http://twitter.com/home/?status=A+Grails+App+Demoing+the+StackExchange+API+http://7tpnr.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.kellyrob99.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=A+Grails+App+Demoing+the+StackExchange+API+http://7tpnr.th8.us" title="Post to Twitter">Tweet This Post</a></p>

<p>Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/10/25/grails-ui-datatable-using-xml-for-a-model/' rel='bookmark' title='Permanent Link: Grails-UI DataTable using XML for a model'>Grails-UI DataTable using XML for a model</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Permanent Link: Jira Grails Plugin'>Jira Grails Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/03/21/gource-visualizations-of-the-groovygrailsgriffon-projects/' rel='bookmark' title='Permanent Link: Gource Visualizations of the Groovy/Grails/Griffon Projects'>Gource Visualizations of the Groovy/Grails/Griffon Projects</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/06/02/a-grails-app-demoing-the-stackexchange-api/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Groovy and Hibernate Validator for Dynamic Constraints</title>
		<link>http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=groovy-and-hibernate-validator-for-dynamic-constraints</link>
		<comments>http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/#comments</comments>
		<pubDate>Sun, 18 Apr 2010 06:17:50 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Hibernate]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[JBoss Seam]]></category>
		<category><![CDATA[kellyrob99.com]]></category>
		<category><![CDATA[Languages]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[User interface]]></category>
		<category><![CDATA[validator]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1263</guid>
		<description><![CDATA[I was reading this article about hibernate validator today and it inspired me to apply a little Groovy to the problem of validating a bean. More specifically, finding out how hard it would be to apply different validation rules to the same classes at runtime. Turns out it&#8217;s really pretty simple. Hibernate validator, if you [...]


Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Permanent Link: Jira Grails Plugin'>Jira Grails Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Permanent Link: Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/' rel='bookmark' title='Permanent Link: Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration'>Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I was reading <a href="http://java.dzone.com/articles/using-hibernate-validator">this article about hibernate validator</a> today and it inspired me to apply a little <a class="zem_slink" href="http://groovy.codehaus.org" title="Groovy (programming language)" rel="homepage">Groovy</a> to the problem of validating a bean.  More specifically, finding out how hard it would be to apply different validation rules to the same classes at runtime. Turns out it&#8217;s really pretty simple.<br />
<a href="http://www.hibernate.org/subprojects/validator/download.html">Hibernate validator</a>, if you didn&#8217;t already know, is the reference implementation of <a href="http://jcp.org/en/jsr/detail?id=303">JSR-303</a> and it provides the ability to specify by xml or annotation configuration validation rules for pojos.</p>
<p></p>
<h2>Where Hibernate Validator Shines</h2>
<p>Annotations on domain classes allow for easily validating object state at the time of persistence. Excellent integration with frameworks like <a class="zem_slink" href="http://www.seamframework.org" title="JBoss Seam" rel="homepage">JBoss Seam</a> allow this same ability to be utilized for validating web forms on the client-side with little more than an <a href="http://docs.jboss.org/seam/1.2.1.GA/reference/en/html/validation.html">&lt;s:validateAll/&gt; tag</a>. Seam practically hides the entire interaction with validation components from the developer. Since validation rules are defined directly in the domain class, you can (almost) guarantee that no objects with inconsistent state will ever end up being saved in your database.  There are certain validations that aren&#8217;t possible to verify without actually looking in the database, unique constraints for example, but generally in my experience hibernate validator is extremely easy to configure and work with. Implementing <a class="zem_slink" href="http://en.wikipedia.org/wiki/Create%2C_read%2C_update_and_delete" title="Create, read, update and delete" rel="wikipedia">CRUD</a> functionality is pretty trivial, and UIs can achieve consistency since all validations are applied equally.<br />
Alternatively, if you can&#8217;t or don&#8217;t want to use annotations for some reason, you can specify your validation rules in an xml file. Usually a singleton validation.xml file is made available on the classpath and picked up automagically when a ValidationFactory is created. A simple xml configuration looks like this:</p>
<pre class="brush: xml;">
&lt;constraint-mappings xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemalocation=&quot;http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd&quot; xmlns=&quot;http://jboss.org/xml/ns/javax/validation/mapping&quot;&gt;
    &lt;default-package&gt;org.kar.test&lt;/default-package&gt;
    &lt;bean class=&quot;ValidateTestableClass&quot;&gt;
        &lt;field name=&quot;name&quot;&gt;
            &lt;constraint annotation=&quot;javax.validation.constraints.NotNull&quot;&gt;
        &lt;/constraint&gt;
    &lt;/field&gt;
&lt;/bean&gt;
</pre>
<p>and is meant to be applied to this simple class:</p>
<pre class="brush: groovy;">
class ValidateTestableClass
{
    int id
    String name
    String description
    boolean enabled
}
</pre>
<p></p>
<h2>Comparing with <a class="zem_slink" href="http://grails.org" title="Grails (framework)" rel="homepage">Grails</a> Validation</h2>
<p>Grails automatically provides <a href="http://www.grails.org/doc/latest/guide/7.%20Validation.html">validation capabilities</a> for domain classes and command objects, and enables adding the same behavior to any pogo through a combination of the @Validateable annotation and a static constraints closure. Adding validation support to arbitrary classes also requires specifying which packages to scan for the annotation.<br />
Plugin support from projects like <a href="http://www.grails.org/plugin/bean-fields">bean-fields</a> simplifies the handling of client-side validation and rendering error markers in the UI, an ability which the Grails framework provides natively by adding an &#8216;errors&#8217; field directly onto the domain or command object class instances bound to a web form.</p>
<p></p>
<h2>Dynamic Constraints</h2>
<p>Both the hibernate validator and the Grails strategies for applying validation described here have the same limitation: both are universally applied to all instances of a class. There&#8217;s no easy apparent way to override those constraints at runtime, although I suspect that some fancy MOP&#8217;ing or configuration could probably be used to accomplish overrides at runtime.<br />
Hibernate validator also supports creation of ad hoc validators by seeding with one or more xml documents. Or if you&#8217;re like me and hate hand editing xml, you can leverage Groovy to take a bit of the pain away. Here&#8217;s the same xml snippet from above in a Groovy Closure, generated simply by turning the DomToGroovy class loose on the raw xml:</p>
<pre class="brush: groovy;">
looseConstraint = {
        mkp.declareNamespace(xsi: 'http://www.w3.org/2001/XMLSchema-instance')
        'constraint-mappings'(xmlns: 'http://jboss.org/xml/ns/javax/validation/mapping',
                'xsi:schemaLocation': 'http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd') {
            'default-package'('org.kar.test.objects')
            bean('class': 'ValidateTestableClass') {
                field(name: 'name') {
                    constraint(annotation: 'javax.validation.constraints.NotNull')
                }
            }
        }
    }
</pre>
<p>Losing all the angle brackets is a good start, but we really haven&#8217;t saved a lot of typing. Until you start taking advantage of the ability to define more complicated structures. Note the use of a list structure here to apply NotNull constraints to multiple fields.</p>
<pre class="brush: groovy;">
strictConstraint = {
        mkp.declareNamespace(xsi: 'http://www.w3.org/2001/XMLSchema-instance')
        'constraint-mappings'(xmlns: 'http://jboss.org/xml/ns/javax/validation/mapping',
                'xsi:schemaLocation': 'http://jboss.org/xml/ns/javax/validation/mapping validation-mapping-1.0.xsd') {
            'default-package'('org.kar.test.objects')
            bean('class': 'ValidateTestableClass') {
                ['name', 'description'].each {
                    field(name: it) {
                        constraint(annotation: 'javax.validation.constraints.NotNull')
                    }
                }
                field(name: 'id') {
                    constraint(annotation: 'javax.validation.constraints.DecimalMin') {
                        element(name: 'value', '2')
                    }
                }
                field(name: 'enabled') {
                    constraint(annotation: 'javax.validation.constraints.AssertTrue')
                }
            }
        }
    }
</pre>
<p></p>
<h2>Applying Dynamic Constraints</h2>
<p>Applying constraints is as simple as converting Closures to xml and mapping them to a Configuration object, which then supplies a Validator to use. StreamingMarkupBuilder is utilized to create the xml behind the scenes.</p>
<pre class="brush: groovy;">
    /**
     * Create a configuration object passing closures as validation mapping documents.
     * @param closures closures to render into validation mapping documents
     * @return config
     */
    public Configuration createConfig(Closure... closures)
    {
        Configuration config = Validation.byDefaultProvider().configure()
        closures.each {
            config.addMapping(new ByteArrayInputStream(GroovyXmlConversionUtil.convertToXml(it).bytes))
        }
        config
    }
</pre>
<p>I haven&#8217;t tested the use of multiple mappings extensively, but minimally each class you&#8217;re configuring must be confined to a single mapping &#8211; you can&#8217;t extend the validations by layering configurations on top of one another. You should however be able to map constraints for different classes in separate Closures.</p>
<p></p>
<h2>Crying out for a Builder!</h2>
<p>Going from Closures to xml is a quick and dirty way to test out this functionality, but what would really be nice is a Builder that could create an appropriate validation environment more directly. At the least it would allow for removing the namespace declarations and explicit package naming that make up the bulk of the content.</p>
<h2>So what do you get?</h2>
<ol>
<li>1. Ability to declare validations against any existing <a class="zem_slink" href="http://java.sun.com" title="Java (programming language)" rel="homepage">Java</a> or Groovy class without changing the source code</li>
<li>2. Programmatic ability to create the configuration of validations</li>
<li>3. A choice of which validations to apply at runtime</li>
<li>4. Consistency with the behavior of domain class validation</li>
</ol>
<p>And what&#8217;d I get? A fun bit of quick coding on a Saturday afternoon. Nice! Source code is <a href="http://github.com/kellyrob99/groovy-hibernate-validator">available on git-hub</a> if you want to check it out.</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" title="Reblog this post [with Zemanta]" href="http://reblog.zemanta.com/zemified/c83e9a1b-1079-49a8-80cb-95c76b967f69/"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=c83e9a1b-1079-49a8-80cb-95c76b967f69" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script src="http://static.zemanta.com/readside/loader.js" type="text/javascript"></script></span></div>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Groovy+and+Hibernate+Validator+for+Dynamic+Constraints+http://xi38w.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.kellyrob99.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=Groovy+and+Hibernate+Validator+for+Dynamic+Constraints+http://xi38w.th8.us" title="Post to Twitter">Tweet This Post</a></p>

<p>Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/12/16/jira-grails-plugin/' rel='bookmark' title='Permanent Link: Jira Grails Plugin'>Jira Grails Plugin</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/14/groovy-and-bash-can-scripting-get-much-easier/' rel='bookmark' title='Permanent Link: Groovy and Bash &#8211; can scripting get much easier?'>Groovy and Bash &#8211; can scripting get much easier?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/05/10/gracelets-and-seam-a-dsl-for-facelets-with-easy-integration/' rel='bookmark' title='Permanent Link: Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration'>Gracelets and Seam &#8211; a DSL for Facelets and Groovy with easy integration</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Breaking Weak CAPTCHA in&#8230; slightly more than 26 Lines of Groovy Code</title>
		<link>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code</link>
		<comments>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/#comments</comments>
		<pubDate>Sun, 14 Mar 2010 23:44:59 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Application programming interface]]></category>
		<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Java2D]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[Open source]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[tesseract-ocr]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1158</guid>
		<description><![CDATA[I read an interesting article recently about using python and open source software to defeat a particular captcha implementation and I set out to see how hard it would be to do the same in Groovy. In particular, coming from the Java side of the fence, I was impressed by how the available libraries in [...]


Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Permanent Link: Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/' rel='bookmark' title='Permanent Link: Groovy and CSV: How to Get Your Data Out?'>Groovy and CSV: How to Get Your Data Out?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Permanent Link: Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I read <a href="http://www.bonsai-sec.com/blog/index.php/breaking-weak-captcha-in-26-lines-of-code/">an interesting article</a> recently about using python and <a class="zem_slink" href="http://www.wikinvest.com/concept/Open_Source" title="Open Source" rel="wikinvest">open source</a> software to defeat a particular captcha implementation and I set out to see how hard it would be to do the same in Groovy. In particular, coming from the <a class="zem_slink" href="http://java.sun.com" title="Java (programming language)" rel="homepage">Java</a> side of the fence, I was impressed by how the available libraries in python made loading, mutating and saving images so easy. Admittedly I have limited experience working with image data, but when I have it has always seemed like a complex(and easy to get wrong) process. Maybe there&#8217;s a Java library out there that provides a simple &#8216;image_resize&#8217; method, but it&#8217;s certainly not in the BufferedImage <a class="zem_slink" href="http://en.wikipedia.org/wiki/Application_programming_interface" title="Application programming interface" rel="wikipedia">API</a>. Still, when porting the 26 lines of code over to Groovy, I was able to get it considerably less verbose than the Java equivalent.</p>
<p></p>
<h2>The Pretty Pictures</h2>
<p>Here are the three images to test against. In order to put them in a suitable format for <a href="http://code.google.com/p/tesseract-ocr">the open source tesseract-ocr program</a> to process we need to make them bigger, remove the background noise and transform them into a &#8216;tif&#8217; format. The python program we&#8217;re porting utilizes the PIL library for image handling and the pytesseract library for wrapping tesseract; I didn&#8217;t look very hard for java equivalents and just coded the required functions directly.</p>
<table>
<tbody>
<tr>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/9koo.gif" title="Original image for 9koO" class="shutterset_singlepic58" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/58__x_9koo.gif" alt="9koo" title="9koo" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/jxt9.gif" title="Original image for jxt9" class="shutterset_singlepic60" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/60__x_jxt9.gif" alt="jxt9" title="jxt9" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/e4ya.gif" title="Original image for e4ya" class="shutterset_singlepic59" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/59__x_e4ya.gif" alt="e4ya" title="e4ya" />
</a>
</td>
</tr>
</tbody>
</table>
<p></p>
<h2>Reading in the Image</h2>
<p>The python code for this is three lines, one to load the image and a couple more to convert it into a format suitable for directly manipulating pixel color through <a class="zem_slink" href="http://en.wikipedia.org/wiki/RGB_color_model" title="RGB color model" rel="wikipedia">RGB</a> values. Groovy takes a bit more to do the same, but being able to use a &#8216;with&#8217; block makes interacting with the Graphics object a lot cleaner than the same Java code</p>
<pre class="brush: groovy;">
//python
from PIL import Image
img = Image.open('input.gif')
img = img.convert(&quot;RGBA&quot;)
pixdata = img.load()

//Groovy
BufferedImage image = ImageIO.read(new File(fileName))
BufferedImage dimg = new BufferedImage(image.width, image.height, BufferedImage.TYPE_INT_ARGB)
dimg.createGraphics().with {
    setComposite(AlphaComposite.Src)
    drawImage(image, null, 0, 0)
    dispose()
}
</pre>
<p></p>
<h2>Removing the Background Noise</h2>
<p>In both cases we&#8217;re doing essentially the same thing: finding all non-black pixels and setting them to white. This leaves only the actual embedded text to stand out. Being able to utilize the Java Color constants makes the Groovy version a little more readable, IMO, but otherwise the two pieces of code are generally equivalent.</p>
<pre class="brush: groovy;">
//python
for y in xrange(img.size[1]):
    for x in xrange(img.size[0]):
        if pixdata[x, y] != (0, 0, 0, 255):
            pixdata[x, y] = (255, 255, 255, 255)

//Groovy
(0..&lt;dimg.height).each {i=&quot;&quot; -=&quot;&quot;&gt;
    (0..&lt;dimg.width).each {j=&quot;&quot; -=&quot;&quot;&gt;
        if (dimg.getRGB(j, i) != Color.BLACK.RGB)
        {
            dimg.setRGB(j, i, Color.WHITE.RGB)
        }
    }
}
</pre>
<p></p>
<h2>Resizing the Image</h2>
<p><a class="zem_slink" href="http://www.python.org/" title="Python (programming language)" rel="homepage">Python</a>&#8216;s library usage really shines here, making this a one line call. Not quite the same in Java-land, although again there&#8217;s probably a better way to do this(I just don&#8217;t know it offhand).</p>
<pre class="brush: groovy;">
//python
big = im_orig.resize((116, 56), Image.NEAREST)

//Groovy
dimg = resizeImage(dimg, 116, 56)
...
def resizeImage = {BufferedImage image, int w, int h -&amp;gt;
    BufferedImage dimg = new BufferedImage(w, h, image.type)
    dimg.createGraphics().with {
        setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR)
        drawImage(image, 0, 0, w, h, 0, 0, image.width, image.height, null)
        dispose()
    }
    return dimg
}
</pre>
<p>By this point the original images now look like this, and are <i>almost</i> ready for OCR.</p>
<table>
<tbody>
<tr>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp0.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic61" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/61__x_tmp0.gif" alt="9koO-readyForOCR" title="9koO-readyForOCR" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp1.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic62" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/62__x_tmp1.gif" alt="jxt9-readyForOCR" title="jxt9-readyForOCR" />
</a>
</td>
<td>
<a href="http://www.kellyrob99.com/blog/wp-content/gallery/captcha-breaker/tmp2.gif" title="Resized and cleaned for OCR" class="shutterset_singlepic63" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/63__x_tmp2.gif" alt="e4ya-readyForOCR" title="e4ya-readyForOCR" />
</a>
</td>
</tr>
</tbody>
</table>
<p></p>
<h2>Converting to a tif File</h2>
<p>This one turns out to be a bit of a PITA in Java and particularly on a Mac, and represents the bulk of the Groovy code. Unfortunately it is also the only format that tesseract appears to accept &#8216;out of the box&#8217;.  After googling the fun that is JAI and working with the <a class="zem_slink" href="http://en.wikipedia.org/wiki/Tagged_Image_File_Format" title="Tagged Image File Format" rel="wikipedia">.tif</a>(f) format with it on a Mac,   I ended up taking the code kindly provided in <a href="http://www.ideyatech.com/2009/05/converting-to-tiff-on-mac-using-java-advanced-imaging/">this blog post</a> and Groovified it a bit to make a working transformation. Thanks very much to Allan Tan for that. One more time, there&#8217;s likely a better/easier way to do this, but honestly it&#8217;s more effort than I&#8217;m willing to put in on a weekend afternoon just to satisfy my curiosity.<br />
 <img src='http://www.kellyrob99.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<pre class="brush: groovy;">
//python
ext = &quot;.tif&quot;
big.save(&quot;input-NEAREST&quot; + ext)

//Groovy
void convertToTiff(String inputFile, String outputFile)
{
    OutputStream ios
    try
    {
        ios = new BufferedOutputStream(new FileOutputStream(new File(outputFile)))
        ImageEncoder enc = ImageCodec.createImageEncoder(&quot;tiff&quot;, ios, new TIFFEncodeParam(compression: TIFFEncodeParam.COMPRESSION_NONE, littleEndian: false))
        RenderedOp src = JAI.create(&quot;fileload&quot;, inputFile)

        //Apply the color filter and return the result.
        ColorConvertOp filterObj = new ColorConvertOp(ColorSpace.getInstance(ColorSpace.CS_sRGB), null)
        BufferedImage dst = new BufferedImage(src.width, src.height, BufferedImage.TYPE_3BYTE_BGR)
        filterObj.filter(src.getAsBufferedImage(), dst)

        // save the output file
        enc.encode(dst)
    }
    catch (Exception e)
    {
        println e
    }
    finally
    {
        ios.close()
    }
}
</pre>
<p></p>
<h2>OCR with Tesseract-OCR</h2>
<p>Finally we need to pass the processed image to tesseract so it can &#8216;read&#8217; it for us. Again, the python library makes this a breeze, but calling out to a command line program with Groovy is so simple that it ends up being about the same. Tesseract itself is available as a macport, as well in downloadable unix binaries and a windows executable so installing the software is a breeze.</p>
<pre class="brush: groovy;">
//python
from pytesser import *
image = Image.open('input-NEAREST.tif')
print image_to_string(image)

//Groovy
def tesseract = ['/opt/local/bin/tesseract', tmpTif, tmpTesseract].execute()
tesseract.waitFor()
return new File(&quot;${tmpTesseract}.txt&quot;).readLines()[0]
</pre>
<p></p>
<h2>Testing it out</h2>
<p>To test it out I implemented the code in a maven project, iterate over the images and write out intermediate results to a temp directory. And it only works on two out of three of the cases. For some reason tesseract insists on consistently seeing &#8216;e4ya&#8217; as &#8216;e4ga&#8217;.  I tried to see if I could get it working by tweaking the image manipulation parameters and the order of operations(resizing before removing the background noise for instance) but that just caused the other cases to fail as well. Since in the final image the &#8216;y&#8217; seems pretty clear, it&#8217;s more likely that tweaking tesseract configuration might yield better results.</p>
<pre class="brush: groovy;">
public void testPrintImage()
{
    def breaker = new CaptchaBreaker()
    /* tesseract interprets &quot;e4ya&quot; as &quot;e4ga&quot; unfortunately */
    ['9koO', 'jxt9'/*,'e4ya'*/].each {String imageName -&amp;gt;
        def fileName = &quot;src/test/resources/${imageName}.gif&quot;
        assertEquals(&quot;Testing $imageName&quot;,imageName, breaker.imageToString(fileName))
    }
}
</pre>
<p></p>
<h2>C&#8217;est Finis</h2>
<p>I had some fun playing with areas of Java that I don&#8217;t usually interact with, and gained some appreciation for the diversity and ease-of-use exposed by just a couple of python libraries. It&#8217;s comforting to note that I was able to implement all of the required functionality from those libraries in &lt; 90 lines of Groovy. With a little more effort I think the final product could be tweaked to avoid the intermediate file system reads/writes as well, but that&#8217;s for another day.<br />
Source code is <a href="http://github.com/kellyrob99/catcha-breaker">available on github</a> if you&#8217;d care to take a look, and thanks for stopping by!</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/7a2ae51d-774b-47b5-894b-592c38ebf542/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=7a2ae51d-774b-47b5-894b-592c38ebf542" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Breaking+Weak+CAPTCHA+in%E2%80%A6+slightly+more+than+26+Lines+of+Groovy+Code+http://zy6pc.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.kellyrob99.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=Breaking+Weak+CAPTCHA+in%E2%80%A6+slightly+more+than+26+Lines+of+Groovy+Code+http://zy6pc.th8.us" title="Post to Twitter">Tweet This Post</a></p>

<p>Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/' rel='bookmark' title='Permanent Link: Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;'>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/07/01/groovy-and-csv-how-to-get-your-data-out/' rel='bookmark' title='Permanent Link: Groovy and CSV: How to Get Your Data Out?'>Groovy and CSV: How to Get Your Data Out?</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/04/17/groovy-and-hibernate-validator-for-dynamic-constraints/' rel='bookmark' title='Permanent Link: Groovy and Hibernate Validator for Dynamic Constraints'>Groovy and Hibernate Validator for Dynamic Constraints</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/03/14/breaking-weak-captcha-in-slightly-more-than-26-lines-of-groovy-code/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>A One Day Griffon Application/Presentation</title>
		<link>http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=a-one-day-griffon-applicationpresentation</link>
		<comments>http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 05:15:57 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[Collections]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Griffon]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[kellyrob99]]></category>
		<category><![CDATA[plugin architecture]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[slideware]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[Swing]]></category>
		<category><![CDATA[TestNG]]></category>
		<category><![CDATA[theKaptain]]></category>
		<category><![CDATA[Transitions2D]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=1072</guid>
		<description><![CDATA[I took the opportunity this past weekend to test drive the latest beta version of Griffon and along with it the as-of-yet unreleased slideware plugin. If you&#8217;re not already aware, Griffon is a Grails inspired framework for creating Java Swing applications. The project lead, Andres Almiray, has given several presentations using this plugin and it [...]


Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/' rel='bookmark' title='Permanent Link: VIJUG Griffon/Groovy Presentation'>VIJUG Griffon/Groovy Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Permanent Link: Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/swingset-on-griffon/' rel='bookmark' title='Permanent Link: SwingSet on Griffon'>SwingSet on Griffon</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>I took the opportunity this past weekend to test drive the latest beta version of <a href="http://griffon.codehaus.org/">Griffon</a> and along with it the as-of-yet unreleased slideware plugin. If you&#8217;re not already aware, Griffon is a Grails inspired framework for creating <a class="zem_slink" href="http://en.wikipedia.org/wiki/Swing_%28Java%29" title="Swing (Java)" rel="wikipedia">Java Swing</a> applications. The project lead, Andres Almiray, has given several presentations using this plugin and it provides an excellent platform for showcasing both the power of Swing and the capabilities of Griffon to make it all look so easy.</p>
<p>The slideware plugin provides a framework for creating presentations with a little twist &#8211; you can execute code live from the presentation software.  If you&#8217;ve ever given a presentation about programming you probably are fully aware of the transition from presentation software to your preferred environment for demonstrating code samples. Well, now you can stay entirely within the same application, editing and running code live.</p>
<p>The plugin itself isn&#8217;t available from the Griffon repository but source code and a built 0.2 version can be <a href="http://github.com/aalmiray/Presentations">found on github</a>.  Considering both the youth of the plugin and the beta status of the framework, it worked impressively well AND had a rich feature set.  All of the expected &#8220;powerpoint&#8221; features are there: themes, layout control, styling, slide transitions and export are all pretty easy to incorporate and configure. The code editor view also works very well. A great variety of additional plugins are harnessed to put all the pieces together and as a result building one of these applications is a great way to tour the platform.</p>
<p></p>
<h2>Theming</h2>
<p>Applying a theme to the presentation is simply selecting a Java Look and Feel to apply in Initialize.groovy. The Substance jar is included with the plugin so I test drove a few of the nice setups in there and finally settled on the SubstanceMagmaLookAndFeel. There is definitely a wide variety of L&amp;F&#8217;s to choose from in that bundle alone and, although I haven&#8217;t done it myself, they seem pretty tweakable as well. Plus any old L&amp;F should plug in nicely, I would imagine. </p>
<pre class="brush: groovy;">
//Initialize.groovy
SwingBuilder.lookAndFeel('org.jvnet.substance.skin.SubstanceMagmaLookAndFeel',
       'mac', 'nimbus', 'gtk', ['metal', [boldFonts: false]])
</pre>
<p></p>
<h2>Layout</h2>
<p>Controlling the page composition is a standard Swing Layout or, in the case of the default slide you get with the included &#8220;create-slide&#8221; script, a MigLayout. Framing the standard variety of slides is very simple. Bulleted pages, title slides, code slides and custom layouts are very easy to accomplish. I don&#8217;t have a lot of experience using this particular layout but the presentations Andres has made available on github have a good diversity of examples of how they look in practice.</p>
<pre class="brush: groovy;">
//the default create-slide generated template
import net.miginfocom.swing.MigLayout

slide(id: &quot;slide0&quot;, layout: new MigLayout(&quot;fill&quot;,&quot;[center]&quot;,&quot;[center]&quot;)) {
    label(&quot;Insert your text here&quot;)
}
</pre>
<p></p>
<h2>Styling</h2>
<p>Styling is supplied by the css plugin, on which slideware has a dependency. The default style.css file sets out just some reasonable defaults for the fonts used in different parts of the app, and I didn&#8217;t see any real need to fiddle with it. Especially happy to see the nice monospace code font. On a totally related note I recently installed the <a href="http://www.levien.com/type/myfonts/inconsolata.html">Inconsolata</a> monospace font to try for development and I&#8217;ve been very happy seeing it in my editor, but it&#8217;s still nice to see this kind of polish applied to the presentation. The code editor view even includes syntax highlighting! More on that coming right up&#8230;</p>
<p></p>
<h2>Slide Transitions</h2>
<p>Moving between slides with style is the responsibility of the <a href="http://griffon.codehaus.org/Transitions+Plugin">transitions plugin</a>. You can see see all of the animations this plugin enables over here at <a href="http://javagraphics.blogspot.com/2007/04/slideshows-transitions-swf.html">this page describing Transitions and Transition2Ds</a>. Pretty slick stuff and defined as simply as a parameter to each &#8220;slide&#8221; node in a script.</p>
<pre class="brush: groovy;">
slide(id: &quot;slide3&quot;, layout: new MigLayout(&quot;fill&quot;,&quot;3%[center]3%&quot;,&quot;3%[center]3%&quot;),
        title: &quot;Junit3&quot;,
        transition: new FlurryTransition2D(Transition2D.OUT)) {
    scrollPane(constraints: &quot;grow&quot;) {
        widget(createEditor(text: script))
    }
}
</pre>
<p></p>
<h2>Code Editor</h2>
<p>Code slides embed an editable widget and allow for composing and executing Groovy scripts or classes of arbitrary complexity. You can execute the code with a keyboard shortcut and a window will open displaying the console output. The code itself is executed through a GroovyShell, enabling pretty much anything you might want to do. If you have an internet connection and the required repositories configured, Grapes simplifies packaging the dependencies for the application as your code samples can directly Grab the jars they need. Basically, the first time you execute a code slide you&#8217;ll have to put up with a small pause while Ivy downloads to your local repository, unless of course the required dependencies are already there.  In my case I changed strategies from including jars in the application lib directory to a Grapes approach and I think it&#8217;s a better way to go.</p>
<p>I was surprised to find that the editor even included undo functionality. It&#8217;s definitely not close to a full blown IDE, and there&#8217;s absolutely no reason that it should be. For the task of demoing simple code examples it&#8217;s more than up to the task, even to the point of maintaining your edits between slide transitions, allowing you to move back and forth through the slide deck without any state problems.<br />

<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-04-pm.png" title="Code slide with JUnit4 and Hamcrest matcher example" class="shutterset_singlepic38" >
	<img class="ngg-singlepic" src="http://www.kellyrob99.com/blog/wp-content/gallery/cache/38__x_screen-shot-2010-02-11-at-7-47-04-pm.png" alt="Code slide with JUnit4 and Hamcrest matcher example" title="Code slide with JUnit4 and Hamcrest matcher example" />
</a>
</p>
<p></p>
<h2>Export</h2>
<p>The application includes a &#8220;Print&#8221; feature which iterates through the entire slide deck and renders it to a pdf. Distribution of one of these presentations is really very easy, including the ability to create installers for all major platforms simply by adding the packaging plugin.</p>
<p></p>
<h2>Test Application</h2>
<p>The test app I built while looking into this is pretty simple. It&#8217;s got a title slide, a bullet slide and 4 code slides. The code simply demonstrates how you can create test classes and make assertions for Junit 3(with GroovyTestCase), Junit 4 and TestNG. GroovyShell recognizes all 3 of these test files by interface or annotation and executes them appropriately. In each case the console output of the test framework is the result, including the new Spock inspired ascii art assert failure renderings. The Test result files are also written to disk, and that TestNG html output is what I&#8217;m used to looking at anyhow. Show me the Green!</p>
<p>The last code slide is just a slightly updated version of an example script on the Grapes page, using the current version of Google Collections and intentionally introducing a failure- mostly just to show off that new assert rendering I mentioned a moment ago. VERY helpful at highlighting the exact nature of a failure. It also encourages me to pay more attention to how I name variables, something I&#8217;m sure every developer that has ever worked with me will cheer at. Man, I suck at naming things.</p>
<p>I also developed a brute force test that loads each slide and executes scripts if finds embedded there. Failures are hard to detect since the direct output is simply a text block, but some fairly simple regex&#8217;s applied to the output make me at least moderately confident that the code won&#8217;t fail at show time.</p>
<p></p>
<h2>Overall Impression</h2>
<p>It took a couple of afternoons(six hours or so total) to download the source code from github, explore it, create a simple presentation and document the experience. I won&#8217;t begin to suggest that I&#8217;m fully aware of all the details happening behind the scenes, but the end user experience is pretty fluid: create a slide, tailor the layout, add content and then repeat. The included examples were more than enough documentation on how to hit the ground running. The plugin code itself is a great example of the MVC nature of Griffon, not a whole lot of code, but a great deal of power and expressability. There were a couple of glitches happening in the background, mostly just logging to the console with no visible effect to the application, but overall it functioned as well as (not) advertised. For publicly unreleased software it was an absolute pleasure to work with and I plan on continuing with the development of this particular presentation.</p>
<p>Everything you need to build and run this stuff yourself is publicly available. In my case, Griffon generally has a recent Macport available for both the released(griffon @0.2.1) and development versions(griffon-devel @0.3-BETA-2). Switching versions is relatively painless and, for applications this simple, testing out upgrades is basically just going through the presentation once in a functional test. Versions for other platforms can be downloaded from the <a href="http://griffon.codehaus.org/Download">Griffon download page</a>.</p>
<p></p>
<h2>Deliverables</h2>
<p>Source code for the sample application is <a href="http://github.com/kellyrob99/Groovy-Testing-Presentation">available on github here</a>. Please just leave a comment on this page if you have any problems running it.</p>
<p>Here&#8217;s the pdf produced by the application &#8216;Print&#8217; feature: <a class="downloadlink" href="http://www.kellyrob99.com/blog/wp-content/plugins/download-monitor/download.php?id=2" title="Version0.1 downloaded 116 times" >Groovy Testing Presentation (116)</a></p>
<p>And if you don&#8217;t feel like downloading anything, here&#8217;s how it all looks in pretty pictures.<br />

<div class="ngg-galleryoverview" id="ngg-gallery-9-1072">


	<!-- Piclense link -->
	<div class="piclenselink">
		<a class="piclenselink" href="javascript:PicLensLite.start({feedUrl:'http://www.kellyrob99.com/blog/wp-content/plugins/nextgen-gallery/xml/media-rss.php?gid=9&amp;mode=gallery'});">
			[View with PicLens]		</a>
	</div>
	
	<!-- Thumbnails -->
		
	<div id="ngg-image-35" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-46-46-pm.png" title="Title slide" class="shutterset_set_9" >
								<img title="Title slide" alt="Title slide" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-46-46-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-36" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-46-50-pm.png" title="Bullet slide" class="shutterset_set_9" >
								<img title="Bullet slide" alt="Bullet slide" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-46-50-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-37" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-00-pm.png" title="Code slide with JUnit 3 example" class="shutterset_set_9" >
								<img title="Code slide with JUnit 3 example" alt="Code slide with JUnit 3 example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-00-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-38" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-04-pm.png" title="Code slide with JUnit4 and Hamcrest matcher example" class="shutterset_set_9" >
								<img title="Code slide with JUnit4 and Hamcrest matcher example" alt="Code slide with JUnit4 and Hamcrest matcher example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-04-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-39" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-08-pm.png" title="Code slide with TestNG example" class="shutterset_set_9" >
								<img title="Code slide with TestNG example" alt="Code slide with TestNG example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-08-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-40" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-11-at-7-47-13-pm.png" title="Code slide with Google Collections example" class="shutterset_set_9" >
								<img title="Code slide with Google Collections example" alt="Code slide with Google Collections example" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-11-at-7-47-13-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-41" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/screen-shot-2010-02-08-at-8-53-43-pm.png" title="Help screen showing keyboard shortcuts" class="shutterset_set_9" >
								<img title="Help screen showing keyboard shortcuts" alt="Help screen showing keyboard shortcuts" src="http://www.kellyrob99.com/blog/wp-content/gallery/groovy-testing-presentation-with-griffon/thumbs/thumbs_screen-shot-2010-02-08-at-8-53-43-pm.png" width="99" height="75" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>

</p>
<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/a9a507d7-67b9-4178-bf0f-e90f2cc1d0a6/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=a9a507d7-67b9-4178-bf0f-e90f2cc1d0a6" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=A+One+Day+Griffon+Application%2FPresentation+http://yi58w.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.kellyrob99.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=A+One+Day+Griffon+Application%2FPresentation+http://yi58w.th8.us" title="Post to Twitter">Tweet This Post</a></p>

<p>Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/08/27/vijug-griffongroovy-presentation/' rel='bookmark' title='Permanent Link: VIJUG Griffon/Groovy Presentation'>VIJUG Griffon/Groovy Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Permanent Link: Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
<li><a href='http://www.kellyrob99.com/blog/2009/04/03/swingset-on-griffon/' rel='bookmark' title='Permanent Link: SwingSet on Griffon'>SwingSet on Griffon</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Different Flavors of Embedded Groovy in Java Apps or &#8220;How To Make your Java Groovier!&#8221;</title>
		<link>http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/?utm_source=rss&amp;utm_medium=rss&amp;utm_campaign=different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier</link>
		<comments>http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 04:28:04 +0000</pubDate>
		<dc:creator>TheKaptain</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Console]]></category>
		<category><![CDATA[dynamic execution]]></category>
		<category><![CDATA[embedded]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[groovyConsole]]></category>
		<category><![CDATA[GroovyScriptEngine]]></category>
		<category><![CDATA[GroovyShell]]></category>
		<category><![CDATA[Hello world program]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[script]]></category>
		<category><![CDATA[Source code]]></category>
		<category><![CDATA[theKaptain]]></category>

		<guid isPermaLink="false">http://www.kellyrob99.com/blog/?p=858</guid>
		<description><![CDATA[Lately I&#8217;ve been thinking about all the different ways to bring Groovy into a pure Java or command line environment, and ended up diving into some code to explore the various options. Turns out there&#8217;s definitely a good variety of options for running Groovy dynamically inside and out of a Java application. I started out [...]


Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/10/04/groovy-clibuilder-with-multiple-arguments/' rel='bookmark' title='Permanent Link: Groovy CliBuilder with multiple arguments'>Groovy CliBuilder with multiple arguments</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='Permanent Link: A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Permanent Link: Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[<p>Lately I&#8217;ve been thinking about all the different ways to bring Groovy into a pure Java or command line environment, and ended up diving into some code to explore the various options.  Turns out there&#8217;s definitely a good variety of options for running Groovy dynamically inside and out of a Java application. I started out on <a href="http://groovy.codehaus.org/Embedding+Groovy">this page from the Groovy site</a>.<br />
In particular for the environments I&#8217;ve been working in lately it&#8217;s been important to be able to run the same code both from within a Java application and from the command line. It&#8217;s also been a &#8216;nice to have&#8217; to be able to package a jar with a bunch of the same scripts compiled together. Using maven as a harness also has the benefit of allowing for testing compiled scripts directly through instantiation even though the intended usage is from within a Java app using one of these methods. Source code is <a href="http://github.com/kellyrob99/running-groovy">available here on github</a>.</p>
<p></p>
<h3>Groovy on the command line</h3>
<p>The quickest and simplest way to run a Groovy Script or Class, command line arguments are automatically marshalled into an &#8216;args&#8217; String array. Please note that due to a problem I&#8217;m having with my syntax highlighter plugin the process execution is shown here in single quotes; the actual code requires a GString(double quoted) in order to do the replacement for the inline variable. <code>&amp;quot;</code> THAT WordPress!</p>
<pre class="brush: groovy;">
//the script
myArgs = args
result = args.join(' ')
println result
println myArgs

//...and the test
    void testGroovyCall()
    {
        def proc = 'groovy $groovyScriptOne Hello World'.execute()
        proc.waitFor()
        def result = proc.text.split()
        assert result[0] == 'Hello'
        assert result[1] == 'World'
    }
</pre>
<p></p>
<h3>GroovyShell</h3>
<p>This is the basis of Groovy script execution. The <a href="http://groovy.codehaus.org/api/groovy/lang/GroovyShell.html">GroovyShell</a> allows for executing scripts, passing in a particular Binding context that allows for bi-directional communication between the script and the calling code. Parameters can be passed into the executing script in the Binding and results can be stored there to be returned to the calling context. GroovyShell also allows for running a class from the &#8216;main&#8217; method, passing in String arguments. It will also execute implementers of Runnable and test files for  JUnit or TestNG. Script text can also be declared inline and executed in the same way as files on disk. All in all, pretty bloody handy. Here&#8217;s a straightforward example of running a dirt simple Groovy script and inspecting the results. Note that this isn&#8217;t executable as shown, but I&#8217;ll provide the full source code on github for anyone who wants a closer look. Note that I&#8217;m also passing in an &#8216;out&#8217; variable in the Binding, which effectively redirect System.out to a specified Writer implementation &#8211; a nice touch for inspecting output.</p>
<pre class="brush: groovy;">
//the script
myArgs = args
result = args.join(' ')
println result
println myArgs

 //...and the test
    void testGroovyShell()
    {
        Binding binding = helper.createBinding()
        def shell = new GroovyShell(binding)
        shell.evaluate(new File(groovyScriptOne))
        helper.assertBinding(binding)
    }

//...and the Binding creation/assertion
     def static args = ['Hello', 'World'].asImmutable()
     /**
     * Create a Binding with a single parameter to be passed to scripts and an 'out' Writer to redirect console output.
     */
    private Binding createBinding()
    {
        Binding binding = new Binding()
        def sWriter = new StringWriter()
        def pWriter = new PrintWriter(sWriter)
        binding.setVariable ('args', new ArrayList(args))
        binding.setVariable ('out', pWriter)
        return binding
    }

    /**
     * Assert that the expected 'common' actions are done with the Binding by each of the use cases.
     * The original 'args' should be as expected.
     * A copy of 'args' should have been placed in the Binding during execution.
     * The 'result' should be the concatentation of 'args' separated by spaces.
     */
    private def assertBinding(Binding binding)
    {
        assert binding.variables.size() == 4
        assert binding.variables.args.value[0].toString() == args[0]
        assert binding.variables.args.value[1].toString() == args[1]
        assert binding.variables.result.value.toString() == args.join(' ')
        assert binding.variables.myArgs.value[0].toString() == args[0]
        assert binding.variables.myArgs.value[1].toString() == args[1]
    }
</pre>
<p></p>
<h3>GroovyScriptEngine</h3>
<p>The <a href="http://groovy.codehaus.org/api/groovy/util/GroovyScriptEngine.html">GroovyScriptEngine</a> enables dynamically running Groovy sources located in a fixed set of content roots,  complete with reloading modified scripts in between executions. Running a Groovy script this way is essentially the same as using GroovyShell.</p>
<pre class="brush: groovy;">
    void testGroovyScriptEngine()
    {
        Binding binding = helper.createBinding()
        def gse = new GroovyScriptEngine(new File('.').toURL())
        gse.run(groovyScriptOne, binding)
        helper.assertBinding(binding)
    }
</pre>
<p></p>
<h3>GroovyClassLoader</h3>
<p>An extension to URLClassLoader that enables parsing Groovy sources into Class representations. Once a Class object is created, instances of the class can be created easily and either cast to a known type or manipulated through convention by use of the standard Groovy &#8216;invokeMethod&#8217;.  This works equally well on Groovy and Java btw. Here&#8217;s an example of running a Java class using <a href="http://groovy.codehaus.org/api/groovy/lang/GroovyClassLoader.html">GroovyClassLoader</a>. In this case the Java file has a field called &#8216;binding&#8217; and implements a &#8216;run&#8217; method.</p>
<pre class="brush: groovy;">
    /**
     * Dynamically compile, instantiate, inspect and call methods on a POJO.
     */
    void testGroovyClassLoaderOnJava()
    {
        GroovyClassLoader loader = new GroovyClassLoader();
        Class javaClass = loader.parseClass(new File(javaFileOne));

        def groovyObject = javaClass.newInstance();
        def binding = helper.createBinding()
        groovyObject.binding = binding
        if(groovyObject.metaClass.respondsTo(groovyObject, 'run'))
        {
            groovyObject.invokeMethod('run', null);
            helper.assertBinding(binding)
        }
        if(groovyObject.metaClass.respondsTo(groovyObject, 'main'))
        {
            groovyObject.invokeMethod('main', new ArrayList(helper.args) as String[]);
        }
    }
</pre>
<p></p>
<h3>(Groovy)Console</h3>
<p>The <a href="http://groovy.codehaus.org/gapi/groovy/ui/Console.html">Console</a> can be embedded in Java or Groovy code to provide a dynamic interactive Swing environment. This is the same UI spawned from the command line invocation of &#8216;groovyConsole&#8217;. Internally it uses GroovyShell for actual execution, and so can do everything that GroovyShell can do &#8211; plus a couple of additions. For one, you can add jars and/or directories to the classpath used when executing your scripts.<br />
<a href="http://www.kellyrob99.com/blog/?attachment_id=885" rel="attachment wp-att-885"><img src="http://www.kellyrob99.com/blog/wp-content/uploads/2009/11/Picture-6.png" alt="Groovy Console" title="Groovy Console" class="size-full wp-image-885" width="651" height="457" /></a></p>
<p></p>
<h3>The Best of Both Worlds &#8211; at Least for my use case</h3>
<p>In actual practice these patterns can be used a lot more successfully by observing standard Java practices, like casting classes parsed using GroovyClassLoader to a known interface before interacting with them, or by using Classes to organize business logic inside of a Script that essentially functions as a &#8216;main&#8217; method.  This example defines two dependent internal classes, marshals parameters to them and then returns the results attached to the originally passed in Binding.</p>
<pre class="brush: groovy;">
/**
 * Classes inside of a Script.
 */
class TestableClass
{
    Binding binding

    def run()
    {
        binding.with
        {
            setVariable('myArgs', getVariable('args'))
            setVariable('result', getVariable('args')?.join(' '))
        }
        return binding
    }
}

class TestableClass2
{
    Binding binding

    public TestableClass2(Binding binding)
    {
        this.binding = binding;
    }

    def run()
    {
        return new TestableClass(binding: binding).run()
    }
}

if (args)
{
    def internalBinding = new Binding()
    internalBinding.setVariable('args', new ArrayList(args))
    internalBinding = new TestableClass2(internalBinding).run()
    args = internalBinding.args
    myArgs = internalBinding.myArgs
    result = internalBinding.result  //return value from script
}
else
{
    println 'no args!!'
}
</pre>
<h2 class="wp-table-reloaded-table-name">Summary of Groovy Execution Methods</h2>

<table id="wp-table-reloaded-id-1-no-1" class="wp-table-reloaded wp-table-reloaded-id-1">
<thead>
	<tr class="row-1 odd">
		<th class="column-1">Method</th><th class="column-2">Groovy Scripts</th><th class="column-3">Groovy Classes</th><th class="column-4">Java</th>
	</tr>
</thead>
<tbody>
	<tr class="row-2 even">
		<td class="column-1">groovy exec on the command line</td><td class="column-2">Yes, passes in String command line argments in a variable called 'args'</td><td class="column-3">Yes, calls the main method with String arguments</td><td class="column-4">No</td>
	</tr>
	<tr class="row-3 odd">
		<td class="column-1">GroovyShell</td><td class="column-2">Yes, parameters passed in a Binding object that the Script can mutate</td><td class="column-3">Yes, calls the main method with String arguments</td><td class="column-4">Yes, no apparent way to pass arguments</td>
	</tr>
	<tr class="row-4 even">
		<td class="column-1">GroovyScriptEngine</td><td class="column-2">Yes, parameters passed in a Binding object that the Script can mutate</td><td class="column-3">Yes, no apparent way to pass arguments</td><td class="column-4">Yes, no apparent way to pass arguments</td>
	</tr>
	<tr class="row-5 odd">
		<td class="column-1">GroovyClassLoader</td><td class="column-2">Yes, instantiate a parsed Class and either cast to a known type or use Groovy reflection methods to call methods</td><td class="column-3">Yes, instantiate a parsed Class and either cast to a known type or use Groovy reflection methods to call methods</td><td class="column-4">Yes, instantiate a parsed Class and either cast to a known type or use Groovy reflection methods to call methods</td>
	</tr>
	<tr class="row-6 even">
		<td class="column-1">(Groovy)Console</td><td class="column-2">Same as GroovyShell</td><td class="column-3">Same as GroovyShell</td><td class="column-4">Same as GroovyShell</td>
	</tr>
</tbody>
</table>
<span class="wp-table-reloaded-table-description"></span>

<div class="zemanta-pixie"><a class="zemanta-pixie-a" href="http://reblog.zemanta.com/zemified/8cba1f46-7f81-473a-8fe0-ce5f0a45ec40/" title="Reblog this post [with Zemanta]"><img class="zemanta-pixie-img" src="http://img.zemanta.com/reblog_c.png?x-id=8cba1f46-7f81-473a-8fe0-ce5f0a45ec40" alt="Reblog this post [with Zemanta]" /></a><span class="zem-script more-related pretty-attribution"><script type="text/javascript" src="http://static.zemanta.com/readside/loader.js" defer="defer"></script></span></div>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Different+Flavors+of+Embedded+Groovy+in+Java+Apps+or+%E2%80%9CHow+To+Make+your+Java+Groovier...+http://9bnoi.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.kellyrob99.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://twitter.com/home/?status=Different+Flavors+of+Embedded+Groovy+in+Java+Apps+or+%E2%80%9CHow+To+Make+your+Java+Groovier...+http://9bnoi.th8.us" title="Post to Twitter">Tweet This Post</a></p>

<p>Related posts:<ol><li><a href='http://www.kellyrob99.com/blog/2009/10/04/groovy-clibuilder-with-multiple-arguments/' rel='bookmark' title='Permanent Link: Groovy CliBuilder with multiple arguments'>Groovy CliBuilder with multiple arguments</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/02/11/a-one-day-griffon-applicationpresentation/' rel='bookmark' title='Permanent Link: A One Day Griffon Application/Presentation'>A One Day Griffon Application/Presentation</a></li>
<li><a href='http://www.kellyrob99.com/blog/2010/05/15/achieving-groovy-like-fluency-in-java-with-google-collections/' rel='bookmark' title='Permanent Link: Achieving Groovy-like Fluency in Java with Google Collections'>Achieving Groovy-like Fluency in Java with Google Collections</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.kellyrob99.com/blog/2009/11/21/different-flavors-of-embedded-groovy-in-java-apps-or-how-to-make-your-java-groovier/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
