<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-4499562010259202212</id><updated>2012-02-10T01:33:05.841-08:00</updated><category term='grails bug workaround'/><category term='grails plugin javascript validation experience'/><category term='groovy interfaces multi methods jruby'/><category term='grails plugins awesomeness'/><category term='java grails hosts ipv6'/><category term='grails groovy iron man'/><category term='grails paypal pro monkey'/><category term='grails plugin javascript validator validation'/><category term='grails job role developer available'/><category term='grails groovy many-to-many collect'/><category term='grails plugin file upload progress bar'/><category term='grails lazy list create dynamic'/><category term='grails validation plugin feeback'/><category term='grails ec2'/><category term='grails live production deployment war size'/><category term='Grails GORM read get'/><category term='amazon RDS stored procedure'/><category term='liferay caching developer mode'/><category term='extra'/><category term='grails'/><category term='grails urlmapping homepage'/><category term='grails plugin community ebook pdf stamper'/><category term='grails groovy errors command object or domain object'/><category term='grails groovy book Graeme Rocher'/><category term='grails rails plugins porting'/><category term='grails groovy gotcha detach hibernate transaction'/><category term='grails admin interface'/><category term='ec2 amazon block store s3'/><category term='grails roles cool'/><category term='groovy grails tips top ten'/><category term='grails plugins communtiy give back'/><category term='validator validation grails plugin javascript'/><category term='YAGNI grails agile'/><category term='grails groovy meta programming format name'/><category term='java regular expressions'/><category term='grails taglib decorator'/><category term='new Domain object save many to many grails gorm'/><title type='text'>delahuntyware</title><subtitle type='html'>Software engineer by day, web ideas maniac by night.
This Blog is about my experience as a web entrepreneur. The tools i use (grails, groovy, java, css, ec2), the problems i solve, the books i read. Basically an over all brain dump... enjoy :)</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>50</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-4039706427151738351</id><published>2011-08-29T18:43:00.000-07:00</published><updated>2011-08-29T18:48:09.834-07:00</updated><title type='text'>My latest Web service is LIVE</title><content type='html'>It's been a while since i last posted. But i have been busy working on this new service.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.hugglehub.com"&gt;http://www.hugglehub.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The service is all about making it easy to share you photos with your parents. &lt;br /&gt;&lt;br /&gt;Check it out let me know what you think.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-4039706427151738351?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/4039706427151738351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=4039706427151738351' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4039706427151738351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4039706427151738351'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2011/08/my-latest-web-service-is-live.html' title='My latest Web service is LIVE'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-8116998172964427547</id><published>2011-05-16T06:54:00.001-07:00</published><updated>2011-05-16T07:01:20.647-07:00</updated><title type='text'>User tracking logging in Grails</title><content type='html'>Hi peeps&lt;br /&gt;&lt;br /&gt;Thought i would just do a quick post about how to create a custom logging filter for logging which pages a user went to.&lt;br /&gt;&lt;br /&gt;First setup log4j config to add a new apppender nd logger called utlog (usage tracking)&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; def utLog = "${System.properties.getProperty('catalina.base')}${File.separator}logs${File.separator}utlog.log"  &lt;br /&gt; println utLog  &lt;br /&gt; log4j = {  &lt;br /&gt;  appenders {  &lt;br /&gt;   rollingFile name: 'utlog', file: utLog, layout: pattern(conversionPattern: '%d{dd-MM-yyyy HH:mm:ss,SSS}|%p|%c{1}|%X{userId}|%X{sessionId}|%m%n'), maxFileSize: '10MB', threshold: org.apache.log4j.Level.DEBUG  &lt;br /&gt;   console name: 'stdout', layout:pattern(conversionPattern: '%d{dd-MM-yyyy HH:mm:ss,SSS}|%p|%c{1}|%X{userId}|%X{sessionId}|%m%n'), threshold: org.apache.log4j.Level.DEBUG  &lt;br /&gt;  }  &lt;br /&gt;  error 'org.codehaus.groovy.grails.web.servlet', // controllers  &lt;br /&gt;      'org.codehaus.groovy.grails.web.pages', // GSP  &lt;br /&gt;      'org.codehaus.groovy.grails.web.sitemesh', // layouts  &lt;br /&gt;      'org.codehaus.groovy.grails.web.mapping.filter', // URL mapping  &lt;br /&gt;      'org.codehaus.groovy.grails.web.mapping', // URL mapping  &lt;br /&gt;      'org.codehaus.groovy.grails.commons', // core / classloading  &lt;br /&gt;      'org.codehaus.groovy.grails.plugins', // plugins  &lt;br /&gt;      'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration  &lt;br /&gt;      'org.springframework',  &lt;br /&gt;      'org.hibernate',  &lt;br /&gt;      'net.sf.ehcache.hibernate'  &lt;br /&gt;  warn 'org.mortbay.log'    &lt;br /&gt;  info utlog: ['ut'],additivity:true  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next create a filter that uses Spring security plugin to fetch the current logged in user:&lt;br /&gt;&lt;br /&gt;&lt;pre  style="font-family:arial;font-size:12px;border:1px dashed #CCCCCC;width:99%;height:auto;overflow:auto;background:#f0f0f0;;background-image:URL(http://2.bp.blogspot.com/_z5ltvMQPaa8/SjJXr_U2YBI/AAAAAAAAAAM/46OqEP32CJ8/s320/codebg.gif);padding:0px;color:#000000;text-align:left;line-height:20px;"&gt;&lt;code style="color:#000000;word-wrap:normal;"&gt; class UsageTrackingFilters {  &lt;br /&gt;   def springSecurityService  &lt;br /&gt;   private static final Log usagetrackingLog = LogFactory.getLog('ut')  &lt;br /&gt;   def filters = {  &lt;br /&gt;     all(controller: '*', action: '*') {  &lt;br /&gt;       before = {  &lt;br /&gt;         String sessionId = RequestContextHolder.getRequestAttributes()?.getSessionId()  &lt;br /&gt;         if (sessionId) {  &lt;br /&gt;           MDC.put('sessionId', sessionId)  &lt;br /&gt;         }  &lt;br /&gt;         if (springSecurityService.isLoggedIn()) {  &lt;br /&gt;           def userId = springSecurityService.getPrincipal().id  &lt;br /&gt;           MDC.put('userId', userId + "")  &lt;br /&gt;         }else{  &lt;br /&gt;           MDC.put('userId', "0")  &lt;br /&gt;         }  &lt;br /&gt;         usagetrackingLog.info(request.getRequestURI())  &lt;br /&gt;       }  &lt;br /&gt;       after = {  &lt;br /&gt;       }  &lt;br /&gt;       afterView = {  &lt;br /&gt;         MDC.remove('sessionId')  &lt;br /&gt;         MDC.remove('userId')  &lt;br /&gt;       }  &lt;br /&gt;     }  &lt;br /&gt;   }  &lt;br /&gt; }  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That is it&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-8116998172964427547?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/8116998172964427547/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=8116998172964427547' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8116998172964427547'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8116998172964427547'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2011/05/user-tracking-logging-in-grails.html' title='User tracking logging in Grails'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-8277465413015009765</id><published>2011-02-26T20:42:00.000-08:00</published><updated>2011-02-26T20:46:18.878-08:00</updated><title type='text'>Setup Amazon linux for Grails</title><content type='html'>Install mysql&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;yum install mysql mysql-server mysql-libs&lt;br /&gt;service mysqld start&lt;br /&gt;chkconfig --levels 235 mysqld on&lt;br /&gt;mysql_secure_installation&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Install apache&lt;br /&gt;&lt;br /&gt;sudo yum install httpd httpd-devel&lt;br /&gt;&lt;br /&gt;add /etc/httpd/conf.d/proxy_ajp.conf&lt;br /&gt;&lt;br /&gt;With this in it:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;Ifmodule mod_proxy_ajp.c&amp;gt;&lt;br /&gt;ProxyRequests On&lt;br /&gt;ProxyVia On&lt;br /&gt;&lt;br /&gt;&amp;lt;Location /&amp;gt;&lt;br /&gt;Order allow,deny&lt;br /&gt;Allow from all&lt;br /&gt;ProxyPass ajp://localhost:8009/&lt;br /&gt;ProxyPassReverse ajp://localhost:8009/&lt;br /&gt;&amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/Ifmodule&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-8277465413015009765?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/8277465413015009765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=8277465413015009765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8277465413015009765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8277465413015009765'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2011/02/setup-amazon-linux-for-grails.html' title='Setup Amazon linux for Grails'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-4024927640372038250</id><published>2010-10-20T05:11:00.000-07:00</published><updated>2010-10-20T05:16:48.467-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Grails GORM read get'/><title type='text'>Grails GORM trick: Use read() rather than get() on updates</title><content type='html'>Hi&lt;br /&gt;&lt;br /&gt;So i discovered that it might be a good idea use read() on your update method.&lt;br /&gt;&lt;br /&gt;So use &lt;br /&gt;&lt;br /&gt;def person = Person.read(params.id)&lt;br /&gt;&lt;br /&gt;instead of &lt;br /&gt;&lt;br /&gt;def person = Person.get(params.id)&lt;br /&gt;&lt;br /&gt;The consequence of this is that hibernate dirty checking is turned off. So to save your domain object you MUST call save(). So if you cancel the update for any reason without calling save() you do not have to to worry about grails persisting things automatically due to dirty checking :)&lt;br /&gt;&lt;br /&gt;Hope this helps&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-4024927640372038250?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/4024927640372038250/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=4024927640372038250' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4024927640372038250'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4024927640372038250'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2010/10/grails-gorm-trick-use-read-rather-than.html' title='Grails GORM trick: Use read() rather than get() on updates'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1175116450649423509</id><published>2010-10-17T19:03:00.000-07:00</published><updated>2010-10-17T19:26:16.985-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='new Domain object save many to many grails gorm'/><title type='text'>GORM gotcha: Many to Many mapping causing new Domain to be saved</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;I came across a new Grails GORM subtle gotcha this week.&lt;br /&gt;&lt;br /&gt;I was creating a new Domain object and it was still getting persisted to the database even though i was not calling save().&lt;br /&gt;&lt;br /&gt;This is not normal behavior for NEW objects. As you may or may not be aware this is the behavior when updating objects though. So i was quite surprised by this and did some trials in trying to fix the problem.&lt;br /&gt;&lt;br /&gt;First calling discard() on my NEW object was the first try. But that was a guess and i knew really it would not work. Because that object not yet associated with the session. And it didn't. So i finally found the problem.&lt;br /&gt;&lt;br /&gt;This was all to do the the many to many relationship that was setup on the domain object.&lt;br /&gt;&lt;br /&gt;So for example i have somethings like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;class Location {&lt;br /&gt;&lt;br /&gt;static hasMany = [posters:Poster]&lt;br /&gt;&lt;br /&gt;String name&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;class Poster {&lt;br /&gt;&lt;br /&gt;static belongsTo = [Location]&lt;br /&gt;&lt;br /&gt;static hasMany = [locations:Location]&lt;br /&gt;&lt;br /&gt;String name&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So in my controller i allow a user to select multiple locations. These locations all get added to the new Poster in this line of code:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;Poster poster = new Poster(params)&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So if i then have some business logic that decides that i do not want to create this new Poster i just need to not call save right. Turns out that is wrong.&lt;br /&gt;&lt;br /&gt;Because of the many to many relationship between Location and Poster. Poster has been assoiated with the locations. So the locations are now dirty and will get persisted at the end of the transaction. This will cascade to my new Poster and save it.&lt;br /&gt;&lt;br /&gt;So to fix this you need to discard the Location objects so they do not save your Poster object.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;Poster poster = new Poster(params)&lt;br /&gt;&lt;br /&gt;if(businessLogicValidate() == false){&lt;br /&gt;&lt;br /&gt;poster.locations.each{Location l -&amp;gt;&lt;br /&gt;l.discard();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;}else{&lt;br /&gt;&lt;br /&gt;poster.save()&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt;Hope this helps someone.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1175116450649423509?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1175116450649423509/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1175116450649423509' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1175116450649423509'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1175116450649423509'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2010/10/gorm-gotcha-many-to-many-mapping.html' title='GORM gotcha: Many to Many mapping causing new Domain to be saved'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-2032515568081702199</id><published>2010-10-14T03:27:00.001-07:00</published><updated>2010-10-14T03:44:39.681-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='amazon RDS stored procedure'/><title type='text'>Stored procedures on Amazon RDS</title><content type='html'>Been a long time since i blogged but need to document this pain in the arse.&lt;br /&gt;&lt;br /&gt;So for a new project i need to create a mysql function (same for stored proc) on amazon RDS.&lt;br /&gt;&lt;br /&gt;When i tried to install it i got this error:&lt;br /&gt;&lt;br /&gt;ERROR 1419 (HY000) at line 3: You do not have the SUPER privilege and binary logging is enabled (you *might* want to use the less safe log_bin_trust_function_creators variable)&lt;br /&gt;&lt;br /&gt;So to get them to install you need to set that database parameter to ON. However to do that is not so simple.&lt;br /&gt;&lt;br /&gt;Lucky for you people i have found out how to do it and here are the steps:&lt;br /&gt;&lt;br /&gt;1) Install the RDS CLI tools. I installed these on my EC2 instance.&lt;br /&gt;&lt;br /&gt;Download from here:&lt;br /&gt;http://developer.amazonwebservices.com/connect/entry.jspa?categoryID=294&amp;externalID=2928&lt;br /&gt;&lt;br /&gt;They are java based and so you need have Java running. Plus they need your amazon key and secret key. Once you have them installed following the readme do the following:&lt;br /&gt;&lt;br /&gt;Important!! make sure you set the AWS region you are working in. &lt;br /&gt;Eg export EC2_REGION=ap-southeast-1&lt;br /&gt;&lt;br /&gt;2) create a new parameter group&lt;br /&gt;&lt;br /&gt;rds-create-db-parameter-group peters-params -f mysql5.1 -d "peters params"&lt;br /&gt;&lt;br /&gt;3) modify the log_bin_trust_function_creators to be set to ON&lt;br /&gt;&lt;br /&gt;rds-modify-db-parameter-group peters-params --parameters="name=log_bin_trust_function_creators, value=on, method=immediate"&lt;br /&gt;&lt;br /&gt;4) change your running db instance to use the new param group&lt;br /&gt;&lt;br /&gt;rds-modify-db-instance petersdbinstance --db-parameter-group-name=peters-params&lt;br /&gt;&lt;br /&gt;5) restart the instance &lt;br /&gt;&lt;br /&gt;rds-reboot-db-instance petersdbinstance&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That will allow you to create a function or stored procedure:&lt;br /&gt;&lt;br /&gt;Some point about the function / stored proc:&lt;br /&gt;&lt;br /&gt;You need to specify the DETERMINISTIC stuff and you need to add a DEFINER=CURRENT_USER&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;DELIMITER $$&lt;br /&gt;DROP FUNCTION IF EXISTS `sayhello`$$&lt;br /&gt;CREATE DEFINER=CURRENT_USER FUNCTION `sayhello`(param1 VARCHAR(120))&lt;br /&gt;       RETURNS VARCHAR(120)&lt;br /&gt;NOT DETERMINISTIC&lt;br /&gt;READS SQL DATA       &lt;br /&gt;BEGIN&lt;br /&gt;RETURN CONCAT('Hello, ',s,'!'); &lt;br /&gt;&lt;br /&gt;END$$&lt;br /&gt;DELIMITER ;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This works for me hope it helps&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-2032515568081702199?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/2032515568081702199/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=2032515568081702199' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/2032515568081702199'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/2032515568081702199'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2010/10/stored-procedures-on-amazon-rds.html' title='Stored procedures on Amazon RDS'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1330840508001498293</id><published>2009-11-02T18:42:00.000-08:00</published><updated>2009-11-02T21:29:15.917-08:00</updated><title type='text'>how to setup clover with multi-module maven project and build with bamboo</title><content type='html'>Ok so i figured how to setup clover with maven on a mulit-module project with putting the config in a maven profile:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;profile&amp;gt;&lt;br /&gt;   &amp;lt;id&amp;gt;clover&amp;lt;/id&amp;gt;&lt;br /&gt;   &amp;lt;build&amp;gt;&lt;br /&gt;       &amp;lt;plugins&amp;gt;&lt;br /&gt;           &amp;lt;plugin&amp;gt;&lt;br /&gt;               &amp;lt;groupId&amp;gt;com.atlassian.maven.plugins&amp;lt;/groupId&amp;gt;&lt;br /&gt;               &amp;lt;artifactId&amp;gt;maven-clover2-plugin&amp;lt;/artifactId&amp;gt;&lt;br /&gt;               &amp;lt;configuration&amp;gt;&lt;br /&gt;                   &amp;lt;targetPercentage&amp;gt;${clover.coverage.percent}&amp;lt;/targetPercentage&amp;gt;&lt;br /&gt;                   &amp;lt;snapshot&amp;gt;/development/build-server/clover/${groupId}-${artifactId}/clover.snapshot&amp;lt;/snapshot&amp;gt;&lt;br /&gt;                   &amp;lt;generateHtml&amp;gt;true&amp;lt;/generateHtml&amp;gt;&lt;br /&gt;                   &amp;lt;generateXml&amp;gt;true&amp;lt;/generateXml&amp;gt;&lt;br /&gt;                   &amp;lt;baseDir&amp;gt;${project.basedir}&amp;lt;/baseDir&amp;gt;&lt;br /&gt;                   &amp;lt;licenseLocation&amp;gt;/development/build-server/clover/clover.license&amp;lt;/licenseLocation&amp;gt;&lt;br /&gt;               &amp;lt;/configuration&amp;gt;&lt;br /&gt;               &amp;lt;executions&amp;gt;&lt;br /&gt;                         &amp;lt;execution&amp;gt;&lt;br /&gt;                             &amp;lt;id&amp;gt;clover&amp;lt;/id&amp;gt;&lt;br /&gt;                             &amp;lt;goals&amp;gt;&lt;br /&gt;                                 &amp;lt;goal&amp;gt;setup&amp;lt;/goal&amp;gt;&lt;br /&gt;                                 &amp;lt;goal&amp;gt;snapshot&amp;lt;/goal&amp;gt;&lt;br /&gt;                             &amp;lt;/goals&amp;gt;&lt;br /&gt;                         &amp;lt;/execution&amp;gt;&lt;br /&gt;                         &amp;lt;execution&amp;gt;&lt;br /&gt;                             &amp;lt;phase&amp;gt;verify&amp;lt;/phase&amp;gt;&lt;br /&gt;                             &amp;lt;goals&amp;gt;&lt;br /&gt;                                 &amp;lt;goal&amp;gt;aggregate&amp;lt;/goal&amp;gt;&lt;br /&gt;                                 &amp;lt;goal&amp;gt;clover&amp;lt;/goal&amp;gt;&lt;br /&gt;                                 &amp;lt;goal&amp;gt;check&amp;lt;/goal&amp;gt;&lt;br /&gt;                             &amp;lt;/goals&amp;gt;&lt;br /&gt;                         &amp;lt;/execution&amp;gt;&lt;br /&gt;                     &amp;lt;/executions&amp;gt;&lt;br /&gt;           &amp;lt;/plugin&amp;gt;&lt;br /&gt;&lt;br /&gt;       &amp;lt;/plugins&amp;gt;&lt;br /&gt;   &amp;lt;/build&amp;gt;&lt;br /&gt;&amp;lt;/profile&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Simply drop that into your profiles section in your pom. You will need to change the paths of where you have put your clover licence and where you want the snapshots to be stored. Then when you want to run it use this command.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;mvn -P clover install&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Bamboo&lt;br /&gt;&lt;br /&gt;Setup bamboo as normal but make sure you don't let bamboo clear out your build directory each time or clover won't work. So untick the option to clean out the build directory each time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1330840508001498293?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1330840508001498293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1330840508001498293' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1330840508001498293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1330840508001498293'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/11/how-to-setup-clover-with-multi-module.html' title='how to setup clover with multi-module maven project and build with bamboo'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-2032743209017512603</id><published>2009-10-15T15:13:00.000-07:00</published><updated>2009-10-15T15:24:26.590-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy iron man'/><title type='text'>Grails: the Iron Man suit for the Tony Stark developer</title><content type='html'>Just thought i would put a response together for this post:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://slackhacker.wordpress.com/2009/10/15/the-dark-side-of-grails/"&gt;Grails dark side&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;In my opinion the Grails sweet spot is for developers who already have years of experience of building web app with spring/hibernate/sitemesh and java.&lt;br /&gt;&lt;br /&gt;Basically it is the "iron man suit" for an already established "Tony Stark" developer. The iron man suit is at its most powerful when it is controlled by Tony Stark. A man who has years of experience of solving problems. The suit simply enhances him :)&lt;br /&gt;&lt;br /&gt;I have years of experience of using the spring/hibernate/sitemesh/java stack along with deploying java web apps on java app servers.  So Grails is my "Iron Man Suit"&lt;br /&gt;&lt;br /&gt;For me Grails is essentially the same core deployed in the same way. The difference is that Grails + Groovy is literally super glue for these components. Almost like comparing assembling your own Ikea furniture vs carving your own out of wood. Except the end quality is even better.&lt;br /&gt;&lt;br /&gt;So thinking that you can get the absolute most out of Grails without knowing anything about spring or hibernate etc is ignorant. And actually being ignorant of the underline technologies  often leads to assumption that a bug with the underline technology (eg hibernate) is a bug with Grails.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-2032743209017512603?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/2032743209017512603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=2032743209017512603' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/2032743209017512603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/2032743209017512603'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/10/grails-iron-man-suit-for-tony-stark.html' title='Grails: the Iron Man suit for the Tony Stark developer'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-7621863007202970633</id><published>2009-09-16T16:56:00.000-07:00</published><updated>2009-09-16T17:00:50.279-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='liferay caching developer mode'/><title type='text'>Turn off caching in Liferay (development mode)</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;Long time no post. But here is a little snippit of a trick I discovered but had to do some serious google searches to find.&lt;br /&gt;&lt;br /&gt;To turn off the liferay caching in Liferay for when you are developing all you have to do is this:&lt;br /&gt;&lt;br /&gt;Find this file:&lt;br /&gt;&lt;br /&gt;$LIFERAY_HOME/tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/portal-developer.properties&lt;br /&gt;&lt;br /&gt;Can copy it and rename it to:&lt;br /&gt;&lt;br /&gt;$LIFERAY_HOME/tomcat-6.0.18/webapps/ROOT/WEB-INF/classes/portal-ext.properties&lt;br /&gt;&lt;br /&gt;This will disable all caching in Liferay such as css, javascript and vm templates.&lt;br /&gt;&lt;br /&gt;Hope this helps.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-7621863007202970633?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/7621863007202970633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=7621863007202970633' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7621863007202970633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7621863007202970633'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/09/turn-off-caching-in-liferay-development.html' title='Turn off caching in Liferay (development mode)'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-6310580821179119358</id><published>2009-07-21T09:50:00.000-07:00</published><updated>2009-07-21T10:13:18.162-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails bug workaround'/><title type='text'>Workaround to a nasty Grails 1.1.1 bug</title><content type='html'>Hi all&lt;br /&gt;&lt;br /&gt;Just wanted to post quickly about a workaround to a Grails bug I dropped into to my application lately. There seems to some strange problem with Grails not binding the GORM methods to the domain objects intermittently.&lt;br /&gt;Eg horrible errors like this&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;groovy.lang.MissingPropertyException: No such property: save for class: XXXXX&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I only seem to get this problem in production on a Tomcat 6.0 server. I super quick fix that seemed to solve it at the time was to restart the tomcat server after a deployment. But that was too shaky for me.&lt;br /&gt;&lt;br /&gt;Unfortunately is happening on a really important piece of my application. When i take payment. So i end up taking payment via my provider Paypal but not saving the transaction details in my own database.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyway after some searching around it seems like the problem it might have been fixed in the upcoming Grails 1.1.2&lt;br /&gt;&lt;br /&gt;But for now this seems to do the trick. Someone posted this quick fix on the forums. The problem is with the hibernate only lazily adding the GORM method and some problem with groovy not recognising them.&lt;br /&gt;&lt;br /&gt;So the trick is to get Hibernate plugin to register them at start up. So in your bootstrap.groovy add the following:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;class BootStrap {&lt;br /&gt;&lt;br /&gt;   def grailsApplication&lt;br /&gt;&lt;br /&gt;   def init = {servletContext -&amp;gt;&lt;br /&gt;&lt;br /&gt;     &lt;br /&gt;       switch (grails.util.GrailsUtil.environment) {&lt;br /&gt;         &lt;br /&gt;           case "production":&lt;br /&gt;               grailsApplication.domainClasses.each{&lt;br /&gt;                   def clazz = it.clazz&lt;br /&gt;                   println "Clazz: $clazz count: " + clazz.count();&lt;br /&gt;               }&lt;br /&gt;           break;&lt;br /&gt;         &lt;br /&gt;           case "development":&lt;br /&gt;               // dev stuff&lt;br /&gt;           break;  &lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt; &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This simply calls count on all domain objects and prints out the count. You don't have to print out the count it was just nice for me.&lt;br /&gt;&lt;br /&gt;Hope this helps&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-6310580821179119358?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/6310580821179119358/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=6310580821179119358' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6310580821179119358'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6310580821179119358'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/07/workaround-to-nasty-grails-111-bug.html' title='Workaround to a nasty Grails 1.1.1 bug'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-7003515991423528312</id><published>2009-07-07T02:38:00.000-07:00</published><updated>2009-07-07T04:30:45.638-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails job role developer available'/><title type='text'>Grails developer available: Get them while there hot</title><content type='html'>Hi Peeps&lt;br /&gt;&lt;br /&gt;This is just quick shout out to the community. I will be available to start a Grails contract from 20&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;th&lt;/span&gt; July. So if you have any new cool projects &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_1"&gt;coming&lt;/span&gt; up and are looking for a developer then let me know.&lt;br /&gt;&lt;br /&gt;You can get me on peter.delahunty@gmail.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-7003515991423528312?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/7003515991423528312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=7003515991423528312' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7003515991423528312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7003515991423528312'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/07/grails-developer-available-get-them.html' title='Grails developer available: Get them while there hot'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3087942020607876942</id><published>2009-06-30T01:19:00.000-07:00</published><updated>2009-12-04T17:07:45.219-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails ec2'/><title type='text'>Deploying a Grails app on EC2 from scratch.</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;Ok so i have found some time write up how to deploy a Grails app onto EC2. This is a step by step guide to setting up Apache, Tomcat, Mysql, Java on an ubuntu Ec2 Box&lt;br /&gt;&lt;br /&gt;For those who do not know. EC2 is Amazon's (that's right the one famous for books) hosting service of its webservice suite. It allows you to run virtual server images on it amazingly scaleable infrastructure. Plus you only pay for what you use. If your server is up for 4 hours you pay for 4 hours. $0.10 per hour (about). You can build your own server as i will show you in the steps below and manange it on their infrastructure.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;These are the steps i have taken and they work for me. I am sure there are hundreds of ways to skin a cat (so the cat skinners say) but this is my way. Take it or leave it :)&lt;br /&gt;&lt;br /&gt;Pre-Requisites&lt;br /&gt;&lt;br /&gt;1) Get Firefox i am sure you have it already if you don't get it you will need it.  As of writing this i am using 3.0.11 &lt;a href="http://www.mozilla-europe.org/en/firefox/"&gt;download here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;2) Install the EC2 Firefox plugin (Elasticfox)  &lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=609"&gt;download here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;3) Install the S3 firefox plugin &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/3247"&gt;download here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;4) Open an amazon account. This is a five min job requiring a valid credit card.  Signup &lt;a href="http://aws.amazon.com/"&gt;here&lt;/a&gt;&lt;br /&gt;Once you have an account you then need to open a EC2 account and an S3 account.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;5) Then next step is for you get familiar with the tools. You can do this by following the getting started guides in this ebook.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1797"&gt;Gettings started&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;IMPORTANT !!!&lt;br /&gt;&lt;br /&gt;You need to read the getting started guide and get familiar with things before you read the rest of this blog post. Otherwise it will not make sense. I am assuming from here onwards you have read an tried out the service.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Setting up a server to run a Grails app.&lt;br /&gt;&lt;br /&gt;By now you should have terminated any test instances you had running on EC2 and be ready start a fresh.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;1) Start with a baseline Linux image&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ok i have decided to host my application on Linux basically because there was no descion to be made. I would only ever host a serious website on Linux and never windows.&lt;br /&gt;&lt;br /&gt;The base linux version i used is Ubuntu 8.10 (intrepid) i am also using a 32bit and not 64 bit. You can find the AMI codes here&lt;br /&gt;&lt;br /&gt;&lt;a href="https://help.ubuntu.com/community/EC2StartersGuide"&gt;https://help.ubuntu.com/community/EC2StartersGuide&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have chosen to go with AMI &lt;span style="font-weight: bold;"&gt;ami-5059be39&lt;/span&gt; because it is based in the US and is 32Bit. If you want to run your servers in Europe then go with this &lt;span style="font-weight: bold;"&gt;ami-80c0e8f4&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Ok now you should have a running instance of the ubuntu basic server. Connect to the server using an SSH terminal&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;Create a directory called downloads in side your home directory /home/ubuntu and cd into it.&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;2) Next you want to install Java&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You should be in the downloads directory you created above&lt;br /&gt;&lt;br /&gt;Download java 1.6. Right that now happens to be JDK 6 update 14. To do this i goto the java download &lt;a href="http://java.sun.com/javase/downloads/index.jsp"&gt;website&lt;/a&gt; .&lt;br /&gt;&lt;br /&gt;Choose JDK 6 update 14&lt;br /&gt;Choose linux&lt;br /&gt;Then copy the download link for the NON rpm version the second link&lt;br /&gt;&lt;br /&gt;Now on your EC2 machine run the following command&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;wget &amp;lt;THE JDK DOWNLOAD URL&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This will now download the JDK install file onto the box&lt;br /&gt;&lt;br /&gt;NOTE you might want to rename the file:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;mv &amp;lt;NAME OF THE FILE&amp;gt;  jdk-6u14-linux-i586.bin&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next copy the file to /usr/local&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;sudo cp jdk-6u14-linux-i586.bin /usr/local&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Change the permissions&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo chmod +x jdk-6u14-linux-i586.bin&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then run the install file&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo ./jdk-6u14-linux-i586.bin&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This should unpack the java file to this directory /usr/local/jdk1.6.0_14&lt;br /&gt;&lt;br /&gt;Next create a symbolic link to the directory called java&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo ln -s /usr/local/jdk1.6.0_14 /usr/local/java&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That is java installed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;3) Next install MYSQL&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Download mysql via the same way you downloaded java above using wget you get the download link &lt;a href="http://dev.mysql.com/downloads/mysql/5.1.html#linux"&gt;here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Choose the Linux (x86) download&lt;br /&gt;&lt;br /&gt;Copy the mysql tar file into /usr/local&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo cp mysql-5.1.35-linux-i686-glibc23.tar.gz /usr/local&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Delete any existing mysql directories. (this maybe optional)&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo rm -rf /etc/mysql&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next follow these commands to install it. IMPORTANT: Don't follow any of the step that are listed by the mysql_install_db script they will be covered later.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo groupadd mysql&lt;br /&gt;sudo useradd -g mysql mysql&lt;br /&gt;sudo cp mysql-5.1.35-linux-i686-glibc23.tar.gz /usr/local&lt;br /&gt;sudo cd /usr/local&lt;br /&gt;sudo gunzip mysql-5.1.35-linux-i686-glibc23.tar.gz&lt;br /&gt;sudo tar -xvf mysql-5.1.35-linux-i686-glibc23.tar&lt;br /&gt;sudo mv /usr/local/mysql-5.1.35-linux-i686-glibc23 /usr/local/mysql &lt;br /&gt;sudo cd mysql &lt;br /&gt;sudo mkdir logs&lt;br /&gt;sudo chown -R mysql . &lt;br /&gt;sudo chgrp -R mysql . &lt;br /&gt;sudo scripts/mysql_install_db --user=mysql &lt;br /&gt;sudo chown -R root . &lt;br /&gt;sudo chown -R mysql data &lt;br /&gt;sudo bin/mysqld_safe --user=mysql &amp;amp;  &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Right now you should have running mysql instance&lt;br /&gt;&lt;br /&gt;Copy the standard startup script into the linux startup area&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo cp /usr/local/mysql/support_files/mysql.server /etc/init.d/mysql&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Setup mysql to run at all levels&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo update-rc.d mysql defaults&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Set a root password&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo /usr/local/mysql/bin/mysqladmin -u root password 'new-password'&lt;br /&gt;sudo /usr/local/mysql/bin/mysqladmin -u root -h 'localhost' password 'new-password'&lt;br /&gt; &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Ok now you have a running mysql instance&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;4) Next you want to move the Mysql installation on to an amazon EBS.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You should already know about an EBS from reading the EC2 getting start guide above.&lt;br /&gt;&lt;br /&gt;Create a new EBS using Elastic fox and attach it to your EC2 instance. You will be asked to enter a device when you are attaching the EBS to your running EC2 instance. Enter the following:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;/dev/sdh&lt;br /&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Once you have done that you want to mount and format that diskspace. I am simply following the instructions found &lt;a href="http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663"&gt;here &lt;/a&gt;but have modified it bit as my paths are different&lt;br /&gt;&lt;br /&gt;Install XFS. This is a secure file system.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install -y xfsprogs&lt;br /&gt;   &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Setup the mount and fomat the disk&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo modprobe xfs&lt;br /&gt;sudo mkfs.xfs /dev/sdh&lt;br /&gt;&lt;br /&gt;echo "/dev/sdh /vol xfs noatime 0 0" | sudo tee -a /etc/fstab&lt;br /&gt;sudo mkdir /vol&lt;br /&gt;sudo mount /vol&lt;br /&gt;    &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You should now have a new filesystem under /vol&lt;br /&gt;&lt;br /&gt;Stop mysql if running&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo /etc/init.d/mysql stop&lt;br /&gt;    &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Move all the mysql files&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo mkdir -p /vol/usr/local/mysql&lt;br /&gt;&lt;br /&gt;sudo mv /usr/local/mysql /vol/usr/local&lt;br /&gt;     &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Remount the mysql directory to the volume&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo mkdir /usr/local/mysql&lt;br /&gt;&lt;br /&gt;echo "/vol/usr/local/mysql /usr/local/mysql     none bind" | sudo tee -a /etc/fstab&lt;br /&gt;sudo mount /usr/local/mysql&lt;br /&gt;&lt;br /&gt;      &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Restart mysql&lt;br /&gt;&lt;br /&gt;Stop mysql if running&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo /etc/init.d/mysql start&lt;br /&gt;     &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You now have mysql running from an EBS&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Setup mysql database user and backup script&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;/usr/local/mysql/bin/mysql -p -u root &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;create database &lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;CREATE DATABASE demodb CHARACTER SET utf8 COLLATE utf8_general_ci; &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;create app user and backup user and give access:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;CREATE USER 'demouser'@'localhost' IDENTIFIED BY 'demouser123';&lt;br /&gt;GRANT ALL PRIVILEGES ON demodb.* TO 'demouser'@'localhost' WITH GRANT OPTION;&lt;br /&gt;&lt;br /&gt;CREATE USER 'backup'@'localhost' IDENTIFIED BY 'backup123';&lt;br /&gt;GRANT LOCK TABLES, SELECT ON demodb.* TO 'backup'@'localhost';&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Setup db backup:&lt;br /&gt;&lt;br /&gt;Download the mysql backup script:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;http://sourceforge.net/projects/automysqlbackup/&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;For putting files in s3 use this&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;http://s3tools.org/s3cmd&lt;br /&gt;&lt;br /&gt;apt-get install s3cmd&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;6) Install Tomcat&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is easy to install&lt;br /&gt;Download tomcat 6 into your /home/ubuntu/downloads using wget&lt;br /&gt;Copy the jar file it to /usr/local&lt;br /&gt;&lt;br /&gt;Use the java jar command to unpack tomcat zip&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo /usr/local/java/bin/jar -xvf /usr/local/tomcatXXX.zip&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Create a symbolic link to Tomcat&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo ln -s /usr/local/tomcatXXXX /usr/local/tomcat&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next create tomcat user to run tomcat&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo groupadd tomcat&lt;br /&gt;sudo useradd -m -s /bin/bash -g tomcat tomcat&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Change to tomcat user and edit the .profile to add java in the PATH&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo su - tomcat&lt;br /&gt;vi /home/tomcat/.profile&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Edit the file using vi to contain&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;export JAVA_HOME=/usr/local/java&lt;br /&gt;PATH=$JAVA_HOME/bin:$PATH&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;configure the server.xml to use an AJP connector to work with apache.&lt;br /&gt;&lt;br /&gt;save your old /usr/local/tomcat/conf/server.xml to server.xml.orig&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;cp /usr/local/tomcat/conf/server.xml /usr/local/tomcat/conf/server.xml.orig&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;edit a new server.xml&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;vi /usr/local/tomcat/conf/server.xml &lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;copy this config in there:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;?xml version='1.0' encoding='utf-8'?&amp;gt;&lt;br /&gt;&amp;lt;Server port=&amp;quot;8005&amp;quot; shutdown=&amp;quot;SHUTDOWN&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;Listener className=&amp;quot;org.apache.catalina.core.AprLifecycleListener&amp;quot; SSLEngine=&amp;quot;on&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;Listener className=&amp;quot;org.apache.catalina.core.JasperListener&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;Listener className=&amp;quot;org.apache.catalina.mbeans.ServerLifecycleListener&amp;quot; /&amp;gt;&lt;br /&gt;  &amp;lt;Listener className=&amp;quot;org.apache.catalina.mbeans.GlobalResourcesLifecycleListener&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;Service name=&amp;quot;Catalina&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;!--&lt;br /&gt;    &amp;lt;Connector port=&amp;quot;8080&amp;quot; protocol=&amp;quot;HTTP/1.1&amp;quot;&lt;br /&gt;               connectionTimeout=&amp;quot;20000&amp;quot;&lt;br /&gt;               redirectPort=&amp;quot;8443&amp;quot; /&amp;gt;&lt;br /&gt;        --&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;Connector      port=&amp;quot;8009&amp;quot;&lt;br /&gt;                                protocol=&amp;quot;AJP/1.3&amp;quot;&lt;br /&gt;                                redirectPort=&amp;quot;8443&amp;quot;&lt;br /&gt;                                connectionTimeout=&amp;quot;300000&amp;quot;&lt;br /&gt;                                maxThreads=&amp;quot;200&amp;quot;&lt;br /&gt;                                backlog=&amp;quot;50&amp;quot;&lt;br /&gt;                                enableLookups=&amp;quot;true&amp;quot;&lt;br /&gt;                                emptySessionPath=&amp;quot;true&amp;quot;&lt;br /&gt;&lt;br /&gt;        /&amp;gt;&lt;br /&gt;&lt;br /&gt;        &amp;lt;Engine name=&amp;quot;Catalina&amp;quot; defaultHost=&amp;quot;localhost&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;Host name=&amp;quot;localhost&amp;quot;  appBase=&amp;quot;webapps&amp;quot;&lt;br /&gt;            unpackWARs=&amp;quot;true&amp;quot; autoDeploy=&amp;quot;true&amp;quot;&lt;br /&gt;            xmlValidation=&amp;quot;false&amp;quot; xmlNamespaceAware=&amp;quot;false&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;/Host&amp;gt;&lt;br /&gt;    &amp;lt;/Engine&amp;gt;&lt;br /&gt;  &amp;lt;/Service&amp;gt;&lt;br /&gt;&amp;lt;/Server&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That is tomcat setup. You can run it if you like to see it working.&lt;br /&gt;&lt;br /&gt;Now just run tomcat&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo su - tomcat&lt;br /&gt;/usr/local/tomcat/bin/startup.sh&lt;br /&gt;      &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;6) Install Apache&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is easy&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo apt-get install apache2&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Enable AJP mod&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo a2enmod proxy_ajp&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Create a new site to configure AJP with tomcat. You can change the to whatever you want.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo vi /etc/apache2/sites-available/webapp&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;add the following config to link apache to tomcat&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&amp;lt;ifmodule&amp;gt;&lt;br /&gt;ProxyRequests On&lt;br /&gt;ProxyVia On&lt;br /&gt;&lt;br /&gt;&amp;lt;location&amp;gt;&lt;br /&gt;Order allow,deny&lt;br /&gt;Allow from all&lt;br /&gt;ProxyPass ajp://localhost:8009/&lt;br /&gt;ProxyPassReverse ajp://localhost:8009/&lt;br /&gt;&amp;lt;/location&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/ifmodule&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;Enable your site&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo a2ensite webapp&lt;br /&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;disable the default apache config&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo a2dissite default&lt;br /&gt;  &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;start or restart apache&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo /etc/init.d/apache2 restart&lt;br /&gt;   &lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That is basic apache installed&lt;br /&gt;&lt;br /&gt;To secure apache with basic authenication:&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo mkdir /etc/apache2/passwd&lt;br /&gt;cd /etc/apache2/passwd&lt;br /&gt;sudo htpasswd -c site-access &lt;USERNAME&gt;&lt;br /&gt;&lt;ENTER PASSWORD&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;add these lines to the webapp config to secure:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;Location /&amp;gt;&lt;br /&gt;Order allow,deny&lt;br /&gt;Allow from all&lt;br /&gt;&lt;br /&gt;AuthType Basic&lt;br /&gt;AuthName &amp;quot;Restricted area&amp;quot;&lt;br /&gt;AuthUserFile /etc/apache2/passwd/site-access&lt;br /&gt;Require valid-user&lt;br /&gt;&lt;br /&gt;ProxyPass ajp://localhost:8009/&lt;br /&gt;ProxyPassReverse ajp://localhost:8009/&lt;br /&gt;&amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To enable SSL on the apache instance:&lt;br /&gt;&lt;br /&gt;Enable ssl mod&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo a2enmod ssl&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;generate your .key and .crt files. The company who you bought your SSL certs from should tell you how to do this. &lt;br /&gt;&lt;br /&gt;make a new director to put the .key and .crt file in:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo mkdir /etc/apache2/ssl&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;copy the .key and .crt files into that directory. eg:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;/etc/apache2/ssl/www.mydomain.com.crt&lt;br /&gt;/etc/apache2/ssl/www.mydomain.com.key&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Create a new site to configure ssl. &lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;&lt;br /&gt;sudo vi /etc/apache2/sites-available/ssl&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;copy this config&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;VirtualHost *:443&amp;gt;&lt;br /&gt;DocumentRoot /var/www/&lt;br /&gt;&lt;br /&gt;&amp;lt;IfModule mod_proxy_ajp.c&amp;gt;&lt;br /&gt;&lt;br /&gt;ProxyRequests On&lt;br /&gt;ProxyVia On&lt;br /&gt;&lt;br /&gt;&amp;lt;Location /&amp;gt;&lt;br /&gt;Order allow,deny&lt;br /&gt;Allow from all&lt;br /&gt;#AuthType Basic&lt;br /&gt;#AuthName &amp;quot;Restricted area&amp;quot;&lt;br /&gt;#AuthUserFile /etc/apache2/passwd/site-access&lt;br /&gt;#Require valid-user&lt;br /&gt;ProxyPass ajp://localhost:8009/&lt;br /&gt;ProxyPassReverse ajp://localhost:8009/&lt;br /&gt;&amp;lt;/Location&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;/IfModule&amp;gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;IfModule mod_ssl.c&amp;gt;&lt;br /&gt;&lt;br /&gt;SSLEngine On&lt;br /&gt;SSLCertificateFile /etc/apache2/ssl/www.mydomain.com.crt&lt;br /&gt;SSLCertificateKeyFile /etc/apache2/ssl/www.mydomain.com.key&lt;br /&gt;&lt;br /&gt;&amp;lt;/IfModule&amp;gt;&lt;br /&gt;&amp;lt;/VirtualHost&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Just change the paths at the bottom to point to your .crt and .key files.&lt;br /&gt;&lt;br /&gt;Ok few that was long ish for me to write...&lt;br /&gt;&lt;br /&gt;By now you should have Tomcat running with Apache and Mysql. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;UPDATE:&lt;br /&gt;&lt;br /&gt;Extra steps i take for Grails:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.peterdelahunty.com/2009/06/going-live-with-your-grails-app-part-1.html"&gt;Going live with grails&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope this helps someone....&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3087942020607876942?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3087942020607876942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3087942020607876942' title='16 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3087942020607876942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3087942020607876942'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/06/deploying-grails-app-on-ec2-in-from.html' title='Deploying a Grails app on EC2 from scratch.'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>16</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-8777226413114187584</id><published>2009-06-29T08:28:00.000-07:00</published><updated>2009-06-29T08:35:06.500-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails paypal pro monkey'/><title type='text'>Paypal Pro Plugin documentation done</title><content type='html'>Hi&lt;br /&gt;&lt;br /&gt;I have release the Paypal Pro plugin. Basically this is NOT a replacement for the existing Grails paypal plugin. It allows you to directly interface with a Paypal &lt;a href="https://www.paypal.com/uk/cgi-bin/webscr?cmd=_wp-pro-overview-outside"&gt;Webpayment Pro&lt;/a&gt; account. This is a service provided by Paypal that you have to pay for each month but it allows you to take payments on your website via forms on your website without the customer ever getting redirected to Paypal.&lt;br /&gt;&lt;br /&gt;The plugin is all working and i have been using it on &lt;a href="http://www.ebookstamper.com"&gt;www.ebookstamper.com&lt;/a&gt; for the last few weeks.&lt;br /&gt;&lt;br /&gt;Check it out here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://grails.org/plugin/paypal-pro"&gt;http://grails.org/plugin/paypal-pro&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Peace&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-8777226413114187584?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/8777226413114187584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=8777226413114187584' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8777226413114187584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8777226413114187584'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/06/paypal-pro-plugin-documentation-done.html' title='Paypal Pro Plugin documentation done'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1973523215120862842</id><published>2009-06-18T05:01:00.000-07:00</published><updated>2009-06-18T05:14:53.115-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails plugin file upload progress bar'/><title type='text'>Grails Super File Upload plugin complete and uploaded (mind the pun!)</title><content type='html'>Ho ho ho&lt;br /&gt;&lt;br /&gt;I have uploaded and released my latest Grails plugin&lt;br /&gt;&lt;br /&gt;&lt;a href="http://grails.org/plugin/super-file-upload"&gt;Super File Upload&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;Finally you can easily style your file upload control and have a fully working progress bar with it.&lt;br /&gt;&lt;br /&gt;If you want to see it action then head to my new website &lt;a href="http://www.ebookstamper.com/"&gt;www.ebookstamper.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1973523215120862842?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1973523215120862842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1973523215120862842' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1973523215120862842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1973523215120862842'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/06/grails-super-file-upload-complete-and.html' title='Grails Super File Upload plugin complete and uploaded (mind the pun!)'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3523195346904059272</id><published>2009-06-12T01:36:00.001-07:00</published><updated>2009-06-12T02:15:16.387-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails live production deployment war size'/><title type='text'>Going live with your Grails app part 1 of X</title><content type='html'>So I thought I would right up some problem/solutions I had with deploying a Grails app into production.&lt;br /&gt;&lt;br /&gt;First step is reducing grails WAR file size.&lt;br /&gt;&lt;br /&gt;I have depolyed my latest app &lt;a href="http://www.ebookstamper.com"&gt;http://www.ebookstamper.com&lt;/a&gt; on Amazon EC2 (i will do a later step by step post for EC2 deployment). After a few round trips i realised that i was getting pi**ed off with the time it was taking to upload my 20-30meg war file to my server. So after a bit of digging around on the web and some trial and error I devised a way to reduce my WAR size. Here are the steps below:&lt;br /&gt;&lt;br /&gt;1) Use Tomcat 6.X&lt;br /&gt;I won't bother giving arguments for using Tomcat 6. Let me just say if you are developing a new app then take it from me this is what you want to be using for your app server. I worked on a large project for the last 12 month getting this website live &lt;a href="http://www.carphonewarehouse.com/"&gt;http://www.carphonewarehouse.com/&lt;/a&gt; and we really squeezed out the performace of Tomcat and the sun JDK1.6 with great results.&lt;br /&gt;&lt;br /&gt;2) Set up a shared library in tomcat&lt;br /&gt;&lt;br /&gt;Make a directory called shared/lib under tomcat home directory&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;mkdir -p $TOMCAT_HOME/shared/lib&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;3) Tell tomcat about this lib&lt;br /&gt;&lt;br /&gt;Find the file $TOMCAT_HOME/conf/catalina.properties&lt;br /&gt;&lt;br /&gt;Change this line&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;shared.loader=&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;to&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;shared.loader=${catalina.base}/shared/lib,${catalina.base}/shared/lib/*.jar&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;4) Build your Grails war file&lt;br /&gt;&lt;br /&gt;Ok first off you should build your grails war file as normal to get all the jars.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;grails war&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Or if you going to deploy the app as root context "/" on tomcat do this&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;grails war ROOT.war&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The main point of this exercise is to have grails build a complete WAR file including all the jar librarys you need. These jars come from all over. Grails home/dist, Grails home/lib, plugins and your app lib. So instead of you manually going to find all these jar files just have grails do it for you.&lt;br /&gt;&lt;br /&gt;So once you have your WAR file you will have all the jars you need for your app inside the war file in WEB-INF/lib.&lt;br /&gt;&lt;br /&gt;5) Copy all the jar files to $TOMCAT_HOME/shared/lib&lt;br /&gt;&lt;br /&gt;So unpack the war file and copy all the jar files to the $TOMCAT_HOME/shared/lib directory you created earlier. My simple technique for this was.&lt;br /&gt;&lt;br /&gt;a) Upload the ROOT.war file to your server and put it in the $TOMCAT_HOME/webapps directory. This way it is one (a big one) file to upload.&lt;br /&gt;&lt;br /&gt;b) Start tomcat and have it deploy your application. This will get tomcat to unpack the war file for you.&lt;br /&gt;&lt;br /&gt;c) Stop tomat then go into the unpacked war lib directory $TOMCAT_HOME/webapps/ROOT/WEB-INF/lib and move all the jar files in there to $TOMCAT_HOME/shared/lib. You can then delete the contents of webapps.&lt;br /&gt;&lt;br /&gt;6) Next build yourself an empty war file&lt;br /&gt;&lt;br /&gt;Now this is the magic bit that i found somewhere out on the web. The --nojars arguement.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;grails war --nojars ROOT.war&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The --nojars argument will build a grails war file without any jars in the WEB-INF/lib directory in the war file. You should see that this will reduce the war file size by rather pleaseable amount.&lt;br /&gt;&lt;br /&gt;7) Redeploy your new lightweight ROOT.war on tomcat&lt;br /&gt;You can then redeploy your new war on tomcat and have a new working app&lt;br /&gt;&lt;br /&gt;Next time around you only need to build the war without any jar file.&lt;br /&gt;&lt;br /&gt;Now this should be obvious but i will point it out anyway. If you add a new plugin, upgrade grails or add a new lib jar to your app then you should repeat all of this from the start to avoid class not found problems.&lt;br /&gt;&lt;br /&gt;Enjoy&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3523195346904059272?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3523195346904059272/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3523195346904059272' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3523195346904059272'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3523195346904059272'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/06/going-live-with-your-grails-app-part-1.html' title='Going live with your Grails app part 1 of X'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1598627038516459411</id><published>2009-06-11T06:21:00.000-07:00</published><updated>2009-06-11T06:55:03.142-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails plugins communtiy give back'/><title type='text'>Love Grails? Give something back to the community</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;Been thinking today how important it to the success of the Grails eco system that people give back as much as they take.  Grails is simply a revolutionary full stack web development framework. It personally saves me so much development time that it is simply my only choice for web development now.&lt;br /&gt;&lt;br /&gt;Anyway I have been using Grails on and off for about 2-3 years. I think is started dabbling with it from version 0.3 but have seen it grow from strength to strength upto its current release of 1.1.1.&lt;br /&gt;&lt;br /&gt;The projects I built in grails were most beta ideas and most never seen light of day. They are in my great ideas hardrive graveyard. Anyway one of them has finally seen the light of day: &lt;a href="http://www.ebookstamper.com"&gt;www.ebookstamper.com &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Throughout the development of this site I came accross a few missing features in grails that I would only have found from building a commercial website. So I decide to build these features myself in the form of a plugin. I have to tell you it one the best decicions i made.&lt;br /&gt;&lt;br /&gt;Grails makes it so easy to create a new plugin and release it that it seem criminal not to. Anyone can apply for a grails plugin developer account and Graeme will probably grant it in 5 mins from his iphone.  Then you can check in your work and hey presto you can call yourself a grails plugin developer.&lt;br /&gt;&lt;br /&gt;So what can a plugin be. Well anything really. Have you written some code in your Grails app that you think can be made more general. Well do it and refactor it out it into a plugin.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Here are some good ideas for plugins:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Wrap an existing java library as a grails plugin. &lt;/span&gt;&lt;br /&gt;There are so many great java libs out there that do specific cool things. Make them available in grails as a plugin. Some good examples of this already are the amazon s3 plugin or the awesome searchable plugin or even the quartz plugin.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Wrap an existing javascript library&lt;/span&gt;&lt;br /&gt;This the same as the java lib example above. There are some many javascript utils out there. If you use one think about making it into a plugin for grails. I did this with the super file upload plugin i wrote. I also see it with the grails ui plugin.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Wrap up a handler for new protocol&lt;/span&gt;&lt;br /&gt;Have you had to write your own protocol handler for your grails app release it as a plugin. New xml protocols come out all the time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Wrap up some cool algorithim you have written&lt;/span&gt;&lt;br /&gt;So you have written some code that does something cool. If you think it can be useful to someone else then release it as a plugin.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Create a taglib library&lt;/span&gt;&lt;br /&gt;Have you written some cool tag libs that you use again and again. Why not package them up as a plugin. I have done this with my paypal pro plugin. You can use the tag libs to create credit card fields such as country select box, credit card type select box, and expriy date etc&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Finally rememeber, this all about Karma. If you give good things wil always happen in some shape or form.&lt;br /&gt;&lt;br /&gt;So start today: See what code you can give back to your Grails Communtity :)&lt;br /&gt;&lt;br /&gt;Peace&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1598627038516459411?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1598627038516459411/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1598627038516459411' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1598627038516459411'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1598627038516459411'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/06/love-grails-give-something-back-to.html' title='Love Grails? Give something back to the community'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-745227405026189508</id><published>2009-06-11T04:49:00.000-07:00</published><updated>2009-06-11T05:09:02.995-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails plugin community ebook pdf stamper'/><title type='text'>My new Grails site finally goes live www.ebookstamper.com</title><content type='html'>Hi all&lt;br /&gt;&lt;br /&gt;So i finally put my new grails built website live this week.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.ebookstamper.com"&gt;http://www.ebookstamper.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The elevator pitch is:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;On demand stamping of PDF ebooks with your customers name and email&lt;/blockquote&gt;&lt;br /&gt;The long description is:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;A web based service providing on demand stamping of PDF ebooks with your customers name and email. Helps protect your intellectual property by providing a deterrent against file sharing.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;People who write ebooks and self publish will know what I am talking about.&lt;br /&gt;&lt;br /&gt;I have been working on it in my spare time (is there such thing as spare time) for the last few months. Recently I took some quality time out and worked on it full time to get it out the door. The good new is that I have developed 4 grails plugins that have come out of building this website.&lt;br /&gt;&lt;br /&gt;I love grails and it has help me so much in getting things out the door as soon as possible so I feel it is only right to give back to the community. So I have released these four plugins:&lt;br /&gt;&lt;br /&gt;These are:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/plugin/javascript-validator"&gt;Javascript validator plugin&lt;/a&gt;&lt;br /&gt;&lt;a href="http://grails.org/plugin/grails-template-engine"&gt;Grails template engine&lt;/a&gt; &lt;a href="http://www.grails.org/plugin/javascript-validator"&gt;plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://grails.org/plugin/super-file-upload"&gt;Super file upload &lt;/a&gt;&lt;a href="http://www.grails.org/plugin/javascript-validator"&gt;plugin&lt;/a&gt;&lt;br /&gt;&lt;a href="http://grails.org/plugin/paypal-pro"&gt;Paypal Pro &lt;/a&gt;&lt;a href="http://www.grails.org/plugin/javascript-validator"&gt;plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Although the code for the last 2 is checked in i have not found time to write up the docs. But will get to that asap. If you want to see the Super file upload plugin (SFU) in action go to my new website above and click on the demo button. The styled red browse button you see there is using the SFU plugin. When you upload a PDF you get the upload progress bar showing too.&lt;br /&gt;&lt;br /&gt;Also I am hosting the whole thing on Amazon EC2 so will write up some posts on running grails apps on EC2. Some ticky bits worth documenting.&lt;br /&gt;&lt;br /&gt;Peace...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-745227405026189508?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/745227405026189508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=745227405026189508' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/745227405026189508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/745227405026189508'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/06/my-new-grails-site-finally-goes-live.html' title='My new Grails site finally goes live www.ebookstamper.com'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-8231507137221493106</id><published>2009-05-27T06:38:00.000-07:00</published><updated>2009-05-27T06:44:41.563-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails admin interface'/><title type='text'>Instant Admin Interface with Grails 1.1</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;I think I have just had a great idea for an instant admin interface for my new Grails app. I have almost completed my new web app and was just thinking that I could really do with simple admin interface. So I came up with this idea.&lt;br /&gt;&lt;br /&gt;I can pull out my current domain classes out into a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;plugin&lt;/span&gt;.  I can then install this &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;plugin&lt;/span&gt; into the main application. Then the main app is back to normal&lt;br /&gt;&lt;br /&gt;Then i can create a new app called XXX-admin. I then install the domain classes &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;plugin&lt;/span&gt; into the admin app then generate scaffold controllers/views for the domain.&lt;br /&gt;&lt;br /&gt;This then gives me an instant admin interface.&lt;br /&gt;&lt;br /&gt;Gonna try this out and will write again about how it goes.&lt;br /&gt;&lt;br /&gt;Peace...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-8231507137221493106?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/8231507137221493106/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=8231507137221493106' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8231507137221493106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8231507137221493106'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/05/instant-admin-interface-with-grails-11.html' title='Instant Admin Interface with Grails 1.1'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-4826549119114859416</id><published>2009-05-26T01:44:00.000-07:00</published><updated>2009-05-26T02:15:06.092-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails plugins awesomeness'/><title type='text'>Grails magical second act: The plugin ecosystem</title><content type='html'>So as you might have gathered I love the Grails framework. The full stack framework is nothing short of magic compared to anything else in its domain. Since the arrival of the core framework (the first act) it has completely transformed my web development: Better, Faster, Smarter,&lt;br /&gt;&lt;br /&gt;Anyway it just occurred to me over the weekend that Grails is &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;in fact&lt;/span&gt; now on its &lt;span style="font-weight: bold;"&gt;second act&lt;/span&gt;. That in someways is more spectacular than the first. So what is this second act that tops the first one.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;plugin&lt;/span&gt; architecture:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I have always thought that the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;plugin&lt;/span&gt; architecture is "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;tres&lt;/span&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;kool&lt;/span&gt;" and I have even written and released my own (&lt;a href="http://www.grails.org/plugin/javascript-validator"&gt;Javascript &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Validator&lt;/span&gt;&lt;/a&gt;, &lt;a href="http://www.grails.org/plugin/grails-template-engine"&gt;Grails Template Engine&lt;/a&gt;). But it wasn't until i used the &lt;a href="http://www.grails.org/plugin/amazon-s3"&gt;S3 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;Plugin&lt;/span&gt;&lt;/a&gt; this weekend that it really dawned on my how powerful the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;plugins&lt;/span&gt; are (and can be).&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://aws.amazon.com/s3/"&gt;S3&lt;/a&gt; &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;plugin&lt;/span&gt; is the first "full stack" &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;plugin&lt;/span&gt; that i have used. It comes with a domain class, tag lib and background tasks. All aimed at &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_10"&gt;seamlessly&lt;/span&gt; adding &lt;a href="http://aws.amazon.com/s3/"&gt;S3&lt;/a&gt; support to your application in no time. I took me about 3-4 hours to integrate and test the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;plugin&lt;/span&gt; into my new app.&lt;br /&gt;&lt;br /&gt;With its sync and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;async&lt;/span&gt; modes the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;plugin&lt;/span&gt; is very will written. Also keeping with the Grails philosophy it &lt;span style="font-weight: bold;"&gt;simply sprinkles magic groovy dust&lt;/span&gt; over an existing java framework (&lt;a href="https://jets3t.dev.java.net/"&gt;jets3&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Anyway just thought I would share this with you all. I think that the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_14"&gt;awesomeness&lt;/span&gt; of the the potential in grails &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;plugins&lt;/span&gt; is just beginning and that we can expect to see some really cool stuff coming.&lt;br /&gt;&lt;br /&gt;Peace...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-4826549119114859416?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/4826549119114859416/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=4826549119114859416' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4826549119114859416'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4826549119114859416'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/05/grails-magical-second-act-plugin.html' title='Grails magical second act: The plugin ecosystem'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3410555437838068186</id><published>2009-05-21T05:56:00.000-07:00</published><updated>2009-05-21T06:11:10.917-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>New Grails Plugin Grails Template Engine</title><content type='html'>Hello Alpha Geeks&lt;br /&gt;&lt;br /&gt;I put a small grails plugin out today.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/plugin/grails-template-engine"&gt;http://www.grails.org/plugin/grails-template-engine&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The plugin simply exposes the GSP render engine as a service for backend GSP template rendering . It also adds a new convenient method to the controllers called renderWithTemplateEngine&lt;br /&gt;&lt;br /&gt;The implementation was mostly lifed from Graeme's mail plugin. Now it is available standalone.&lt;br /&gt;&lt;br /&gt;Hopefully this is useful to someone out there :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3410555437838068186?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3410555437838068186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3410555437838068186' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3410555437838068186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3410555437838068186'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/05/new-grails-plugin-grails-template.html' title='New Grails Plugin Grails Template Engine'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-8077739526219117360</id><published>2009-05-06T02:29:00.001-07:00</published><updated>2009-05-06T02:45:46.206-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails rails plugins porting'/><title type='text'>Call to arms for Rails to Grails plugin porting</title><content type='html'>One more thing while I am on a role braindumping on my blog.&lt;br /&gt;&lt;br /&gt;I am currently now sharing offices in London with a good friend of mine and others.  Anyway this good friend of mine is a Ruby on Rails Developer and a very good one at that.&lt;br /&gt;&lt;br /&gt;So I quizzed him a bit about Rails to find out some info. Anyway one of the strong points of Rails is its plugins. They have loads and some really really good ones.&lt;br /&gt;&lt;br /&gt;So got me thinking. From what I can see these plugins are all possible in Grails (if they don't already exist) so why don't we replicate them. The Rails guys are basically solving the same problems as the Grails guys and the fact that a Rails plugins exists means that it is a helpful tool to someone. &lt;br /&gt;&lt;br /&gt;So anyway I am going to start this porting off. Here are some of my first targets:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: 'Bitstream Vera Sans Mono'; font-size: 12px; line-height: 17px; white-space: pre;"&gt;&lt;/span&gt;&lt;a href="http://github.com/technoweenie/acts_as_paranoid" target="_blank"&gt;http://github.com/&lt;wbr&gt;technoweenie/acts_as_paranoid&lt;/a&gt;&lt;br /&gt;&lt;a href="http://thoughtbot.com/projects/paperclip" target="_blank"&gt;http://thoughtbot.com/&lt;wbr&gt;projects/paperclip&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Next I guess I search for "Top 10 Rails plugins"&lt;br /&gt;&lt;br /&gt;http://thetacom.info/2008/02/17/my-10-favorite-rails-plugins/&lt;br /&gt;&lt;br /&gt;Pete :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-8077739526219117360?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/8077739526219117360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=8077739526219117360' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8077739526219117360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8077739526219117360'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/05/call-to-arms-for-rails-to-grails-plugin.html' title='Call to arms for Rails to Grails plugin porting'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-7362203843426270327</id><published>2009-05-06T01:58:00.000-07:00</published><updated>2009-05-06T02:28:52.661-07:00</updated><title type='text'>Dave Klien reviews my Javascript validator plugin in Groovy Mag (April)</title><content type='html'>So having popped my head up after an intensive month or so of major S**t going on in my life and trying to ship my new on-line service (written in grails of course). Anyway I just seen Mr Dave Klien has done a wonderful review of my Javascript Validation grails plug-in. So I bought the mag. It is actually very good so I recommend you do too. Anyway in his own words:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;This plug-in has great potential. It will already save&lt;br /&gt;significant development time in setting up client-side&lt;br /&gt;validation and I’m sure it’s going to keep getting better.&lt;br /&gt;Stop by the Grails Plugin Portal and check it out. You&lt;br /&gt;can leave a comment with enhancement suggestions or&lt;br /&gt;if you’ve tried it out, let others know what you think&lt;br /&gt;with a rating. I’m giving it 5 stars!&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I am really happy about this. It is nice to see that the things you do help other people. I guess that is what the open source community is all about. Anyway just wanted to express another thought.&lt;br /&gt;&lt;br /&gt;I think the best things, the ones that rise above come from passion and believing "there has to be a better way". That's where the grails framework came from, where groovy came from, where Spring came from, Hibernate, hell even Java too one upon a time.&lt;br /&gt;&lt;br /&gt;However another ingredient that means the difference between longevity or 15 seconds of fame is "coming from the trenches"... You can see that with grails.&lt;br /&gt;&lt;br /&gt;Graeme Rocher built grails from is own real life experience of using web frameworks. That is why even now I find little gems of goodness in there. The framework helps you all the way from development to production. That is something special.&lt;br /&gt;&lt;br /&gt;I guess with my own little javascript validator plug-in in a much much smaller way that same is true for me. I needed client side validation and I had used Sprig'svalang before with spring mvc and really missed it with Grails. So I built it. When I say built it a really mean I made the "glue of convenience" that glues together some already established fantastic framework patterns (grails constraints, i18n, commons validator js libs). Then guess what. I actually used it on my own project as a user. I made it fit my own needs while trying to keep it generic. Anyway I think that's why people love it.&lt;br /&gt;&lt;br /&gt;One last final thought... I love this quote just can't remember who said it.&lt;br /&gt;&lt;br /&gt;A reasonable man changes and adapts to the world around him. The unreasonable man changes and adapts the world around him. Therefore all the innovation in the world lies in the hands of the unreasonable man :)&lt;br /&gt;&lt;br /&gt;Ps. I have two new plug ins coming out this week. Again the came from the trenches of a need for them in my own app. I am sure you will love them.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-7362203843426270327?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/7362203843426270327/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=7362203843426270327' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7362203843426270327'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7362203843426270327'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/05/dave-klien-reviews-my-javascript.html' title='Dave Klien reviews my Javascript validator plugin in Groovy Mag (April)'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3196223814358697703</id><published>2009-05-06T01:53:00.000-07:00</published><updated>2009-05-06T01:58:36.342-07:00</updated><title type='text'>Nullable vs Blank sorted i forgot to post about it</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;I just realise i forgot to post about the solution to the Nullable Vs Blank problem. Well after consulting lost of people for input I decided on a simple rule.&lt;br /&gt;&lt;h4&gt;If the blank constraint and the nullable constraint are both used for a String attribute then the blank constraint wins.&lt;/h4&gt;The simple solution always wins :) (&lt;a href="http://en.wikipedia.org/wiki/Occam%27s_razor"&gt;Occam's razor&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3196223814358697703?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3196223814358697703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3196223814358697703' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3196223814358697703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3196223814358697703'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/05/nullable-vs-blank-sorted-i-forgot-to.html' title='Nullable vs Blank sorted i forgot to post about it'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1827598939401213157</id><published>2009-03-17T02:29:00.000-07:00</published><updated>2009-03-17T03:10:49.046-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails validation plugin feeback'/><title type='text'>Nullable vs blank constraints, want feedback from you?</title><content type='html'>So a few people asked me about my comment i made on my new javascript validation grails plugin about blank vs nullable constraints.&lt;br /&gt;&lt;br /&gt;Well the problem i have is. In javascript validation on strings "blank" and "nullable" checks are the same thing.  By default grails adds nullable constraints to all attributes of a domain object.  So:&lt;br /&gt;&lt;br /&gt;When I generate javascript validation checks based on these default constraints I generate a "required" check for each attribute. So the "nullable" constraint maps to a "required" check in javascript.&lt;br /&gt;&lt;br /&gt;The problem is the "blank" constraint also maps to a "required" check. So a string attribute has a nullable=false constraint (which it has by default) AND a blank=false constraint then the use will end up seeing TWO message: Eg&lt;br /&gt;&lt;br /&gt;You must enter a name (nullable message)&lt;br /&gt;You must enter a name (blank message)&lt;br /&gt;&lt;br /&gt;To the user this is duplicate messages.&lt;br /&gt;&lt;br /&gt;I have this idea:&lt;br /&gt;When processing the constraints and generating the javascript validation. The nullable constraint is ignored for String attributes and the blank contstraint is used instead. This would mean if you want to have a javascript required check for a string you must use the blank constraint.&lt;br /&gt;&lt;br /&gt;What do you think ?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1827598939401213157?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1827598939401213157/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1827598939401213157' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1827598939401213157'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1827598939401213157'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/nullable-vs-blank-constraints-want.html' title='Nullable vs blank constraints, want feedback from you?'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1058882933818821019</id><published>2009-03-16T04:15:00.000-07:00</published><updated>2009-03-16T04:56:28.625-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails plugin javascript validation experience'/><title type='text'>Creating your own grails plugin and eating your own dog food</title><content type='html'>So as you may have seen in my last few posts. I spent most of the weekend creating my first grails plugin. My lovely wife is away for 3 weeks on holiday so I am blasting out all the little projects that I have wanted to do.&lt;br /&gt;&lt;br /&gt;So I thought I would just write a little piece about my experience of writing the plugin. First thing i would like to say is what a pleasure it was to write and as how easy it was. So how did it come about.&lt;br /&gt;&lt;br /&gt;Well I have been building my own application in grails for the last few months and one thing I really missed was client side javascript. I was quite suprised to find that there was no direct support for this in grails. In my day job we use the valang library that has greate support for generating client side javascript so I had gotten used to it.  One thing I did find was this disbandond tag lib that sits in the grails core &lt;a href="http://www.grails.org/Tag+-+validate"&gt;validate tag&lt;/a&gt;. So i looked at the source code for this tag and figured out what is was trying todo. It turns out that is was using the javascript support of the commons validation libarary.&lt;br /&gt;&lt;br /&gt;So after some experimentation I realised I could resurect this and put it together as plugin to support client side javascript.  So after some complicated things like getting access to the constraints object of command objects and generating i18n messages for the errors I finally put together the plugin in 4 releases over a weekend.&lt;br /&gt;&lt;br /&gt;So things i found hard to do and never really managed to do it in a nice way was to mock out the grailsattributes object and grails application etc. My tag needs these to get access to domain and command objects but it is very complicated to mock them out.&lt;br /&gt;&lt;br /&gt;Eating your own dog food.&lt;br /&gt;&lt;br /&gt;So before i actually realeased the plugin i installed it in my own application and started using it in a real app. This turned out to be essential for testing. I found several issues that it did not handle. Things like: grails auto generating nullable constraints for all attributes of a domain class but not for command objects was tricky as you ended up with unecessary validation generated.  So after a few rounds of tuning and robusting i realesed it.&lt;br /&gt;&lt;br /&gt;Grails plugin release process.&lt;br /&gt;It is so easy to release and re-release a grails plugin that you have to create one just to see that work. Auto tagging and versioning is handled so smoothly. But i guess i would not expect anything less from grails.&lt;br /&gt;&lt;br /&gt;So to conclude if you have any greate ideas for a plugin then build them. There is nothing stopping you.&lt;br /&gt;&lt;br /&gt;Remember someone once said that the saddest words of tongue or pen are these: "it might have been".&lt;br /&gt;&lt;br /&gt;Ps. Version 0.4 is out now :)&lt;br /&gt;&lt;br /&gt;Enjoy&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1058882933818821019?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1058882933818821019/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1058882933818821019' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1058882933818821019'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1058882933818821019'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/creating-your-own-grails-plugin-and.html' title='Creating your own grails plugin and eating your own dog food'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-6163318083778508286</id><published>2009-03-15T08:40:00.000-07:00</published><updated>2009-03-15T08:44:45.416-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails plugin javascript validator validation'/><title type='text'>Posted version 0.3 of the javascript-validator grails plugin</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;I just posted version 0.3 of the javascript-validator plugin. This update adds support for validating data type conversions. Only numeric (integer and decimal) are supported at the moment.&lt;br /&gt;&lt;br /&gt;So if you try set a non numeric value on a field that is an interger then you will get the standard error.&lt;br /&gt;&lt;br /&gt;thanks&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-6163318083778508286?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/6163318083778508286/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=6163318083778508286' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6163318083778508286'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6163318083778508286'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/posted-version-03-of-javascript.html' title='Posted version 0.3 of the javascript-validator grails plugin'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-6656845393049751999</id><published>2009-03-14T05:26:00.001-07:00</published><updated>2009-03-14T05:29:19.884-07:00</updated><title type='text'>Added documentation for the Javascript Validation plugin</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;OK I got some sleep and I have added some documentation for the new Javascript Validation plugin:&lt;br /&gt;&lt;br /&gt;This can be found here.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/JavascriptValidator+Plugin"&gt;http://www.grails.org/JavascriptValidator+Plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Please give me have feed back.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-6656845393049751999?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/6656845393049751999/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=6656845393049751999' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6656845393049751999'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6656845393049751999'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/added-documentation-for-javascript.html' title='Added documentation for the Javascript Validation plugin'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-8416168674959641523</id><published>2009-03-13T20:24:00.000-07:00</published><updated>2009-03-13T20:50:33.242-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='validator validation grails plugin javascript'/><title type='text'>New: Client Side Javascript Validation plugin for Grails</title><content type='html'>So I created a grails plugin and i think it will be useful to everyone on a grails project.&lt;br /&gt;&lt;br /&gt;So what does it do?&lt;br /&gt;&lt;br /&gt;Well it is a client side javascript validator plugin that works with your existing constraints object. All you have to do is install it then put single tag on your page and you get instant javascript validation for your existing forms.&lt;br /&gt;&lt;br /&gt;To install:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;grails install-plugin javascript-validator&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Next simply add this tag to your form page. This will show the errors as an alert box.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;jv:generate domain=&amp;quot;book&amp;quot; form=&amp;quot;bookForm&amp;quot; display=&amp;quot;alert&amp;quot; /&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Finally you then need to add an onsubmit event to your form. I may make this optional in the next release. But you need it for now.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;form action=&amp;quot;/save&amp;quot; method=&amp;quot;post&amp;quot; name=&amp;quot;bookForm&amp;quot; id=&amp;quot;bookForm&amp;quot; onsubmit=&amp;quot;return validateForm(this);&amp;quot; &amp;gt;&lt;br /&gt;...&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you want the error messages to show as list on the page do this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;jv:generate domain=&amp;quot;book&amp;quot; form=&amp;quot;signUpForm&amp;quot; display=&amp;quot;list&amp;quot; container=&amp;quot;errors&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you want validation on command objects then do this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;br /&gt;&amp;lt;jv:generate command=&amp;quot;signUpCommand&amp;quot; controller=&amp;quot;signUp&amp;quot; form=&amp;quot;signUpForm&amp;quot; display=&amp;quot;alert&amp;quot; /&amp;gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;jv:generate command=&amp;quot;signUpCommand&amp;quot; controller=&amp;quot;signUp&amp;quot; form=&amp;quot;signUpForm&amp;quot; display=&amp;quot;list&amp;quot; container=&amp;quot;errors&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;That should get you going.&lt;br /&gt;&lt;br /&gt;I need to write up the full documentation but will try to do that at the weekend. For now i am off to sleep.&lt;br /&gt;&lt;br /&gt;Enjoy...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-8416168674959641523?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/8416168674959641523/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=8416168674959641523' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8416168674959641523'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8416168674959641523'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/new-client-side-javascript-validation.html' title='New: Client Side Javascript Validation plugin for Grails'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1532373560946988506</id><published>2009-03-10T05:55:00.000-07:00</published><updated>2009-03-10T06:53:53.708-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy meta programming format name'/><title type='text'>Groovy Meta programing to help with names in grails</title><content type='html'>So in my new app I have several places where a user can enter a persons name. In most places they enter a first name and surname.  But on one form they enter a full name. Now ideally i would like to have the first letter of the first name and surname capitalised. As you can't rely on users to do this and not wanting to punish them for not doing it then i decided to implement my own conversion.&lt;br /&gt;&lt;br /&gt;Now in java i can imagine some crazy ways to do it. However probably the simplest in java would be to use the commons lang libs that have support for doing just that.  (&lt;a href="http://commons.apache.org/lang/api/org/apache/commons/lang/StringUtils.html#capitalize%28java.lang.String%29"&gt;capitalize&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;However i want to solve this in a "groovy way".&lt;br /&gt;&lt;br /&gt;So after reading the groovy programming book I got some inpiration to use groovy meta-programming to solve the problem.&lt;br /&gt;&lt;br /&gt;Groovy allows you to effectivly add new methods to java classes. In this case String. So on String i want to add two new methods: capitalizeFirstLetter and capitalizeAllFirstLetters. So to do this i just do this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;String.metaClass.capitalizeFirstLetter = {&lt;br /&gt;    return  (&amp;quot;&amp;quot; == delegate) ? delegate : delegate[0].toUpperCase() + delegate[1..&amp;lt;(delegate.length())]&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;String.metaClass.capitalizeAllFirstLetters = {&lt;br /&gt;    return  (&amp;quot;&amp;quot; == delegate) ? delegate : delegate.split(&amp;quot; &amp;quot;).collect{it[0].toUpperCase() + it[1..&amp;lt;(it.length())] }.join(&amp;quot; &amp;quot;)&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then when I want to use them i just do this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;assert &amp;quot;&amp;quot;.capitalizeFirstLetter() == &amp;quot;&amp;quot;&lt;br /&gt;assert &amp;quot;peter&amp;quot;.capitalizeFirstLetter() == &amp;quot;Peter&amp;quot;&lt;br /&gt;assert &amp;quot;peter delahunty&amp;quot;.capitalizeAllFirstLetters() == &amp;quot;Peter Delahunty&amp;quot;&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In Grails you just pop the metaClass definitions into your boostrap.groovy and they will be available all throughout grails.&lt;br /&gt;&lt;br /&gt;Schweet...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1532373560946988506?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1532373560946988506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1532373560946988506' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1532373560946988506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1532373560946988506'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/groovy-meta-programing-to-help-with.html' title='Groovy Meta programing to help with names in grails'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-4471914370903181803</id><published>2009-03-10T05:46:00.000-07:00</published><updated>2009-03-10T05:51:35.239-07:00</updated><title type='text'>Grails 1.1 is out.... yeah (this has some major awesome new features.</title><content type='html'>So i just heard on the twitter vine that Grails 1.1 is officially released.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/1.1+Release+Notes"&gt;Release notes&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This update has some major awesome updates: My favorites:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Batch fetching&lt;/li&gt;&lt;li&gt;Improved dynamic finders&lt;/li&gt;&lt;li&gt;Read only loads&lt;/li&gt;&lt;li&gt;New plugin architecture (this is a big one)&lt;/li&gt;&lt;li&gt;Integrated test plugin&lt;/li&gt;&lt;li&gt;Maven integration&lt;/li&gt;&lt;li&gt;New Webflow&lt;/li&gt;&lt;/ul&gt;I am off to &lt;a href="http://www.grails.org/Download"&gt;download &lt;/a&gt;now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-4471914370903181803?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/4471914370903181803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=4471914370903181803' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4471914370903181803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4471914370903181803'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/grails-11-is-out-yeah-this-has-some.html' title='Grails 1.1 is out.... yeah (this has some major awesome new features.'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3359086236400343666</id><published>2009-03-09T17:25:00.000-07:00</published><updated>2009-03-09T17:35:08.117-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java grails hosts ipv6'/><title type='text'>Hell with vista and ipv6 and hosts file</title><content type='html'>hmmm&lt;br /&gt;&lt;br /&gt;Just had an amazing amount of time wasted whilst building a grails app. Still not exactly sure what they hell happened here. I think maybe and auto update on vista. Anyway I have had a problem for the last 2 hours with my grails apps suddenly not being able to connect to my local mysql instance. So i knocked up a small java app that just connected to the db and it had the same problem.&lt;br /&gt;&lt;br /&gt;I could connect just find from the command line with mysql client but not java. Anyway after much much digging it seems to have been maybe a change to my hosts file.&lt;br /&gt;&lt;br /&gt;it did say this:&lt;br /&gt;&lt;br /&gt;#############&lt;br /&gt;::1             localhost&lt;br /&gt;&lt;br /&gt;and when i tried to connect via java to url jdbc:mysql://localhost/test then i got a nasty connection refused.&lt;br /&gt;&lt;br /&gt;However when i changed this to&lt;br /&gt;&lt;br /&gt;#############&lt;br /&gt;127.0.0.1  localhost&lt;br /&gt;&lt;br /&gt;Now it all seems to work.&lt;br /&gt;&lt;br /&gt;It seems from searching around that the ::1 setup is for ipv6. Anyway jus thought i would document this ask it was painful to fix.&lt;br /&gt;&lt;br /&gt;Maybe i should move back to ubuntu. See if they have fixed the rendering in java on linux finally.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3359086236400343666?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3359086236400343666/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3359086236400343666' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3359086236400343666'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3359086236400343666'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/hell-with-vista-and-ipv6-and-hosts-file.html' title='Hell with vista and ipv6 and hosts file'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-7172856107092321972</id><published>2009-03-05T03:43:00.000-08:00</published><updated>2009-03-05T04:02:14.547-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails roles cool'/><title type='text'>Available very soon, me !!!</title><content type='html'>So it seems my latest contract is coming to an end at the end of the month (march 2009). So the what to do next???&lt;br /&gt;&lt;br /&gt;Well I have a big backlog of my own good ideas that I want to put some quality time into. Before releasing into the wild to see which ones float and which ones sink. I should imagine I would give myself a solid month of work to get them off the ground. My aim is to get these ideas developed and shipped as quick as possible so I will of course be using Grails. Which brings me to my next question, then what ?&lt;br /&gt;&lt;br /&gt;Developing my own ideas is my first choice at the moment unless some awesome gig comes up :)&lt;br /&gt;&lt;br /&gt;So I ask: Is there anyone out there ???&lt;br /&gt;&lt;br /&gt;Is anyone planning on building anything cool in Grails using Agile development. A funded starup maybe? Are you looking for a new lead Grails developer. I would really like to get into something exciting and really have my skills pushed to the limits and beyond.&lt;br /&gt;&lt;br /&gt;Basically if you can dream it I can build it. So challenge me ?&lt;br /&gt;&lt;br /&gt;Drop me an email peter.delahunty@gmail.com&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-7172856107092321972?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/7172856107092321972/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=7172856107092321972' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7172856107092321972'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7172856107092321972'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/available-very-soon-me.html' title='Available very soon, me !!!'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-5181675327201616179</id><published>2009-03-02T02:19:00.000-08:00</published><updated>2009-03-03T08:37:31.406-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='extra'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy grails tips top ten'/><title type='text'>Top 10 Tips for Grails Developer: Redux (extra bonus tips)</title><content type='html'>Ok so in my last post about &lt;a href="http://blog.peterdelahunty.com/2009/02/10-ten-tips-for-grails-developer.html"&gt;Grails Top 10 Tips&lt;/a&gt; i realised I did not really give that many actual grails specific tips :)&lt;br /&gt;&lt;br /&gt;So i had long think about the way I use grails and I think I have some more tips. These tips are for when you are doing serious development and not just some throwaway prototype.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;1) Follow domain driven development.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This is very very easy to do in grails and is practically common sense to do so (ha ha although in my experience there is no such thing as common sense). So what i mean by this is to follow test driven development starting with your domain first (tddd i guess). Create your domain objects first using the grails macros "grails create-domain". This will also then generate your unit tests for you (how easy is that). Then start fleshing out the unit tests. To make life easy use this plugin (installed default in grails 1.1)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/Testing+Plugin"&gt;Testing plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now if you can delay gratification and fully develop your domain model first just using unit tests then this will pay off later. You will see as i explain below.&lt;br /&gt;&lt;br /&gt;However if you can't wait and you need to see the app come to life then create a controller using "grails create-controller" and use the lovely grails scaffold to have your crud pages generated for you.&lt;br /&gt;&lt;br /&gt;Section 16 of the &lt;a href="http://grails.org/doc/1.1/"&gt;grails docs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;However once you are happy with the domain from the view point of the webpages. Then delete the new scaffold controller because the real deal is about to be generated below.&lt;br /&gt;&lt;br /&gt;So by now in some shape or form you should have developed your domain model. Or more specifically the parts that you need right now to meet the stories (features) you are building (sorry i have my agile hat on here).&lt;br /&gt;&lt;br /&gt;So now you can pull one of the grails gems out of the bag "grails generate-all" or one step better you can install the xtemplates plugin&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/Xtemplates+Plugin"&gt;xtemplate plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then using this plugin you can use "grails uber-xgenerate" and this will create controllers, views and unit tests for all CRUD operations of your new domain model.&lt;br /&gt;&lt;br /&gt;This now basically gives you a working app. All you have to do is skin it how you want.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;2) Change your default development datasource settings&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Once you are building a serious grails app you are going to want to change from the default hsql in- memory database. I actually prefer to use mysql as my deployment db as i can query it easily from the commandline.&lt;br /&gt;&lt;br /&gt;Edit datasource.groovy to something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;dataSource {&lt;br /&gt;   pooled = true&lt;br /&gt;   driverClassName = "com.mysql.jdbc.Driver"&lt;br /&gt;   username = "testuser"&lt;br /&gt;   password = "testuser"&lt;br /&gt;}&lt;br /&gt;hibernate {&lt;br /&gt;   cache.use_second_level_cache=false&lt;br /&gt;   cache.use_query_cache=false&lt;br /&gt;   cache.provider_class='com.opensymphony.oscache.hibernate.OSCacheProvider'&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;// environment specific settings&lt;br /&gt;environments {&lt;br /&gt;   development {&lt;br /&gt;       dataSource {&lt;br /&gt;           println "IN DEVELOPMENT"&lt;br /&gt;       dbCreate = "create-drop" // one of 'create', 'create-drop','update'&lt;br /&gt;           url = "jdbc:mysql://localhost/testdb"&lt;br /&gt;           dialect = "org.hibernate.dialect.MySQL5Dialect"&lt;br /&gt;&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   test {&lt;br /&gt;       dataSource {&lt;br /&gt;           dbCreate = "update"&lt;br /&gt;           url = "jdbc:hsqldb:mem:testDb"&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;   production {&lt;br /&gt;       dataSource {&lt;br /&gt;           dbCreate = "update"&lt;br /&gt;           url = "jdbc:hsqldb:file:prodDb;shutdown=true"&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;3) Use bootstrap.groovy&lt;/span&gt;&lt;br /&gt;This is a very important file. It allows you to populate your database with with your domain model. Here you can create test data and save it to the database.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;4) Use command objects&lt;/span&gt;&lt;br /&gt;I find these little guys are very useful in some circumstances. Sometimes you want to capture user data using a form that does not exactly map to the way you want to store you info in your domain object or perhaps the information does not even get saved. Examples would be an advanced search form or a file upload form. The great thing about Command objects is they still allow you to specify validation constraints. Here is an example:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;class DemoFormCommand {&lt;br /&gt;&lt;br /&gt;   String email;&lt;br /&gt;   String name;&lt;br /&gt; &lt;br /&gt;   static constraints = {&lt;br /&gt;       name(blank: false)&lt;br /&gt;       email(blank: false, email: true)&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then in my controller i can add an action like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;def upload = {DemoFormCommand demoFormCommand -&amp;gt;&lt;br /&gt;&lt;br /&gt;       if (demoFormCommand.hasErrors()) {&lt;br /&gt;....&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-5181675327201616179?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/5181675327201616179/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=5181675327201616179' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/5181675327201616179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/5181675327201616179'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/03/top-10-tips-for-grails-developer-redux.html' title='Top 10 Tips for Grails Developer: Redux (extra bonus tips)'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-6988073722404800871</id><published>2009-02-26T03:21:00.000-08:00</published><updated>2009-03-02T02:24:30.194-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy grails tips top ten'/><title type='text'>Top 10 Tips for Grails Developers</title><content type='html'>&lt;span style="font-size:130%;"&gt;1) Buy the Grails books and read them:&lt;/span&gt;&lt;br /&gt;What can i say about this except Knowledge is Power. Grails is jam packed with so much useful tools and functionality that when you want to do something that might seem off the beaten track. Chances are Grails already has a really elogent solution to it already. Here are some of my favorites that i now take for granted: flash ojbect, pagenation, url mapping, taglibs;&lt;br /&gt;&lt;br /&gt;Anyway the grails books i recommend are:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1590599950?ie=UTF8&amp;tag=delahuntyware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1590599950"&gt;Definitive Guide to Grails 2nd edition&lt;/a&gt;: written by the god father of Grails Graeme Rocher&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/143021600X?ie=UTF8&amp;tag=delahuntyware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=143021600X"&gt;Groovy and Grails Recipes&lt;/a&gt;: This contains lots and lots of examples.&lt;br /&gt;&lt;br /&gt;and the new commer but looks very good from the early release i got:&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1933988932?ie=UTF8&amp;tag=delahuntyware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1933988932"&gt;Grails in Action&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;br /&gt;2) Learn Groovy and think in Groovy&lt;/span&gt;&lt;br /&gt;Grails is an amazing framework but it really does shine brightly when you combine that with the powerful concepts of groovy. Try your best to find out how to solve problems the groovy way. There is always a groovy way to solve problems. Here is good example:&lt;br /&gt;&lt;br /&gt;The spread operator: *&lt;br /&gt;&lt;br /&gt;In java if i want to iterate through a list of people and collect the names. I would do something like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;List names = new ArrayList();&lt;br /&gt;for (Iterator iterator = people.iterator(); iterator.hasNext();) {&lt;br /&gt;Person person = (Person) iterator.next();&lt;br /&gt;names.add(person.getName());&lt;br /&gt;}&lt;br /&gt;System.out.println(names);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In Groovy i would do this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;def names = people*.name&lt;br /&gt;println names&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ha ha so easy. I could also do this which is the same thing:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;def names = people.collect {it.name}&lt;br /&gt;println names&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Another good one to learn is extensions that groovy have made to the JDK classes. These are so cool. Here is a quick example:&lt;br /&gt;&lt;br /&gt;Open a url in java and download the response and print it to the standard out:&lt;br /&gt;&lt;br /&gt;In Java:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;try {&lt;br /&gt;// Create a URL for the desired page&lt;br /&gt;URL url = new URL("http://hostname:80/index.html");&lt;br /&gt;  &lt;br /&gt;// Read all the text returned by the server&lt;br /&gt;BufferedReader in = new BufferedReader(new InputStreamReader(url.openStream()));&lt;br /&gt;String str;&lt;br /&gt;StringBuffer sb = new StringBuffer();&lt;br /&gt;while ((str = in.readLine()) != null) {&lt;br /&gt;   sb.append(str);&lt;br /&gt;}&lt;br /&gt;in.close();&lt;br /&gt;} catch (MalformedURLException e) {&lt;br /&gt;} catch (IOException e) {&lt;br /&gt;}&lt;br /&gt;System.out.println(sb.toString());&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In Groovy&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;def text = new URL("http://hostname:80/index.html").text&lt;br /&gt;println text&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;And no i am not joking that is really it:)&lt;br /&gt;&lt;br /&gt;I am not even getting into builders and dsl. Anyway the point is: Learn groovy and learn the GDK. Here are my book recommendations for learning groovy:&lt;br /&gt;&lt;br /&gt;Here are some greate resources for learning groovy:&lt;br /&gt;&lt;a href="http://groovy.codehaus.org/"&gt;Groovy home&lt;/a&gt;&lt;br /&gt;&lt;a href="http://pleac.sourceforge.net/pleac_groovy/index.html"&gt;PLEAC&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And the Books i recommend:&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1934356093?ie=UTF8&amp;tag=delahuntyware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1934356093"&gt;Groovy Programming&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/0978739299?ie=UTF8&amp;tag=delahuntyware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0978739299"&gt;Groovy Recipies&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/gp/product/1932394842?ie=UTF8&amp;tag=delahuntyware-20&amp;linkCode=as2&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1932394842"&gt;Groovy in action&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;3: Get to know the Grails Plugins:&lt;/span&gt;&lt;br /&gt;Seriously this will save you so much time. There are already so many grails plugins that one of them probably already does what you want to do. It is the classic buy not build saying except you are not actually buying and it is a component level.&lt;br /&gt;&lt;br /&gt;The plugin directory can be found here: &lt;a href="http://www.grails.org/Plugins"&gt;Grails Plugins&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also the new grails in action book seems to have a good coverage of the grails plugins.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;4: Learn Hibernate and Spring&lt;/span&gt;&lt;br /&gt;So this is my top ten tips for grails and for me i believe this is very very important. I personally get more out of Grails because i already new the foundational frameworks it uses inside out. I can then appreciate what grails gives me so much more. Don't get me wrong Grails shields you from most of the complexity (or fluff) of hibernate and spring and you could happily use it without knowing detailed knowledge of either. However i have personally found that is is good to know what is going on under the covers. This knowledge will help you in understanding error messags such as the classic lazy loading exceptions.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;5: Unit Test, integration test and plain test automated (of course)&lt;/span&gt;&lt;br /&gt;Well this is a general tip. Although it should not really have to be a TIP!!! Grails and groovy makes it so easy to test it is just not funny. I won't go into the details but learn the basics Mocking, Stubbing etc. Grails has a fantastic plugin for testing which is now part of the grails 1.1 as standard:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/Testing+Plugin"&gt;Testing Plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;There are also some cool new commers for integration testings:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/Grails+Functional+Testing"&gt;Functional testing plugin&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;6: Use a good IDE&lt;/span&gt;&lt;br /&gt;I personally find that using an IDE saves me even more time when creating grails apps. For me the clear winner at the moment is Intellij. The Grails plugin is awesome. Although there are thing i don't like about Intellij (does not highlight variable occurances easily) but i can live with them. The next best and is free is Netbeans.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;7: Learn and use the HTML W3C standards&lt;/span&gt;&lt;br /&gt;Basically if you using Grails you are building websites. If i can give one tip about doing that is it follow the standards. Sorting out browser render issues can suck away time. But if you follow the standard then you will remove 90% of your problems. First tip is to reset the browsers style sheets so you get a clean playing field. I personally think that YUI offers the best solution to this. Check this out here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://developer.yahoo.com/yui/reset/"&gt;YUI CSS reset&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;8: If it looks good then it is good.&lt;/span&gt;&lt;br /&gt;There is so much truth in that. People are attracted to things that look good. This is evident in the Ruby on Rail camp. Ruby on Rail emerged from a bunch of designers and it shows. Their websites alway look good with a web2.0 style. Where as grail emerged from a more programmer community. An again this show in the websites. The websites do not often look good. This not all website written in grails but a lot. So my tip is spend some time on making your website look good. Even using something like rounded corners and a nice font can really make a website look much better. Bring a designer in if you need to. This good for everyone in the long run. More people are attracted to the grails framework by seeing remarkable sites and the community grows and grows.&lt;br /&gt;&lt;br /&gt;Get designers to compete for you &lt;a href="http://99designs.com/"&gt;99designs.com&lt;/a&gt;&lt;br /&gt;Quickly generate rounded corners: &lt;a href="http://www.roundedcornr.com/"&gt;http://www.roundedcornr.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;9: Use firebug on firefox&lt;/span&gt;&lt;br /&gt;An invaluable tool i use everyday when building sites in grails is not part of grails at all. It is firebug plugin for firefox. If you are not already using firefox then your mad. And as a developer if you are not already using firebug plugin for firefox then you are madder. Get this and use it now it will save you hours and hours of time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;10: Keep upto date with the groovy and grails community&lt;/span&gt;&lt;br /&gt;It important to keep upto date with g ang g communtiy. Here are the best links to do that:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.grails.org/"&gt;Grails home/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://groovyblogs.org/entries/recent"&gt;Grails and Groovy blog aggregator/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Twitter posts from the main people in Grails and Groovy&lt;br /&gt;&lt;a href="http://twitter.com/graemerocher"&gt;Graeme Rocher&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/glaforge"&gt;Guillaume Laforge&lt;/a&gt;&lt;br /&gt;&lt;a href="http://twitter.com/glen_a_smith"&gt;Glen Smith&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;More from you:&lt;br /&gt;&lt;br /&gt;So if anyone out there has anymore tips they would like to share then please do so int the comments section below.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-6988073722404800871?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/6988073722404800871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=6988073722404800871' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6988073722404800871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6988073722404800871'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/02/10-ten-tips-for-grails-developer.html' title='Top 10 Tips for Grails Developers'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-8727770156780392583</id><published>2009-02-11T01:11:00.000-08:00</published><updated>2009-02-11T01:12:10.316-08:00</updated><title type='text'>Wired.com is using Grails</title><content type='html'>Just a quick post. Just heard that Wired.com are using Grails. Check out the case study here. &lt;br /&gt;&lt;br /&gt;http://www.springsource.com/files/Wired.com%20Case%20study..pdf&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-8727770156780392583?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/8727770156780392583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=8727770156780392583' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8727770156780392583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/8727770156780392583'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/02/wiredcom-is-using-grails.html' title='Wired.com is using Grails'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3487620737620229754</id><published>2009-01-19T03:46:00.000-08:00</published><updated>2009-01-19T04:02:49.153-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails lazy list create dynamic'/><title type='text'>Cool way to dynamically add entries to a list on create in grails</title><content type='html'>Hi all&lt;br /&gt;&lt;br /&gt;A good friend had problem recently with adding items to list opon first create in grails. The problem is how can you set the property of an item as position x in a list if it does not yet exist at that position. Well will with a little magic and grails we did this.&lt;br /&gt;&lt;br /&gt;The answer is Lazylist and Lazymap implementations from the commons collection package. So we end up with this result.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;import org.apache.commons.collections.Factory;&lt;br /&gt;import org.apache.commons.collections.ListUtils;&lt;br /&gt;&lt;br /&gt;public class Requirement {&lt;br /&gt;&lt;br /&gt;    String label;&lt;br /&gt;    List requirements = &lt;br /&gt;    new ListUtils.lazyList(new ArrayList(),{new Requirement()} as Factory)&lt;br /&gt;&lt;br /&gt;    static hasMany = [requirements:Requirement];&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;    static constraints = {&lt;br /&gt;        label(blank:false);&lt;br /&gt;    }&lt;br /&gt;        &lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This means in your create form page you can have an entry like this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;g:textField name=&amp;quot;requirements[${i}].label&amp;quot; value=&amp;quot;&amp;quot;/&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When you create a Requirement object like this in the controller action.  &lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;Requirement r = new Requirement(params)&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The new entries will be created in the collection and the label value on them set. The same thing can be done with LazyMap.&lt;br /&gt;&lt;br /&gt;enjoy :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3487620737620229754?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3487620737620229754/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3487620737620229754' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3487620737620229754'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3487620737620229754'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/01/cool-way-to-dynamically-add-entries-to.html' title='Cool way to dynamically add entries to a list on create in grails'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-5283482190669337091</id><published>2009-01-13T02:25:00.000-08:00</published><updated>2009-01-14T05:12:25.359-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='groovy interfaces multi methods jruby'/><title type='text'>Implementing interfaces in Groovy</title><content type='html'>This a quick post just to put some facts out there after i read this &lt;a href="http://www.vitarara.org/cms/why_i_chose_jruby_over_groovy"&gt;post&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;In the post the Vita states that "In Groovy when your class implements a Java interface it must have all the methods present"&lt;br /&gt;&lt;br /&gt;Well this is NOT exactly true. Here is an example below of me implementing only the interfaces i want:&lt;br /&gt;&lt;br /&gt;This is my very simple interface with 3 methods;&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;public interface SaySomething {&lt;br /&gt;&lt;br /&gt; String saySomethingTrue();&lt;br /&gt;&lt;br /&gt; String saySomethingFalse();&lt;br /&gt;&lt;br /&gt; String saySomethingFunny();&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In Groovy you easily implement a multi-method interface with a Map (method name = closure)&lt;br /&gt;&lt;br /&gt;So i have code like this. I ONLY implement the methods i want.&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;SaySomething saySomething = [saySomethingTrue:{'Groovy rocks'},&lt;br /&gt;                          saySomethingFalse:{'Groovy must implement all methods in a Java interface.'},] as SaySomething;&lt;br /&gt;&lt;br /&gt;println "This is true:  "  + saySomething.saySomethingTrue();&lt;br /&gt;&lt;br /&gt;println "This is false: "  + saySomething.saySomethingFalse();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;As you can see in quick example above i don't provide an implementation for saySomethingFunny()&lt;br /&gt;&lt;br /&gt;The result of running this is:&lt;br /&gt;&lt;br /&gt;&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;This is true:  Groovy rocks&lt;br /&gt;This is false: Groovy must implement all methods in a Java interface.&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;UPDATE...&lt;br /&gt;&lt;br /&gt;If you just want to do the same thing for all methods:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;SaySomething saySomething2 = {return &amp;quot;I am handling all methods&amp;quot;} as SaySomething&lt;br /&gt;&lt;br /&gt;println &amp;quot;This is true:  &amp;quot;  + saySomething2.saySomethingTrue();&lt;br /&gt;&lt;br /&gt;println &amp;quot;This is false: &amp;quot;  + saySomething2.saySomethingFalse();&lt;br /&gt;&lt;br /&gt;println &amp;quot;This is funny: &amp;quot;  + saySomething2.saySomethingFunny();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This prints out:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;This is true:  I am handling all methods&lt;br /&gt;This is false: I am handling all methods&lt;br /&gt;This is funny: I am handling all methods&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-5283482190669337091?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/5283482190669337091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=5283482190669337091' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/5283482190669337091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/5283482190669337091'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/01/implementing-interfaces-in-groovy.html' title='Implementing interfaces in Groovy'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1360100978245487099</id><published>2009-01-08T02:19:00.001-08:00</published><updated>2009-01-08T07:19:30.578-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='YAGNI grails agile'/><title type='text'>Most powerful agile principal YAGNI</title><content type='html'>So i have been practicing agile software development for a while now and there are lots of powerful concept that i use during development:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Time boxed iterations&lt;/li&gt;&lt;li&gt;No big up front design&lt;/li&gt;&lt;li&gt;Design evolution&lt;/li&gt;&lt;li&gt;Test Driven development&lt;/li&gt;&lt;li&gt;Pair programming&lt;/li&gt;&lt;li&gt;User stories&lt;/li&gt;&lt;li&gt;Refactoring &lt;/li&gt;&lt;/ul&gt;Many of the power of these concepts have the sum is greater than the parts effect. When they are used in unison the become even more powerful kind of like the power rangers.&lt;br /&gt;&lt;br /&gt;Anyway one of the most powerful concepts is &lt;a href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It"&gt;YAGNI&lt;/a&gt;(You ain't gonna need it). It is so simple in many ways yet so powerful. It is really a kind of extension to another XP principal "do the simplest thing that works".  The idea at the micro level is that a code feature should do enough to pass the unit test and integration tests and NO more. Anymore that is over engineering.&lt;br /&gt;&lt;br /&gt;The idea being that is is silly to do work today for something you think you MIGHT need tomorrow. Rather take the view you can't predict the future and that you probably WON'T need that feature in the future when the future come. Instead in the future you will learn something new and want a different feature.  So although "do the simplest thing that works" principal is powerful at the code level... &lt;a href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It"&gt;YAGNI&lt;/a&gt; can be applied all over.&lt;br /&gt;&lt;br /&gt;The Grails framework is great example of applying the &lt;a href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It"&gt;YAGNI&lt;/a&gt; principal. It uses convention over configuration because You Ain't Gonna Need configuration.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It"&gt;YAGNI&lt;/a&gt; problems: Hard to adapt because of old habits.&lt;br /&gt;&lt;br /&gt;It can be hard for older developers to adapt to &lt;a href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It"&gt;YAGNI&lt;/a&gt; because traditional software development encourages you to make your code generic and reusable, to be able to do everything even make the coffee. However reusable application code  is a myth. YAGNI is also hard to measure. How do you measure the time you have not spend on doing something. YAGNI can also be boring for some developers. Some developers like &lt;a href="http://sethgodin.typepad.com/seths_blog/2005/03/dont_shave_that.html"&gt;yak shave&lt;/a&gt; as in find the most complicated (but stimulating) way to solve a problem.&lt;br /&gt;&lt;br /&gt;My suggestion for this is. Just do &lt;a href="http://en.wikipedia.org/wiki/You_Ain%27t_Gonna_Need_It"&gt;YAGNI&lt;/a&gt;. Don't try, just do. As YODA says there is no try only do or do not!!!.&lt;br /&gt;&lt;br /&gt;Once you start doing YAGNI your joy and motivation will come from building things that people want and not what you think they want. More people will use your software and will benefit from it. It will also reduce the 80/20 rule where 80% of people use only 20% of the features. Finally you will actually ship software fancy that.&lt;br /&gt;&lt;br /&gt;Once you start practicing YAGNI. You can start applying it to your life. Use it for things like:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Packing your suit case for holiday.&lt;/li&gt;&lt;li&gt;Ordering food at a restaurant&lt;/li&gt;&lt;li&gt;Life insurance :)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You get the idea.&lt;br /&gt;&lt;br /&gt;One more thought:&lt;br /&gt;&lt;br /&gt;Henry Ford once said: "if i asked the people what they wanted they would have said a faster horse"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;enjoy :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1360100978245487099?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1360100978245487099/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1360100978245487099' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1360100978245487099'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1360100978245487099'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/01/most-powerful-agile-princepal-yagni.html' title='Most powerful agile principal YAGNI'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3599426981373268508</id><published>2009-01-04T15:45:00.000-08:00</published><updated>2009-01-04T16:03:44.226-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails urlmapping homepage'/><title type='text'>Grails tips for homepage url mapping</title><content type='html'>Hi anyone who's reading&lt;br /&gt;&lt;br /&gt;Heres a little undocumented tip for grails. It is only a small thing and very easy to solve in grails (once you know how) but none the less it did give me some trouble but only in grails years (which are 100 times less than other frameworks ;) )&lt;br /&gt;&lt;br /&gt;Anyway i needed to create link to my homepage on my new site. Now this is default page the root or root context (if you have a root context). &lt;br /&gt;&lt;br /&gt;eg in development it would be http://server.com/myappname where as in production it would be http://server.com/&lt;br /&gt;&lt;br /&gt;So how do you get grails to create a link for you. You can't just use ${createLink(url:'/')} as that is not contextual to the context and so would not work in development as this is harded coded url. Plus you do not have any default controller to link too. So what to do? Well it turns out this very easily solved by creating new controller and urlmapping combination.&lt;br /&gt;&lt;br /&gt;Create a new Home Controller:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;class HomeController {&lt;br /&gt;&lt;br /&gt;    def index = {}&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then in your grails-app/views/home directory copy your index.gsp&lt;br /&gt;&lt;br /&gt;Then create a urlmapping to go with it that links the controller and action to the root url &amp;quot;/&amp;quot;.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;class UrlMappings {&lt;br /&gt;    static mappings = {&lt;br /&gt;   &lt;br /&gt;      &lt;b&gt;&amp;quot;/&amp;quot;(controller:'home',action:'index')&lt;/b&gt; &lt;br /&gt;&lt;br /&gt;      &amp;quot;/$controller/$action?/$id?&amp;quot;{&lt;br /&gt;          constraints {&lt;br /&gt;             // apply constraints here&lt;br /&gt;          }&lt;br /&gt;      }&lt;br /&gt;      &lt;br /&gt;      &amp;quot;500&amp;quot;(view:'/error')&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then finally to create a link to the controller simple do this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;a href=&amp;quot;${createLink(controller:'home',action:'index')}&amp;quot;&amp;gt;Home&amp;lt;/a&amp;gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Hope this helps someone :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3599426981373268508?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3599426981373268508/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3599426981373268508' title='13 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3599426981373268508'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3599426981373268508'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2009/01/grails-tips-for-homepage-url-mapping.html' title='Grails tips for homepage url mapping'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>13</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-6746149255767677932</id><published>2008-12-03T16:10:00.000-08:00</published><updated>2008-12-04T01:42:07.555-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy gotcha detach hibernate transaction'/><title type='text'>Stealth little gotcha in grails (with a happy ending of course)</title><content type='html'>So i noticed a little Gotcha in Grails the other day. This is all down to the way hibernate works and and how grails uses it.&lt;br /&gt;&lt;br /&gt;The way hibernate works:&lt;br /&gt;&lt;br /&gt;When you load objects using hibernate this is done using an hibernate session. Once an object is loaded by the hibernate session it automatically becomes a managed object as far as hibernate is concerned. By managed, amongst other things i mean to automatically do dirty checking on any changes to the object.&lt;br /&gt;&lt;br /&gt;Now when hibernate is setup for auto flushing (as is the default case with grails) it will flush any changes to the object to the database on the following events:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Whenever a query is run&lt;/li&gt;&lt;li&gt;Directly before a transaction is committed&lt;/li&gt;&lt;li&gt;Directly after a grails action completes if no exception is thrown&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;So this leads to some interesting Gotchas if you are not careful especially in the update action:&lt;br /&gt;&lt;br /&gt;So here is an example:&lt;br /&gt;&lt;br /&gt;Say i have the following domain object:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;class EBook{&lt;br /&gt;    String name;&lt;br /&gt;    String summary;&lt;br /&gt;    String filename;&lt;br /&gt;&lt;br /&gt;    static constraints = {&lt;br /&gt;        name(blank:false)&lt;br /&gt;        summary(nullable:true)&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now in my controller i have this:&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;def update = {&lt;br /&gt;        def ebook = Ebook.get(params.id)&lt;br /&gt;        if (ebook) {&lt;br /&gt;            ebook.properties = params;&lt;br /&gt;            &lt;br /&gt;            if(!ebook.hasErrors() &amp;amp;&amp;amp; ebook.validate()){&lt;br /&gt;                if(!ebook.fileName){&lt;br /&gt;                    ebook.generateFileName() //generates a default filename based on the name&lt;br /&gt;                }&lt;br /&gt;                if(ebook.save()){&lt;br /&gt;                    flash.message = &amp;quot;Your changes have been saved&amp;quot;&lt;br /&gt;                    render(view: 'show', model: [ebook: ebook])&lt;br /&gt;                }else{&lt;br /&gt;                    render(view: 'edit', model: [ebook: ebook])&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;            }else{&lt;br /&gt;                render(view: 'edit', model: [ebook: ebook])&lt;br /&gt;            }&lt;br /&gt;            &lt;br /&gt;        }else{&lt;br /&gt;            render(view: 'edit', model: [ebook: ebook])&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now the problem with this code is. If validation fails then the ebook object still gets saved to the database. This is because of the rules discussed above. The ebook object has been changed via &lt;span style="font-weight: bold;"&gt;ebook.properties = params &lt;/span&gt;so hibernate knows it is dirty. So when the action finishes hibernate will flush the dirty changes to the database. This means i get bad data in my database.&lt;br /&gt;&lt;br /&gt;So what to do ? Well like everything in Grails it turns out to be VERY easy to solve. The discard() method to the rescue.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;def update = {&lt;br /&gt;        def ebook = Ebook.get(params.id)&lt;br /&gt;        if (ebook) {&lt;br /&gt;            ebook.properties = params;&lt;br /&gt;            &lt;br /&gt;            if(!ebook.hasErrors() &amp;amp;&amp;amp; ebook.validate()){&lt;br /&gt;                if(!ebook.fileName){&lt;br /&gt;                    ebook.generateFileName() //generates a default filename based on the name&lt;br /&gt;                }&lt;br /&gt;                if(ebook.save()){&lt;br /&gt;                    flash.message = &amp;quot;Your changes have been saved&amp;quot;&lt;br /&gt;                    render(view: 'show', model: [ebook: ebook])&lt;br /&gt;                }else{&lt;br /&gt;                    render(view: 'edit', model: [ebook: ebook])&lt;br /&gt;                }&lt;br /&gt;                &lt;br /&gt;            }else{&lt;br /&gt;                &lt;b&gt;ebook.discard()&lt;/b&gt;&lt;br /&gt;                render(view: 'edit', model: [ebook: ebook])&lt;br /&gt;            }&lt;br /&gt;            &lt;br /&gt;        }else{&lt;br /&gt;            render(view: 'edit', model: [ebook: ebook])&lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The discard() method will detatch the ebook object from the session. This should then solve the problem. The only possible issue then would be LazyInitializationException depending on your object. Anyway for now that is a solution for my problem but may not a solution for all problems like this.&lt;br /&gt;&lt;br /&gt;Hope this helps :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-6746149255767677932?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/6746149255767677932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=6746149255767677932' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6746149255767677932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/6746149255767677932'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/12/stealth-little-gotcha-in-grails-with.html' title='Stealth little gotcha in grails (with a happy ending of course)'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-3554804887327037955</id><published>2008-11-27T03:44:00.000-08:00</published><updated>2008-11-27T04:00:25.382-08:00</updated><title type='text'>Why i use Grooy and Grails (evolution) !!!</title><content type='html'>I thought i would just start a new post about some of my thoughts on why i am using Groovy and Grails. This has been spun out from a few comments on a previous post of mine from Ricky and Greg.&lt;br /&gt;&lt;br /&gt;So Admittedly i am fairly ignorant of other languages outside those with a C lineage. Eg C,C++,Java,C#,groovy&lt;br /&gt;&lt;br /&gt;I generally don't get excited about just a language alone. Because the language for me is just one part of the puzzle to my whole development experience.&lt;br /&gt;&lt;br /&gt;If i was building a house i see the language as the cement. I could (maybe) build a whole house out of cement but that would be crazy. Rather i use the cement with existing bricks (components) and other things putting them together in a away unique to my application.&lt;br /&gt;&lt;br /&gt;For me language along is not enough. If the language does not have support tools, existing pre-build components and a vibrant community of users then already it is already no go...&lt;br /&gt;&lt;br /&gt;So really i am limiting scope to evolutionary languages that build on existing tools, frameworks, communities.  And that is Groovy and that is Grails.&lt;br /&gt;&lt;br /&gt;Both Groovy and Grails stand on the shoulders of Giants.&lt;br /&gt;&lt;br /&gt;If we go back to the house analogy then they are the SUPER CEMENT i use them to pull together existing bricks (Spring, Hibernate, Jetty, HSQL, sitemesh). In fact i would say that they are both actually closer to a magic wand rather than cement :)&lt;br /&gt;&lt;br /&gt;So that fact at a language can do something cool is for me "not cool enough"&lt;br /&gt;&lt;br /&gt;Building something in a language without tools, without existing component and with out a vibrant community is &lt;a href="http://sethgodin.typepad.com/seths_blog/2005/03/dont_shave_that.html"&gt;Yak Shaving&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;But hey that is what some people like doing :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-3554804887327037955?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/3554804887327037955/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=3554804887327037955' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3554804887327037955'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/3554804887327037955'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/11/why-i-use-grooy-and-grails-evolution.html' title='Why i use Grooy and Grails (evolution) !!!'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-4179498706668531143</id><published>2008-11-25T14:20:00.000-08:00</published><updated>2008-11-26T10:37:03.155-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy errors command object or domain object'/><title type='text'>Adding your own error message to a Grails Command Object</title><content type='html'>Here is another little trick I got to use in Grails recently:&lt;br /&gt;&lt;br /&gt;Before I started using Grails I used Spring MVC and in fact i still do i my day job. Any way one of the things Spring provided was the &lt;a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/validation/Errors.html"&gt;Errors&lt;/a&gt; interface. This allowed you to add your own error message that would end up available to your view layer. By using methods such as&lt;br /&gt;&lt;br /&gt;reject() and rejectValue()&lt;br /&gt;&lt;br /&gt;So as Grails is built on top of Spring it also makes use of the Errors interface and it automatically injects an instance of this into your domain objects and &lt;a href="http://grails.org/doc/1.0.x/guide/single.html#6.1.9%20Command%20Objects"&gt;command objects&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;So in your controller if you want add an error message to your command object (eg HolidayQueryCommand)&lt;br /&gt;&lt;br /&gt;Then all you have to is this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;holidayQueryCommand.errors.reject("message.code","default error message");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;If you wanted to attach and error message to a particular property then do this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;holidayQueryCommand.errors.rejectValue("property","message.code","default error message");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;These error messages are then all available in your GSP:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;g:rendererrors bean="${holidayQueryCommand}" as="list"&amp;gt;&amp;lt;/g:rendererrors&amp;gt;&lt;/span&gt;&lt;g:rendererrors bean="${stampConfigurationCommand}" as="list"&gt;&lt;br /&gt;&lt;br /&gt;That also goes for domain objects too not just command objects.&lt;br /&gt;&lt;br /&gt;If this is useful to even 1 person then i am glad i posted it :)&lt;/g:rendererrors&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-4179498706668531143?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/4179498706668531143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=4179498706668531143' title='15 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4179498706668531143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4179498706668531143'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/11/adding-your-own-error-message-to-grails.html' title='Adding your own error message to a Grails Command Object'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>15</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-825786085898894334</id><published>2008-11-25T08:09:00.001-08:00</published><updated>2008-11-25T13:29:53.657-08:00</updated><title type='text'>And another book Groovy and Grails Recipes</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;I also found another book that is available for download called "Groovy and Grails Recipes" you can also download it &lt;a href="http://www.apress.com/ecommerce/goto?userid=87806&amp;amp;link=book%2Fview%2F143021600x&amp;amp;key=ffb3c7d689916eb79f293cf0d2070ff9"&gt;here &lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I have not yet downloaded this one myself yet but it is next on my list :)&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.apress.com/ecommerce/goto?userid=87806&amp;amp;link=book%2Fview%2F143021600x&amp;amp;key=ffb3c7d689916eb79f293cf0d2070ff9"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 125px; height: 164px;" src="http://www.apress.com/resource/bookcover/9781430216001?size=medium" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Enjoy !!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-825786085898894334?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/825786085898894334/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=825786085898894334' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/825786085898894334'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/825786085898894334'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/11/and-another-book-groovy-and-grails.html' title='And another book Groovy and Grails Recipes'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-2919618488244349257</id><published>2008-11-25T07:12:00.000-08:00</published><updated>2008-11-25T07:56:51.948-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy book Graeme Rocher'/><title type='text'>Definitive guide to grails 2nd ed available for early download</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;Just wanted to let all the early birds know that the early access to Grahams "Definitive Guide to Grails second edition" is available for download &lt;a href="http://www.apress.com/ecommerce/goto?userid=87806&amp;amp;link=book%2Fview%2F1590599950&amp;amp;key=5490d85f96c49b2eab8f3f1017cc5304"&gt;here&lt;/a&gt; . It says that it is alpha book but most of the chapters are available. So anyway i bought and downloaded what was available and so far it looks really good. I already have the first edition in "dead tree" format so hopefully it lives up to the first one.&lt;br /&gt;&lt;br /&gt;Anyway congrats to Graham for completing it and i will post a review once i have read what i have.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.apress.com/ecommerce/goto?userid=87806&amp;amp;link=book%2Fview%2F1590599950&amp;amp;key=5490d85f96c49b2eab8f3f1017cc5304"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 125px; height: 164px;" src="http://www.apress.com/resource/bookcover/9781590599952?size=medium" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Peace&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-2919618488244349257?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/2919618488244349257/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=2919618488244349257' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/2919618488244349257'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/2919618488244349257'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/11/definitive-guide-to-grails-2nd-ed.html' title='Definitive guide to grails 2nd ed available for early download'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-1668884163719302306</id><published>2008-11-24T03:34:00.000-08:00</published><updated>2008-11-25T13:31:09.970-08:00</updated><title type='text'>Groovy's Design by capabilty or (duck typing) to the rescue</title><content type='html'>One of the many cool features available in Groovy is "&lt;a href="http://en.wikipedia.org/wiki/Duck_typing"&gt;Duck Typing&lt;/a&gt;". The phrase comes from "If it walks like a duck, if it talks like a duck then it is probably a duck".&lt;br /&gt;&lt;br /&gt;Because groovy is dynamic, it allow you to call methods on an object without knowing until runtime if that method exists. So this has helped me this weekend on one of my Grails projects.&lt;br /&gt;&lt;br /&gt;I have two domain objects.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Stamp &lt;/span&gt;and &lt;span style="font-family:courier new;"&gt;CustomStamp&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;They are similar but different. Anyway they currently both have a method called:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;createStampText(String name,String email)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I then have a method on a Grails Service class that takes a Stamp and some other parameters to construct the desired output.&lt;br /&gt;&lt;br /&gt;This service method should not need to care if a Stamp or a CustomStamp is passed in. So how to do this?&lt;br /&gt;&lt;br /&gt;Well in Java i would introduce an interface that contains the method:&lt;br /&gt;createStampText(String name,String email) maybe called IStamp&lt;br /&gt;Then both Stamp and CustomStamp could implement it. Then my service method could be like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;service.doSomething(IStamp stamp,String other,String more){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    stamp.createStampText(name,email)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;But already this is maybe the norm in the pure java world but it is NOT the groovy way and is quite frankly "&lt;a href="http://sethgodin.typepad.com/seths_blog/2005/03/dont_shave_that.html"&gt;Yak Shaving&lt;/a&gt;" just to get the method called polymorphically.&lt;br /&gt;&lt;br /&gt;But using Groovy which my service object are thanks to Grails i can use Duck Typing. Now to use this i simply remove the type. So my service method becomes something like this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;service.doSomething(stamp,String other,String more){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;     stamp.createStampText(name,email)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This way i do not have to create a new interface and i do not have to modify my two domain objects. The service method will just try to call createStampText on any object that is passed in as the first parameter.&lt;br /&gt;&lt;br /&gt;Now that is shweet !!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-1668884163719302306?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/1668884163719302306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=1668884163719302306' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1668884163719302306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/1668884163719302306'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/11/groovys-design-by-capabiltiy-or-duck.html' title='Groovy&apos;s Design by capabilty or (duck typing) to the rescue'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-4050094567674606921</id><published>2008-11-19T11:40:00.000-08:00</published><updated>2008-12-04T01:44:57.116-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails taglib decorator'/><title type='text'>Great little Grails Gem</title><content type='html'>Hi All&lt;br /&gt;&lt;br /&gt;I have not blogged for ages. Been really busy trying to get a large retail web site live for the x-mas. Any way here is little gem i found.&lt;br /&gt;&lt;br /&gt;I need to have a drop down list of accounts a user has access to. This needs to show on every page so they can quickly change accounts. Now there are many way i could do this in grails but i thought a tag lib would fit quite well.&lt;br /&gt;&lt;br /&gt;So basically i want a drop down select list but i want to transparently get the list of accounts from info in the session. So i figure all i have do is wrap the existing grails select taglib. Grails allows you to call existing tags from within a controller or in my case another taglib. So i simply call the grails select tag with the correct parameters and send it to the out stream.&lt;br /&gt;&lt;br /&gt;Here is the tag lib.&lt;br /&gt;&lt;br /&gt;&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;class GlobalCommonTagLib {&lt;br /&gt;        &lt;br /&gt;        &lt;br /&gt;        def accountListSelect = {attrs,body -&amp;gt;&lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;            User user = User.get(session.userId)&lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;            def accountList = user.accountAccesses.collect {it.account};&lt;br /&gt;            attrs.from = accountList&lt;br /&gt;            &lt;br /&gt;            attrs.optionKey = 'id'&lt;br /&gt;            &lt;br /&gt;            attrs.optionValue = 'name'&lt;br /&gt;            &lt;br /&gt;            out &amp;lt;&amp;lt; g.select(attrs)&lt;br /&gt;            &lt;br /&gt;            &lt;br /&gt;        }&lt;br /&gt;        &lt;br /&gt;    }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Then in my GSP&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;g:accountListSelect id="acountId" name="id"/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So easy i am writing this blog with the time i saved.&lt;br /&gt;Enjoy :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-4050094567674606921?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/4050094567674606921/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=4050094567674606921' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4050094567674606921'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/4050094567674606921'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/11/great-little-grails-gem.html' title='Great little Grails Gem'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-7371757996307569066</id><published>2008-08-30T04:15:00.000-07:00</published><updated>2008-08-31T10:26:16.096-07:00</updated><title type='text'>The web and the tools to use: From inception to perfection (Part 1)</title><content type='html'>&lt;span style="font-size:130%;"&gt;&lt;span style="font-size:100%;"&gt;So this entry is going to over several parts. It is basically a summarized brain dump of what i have learned over the last 12 years in web based &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;development&lt;/span&gt;. It will really concentrate on the tools i use and why i use them.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Java Platform&lt;/span&gt;: (&lt;a href="http://java.sun.com/"&gt;http://java.sun.com/&lt;/a&gt;)&lt;br /&gt;I have used Java for over 10 years now and i know it inside out. Admittedly the actual language is getting a bit old in the tooth now but the power of Java is so much more than the language. The reason i use Java is because i am buying into an entire &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;eco&lt;/span&gt;-system of tools and frameworks that have evolved over the last 10 years plus and enormous web community of people who have used them. There is a Java library for anything you want to do on the web. So what does this mean for me... Well to put it in one word "&lt;span style="font-weight: bold;"&gt;Time&lt;/span&gt;". To put it in two words "&lt;span style="font-weight: bold;"&gt;Time Saving&lt;/span&gt;". As in saving me time by me not needing to write plumbing code when i start creating a new app. I know if i embark on a new Web project that some nice person somewhere has created a java library that does something i need. Some of my most top used java Libraries (frameworks) are:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.hibernate.org/"&gt;Hibernate &lt;/a&gt;(awesome Object relational mapping &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;ORM&lt;/span&gt; framework)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.springframework.org/"&gt;Spring &lt;/a&gt;(Glue code, provides a framework for easily wiring diverse components together in a consistent manner. But that is just scrapping the surface. This framework provides so much more) &lt;/li&gt;&lt;li&gt;&lt;a href="http://www.opensymphony.com/sitemesh/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Sitemesh&lt;/span&gt; &lt;/a&gt;(allows me to decorate my web page easily)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.opensymphony.com/quartz/"&gt;Quartz &lt;/a&gt;(scheduling framework)&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.lowagie.com/iText/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;IText&lt;/span&gt; &lt;/a&gt;(&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Pdf&lt;/span&gt; manipulation framework)&lt;/li&gt;&lt;li&gt;&lt;a href="http://commons.apache.org/"&gt;Apache Commons&lt;/a&gt; (enormous set of utility classes to help your everyday coding needs)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;and many many more...&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Groovy and Grails&lt;/span&gt;&lt;br /&gt;Well where do i start with Groovy and Grails... Well first there is a difference... Groovy is a new language (about 4 years old) and Grails is a full stack web based framework. Now when i say Java saves me time i can multiply that by magnitudes when i use Grails and Groovy.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;First Groovy:&lt;/span&gt; (&lt;a href="http://groovy.codehaus.org/"&gt;http://groovy.codehaus.org/&lt;/a&gt;)&lt;br /&gt;Essentially Groovy is Java and Java is Groovy. Well what i mean to say is the compiled version are binary compatible but the as far as the source is concerned in many ways they are in different leagues. Essentially Groovy injects magic into Java turning it from essentially static to dynamic. Without going into details it lets you do what you did already but faster, so much faster. Here are some Java Vs Groovy highlights:&lt;br /&gt;&lt;br /&gt;&lt;blockquote  style="font-family:courier new;"&gt;Java:&lt;br /&gt;List list = new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;ArrayList&lt;/span&gt;();&lt;br /&gt;list.add("one");&lt;br /&gt;list.add("two");&lt;br /&gt;System.out.println(list)&lt;br /&gt;list.add("three");&lt;br /&gt;&lt;br /&gt;Groovy:&lt;br /&gt;def list = ["one","two"]&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;println&lt;/span&gt; list&lt;br /&gt;list &lt;&lt; "three" &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;println&lt;/span&gt; list&lt;br /&gt;&lt;br /&gt;Java:&lt;br /&gt;Map map = new &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;HashMap&lt;/span&gt;();&lt;br /&gt;map.put("name","peter")&lt;br /&gt;map.put("age","30")&lt;br /&gt;System.out.println(map)&lt;br /&gt;&lt;br /&gt;Groovy:&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;println&lt;/span&gt; ["name":"peter","age":"30"]&lt;br /&gt;&lt;br /&gt;Java:&lt;br /&gt;String name = "peter";&lt;br /&gt;String message = "Hello " + name + " how are you"; System.out.println(message)&lt;br /&gt;&lt;br /&gt;Groovy:&lt;br /&gt;def name = "Peter"&lt;br /&gt;def message = "Hello $name how are you"&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;println&lt;/span&gt; message &lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Now Grails:&lt;/span&gt;(&lt;a href="http://grails.org/"&gt;http://grails.org/&lt;/a&gt;)&lt;br /&gt;Grails to be fair took a lot of inspiration from Ruby on Rails... However it has since evolved into a framework so much more powerful than anything else available in its domain. So this is Grails in a nutshell as i see it:&lt;br /&gt;&lt;br /&gt;1) First: Take all the best tried and tested Java frameworks for full stack web development available today (Spring, Spring &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;mvc&lt;/span&gt;, Spring &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;webflow&lt;/span&gt;, Hibernate, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;sitemesh&lt;/span&gt;, quartz, commons)&lt;br /&gt;&lt;br /&gt;2) Wire them all together in the most elegant way. Throwing in some magic custom code.&lt;br /&gt;&lt;br /&gt;3) Sprinkle Groovy all the way through the framework and make it the language to use to control and manipulate the framework.&lt;br /&gt;&lt;br /&gt;3) Throw in a built application server Jetty and an in memory database (Hypersonic)&lt;br /&gt;&lt;br /&gt;4) Finally Apply strict agile principals to the framework just as DRY (Don't Repeat Yourself) , &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;COC&lt;/span&gt; (Convention over configuration), domain driven development, test infected.&lt;br /&gt;&lt;br /&gt;What you end up with is nothing short of a "Revolutionary" new Full Stack web framework. The Holy Grail.&lt;br /&gt;&lt;br /&gt;The way i see it all these technologies existed independently on there own. However the Grails guys bring them together in such a unique way the something Magical happens. Grails really is more than the sum of all its parts. A bit like &lt;a href="http://www.extremeprogramming.org/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;Xtream&lt;/span&gt; Programming&lt;/a&gt; is.&lt;br /&gt;&lt;br /&gt;Here are some of the high lights for me:&lt;br /&gt;&lt;br /&gt;Convention over configuration&lt;br /&gt;This saves me untold amount of time. Grails has a place for everything well everything you need. Domain objects, controller, views, services&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;GORM&lt;/span&gt;:&lt;br /&gt;This is grails &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;ORM&lt;/span&gt;. It used hibernate underneath but provides a dynamic groovy interface over the top of it.&lt;br /&gt;&lt;br /&gt;Save an object:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;book.save()&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;query and object&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;Book.&lt;/span&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"  style="font-family:courier new;"&gt;findAllByAuthor&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;(author)&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Those methods don't exist at compile time they are added at &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;runtime&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;GSP&lt;/span&gt;:&lt;br /&gt;Similar to &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_22"&gt;jsp&lt;/span&gt; but &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_23"&gt;exponentially&lt;/span&gt; more powerful.&lt;br /&gt;&lt;br /&gt;Much much more...&lt;br /&gt;&lt;br /&gt;I will leave it there for now: next in part 2 i will talk about&lt;br /&gt;&lt;br /&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_24"&gt;Firefox&lt;/span&gt; and firebug and friends&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-7371757996307569066?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/7371757996307569066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=7371757996307569066' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7371757996307569066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7371757996307569066'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/08/web-and-tools-to-use-from-inception-to_30.html' title='The web and the tools to use: From inception to perfection (Part 1)'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-7025167426619406877</id><published>2008-08-26T06:15:00.000-07:00</published><updated>2008-08-26T06:30:01.982-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails groovy many-to-many collect'/><title type='text'>Return the collection from a many to many relationship in grails</title><content type='html'>I thought i would blog about this one so that it is recorded somewhere. It is a tricky problem but is so easily solved with groovy.&lt;br /&gt;&lt;br /&gt;Say i have a many to many relationship between User and Account that is controlled by the class &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;AccountAccess&lt;/span&gt;. This would be my domain:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;class User {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    static &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;hasMany&lt;/span&gt; = [&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;accountAccesses&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;AccountAccess&lt;/span&gt;]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Date &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;dateCreated&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Date &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;lastUpdated&lt;/span&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    String name;    &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;class Account {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    static &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;hasMany&lt;/span&gt; = [&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;accountAccesses&lt;/span&gt;:&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;AccountAccess&lt;/span&gt;]&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Date &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;dateCreated&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Date &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;lastUpdated&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    String name    &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;class &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;AccountAccess&lt;/span&gt; {&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    static &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;belongsTo&lt;/span&gt; = User;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Date &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;dateCreated&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Date &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;lastUpdated&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    User user;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    Account account;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;If i wanted to get all the Accounts a user has access to i can do this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style="font-family:courier new;"&gt;def accounts = user.accountAccesses.collect {it.account}&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;It uses the collect closure of groovy. I iterate through the &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;AccountAccess&lt;/span&gt; objects and add the Account object referenced by each one. The end result is i get a list of the Accounts a user has access to.&lt;br /&gt;&lt;br /&gt;Hope this helps&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-7025167426619406877?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/7025167426619406877/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=7025167426619406877' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7025167426619406877'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7025167426619406877'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/08/return-collection-from-many-to-many.html' title='Return the collection from a many to many relationship in grails'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-76467585447434922</id><published>2008-08-26T04:32:00.000-07:00</published><updated>2008-08-29T04:47:36.317-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java regular expressions'/><title type='text'>Using Back References with String replaceAll method</title><content type='html'>This is small problem i was facing the other day and couldn't find much information about it on the web so thought i would blog about it.&lt;br /&gt;&lt;br /&gt;The problem is how to use back references in Java regular expressions.&lt;br /&gt;&lt;br /&gt;The problem is this. Say i have a String like so&lt;br /&gt;&lt;br /&gt;"&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;orderM&lt;/span&gt;8&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;orderA&lt;/span&gt;3&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;orderX&lt;/span&gt;2&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;NoReturn&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;and i want to turn it into a String like so:&lt;br /&gt;&lt;br /&gt;"order M#8 order A#3 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;orderX&lt;/span&gt;#2 &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;NoReturn&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;i can do this:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;String test = "&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;orderM&lt;/span&gt;8&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;orderA&lt;/span&gt;3&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;orderX&lt;/span&gt;2&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;NoReturn&lt;/span&gt;";&lt;br /&gt;   &lt;br /&gt;String replaced = test.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;replaceAll&lt;/span&gt;("([A-Z])([0-9])", " $1#$2 ");&lt;/blockquote&gt;&lt;br /&gt;What happens here is:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;first create two regular expression for matching all capital letters [A-Z] and all single digits [0-9]&lt;/li&gt;&lt;li&gt;Next i then put each of these in a group. using ( ) brackets. The grouping means that the match is &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_11"&gt;remembered&lt;/span&gt; and can be referenced by the replace string.&lt;/li&gt;&lt;li&gt;In the replace string i can then reference the matches via the $n notation where n = the number of the group.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;So what happens is: The regular expression processor moves along the string looking for cases of a capital letter next to a &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_12"&gt;digit&lt;/span&gt;. When it find them it stores the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_13"&gt;capital&lt;/span&gt; letter in a group 1 and the &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_14"&gt;digit&lt;/span&gt; in group 2.&lt;br /&gt;&lt;br /&gt;So i want to replace the original match with another string i can.&lt;br /&gt;&lt;br /&gt;Also note. The whole expression is automatically added to an implicit group zero 0 that is a group of the whole expression.&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;String replaced = test.&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;replaceAll&lt;/span&gt;("([A-Z])([0-9])", " '$0' ");&lt;br /&gt;&lt;br /&gt;will give&lt;br /&gt;&lt;br /&gt;order 'M8' order 'A3' order 'X2' &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;NoReturn&lt;/span&gt;&lt;/blockquote&gt;IMPORTANT NOTE:&lt;br /&gt;&lt;br /&gt;The javadoc says that you reference back references with '\n' (were n = number) but that is not true. That does not work you need to use '$n'. The javadoc is wrong and needs to be updated.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://java.sun.com/javase/6/docs/api/"&gt;Pattern javadoc&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Hope this helps :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-76467585447434922?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/76467585447434922/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=76467585447434922' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/76467585447434922'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/76467585447434922'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/08/using-back-references-with-string.html' title='Using Back References with String replaceAll method'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-4499562010259202212.post-7358202587058569729</id><published>2008-08-21T07:24:00.001-07:00</published><updated>2008-08-28T13:50:09.350-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ec2 amazon block store s3'/><title type='text'>Amazon put the icing on the cake...</title><content type='html'>I &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_0"&gt;received&lt;/span&gt; an email to from Amazon web service. This was the title:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;"Amazon Elastic Block Store for Amazon EC2 is Now Available&lt;/span&gt;"&lt;br /&gt;&lt;br /&gt;Yes finally after a long long wait amazon have finally released a persistence storage service for EC2. If you are not familiar with Amazon &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;webservices&lt;/span&gt; check this out.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/aws"&gt;Amazon Web services&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Basically amazon now provides a set of services to allow host all your new "next big thing" websites ideas on. And best of all they are &lt;span style="font-weight: bold;"&gt;pay as you go&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;These are the main ones:&lt;br /&gt;&lt;span class="small"&gt;&lt;a href="http://www.amazon.com/EC2-AWS-Service-Pricing/b/ref=sc_fe_l_2?ie=UTF8&amp;amp;node=201590011&amp;amp;no=3435361&amp;amp;me=A36L942TSJ2AJA"&gt;Amazon Elastic Compute Cloud&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/SimpleDB-AWS-Service-Pricing/b/ref=sc_fe_l_2?ie=UTF8&amp;amp;node=342335011&amp;amp;no=3435361&amp;amp;me=A36L942TSJ2AJA"&gt;Amazon &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;SimpleDB&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/S3-AWS-home-page-Money/b/ref=sc_fe_l_2?ie=UTF8&amp;amp;node=16427261&amp;amp;no=3435361&amp;amp;me=A36L942TSJ2AJA"&gt;Amazon Simple Storage Service&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Simple-Queue-Service-home-page/b/ref=sc_fe_l_2?ie=UTF8&amp;amp;node=13584001&amp;amp;no=3435361&amp;amp;me=A36L942TSJ2AJA"&gt;Amazon Simple Queue Service&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So the top of the list is EC2 the "Elastic Compute Cloud". Basically this service is a pay as you go virtual hosting service. You open an account, take an off the shelf &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;linux&lt;/span&gt; image and press run.&lt;br /&gt;&lt;br /&gt;Then you effectively &lt;/span&gt;&lt;span class="small"&gt;have &lt;/span&gt;&lt;span class="small"&gt;your hosting platform for your new website that you can connect to via ssh. You then configure it with your new application needs. (&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;mysql&lt;/span&gt;, java, tomcat, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;apache&lt;/span&gt;, etc) then take a snapshot of the image. When you need to scale just turn on the new image instances. But only &lt;span style="font-weight: bold;"&gt;PAY AS YOU SCALE&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Anyway one of the reasons i was holding back on EC2 was that is kind of a an in memory instance. This means that if the instance goes down for any reason then you loose everything. This means if you have a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;mysql&lt;/span&gt; database running then you loose the data too. This is not a good thing right. Well until now the only options you had to get around this was some 3rd party companies that offer fail over and periodical back of the the database. Here are some listed below:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.persistentfs.com/"&gt;http://www.persistentfs.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.elasticdrive.com/"&gt;http://www.elasticdrive.com/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.rightscale.com/"&gt;http://www.rightscale.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Of which http://www.rightscale.com seems to be the best. However this costs $2500 setup and $500 per month plus the cost of running multiple &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;ec&lt;/span&gt;2 instances. Now this is a lot of money for a one man &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;startup&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;So along comes Elastic Block Store&lt;br /&gt;&lt;br /&gt;This means you can setup your EC2 instances now with persistence storage. Ideal for a database. Whats more you only pay for what you need which is currently $0.10 per GB per month. &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_9"&gt;Smiley&lt;/span&gt; faces all around...&lt;br /&gt;&lt;br /&gt;Anyway i am going to get this setup and give it ago so it will be ready for my next web &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;startup&lt;/span&gt; venture which is &lt;span class="blsp-spelling-corrected" id="SPELLING_ERROR_11"&gt;all most&lt;/span&gt; built. Stay tuned.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/4499562010259202212-7358202587058569729?l=blog.peterdelahunty.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.peterdelahunty.com/feeds/7358202587058569729/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=4499562010259202212&amp;postID=7358202587058569729' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7358202587058569729'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/4499562010259202212/posts/default/7358202587058569729'/><link rel='alternate' type='text/html' href='http://blog.peterdelahunty.com/2008/08/amazon-put-icing-on-cake.html' title='Amazon put the icing on the cake...'/><author><name>Peter Delahunty</name><uri>http://www.blogger.com/profile/06472770840257045665</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
