<?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>ChangeLog - Jon Chase&#039;s blog &#187; Groovy</title>
	<atom:link href="http://www.juliesoft.com/category/groovy/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.juliesoft.com</link>
	<description>solve niche problems, make users happy</description>
	<lastBuildDate>Sun, 18 Jul 2010 06:56:43 +0000</lastBuildDate>
	
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Automatic http/httpS switching with Grails</title>
		<link>http://www.juliesoft.com/2010/04/automatic-httphttps-switching-with-grails/</link>
		<comments>http://www.juliesoft.com/2010/04/automatic-httphttps-switching-with-grails/#comments</comments>
		<pubDate>Mon, 26 Apr 2010 08:40:56 +0000</pubDate>
		<dc:creator>Jon Chase</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java & Programming]]></category>
		<category><![CDATA[java groovy grails spring security http https]]></category>

		<guid isPermaLink="false">http://www.juliesoft.com/?p=336</guid>
		<description><![CDATA[
A common requirement in webapps nowadays is to switch users between a secure and insecure connection (called protocol switching).  For example, maybe your user needs to enter a password, credit card number, or some other sensitive information.  Of course, you (and the user) would like that information to be sent securely, which means [...]]]></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.juliesoft.com%2F2010%2F04%2Fautomatic-httphttps-switching-with-grails%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.juliesoft.com%2F2010%2F04%2Fautomatic-httphttps-switching-with-grails%2F" height="61" width="51" /></a></div><p><img src="http://www.juliesoft.com/wp-content/uploads/2010/04/switch.jpg" alt="switch" title="switch" width="500" height="333" class="aligncenter size-full wp-image-356" /></p>
<p>A common requirement in webapps nowadays is to switch users between a secure and insecure connection (called <strong>protocol switching</strong>).  For example, maybe your user needs to enter a password, credit card number, or some other sensitive information.  Of course, you (and the user) would like that information to be sent securely, which means requiring http<strong>s</strong>.  Assuming you&#8217;ve already got a server set up with an SSL cert and it&#8217;s ready to serve pages over SSL, you&#8217;ll need to <strong>ensure</strong> your webapp serves all secure pages over http<strong>s</strong>.  Unfortunately, this isn&#8217;t always as easy as it seems.  But it&#8217;s not too tough either, thanks to <a href="http://grails.org">Grails</a> and <a href="http://static.springsource.org/spring-security/site/index.html">Spring Security</a>.  </p>
<p>Here are the <strong>requirements for protocol switching</strong>:</p>
<ul>
<li>Serve secure pages using http<strong>s</strong>, regardless of the link used to get to the page (i.e. http links should be redirected to http<strong>s</strong>)</li>
<li>Make protocol switching transparent to the majority of your application (i.e. links starting with <span class="mono">http://</span> will automatically get redirected to <span class="mono">http<strong>s</strong>://</span> and vice versa)</li>
<li>Easy configuration of which resources must be served as secure, insecure, or either (i.e. images, CSS, and JavaScript should be loaded using the same protocol the page uses to avoid nasty browser warnings (see below))</li>
<li>Security and protocol switching should be handled in a way such that browsers aren&#8217;t continuously popping up warning dialogs</li>
<li>Make it work in Grails</li>
</ul>
<h3>Implementation</h3>
<p>There are several ways to go about automatic protocol switching.  One of the most popular would be to use Apache and <a href="http://www.whoopis.com/howtos/apache-rewrite.html">mod_rewrite</a>.  That solution works fine, but it&#8217;s not portable between different types of servers.  </p>
<p>The solution below is pure Java, and is portable between any servlet container.  By the way, this isn&#8217;t a Grails only solution &#8211; this will work with pretty much any Java web stack &#8211; the only thing that will differ is how you wire things up.  In fact I&#8217;ve used this in a regular Spring MVC app with a regular Spring configuration&#8230;but I&#8217;m only going to show the Grails way to do it today.  </p>
<p>Here&#8217;s how to get automatic protocol switching in Grails:</p>
<ul>
<li>Add a filter definition to web.xml that intercepts all requests and handles the protocol switching and redirecting</li>
<li>Configure which URLs require which protocol</li>
<li>Test!</li>
</ul>
<h3>Adding the filter definition</h3>
<p>Spring Security has <a href="http://static.springsource.org/spring-security/site/docs/3.0.x/reference/ns-config.html#ns-requires-channel">protocol switching built in</a>, so why reinvent the wheel?  (Don&#8217;t worry, you don&#8217;t need to use any other parts of Spring Security to get protocol switching.)  Spring Security refers to protocol switching as Channel Security, but don&#8217;t worry, it&#8217;s the same thing.</p>
<p>If your Grails app isn&#8217;t already using Spring Security, add the following dependencies into grails-app/conf/BuildConfig.groovy to have Grails download the required JARs:</p>
<pre class="brush: groovy">
grails.project.dependency.resolution = {

	// ...
	// other settings...
	// ...

	dependencies {

		// ...
		// other dependencies...
		// ...

		runtime &#x27;org.springframework.security:spring-security-core:3.0.2.RELEASE&#x27; // http -&gt; https redirecting
		runtime &#x27;org.springframework.security:spring-security-web:3.0.2.RELEASE&#x27; // http -&gt; https redirecting
	}
}
</pre>
<p>You&#8217;ll need to add a Servlet Filter to web.xml now.  There are a couple of ways to do this in Grails, namely writing a plugin that can <a href="http://grails.org/doc/latest/guide/12.%20Plug-ins.html#12.7 Hooking into Runtime Configuration">modify web.xml dynamically</a>, or <a href="http://grails.org/doc/latest/ref/Command%20Line/install-templates.html">installing the Grails templates</a> into your app and manually editing web.xml.  I had planned on doing the first option (writing a plugin), but it was overkill for this, so I decided against it.  I&#8217;m glad I did.  Installing the Grails templates and modifying web.xml manually is painless.</p>
<p>Run <span class="mono">grails install-templates</span> from the root of your Grails project to install the web.xml template (along with a few others).  Next, edit <span class="mono">src/templates/war/web.xml</span> and add the filter definition and mapping in the appropriate places:</p>
<pre class="brush: xml">
&lt;!-- START: use SSL on secure pages --&gt;
&lt;filter&gt;
	&lt;filter-name&gt;channelProcessingFilter&lt;/filter-name&gt;
	&lt;filter-class&gt;org.springframework.web.filter.DelegatingFilterProxy&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;!-- END: use SSL on secure pages --&gt;

&lt;!-- ... other filter definitions ... --&gt;

&lt;!-- START: use SSL on secure pages --&gt;
&lt;filter-mapping&gt;
	&lt;filter-name&gt;channelProcessingFilter&lt;/filter-name&gt;
	&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
&lt;!-- END: use SSL on secure pages --&gt;
</pre>
<p>Make sure that the filter-mapping is the first filter-mapping defined in web.xml (above <span class="mono">charEncodingFilter</span> and <span class="mono">sitemesh</span>).</p>
<p>Now to actually define the filter.  Define it as a Spring managed bean in <span class="mono">grails-app/conf/spring/resources.groovy</span>:</p>
<pre class="brush: groovy">
import org.springframework.security.web.util.AntUrlPathMatcher
import org.springframework.security.web.access.intercept.DefaultFilterInvocationSecurityMetadataSource
import org.springframework.security.web.access.channel.SecureChannelProcessor
import org.springframework.security.web.access.channel.InsecureChannelProcessor
import org.springframework.security.web.access.channel.ChannelProcessingFilter
import org.springframework.security.web.access.channel.ChannelDecisionManagerImpl

beans = {

	// -------------------------------------------------------------------------
	// -------------------------------------------------------------------------
	// SPRING SECURITY (CHANNEL SECURITY)
	channelDecisionManager(ChannelDecisionManagerImpl) {
		channelProcessors = [new SecureChannelProcessor(),
							new InsecureChannelProcessor()]
	}
	securityMetadataSource(DefaultFilterInvocationSecurityMetadataSource,
							new AntUrlPathMatcher(),
							ChannelConfig.getChannelConfig()) {
		stripQueryStringFromUrls = true
	}
	channelProcessingFilter(ChannelProcessingFilter) {
		channelDecisionManager = ref(&quot;channelDecisionManager&quot;)
		securityMetadataSource = ref(&quot;securityMetadataSource&quot;)
	}

}
</pre>
<p><span class="mono"><a href="http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/access/channel/ChannelProcessingFilter.html">channelProcessingFilter</a></span> is the filter referenced in web.xml.  It will use the <span class="mono"><a href="http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/access/channel/ChannelDecisionManagerImpl.html">channelDecisionManager</a></span> to decide if the current protocol (http or http<strong>s</strong>) needs to be switched to the other.  And how does <span class="mono">channelProcessingFilter</span> know which URLs require which protocol?  <span class="mono"><a href="http://static.springsource.org/spring-security/site/docs/3.0.x/apidocs/org/springframework/security/web/access/intercept/DefaultFilterInvocationSecurityMetadataSource.html">securityMetadataSource</a></span>, of course. By default, ports 80 and 8080 are considered insecure, and 443 and 8443 are considered secure.  This means that the defaults should work for both development (8080 and 8443) and production (80 and 443).  If you&#8217;re curious as to the specifics of what these beans do, check their Javadocs.  </p>
<h3>Configure which URLs require which protocol</h3>
<p>See that call above to <span class="mono">ChannelConfig.getChannelConfig()</span>?  That&#8217;s where the configuration for URLs is stored.  Create <span class="mono">grails-app/conf/ChannelConfig.groovy</span>:</p>
<pre class="brush: groovy">
import org.springframework.security.access.ConfigAttribute
import org.springframework.security.access.SecurityConfig
import org.springframework.security.web.access.intercept.RequestKey

class ChannelConfig {

	private ChannelConfig() {} // prevent instantiation

	static def getChannelConfig() {
		LinkedHashMap&lt;RequestKey,java.util.Collection&lt;ConfigAttribute&gt;&gt; requestMap = new LinkedHashMap&lt;RequestKey, Collection&lt;ConfigAttribute&gt;&gt;()

		// resources that can be served over http or https (typically whatever the containing page is served as)
		requestMap.put new RequestKey(&quot;/images/**&quot;), [new SecurityConfig(&quot;ANY_CHANNEL&quot;)]
		requestMap.put new RequestKey(&quot;/css/**&quot;), [new SecurityConfig(&quot;ANY_CHANNEL&quot;)]
		requestMap.put new RequestKey(&quot;/js/**&quot;), [new SecurityConfig(&quot;ANY_CHANNEL&quot;)]
		requestMap.put new RequestKey(&quot;/favicon.ico&quot;), [new SecurityConfig(&quot;ANY_CHANNEL&quot;)]

		// resources that must be served over https
		requestMap.put new RequestKey(&quot;/signup&quot;), [new SecurityConfig(&quot;REQUIRES_SECURE_CHANNEL&quot;)]
		requestMap.put new RequestKey(&quot;/auth/**&quot;), [new SecurityConfig(&quot;REQUIRES_SECURE_CHANNEL&quot;)]
		requestMap.put new RequestKey(&quot;/admin/**&quot;), [new SecurityConfig(&quot;REQUIRES_SECURE_CHANNEL&quot;)]
		requestMap.put new RequestKey(&quot;/app/account/edituser&quot;), [new SecurityConfig(&quot;REQUIRES_SECURE_CHANNEL&quot;)]

		// resources that must be served over http (basically everything else not already listed above)
		requestMap.put new RequestKey(&quot;/**&quot;), [new SecurityConfig(&quot;REQUIRES_INSECURE_CHANNEL&quot;)] // all other pages should be served over http

		requestMap
	}
}
</pre>
<p>What&#8217;s happening here?  First, there&#8217;s some horrible nastiness with the definition of the <span class="mono">requestMap</span> variable (gotta love generics).  This is how your configuration is stored and the format <span class="mono">securityMetadataSource</span> expects.  Each call to <span class="mono">requestMap.put()</span> specifies a URL or URL pattern (Apache Ant pattern style) and its corresponding channel security (i.e. http or http<strong>s</strong>).  </p>
<p>There are three options for channel security:</p>
<ul>
<li><span class="mono">ANY_CHANNEL</span> &#8211; Serve the resource with either http or http<strong>s</strong> &#8211; it doesn&#8217;t matter.  This is good for images, CSS, and JavaScript, which should be served using the same protocol as the containing page.</li>
<li><span class="mono">REQUIRES_SECURE_CHANNEL</span> &#8211; Serve the resource using http<strong>s</strong>.  This is what will automatically redirect the user to http<strong>s</strong> when needed.</li>
<li><span class="mono">REQUIRES_INSECURE_CHANNEL</span> &#8211; Serve the resource using http.  You don&#8217;t want to serve your entire site over http<strong>s</strong>, right?  </li>
</ul>
<p>In the configuration above, I first specified all the resources that are protocol agnostic &#8211; images, CSS, etc.  Then in the next section I specified all of the resources that must be served securely.  Finally, the <span class="mono">/**</span> specifies that anything else not already listed above will be served over plain http.</p>
<p>Note that <strong>order matters</strong> (hence the use of a LinkedHashMap that retains insertion order).  Rules should be added from most specific to least specific.  For example, if the <span class="mono">/**</span> rule was at the very top, it would match every resource request, which would be very bad.  </p>
<p>If you want to see the debug output from Spring Security as it makes its decisions about whether or not a resource is being served over the right protocol, add the following to your Log4j config in <span class="mono">grails-app/conf/Config.groovy</span>:</p>
<pre class="brush: groovy">
log4j = {

	// ...
	// ... other logging definitions
	// ...
	debug &#x27;org.springframework.security&#x27;

}
</pre>
<h3>Testing</h3>
<p>Since you&#8217;re testing your app with http<strong>s</strong>, make sure to start Grails with the <span class="mono">-http<strong>s</strong></span> option:</p>
<p><code>grails run-app -http<strong>s</strong></code></p>
<p>This will automatically set up a fake SSL certificate for your app and run http<strong>s</strong> on port 8443.  </p>
<p>You should now be able to go to <span class="mono">http://localhost:8080</span> and see that it is indeed served over http.  If you have a sign up page like configured above, navigating to <span class="mono">http://localhost:8080</span> should automatically redirect your browser to <span class="mono">http<strong>s</strong>://localhost:8443</span>.  Clicking on a link to <span class="mono">http<strong>s</strong>://localhost:8443/index</span> should then automatically take you back to <span class="mono">http://localhost:8080/index</span>.  You&#8217;ll also notice that resources like images, CSS, and JavaScript are served using whatever protocol the containing page uses.  </p>
<h3>Caveats</h3>
<p>Did you know that if an HttpSession is created over an http<strong>s</strong> connection that it won&#8217;t be available to the user when they go back to regular old http?  This means that if you have your user log in using http<strong>s</strong>, when they are redirected back to http, their session will be gone.  This won&#8217;t be a problem for you if you plan to have users always use http<strong>s</strong> once they&#8217;ve logged in.  But some sites (flickr, for example) prefer to serve most of their pages using http for performance reasons once the user has logged in securely.  There is a trick to allow http<strong>s</strong> -&gt; http session migration, but that&#8217;s a topic for a later blog post.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliesoft.com/2010/04/automatic-httphttps-switching-with-grails/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>REVISITED: What is Right with Grails and Wrong with Maven</title>
		<link>http://www.juliesoft.com/2009/10/revisited-what-is-right-with-grails-and-wrong-with-maven/</link>
		<comments>http://www.juliesoft.com/2009/10/revisited-what-is-right-with-grails-and-wrong-with-maven/#comments</comments>
		<pubDate>Tue, 20 Oct 2009 06:43:48 +0000</pubDate>
		<dc:creator>Jon Chase</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java & Programming]]></category>

		<guid isPermaLink="false">http://www.juliesoft.com/2009/10/20/revisited-what-is-right-with-grails-and-wrong-with-maven/</guid>
		<description><![CDATA[With regard to my previous post, it looks like I pulled the Maven command from an old set of documentation.  I believe the preferred way to create a new Grails app with Maven is a command like the following:
mvn grails:create-app appName
I can&#8217;t say I don&#8217;t have anything against Maven, because I don&#8217;t like it. [...]]]></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.juliesoft.com%2F2009%2F10%2Frevisited-what-is-right-with-grails-and-wrong-with-maven%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.juliesoft.com%2F2009%2F10%2Frevisited-what-is-right-with-grails-and-wrong-with-maven%2F" height="61" width="51" /></a></div><p>With regard to <a href="http://www.juliesoft.com/2009/10/15/what-is-right-with-grails-and-wrong-with-maven/">my previous post</a>, it looks like I pulled the Maven command from an <a href="http://grails.org/Maven+Integration">old set of documentation</a>.  I believe <a href="http://forge.octo.com/maven/sites/mtg/grails-maven-plugin/create-app-mojo.html">the preferred way</a> to create a new Grails app with Maven is a command like the following:</p>
<p><code>mvn grails:create-app appName</code></p>
<p>I can&#8217;t say I don&#8217;t have anything against Maven, because I don&#8217;t like it. <img src='http://www.juliesoft.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />   Personally I&#8217;ve had much better luck with Ant, but then I&#8217;ve never worked in a highly distributed team environment with lots of dependencies and builds that couldn&#8217;t be managed with a simple Ant script.</p>
<p>Let the holy wars continue&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliesoft.com/2009/10/revisited-what-is-right-with-grails-and-wrong-with-maven/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>What is Right with Grails and Wrong with Maven</title>
		<link>http://www.juliesoft.com/2009/10/what-is-right-with-grails-and-wrong-with-maven/</link>
		<comments>http://www.juliesoft.com/2009/10/what-is-right-with-grails-and-wrong-with-maven/#comments</comments>
		<pubDate>Fri, 16 Oct 2009 03:50:08 +0000</pubDate>
		<dc:creator>Jon Chase</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java & Programming]]></category>

		<guid isPermaLink="false">http://www.juliesoft.com/2009/10/15/what-is-right-with-grails-and-wrong-with-maven/</guid>
		<description><![CDATA[This just cracks me up.Here&#8217;s how to create a Grails app using the Grails command line:grails create-app demoAnd here&#8217;s how to create the app using the Maven command line:mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:generate -DarchetypeGroupId=org.grails -DarchetypeArtifactId=grails-maven-archetype -DarchetypeVersion=1.1 -DgroupId=example -DartifactId=demo
]]></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.juliesoft.com%2F2009%2F10%2Fwhat-is-right-with-grails-and-wrong-with-maven%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.juliesoft.com%2F2009%2F10%2Fwhat-is-right-with-grails-and-wrong-with-maven%2F" height="61" width="51" /></a></div><p>This just cracks me up.Here&#8217;s how to create a Grails app using the Grails command line:<code>grails create-app demo</code>And here&#8217;s how to create the app using the Maven command line:<code>mvn org.apache.maven.plugins:maven-archetype-plugin:2.0-alpha-4:generate -DarchetypeGroupId=org.grails -DarchetypeArtifactId=grails-maven-archetype -DarchetypeVersion=1.1 -DgroupId=example -DartifactId=demo</code></p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliesoft.com/2009/10/what-is-right-with-grails-and-wrong-with-maven/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Groovy Micro Benchmark Revisited (Groovy is fast&#8230;)</title>
		<link>http://www.juliesoft.com/2008/03/groovy-micro-benchmark-revisited-groovy-is-fast/</link>
		<comments>http://www.juliesoft.com/2008/03/groovy-micro-benchmark-revisited-groovy-is-fast/#comments</comments>
		<pubDate>Wed, 12 Mar 2008 12:27:47 +0000</pubDate>
		<dc:creator>Jon Chase</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java & Programming]]></category>

		<guid isPermaLink="false">http://www.juliesoft.com/2008/03/12/groovy-micro-benchmark-revisited-groovy-is-fast/</guid>
		<description><![CDATA[Alright, no more Groovy posts for a while after this one.  In fact, I hadn&#8217;t planned on posting about this again, but I thought it was worth mention.
From the last post, we saw the following results for parsing an XML dataset with about 450 simple elements in it 1,000 times:

Java: ~9 seconds
Groovy: ~28 seconds [...]]]></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.juliesoft.com%2F2008%2F03%2Fgroovy-micro-benchmark-revisited-groovy-is-fast%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.juliesoft.com%2F2008%2F03%2Fgroovy-micro-benchmark-revisited-groovy-is-fast%2F" height="61" width="51" /></a></div><p><img src="http://www.juliesoft.com/wp-content/uploads/2008/03/medium11.png" class="float-left" alt="Back again…" />Alright, no more Groovy posts for a while after this one.  In fact, I hadn&#8217;t planned on posting about this again, but I thought it was worth mention.</p>
<p>From <a href="http://www.juliesoft.com/2008/03/10/groovy-micro-benchmark/">the last post</a>, we saw the following results for parsing an XML dataset with about 450 simple elements in it 1,000 times:</p>
<ul>
<li>Java: ~9 seconds</li>
<li>Groovy: ~28 seconds (with new results below&#8230;)</li>
</ul>
<p>I decided to rerun the test for Groovy because of <a href="http://www.juliesoft.com/2008/03/09/groovy-is-coming/">a comment John Wilson left on the first post</a>.  He suggested this more concise syntax for the Groovy implementation:</p>
<p><img src="http://www.juliesoft.com/wp-content/uploads/2008/03/sshot-2.png" alt="New Groovy code" /></p>
<p>I reran the same benchmark, and I was very, very surprised at the results:</p>
<ul>
<li>Java: ~9 seconds</li>
<li><strong>Groovy: </strong><strike>~28</strike><strong> </strong><strong>~9 seconds</strong></li>
</ul>
<p>All I can say is wow.  I&#8217;m not sure what is happening differently, but I&#8217;m happy:)</p>
<p>Any ideas what was taking up so much time in <a href="http://www.juliesoft.com/2008/03/09/groovy-is-coming/">the original Groovy implementation</a>?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliesoft.com/2008/03/groovy-micro-benchmark-revisited-groovy-is-fast/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Groovy Micro Benchmark</title>
		<link>http://www.juliesoft.com/2008/03/groovy-micro-benchmark/</link>
		<comments>http://www.juliesoft.com/2008/03/groovy-micro-benchmark/#comments</comments>
		<pubDate>Tue, 11 Mar 2008 03:57:07 +0000</pubDate>
		<dc:creator>Jon Chase</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java & Programming]]></category>

		<guid isPermaLink="false">http://www.juliesoft.com/2008/03/10/groovy-micro-benchmark/</guid>
		<description><![CDATA[Following on from the previous post (and here&#8217;s the last post), here&#8217;s a very quick and dirty, completely unscientific, prone to error, your mileage may vary micro benchmark I did using the code in the last post.
Date set: a String containing roughly 450 XML elements in the form &#60;contact name=&#8221;some name&#8221; email=&#8221;some email&#8221; /&#62;
Methodology: I [...]]]></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.juliesoft.com%2F2008%2F03%2Fgroovy-micro-benchmark%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.juliesoft.com%2F2008%2F03%2Fgroovy-micro-benchmark%2F" height="61" width="51" /></a></div><p><img src="http://www.juliesoft.com/wp-content/uploads/2008/03/medium1.png" class="float-left" alt="Groovy Micro Benchmark" />Following on from <a href="http://www.juliesoft.com/2008/03/09/groovy-is-coming/">the previous post</a> (and here&#8217;s <a href="http://www.juliesoft.com/2008/03/12/groovy-micro-benchmark-revisited-groovy-is-fast/">the last post</a>), here&#8217;s a very quick and dirty, completely unscientific, prone to error, your mileage may vary micro benchmark I did using the code in <a href="http://www.juliesoft.com/2008/03/09/groovy-is-coming/">the last post</a>.</p>
<p>Date set: a String containing roughly 450 XML elements in the form &lt;contact name=&#8221;some name&#8221; email=&#8221;some email&#8221; /&gt;</p>
<p>Methodology: I wrote driver programs in both Groovy and Java to run the test.  Here&#8217;s the one from Java (the Groovy one is similar):</p>
<p><img src="http://www.juliesoft.com/wp-content/uploads/2008/03/driver.png" alt="Driver program" /></p>
<p>As you can see from the code, very quick and dirty.  The test iterates 1,000 times and then prints out the time consumed.</p>
<p>I ran the test several times on my laptop (2Ghz, 2GB ram, blah blah blah it doesn&#8217;t really matter here) and here are the general results for total execution time for 1,000 iterations:</p>
<ul>
<li>Java: ~9 seconds</li>
<li>Groovy: ~28 seconds</li>
</ul>
<p>Quite a difference.  I suspect part of that has to do with my inefficiency as a Groovy programmer.  Certainly though, you can see that there is measurable difference in performance.  I wonder what type of XML parser the Groovy implementation uses behind the scenes. The Java implementation uses SAX.  If Groovy were using DOM with XmlSlurper, I could see that making a very large difference.  Any experts care to chime in?</p>
<p>Now, before you decide to write off Groovy, another metric of interest might be seconds required to develop the code.  It was something like this:</p>
<ul>
<li>Java: ~ 1,800 seconds &#8211; roughly 30 minutes. (First I had to decide what XML library I was going to use &#8211; JDOM?  Dom4J? Xstream? Then I had to search and search for documentation on JDOM&#8230;and of course I had to download JDOM, well, that is, I have to add JDOM as a dependency in my Maven pom.xml (after I looked up the current version of JDOM at the ibiblio repo), and rebuild my Eclipse classpath with the new JAR on it, and then figure out how to use the JDOM API&#8230;) I&#8217;ve been writing Java for about 6 years, so I consider myself fairly adept.</li>
<li>Groovy: ~300 seconds &#8211; roughly 5 minutes.  (I had to find the page on the Groovy wiki that explained how to process XML.)  I&#8217;ve been writing Groovy for less than 2 weeks.</li>
</ul>
<p>So there you have it, my quick and dirty, completely unscientific, prone to error, your mileage may vary micro benchmark.</p>
<p>I&#8217;m not one to reserve judgment, so here goes:</p>
<ul>
<li>First, this is just one example.  Comprehensively measuring performance is a complex thing, and this benchmark doesn&#8217;t claim to do that.  There is no such thing as saying &#8220;Groovy is slow&#8221;.</li>
<li>Second, I&#8217;d gladly trade the frustration and time requirement of the Java solution for the easier to read and write Groovy solution.  Servers are cheap.  I&#8217;ll almost always choose to pay the price in $$$ (which I can always get more of) rather than time (which I can never have enough of).</li>
</ul>
<p>Update: here&#8217;s the <a href="http://www.juliesoft.com/2008/03/12/groovy-micro-benchmark-revisited-groovy-is-fast/">final post</a> in this series.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliesoft.com/2008/03/groovy-micro-benchmark/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Groovy is Coming&#8230;</title>
		<link>http://www.juliesoft.com/2008/03/groovy-is-coming/</link>
		<comments>http://www.juliesoft.com/2008/03/groovy-is-coming/#comments</comments>
		<pubDate>Sun, 09 Mar 2008 22:35:38 +0000</pubDate>
		<dc:creator>Jon Chase</dc:creator>
				<category><![CDATA[Groovy]]></category>
		<category><![CDATA[Java & Programming]]></category>

		<guid isPermaLink="false">http://www.juliesoft.com/2008/03/09/groovy-is-coming/</guid>
		<description><![CDATA[I&#8217;ve been trying to slowly integrate some Groovy into my normal Java coding.  Here&#8217;s just one of the reasons why:

Java code:

Groovy code:

Note that this reduction in complexity happens almost everywhere I choose to use Groovy over Java.  Of course there are myriad other ways I could have done this in Java (I even [...]]]></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.juliesoft.com%2F2008%2F03%2Fgroovy-is-coming%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fwww.juliesoft.com%2F2008%2F03%2Fgroovy-is-coming%2F" height="61" width="51" /></a></div><p><img src="http://www.juliesoft.com/wp-content/uploads/2008/03/medium.png" class="float-left" alt="Here comes Groovy" />I&#8217;ve been trying to slowly integrate some <a href="http://groovy.codehaus.org/">Groovy</a> into my normal Java coding.  Here&#8217;s just one of the reasons why:</p>
<p><br style="clear: both" /></p>
<p>Java code:<br />
<img src="http://www.juliesoft.com/wp-content/uploads/2008/03/java1.png" alt="The Java code" /></p>
<p>Groovy code:<br />
<img src="http://www.juliesoft.com/wp-content/uploads/2008/03/groovy.png" alt="The Groovy code" /></p>
<p>Note that this reduction in complexity happens almost everywhere I choose to use Groovy over Java.  Of course there are myriad other ways I could have done this in Java (I even tried Xstream but I couldn&#8217;t figure part out so I gave up).  The point is that the first way I chose to do it in Groovy was natural, expressive, and easy.</p>
<p>Groovy is not going away any time soon.  If you&#8217;re a Java developer and wish you could move faster, <a href="http://www.amazon.com/Groovy-Action-Dierk-Koenig/dp/1932394842/ref=pd_bbs_sr_1_s9_rk?ie=UTF8&amp;s=books&amp;s9r=8afd079f0eefbbe9010f873c3e10073b&amp;itemPosition=1&amp;qid=1205101426&amp;sr=8-1">buy the book</a>, read it, and then start integrating Groovy into your daily programming a little at a time. You&#8217;ll be happy you did.</p>
<p>And don&#8217;t even get me started on <a href="http://grails.org/">Grails</a>&#8230;</p>
<p><strong>Update:</strong> here are the <a href="http://www.juliesoft.com/2008/03/10/groovy-micro-benchmark/">second</a> and <a href="http://www.juliesoft.com/2008/03/12/groovy-micro-benchmark-revisited-groovy-is-fast/">third</a> posts in this series (benchmarks included).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.juliesoft.com/2008/03/groovy-is-coming/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->