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

<channel>
	<title>Gridshore &#187; groovy and grails</title>
	<atom:link href="http://www.gridshore.nl/category/groovy-and-grails/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.gridshore.nl</link>
	<description>A weblog about software engineering, Architecture, Technology an other things we like.</description>
	<lastBuildDate>Tue, 13 Dec 2011 15:36:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Cleaning up artifactory with a groovy script</title>
		<link>http://www.gridshore.nl/2011/10/03/cleaning-up-artifactory-with-a-groovy-script/</link>
		<comments>http://www.gridshore.nl/2011/10/03/cleaning-up-artifactory-with-a-groovy-script/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 09:10:45 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[artifactory]]></category>
		<category><![CDATA[cleaning]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1192</guid>
		<description><![CDATA[<p>On my employers blog I wrote an article about cleaning up your local maven repository. It gets polluted with old snapshot artifacts easily. It also leaves a lot of build around if you release regularly. After cleaning up your local copy you start thinking about the repository on the server. Would that also become [...]]]></description>
			<content:encoded><![CDATA[<p>On my employers blog I wrote an article about cleaning up your local maven repository. It gets polluted with old snapshot artifacts easily. It also leaves a lot of build around if you release regularly. After cleaning up your local copy you start thinking about the repository on the server. Would that also become as big as your local one? Of course. Therefore we need to clean that one up as well.</p>
<p>In most of our projects we use <a href="http://www.jfrog.com/">Artifactory</a>. It is nice that artifactory comes with a REST based api. The url&#8217;s can be a bit better and the content type of the response is not what I would expect. Still the documentation is good and lost of actions are possible. In this blog post I show you the basics of interacting with the REST api using groovy. Now let us shrink the repo.</p>
<p><span id="more-1192"></span><br />
<h2>Introducing the artifactory api</h2>
<p>The frog wiki has a wiki page dedicated to the api. This page shows the GET/DELETE/PUT requests that you can execute. It shows the url, the response and the content type. If you click the following link you jump to the definition of Folder Info. After the link an image with the same data at the time of writing.</p>
<p><a href="http://wiki.jfrog.org/confluence/display/RTF/Artifactory%27s+REST+API#Artifactory%27sRESTAPI-FolderInfo">http://wiki.jfrog.org/confluence/display/RTF/Artifactory%27s+REST+API#Artifactory%27sRESTAPI-FolderInfo</a><br/><br />
<img style="display:block; margin-left:auto; margin-right:auto;" src="http://www.gridshore.nl/wp-content/uploads/Screen-Shot-2011-09-26-at-16.08.39.png" alt="Screen Shot 2011 09 26 at 16 08 39" border="0" width="600" height="442" /></p>
<p>In the image you can also see the JSON response for the specific request. Have a look at the structure of the response. Look at the children. We will use it later on.</p>
<h2>Obtaining folder info</h2>
<p>Time to show some code. We will first have a look at a function to obtain information about the folder as provided by the caller. Since we group the functions in a class we have to look at configuration of this class as well. The constructor accepts a map that we call config. That way you can provided configuration for the server, the repository and the versions to remove. An example of the config map is.</p>
<pre class="brush: groovy; title: ; notranslate">
def config = [
    server: 'http://localhost:8080',
    repository: 'libs-release-local',
    versionsToRemove: ['/3.2.0-build-'],
    dryRun: false]
</pre>
<p>Than we can ask for information about a folder. The following code block shows two functions, one to obtain information about a folder and the other to ask for a connection with the server.</p>
<pre class="brush: groovy; title: ; notranslate">
def JSON folderInfo(path) {
    def binding = [repository: config.repository, path: path]
    def template = engine.createTemplate('''/artifactory/api/storage/$repository/$path''').make(binding)
    def query = template.toString()

    def server = obtainServerConnection()
    def resp = server.get(path: query)
    if (resp.status != 200) {
        println &quot;ERROR: problem obtaining folder info: &quot; + resp.status
        println query
        System.exit(-1)
    }
    return resp.data
}

private RESTClient obtainServerConnection() {
    def server = new RESTClient(config.server)
    server.parser.'application/vnd.org.jfrog.artifactory.storage.FolderInfo+json' = server.parser.'application/json'
    server.parser.'application/vnd.org.jfrog.artifactory.repositories.RepositoryDetailsList+json' = server.parser.'application/json'

    return server
}
</pre>
<p>We make use of the groovy <a href="http://groovy.codehaus.org/api/groovy/text/SimpleTemplateEngine.html">SimpleTemplateEngine</a>. As you can see we build the query string with placeholders and attach a map with parameters to the template engine. Next step is to generate the query. After obtaining the connection to the server we execute the GET request and obtain the JSON data from the response. Notice the lines in the obtainServerConnection. The last two lines add mappings for the artifactory provided content types. We want them to be treated as normal json responses or else our mapping framework (Jackson) will not be able to process the result.</p>
<h2>Removing items</h2>
<p>The goal for this blog post is to present a script to clean your artifactory repository. Now that we know how to obtain information about a folder in artifactory, it is time to have a look at cleaning. The idea is to take the provided path as a starting point. Go through all the folders recursively and check if we are in an artifact folder. An artifact folder contains artifacts and should not have other folders. If a folder is not an artifact folder we are dealing with a grouped (maven terms). In our case we could determine an artifact folder by its name. All artifacts have -build- in their name. Hence the following function.</p>
<pre class="brush: groovy; title: ; notranslate">
private def isArtifactFolder(child) {
    child.uri.contains(&quot;-build-&quot;)
}
</pre>
<p>The next utility function is to actually delete a folder. The next function removes the provided path if we are not doing a dry run. If we did configure a dry run, we only print a message and do not actually do the delete. We again use the groovy template technology to create the query. Notice that the artifactory api uses the DELETE request.</p>
<pre class="brush: groovy; title: ; notranslate">
private def removeItem(path, child) {
    println &quot;folder: &quot; + path + child.uri + &quot; DELETE&quot;
    def binding = [repository: config.repository, path: path + child.uri]
    def template = engine.createTemplate('''/artifactory/$repository/$path''').make(binding)
    def query = template.toString()
    if (!config.dryRun) {
        def server = new RESTClient(config.server)
        server.delete(path: query)
    }
}
</pre>
<p>The last piece of the puzzle is the recursive function to check a folder for subfolders and give the command to remove a folder if it is in the list of folder to be removed. The next code block shows this function.</p>
<pre class="brush: groovy; title: ; notranslate">
def cleanArtifactsRecursive(path) {
    def deleteCounter = 0
    JSON json = folderInfo(path)
    json.children.each {child -&gt;
        if (child.folder) {
            if (isArtifactFolder(child)) {
                config.versionsToRemove.each {toRemove -&gt;
                    if (child.uri.startsWith(toRemove)) {
                        removeItem(path, child)
                        deleteCounter++
                    }
                }
            } else {
                if (!child.uri.contains(&quot;ro-scripts&quot;)) {
                    deleteCounter += cleanArtifactsRecursive(path + child.uri)
                }
            }
        }
    }
    return deleteCounter
}
</pre>
<p>The code is available online through github, check the references.</p>
<h2>References</h2>
<dl>
<dt><a href="http://blog.jteam.nl/2011/08/01/cleaning-up-your-maven-repository">Cleaning up your maven repository</a></dt>
<dd>Other blogpost about groovy and cleaning your local maven repository automatically.</dd>
<dt><a href="http://www.jfrog.com/">Artifactory</a></dt>
<dd>Homepage of the creators of Artifactory, here you can also find commercial support</dd>
<dt><a href="http://wiki.jfrog.org/confluence/display/RTF/Artifactory%27s+REST+API">Artifactory REST api</a></p>
<dd>Documentation for the REST api that is provided by Artifactory</dd>
<dt><a href="https://github.com/jettro/small-scripts/blob/master/groovy/artifactory/Artifactory.groovy">The source code</a></dt>
<dd>Sourcecode of the script discussed in this article.</dd>
</dl>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2011%2F10%2F03%2Fcleaning-up-artifactory-with-a-groovy-script%2F&amp;title=Cleaning%20up%20artifactory%20with%20a%20groovy%20script&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2011/10/03/cleaning-up-artifactory-with-a-groovy-script/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cleaning up your maven repository with groovy</title>
		<link>http://www.gridshore.nl/2011/08/01/cleaning-up-your-maven-repository-with-groovy/</link>
		<comments>http://www.gridshore.nl/2011/08/01/cleaning-up-your-maven-repository-with-groovy/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 09:25:21 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[maven]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1165</guid>
		<description><![CDATA[<p>Ever looked at the space used by your maven repository? Think that this is to much? Start reading the blog post I wrote on my employers blog about a groovy script that you can use to clean your local maven repository. It removes old snapshots stored in your repo as well as old versions [...]]]></description>
			<content:encoded><![CDATA[<p>Ever looked at the space used by your maven repository? Think that this is to much? Start reading the blog post I wrote on my employers blog about a groovy script that you can use to clean your local maven repository. It removes old snapshots stored in your repo as well as old versions of artifacts.</p>
<p><a href="http://blog.jteam.nl/2011/08/01/cleaning-up-your-maven-repository">http://blog.jteam.nl/2011/08/01/cleaning-up-your-maven-repository</a></p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2011%2F08%2F01%2Fcleaning-up-your-maven-repository-with-groovy%2F&amp;title=Cleaning%20up%20your%20maven%20repository%20with%20groovy&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2011/08/01/cleaning-up-your-maven-repository-with-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Recap of the year 2010</title>
		<link>http://www.gridshore.nl/2011/01/04/recap-of-the-year-2010/</link>
		<comments>http://www.gridshore.nl/2011/01/04/recap-of-the-year-2010/#comments</comments>
		<pubDate>Tue, 04 Jan 2011 20:08:30 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[recap]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1125</guid>
		<description><![CDATA[<p>The new year has started, with it comes one of the last opportunities to look back at 2010. So what happened, what did I try out, what did I like and what didn&#8217;t I like. I also want to have a short look at what you liked, based on the number of visitors.</p> <p>This [...]]]></description>
			<content:encoded><![CDATA[<p>The new year has started, with it comes one of the last opportunities to look back at 2010. So what happened, what did I try out, what did I like and what didn&#8217;t I like. I also want to have a short look at what you liked, based on the number of visitors.</p>
<p>This post will nog contain new technical stuff, only old stuff <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><span id="more-1125"></span><br />
<h2>Statistics</h2>
<p>On average I get 500 visitors each day. Some of the posts got a lot of attention and reached 1000 visits a day. The posts with the highest amount of visits are old ones. A lot of them are coming from my old blog and are about spring web services. The biggest link of 2010 is a blog from June 2009 about Roo : <a href="http://www.gridshore.nl/2009/06/11/why-spring-roo-is-not-my-thing/">Why Spring Roo is not my thing</a>. I think that is pretty funny but also sad. Of course I would like my new blog items to be on top. The first post in the list is from June 2010 and is about jmx and spring <a href="http://www.gridshore.nl/2010/06/02/using-jmx-within-a-spring-application/">Using JMX within a spring application</a>. The last one I want to mention is a blog item from november 2011. This post is somewhere around number 25 in 2010. Which is nice if you take into account that it just had less than 2 months to reach this position. The post is about the spring-social project: <a href="http://www.gridshore.nl/2010/11/04/connecting-to-linkedin-using-spring-social/">Connecting to Linkedin using spring-social</a></p>
<p>Where did all these people come from? Well most of them came through Google, a lot came through DZone and quite a few came through multiple project websites of spring-source [mostly spring-flex and spring-integration].</p>
<p>Most people use Firefox, and Google Chrome is rising. Internet Explorer is still twice as big than safari on my blog. But Firefox is 4 times the size of internet explorer.</p>
<p>Top Countries are Unites States and India followed by Germany and United Kingdom.</p>
<p>Enough statistics, let us move on to the content. What did I write about?</p>
<h2>What did I write about</h2>
<h3>Januari</h3>
<p>In Januari I wrote two blog posts about grails. The results can be found in the <a href="https://github.com/jettro/MyScheduling">MyScheduling sample</a> over at Github. At my employers blog I wrote a piece about <a href="http://blog.jteam.nl/2010/01/14/logging-to-the-syslog-from-a-java-application/">Logging to the syslog from a java application</a>.</p>
<h3>Februari</h3>
<p>In Februari I wrote more on flex. I discovered the Parsley library and I wrote a sample for the <a href="http://www.axonframework.org">Axon framework</a>. The blog post I wrote is <a href="http://www.gridshore.nl/2010/02/25/creating-a-sample-for-axon-using-flex-and-parsley/">Creating a sample for axon using flex and parsley</a>. The sample is part of the axon distribution. Another blogpost was about creating an rss feed with spring 3 and the Rome library. This post was coming from the work I did for a customer.</p>
<h3>April</h3>
<p>In march nothing really happened. In april I wrote about using groovy and I wrote a sample that combined Axon and Grails. This sample is still maintained and is a nice example of what you can do with groovy and axon. Three posts of April from my hand were axon and grails related. You can find the <a href="https://github.com/jettro/axon-addressbook-grails">sample over at Github</a>.</p>
<p>The reason for the quiet month of March was a very busy project. We went live in April, I wrote about it <a href="http://blog.jteam.nl/2010/04/05/jteam-en-rijksoverheid-nl/">on the JTeam blog</a>.</p>
<h3>June</h3>
<p>For the project I was working on I needed monitoring. I decided to use groovy for its flexibility and the integration with spring jmx for easy remote access and exposing beans through jmx. I wrote two posts, <a href="http://www.gridshore.nl/2010/06/02/using-jmx-within-a-spring-application/">Using JMX within a spring application</a> was a post with some screenshots and a lot of code.</p>
<h3>July/August</h3>
<p>These are traditionally the months that Ben gives us a few blog posts. Especially his post <a href="http://www.gridshore.nl/2010/08/16/yes-rest-really-is-not-the-same-as-http/">Yes! REST really is not the same as HTTP!!</a> was received very well.</p>
<p>I wrote a blog post on JTeam blog. Again about jmx and groovy. This time I wrote about <a href="http://blog.jteam.nl/2010/08/19/monitoring-hippo-connection-pool-using-jmx-and-groovy/">Monitoring Hippo Connection Pool using jmx and groovy</a>. Some ideas of this blogpost were used in the actual implementation of hippo repository connector.</p>
<h3>September</h3>
<p>This was the month for new things. Two blog posts about MongoDB. Together with Allard I created the EventStore implementation for Axon based on MongoDB. Sample project is available on Github:<a href="https://github.com/jettro/Axon-trader">https://github.com/jettro/Axon-trader</a>. The other blog post was about gradle. I am trying to find better build tools than maven.</p>
<h3>October</h3>
<p>The month of the JAOO or GOTO conference. No blog items on gridshore. But one post about Git that was read very often and had a lot of dzone votes. <a href="http://blog.jteam.nl/2010/10/08/git-tips-that-i-learned-from-the-master/">Git Tips That I Learned From The Master</a>. Had a lot of inspiration during the conference and some good drinks as well.</p>
<h3>November</h3>
<p>November was a very succesful spring month. I wrote two blog posts about two new spring projects. Spring-social and Spring-mobile. Both posts were received very well. I got some very positive feedback, especially by Keith Donald. He mentioned that parts of my blog post were an inspiration for new functionality in the M2 release of spring-mobile. He also wrote a <a href="http://blog.springsource.com/2010/12/21/social-coding-in-spring-projects/">very nice blog post</a> about using Git and he used the patch I could have created as a red line for his post. Fun to read. Code for the samples is again available on Github: <a href="https://github.com/jettro/GridshoreSamples">https://github.com/jettro/GridshoreSamples</a></p>
<h2>Other things I did</h2>
<p>I reviewed a book about Apache Felix (more on this later). I gave a presentation at the Hippo Gettogether that is available online. Of course I gave some presentations at JTeam tech evenings. I also read a lot of books, the book that made an impact on how I look at presentations: Presentation Zen by Garr Reynolds.</p>
<p>The last thing I want to mention in this chapter is that I bought myself some toys. Of course the iPad, but now I am also owner of Lego Mindstorms. I even did some java programming on the robot. More on that later this year.</p>
<h2>Highlights</h2>
<p>So a well spend year with blog posts about Axon, Grails, Groovy, Flex, JMX, Spring, Git, MongoDB, logging. I am sure 2011 will be as inspiring as 2010. To all of you, have a very good year and hope you will come back to read some of my posts.</p>
<p>Happy New Year, Jettro</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2011%2F01%2F04%2Frecap-of-the-year-2010%2F&amp;title=Recap%20of%20the%20year%202010&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2011/01/04/recap-of-the-year-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My first steps with Gradle: creating a multi module java web project and running it with jetty.</title>
		<link>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/</link>
		<comments>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/#comments</comments>
		<pubDate>Wed, 08 Sep 2010 09:34:06 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[intellij]]></category>
		<category><![CDATA[jetty]]></category>
		<category><![CDATA[maven]]></category>
		<category><![CDATA[wrapper]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1077</guid>
		<description><![CDATA[<p>I am a experienced maven user. Sometime I love it, sometimes I hate it. I like it a lot better than ant, but in some situation you would like maven to be easier and more descriptive. The past year there was a lot of fuzz about Gradle. This would give you the best of [...]]]></description>
			<content:encoded><![CDATA[<p>I am a experienced maven user. Sometime I love it, sometimes I hate it. I like it a lot better than ant, but in some situation you would like maven to be easier and more descriptive. The past year there was a lot of fuzz about Gradle. This would give you the best of ant as well as the best of maven, and even more. My first encounter was not very positive, but I kept it in my mind to try it later with a more serious project. This blogpost is about that second more serious try. It will not teach the gradle experts anything, but it will be an easy introduction in to what gradle has to bring for people that are just interested in gradle.</p>
<p><span id="more-1077"></span><br />
<h2>Project structure</h2>
<p>The structure of the project is fairly straightforward, but big enough to demonstrate some of the features that gradle has to offer. It consists of two modules:</p>
<ul>
<li>App</li>
<li>Web-ui</li>
</ul>
<p>We are creating an <a href="http://www.axonframework.org">Axonframework</a> sample, the app contains the command handling and for now the query part as well. The web-ui contains the spring mvc app with the controllers and the authentication using the spring-security framework. For now we make use of an in memory database and we want to be able to start the application without a lot of hassle. Using jetty in this case.</p>
<p>The modules have some shared dependencies for testing and logging. We also want to centralize the definition of some dependency versions.</p>
<h2>Multi module gradle build</h2>
<p>Gradle was build with multi module support from the start. So what do you need to create a multi-module build. We need a settings.gradle that defines the available modules. Next to that we need the main build.gradle as well as the modules build.gradle. Oke you can do without the per module configuration, but in my case that was not the intention. Let us focus first on the main build.gradle.</p>
<h3>Main build.gradle</h3>
<p>The main build.gradle is used to define some of the versions of the dependencies. The following code block shows the complete script.</p>
<pre class="brush: groovy; title: ; notranslate">
axonVersion = &quot;0.6&quot;
springVersion = &quot;3.0.4.RELEASE&quot;
springSecurityVersion = &quot;3.0.3.RELEASE&quot;
slf4jVersion = &quot;1.5.8&quot;
sourceCompatibility = 1.6

subprojects {
    apply plugin: 'java'

    configurations {
        all*.exclude group: &quot;commons-logging&quot;, module: &quot;commons-logging&quot;
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        compile &quot;org.slf4j:jcl-over-slf4j:$slf4jVersion&quot;,
                &quot;org.slf4j:jul-to-slf4j:$slf4jVersion&quot;
        runtime &quot;org.slf4j:slf4j-log4j12:$slf4jVersion&quot;

        compile(&quot;log4j:log4j:1.2.15&quot;) {
            exclude group: &quot;com.sun.jdmk&quot;, module: &quot;jmxtools&quot;
            exclude group: &quot;com.sun.jmx&quot;, module: &quot;jmxri&quot;
            exclude group: &quot;javax.mail&quot;, module: &quot;mail&quot;
            exclude group: &quot;javax.jms&quot;, module: &quot;jms&quot;
        }

        testCompile 'junit:junit:4.7'
    }

    group = 'org.axonframework.samples.trader'
    version = '1.0-SNAPSHOT'
    sourceCompatibility = 1.6
}
</pre>
<p>As you can see, the script starts with the definition of the versions of dependencies. Than the script contains information for all the subprojects. You see we define the java plugin for all subprojects. Next to that the repositories and the dependencies are defined. Have a look at the mechanism to exclude transitive dependencies. For log4j we explicitly exclude some transitive dependencies. We also use a mechanism to exclude commons-logging from the complete build. Using the configurations hook we exclude it for all phases.</p>
<p>Finally we also define the group, version and source compatibility in the build configuration.</p>
<p>That is it, the following code block shows the required settings.gradle and after that we move on with the build.gradle of the app and web-ui subprojects.</p>
<pre class="brush: groovy; title: ; notranslate">
include &quot;app&quot;, &quot;web-ui&quot;
</pre>
<h3>Subprojects build.gradle</h3>
<p>The build.gradle for the app project is almost to easy to show. But I promised I would, so here we go:</p>
<pre class="brush: groovy; title: ; notranslate">
dependencies {
    compile &quot;org.axonframework:axon-core:$axonVersion&quot;

    compile &quot;org.hibernate:hibernate-entitymanager:3.4.0.GA&quot;,
            &quot;c3p0:c3p0:0.9.1&quot;,
            &quot;org.hsqldb:hsqldb:1.8.0.10&quot;

    compile &quot;org.springframework:spring-tx:$springVersion&quot;,
            &quot;org.springframework:spring-orm:$springVersion&quot;,
            &quot;org.springframework:spring-jdbc:$springVersion&quot;

    compile &quot;com.thoughtworks.xstream:xstream:1.3.1&quot;

    testCompile &quot;org.axonframework:axon-test:$axonVersion&quot;
}
</pre>
<p>The configuration only contains dependencies. I would like to be able to simplify the dependencies on the spring projects. Would be nice if I could group them somehow, like:</p>
<p>compile group:&#8221;org.springframework&#8221;, version:&#8221;$springVersion&#8221;, module:["spring-webmvc", "spring-aop"]</p>
<p>But the build config looks pretty clean. Now we move on to the creation of the war for the web project.</p>
<pre class="brush: groovy; title: ; notranslate">
apply plugin: 'war'

dependencies {
    compile project(':app')

    compile &quot;org.springframework:spring-webmvc:$springVersion&quot;,
            &quot;org.springframework:spring-aop:$springVersion&quot;

    compile &quot;org.springframework.security:spring-security-web:$springSecurityVersion&quot;,
            &quot;org.springframework.security:spring-security-config:$springSecurityVersion&quot;

    compile &quot;javax.validation:validation-api:1.0.0.GA&quot;,
            &quot;org.hibernate:hibernate-validator:4.0.2.GA&quot;

    runtime &quot;javax.servlet:jstl:1.1.2&quot;,
            &quot;taglibs:standard:1.1.2&quot;,
            &quot;opensymphony:sitemesh:2.4.2&quot;

    providedCompile &quot;javax.servlet:servlet-api:2.5&quot;
}
</pre>
<p>Again a pretty straightforward config. We use more types of dependencies. We now introduce the providedCompile. Jars that need not be included in the war should have this config for the dependency. Do mark that we have an apply plugin line at the top for creating the war. Finally have a look at the mechanism to show we have a dependency on another module of the project. We use the <strong>compile project (&#8216;:app&#8217;) </strong>to make the war include this created jar as well.</p>
<h2>Running with Jetty</h2>
<p>You think the jetty plugin for maven is easy, well check this out. We have to change only one word in the web project config. Look for the first line with <strong>apply plugin</strong>. Change the word war into jetty and you are done. Now you can run jetty with the following command from the root of the project:</p>
<p><em>gradle :web-ui:jettyRun</em></p>
<h2>The wrapper</h2>
<p>People that have gradle installed on their system can easily build the project and run jetty. But some people might not have gradle installed. You can help them to make it very easy. Gradle comes with a wrapper that downloads gradle and makes sure it&#8217;s on your path etc. The only thing the user needs to do is the following in the root of the project:</p>
<p><em>gradlew build</em></p>
<p>Pay attention to the &#8216;w&#8217; at the end of the gradle command. Next step is to start jetty. This is done with the same command as before with one change, the w at the end. To help your users with this, you need to do one thing. You have to add the following task to the main build.gradle. Than run gradle wrapper, checkin the generated files into your source control system. The gradlew script can be used by the people to build the project. Good stuff or not?</p>
<pre class="brush: groovy; title: ; notranslate">
task wrapper(type: Wrapper) {
    gradleVersion = '0.9-rc-1'
    jarPath = 'wrapper'
}
</pre>
<h2>Intellij integration</h2>
<p>Oke, this kinda hurts to say, but intellij support is not at a level that you would like to. At least that is what I could find out. You can easily run gradle builds from intellij. That is all nice. But I am really missing the dependency management part. Would be great to have support like for maven to setup your complete project. Wouldn&#8217;t it be great to have the import from external model feature for gradle as well? For now let us all vote for this issue, it might help:</p>
<p><a href="http://youtrack.jetbrains.net/issue/IDEA-57755">﻿http://youtrack.jetbrains.net/issue/IDEA-57755</a></p>
<p>I hope someone from jetbrains reeds this at thinks I am important enough to start creating this plugin <img src='http://www.gridshore.nl/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<h2>Performance</h2>
<p>The last remarks I want to make are about the performance of gradle. At the moment I have this build for maven as well as gradle and maven2 is twice as fast as gradle. I know work is being done on this. Gradle 0.9.1 will support a new feature that at least will speed up building the project of you have to do it a lot during the day. It will do something with a running gradle service that you can call each time you start a build. There are some items on the mailing list about this specific topic if you are interested.</p>
<p><a href="http://gradle.markmail.org/thread/xbqna6lowvsmm4ve">http://gradle.markmail.org/thread/xbqna6lowvsmm4ve</a></p>
<h2>Concluding</h2>
<p>Well that was part one of the experiment. I have not touched everything by a long run. Still I found out I like the configuration of gradle a lot better than I like maven. It is a lot cleaner and let&#8217;s you focus on the things that are important. I prefer groovy for this kind of work over xml. Still gradle has some ground to cover. For starters, tool integration. We must have something that makes working with intellij a lot better. In the future I will have a better look at plugins for release management and other stuff that I think is necessary for a good project build.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F09%2F08%2Fmy-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty%2F&amp;title=My%20first%20steps%20with%20Gradle%3A%20creating%20a%20multi%20module%20java%20web%20project%20and%20running%20it%20with%20jetty.&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/09/08/my-first-steps-with-gradle-creating-a-multi-module-java-web-project-and-running-it-with-jetty/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Exposing jmx through jmxmp and reading the jmx data with groovy</title>
		<link>http://www.gridshore.nl/2010/06/20/exposing-jmx-through-jmxmp-and-reading-the-jmx-data-with-groovy/</link>
		<comments>http://www.gridshore.nl/2010/06/20/exposing-jmx-through-jmxmp-and-reading-the-jmx-data-with-groovy/#comments</comments>
		<pubDate>Sun, 20 Jun 2010 09:22:14 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[jmx]]></category>
		<category><![CDATA[jmxmp]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1065</guid>
		<description><![CDATA[<p></p> <p>In my previous post, &#8220;Using JMX within a spring application&#8220;, I talked about monitoring your application with jmx. I discussed exposing beans with spring. At one of my current projects I am having problems exposing jmx through the default jmxrmi protocol. In his whitepaper about jmx, Allard mentiones another protocol, jmxmp. Spring has support [...]]]></description>
			<content:encoded><![CDATA[<p><img style="float: left;" src="http://www.gridshore.nl/wp-content/uploads/groovy.png" border="0" alt="groovy.png" width="203" height="100" /></p>
<p>In my previous post, &#8220;<a href="http://www.gridshore.nl/2010/06/02/using-jmx-within-a-spring-application/">Using JMX within a spring application</a>&#8220;, I talked about monitoring your application with jmx. I discussed exposing beans with spring. At one of my current projects I am having problems exposing jmx through the default jmxrmi protocol. In his <a href="http://www.jteam.nl/dms/whitepapers/JavaApplicationMonitoringAndManagement.pdf">whitepaper about jmx</a>, Allard mentiones another protocol, jmxmp. Spring has support for this remoting protocol as well. Therefore I wanted to try this out.</p>
<p>Another thing I wanted to experiment with is creating a groovy client. The technique with interfaces and proxies with spring as described in my previous post is  a lot of work when you are interested in a little bit of data. Therefore I wanted to see if using groovy is easier.</p>
<p>This blog post discusses these two topics with respect to JMX.</p>
<p><span id="more-1065"></span>
<p> </p>
<h2>Exposing beans using jmxmp</h2>
<p>To expose jmx beans, we need an mbeanserver. Spring makes it easy to obtain the the platform mbeanserver. By using the context namespace mbean-server bean, spring finds the platform MBeanServer. This server can than be used to register MBeans with and to register connection providers with. A connection provider is called a server connector. A server connector is  created using the spring provided factory bean</p>
<p><em>org.springframework.jmx.support.ConnectorServerFactoryBean</em></p>
<p>Using this factory bean we can configure the protocol used to expose the beans. Choosing the protocol is done using the ServiceUrl property. Other properties are available. You can start the connector in a separate thread and make this a daemon thread. The following code block gives you the complete configuration of jmx through jmxmp.</p>
<pre>
<pre class="brush: xml; title: ; notranslate">
&lt;context:mbean-server/&gt;
&lt;context:mbean-export registration=&quot;replaceExisting&quot; server=&quot;mbeanServer&quot;/&gt;
&lt;bean id=&quot;jmxServerConnector&quot; class=&quot;org.springframework.jmx.support.ConnectorServerFactoryBean&quot;&gt;
    &lt;property name=&quot;threaded&quot; value=&quot;true&quot;/&gt;
    &lt;property name=&quot;daemon&quot; value=&quot;true&quot;/&gt;
    &lt;property name=&quot;server&quot; ref=&quot;mbeanServer&quot;/&gt;
    &lt;property name=&quot;serviceUrl&quot; value=&quot;service:jmx:jmxmp://localhost:9998/&quot;/&gt;
&lt;/bean&gt;
</pre>
</pre>
<p>A few things in this code are important to notice. The serviceUrl that contains the jmxmp protocol definition as well as the port that clients can use to connect. Another thing to notice is the name of the server mbeanServer. This is  the default id of the MBeanServer. We need this id to provide the server to the connection factory and to the mbean exporter.</p>
<p>That is all there is to it. A last thing to remember is that you need an additional jar on your classpath to be able to use jmxmp. This does not come out of the box. I could not find a maven repository out there that has it. Therefore I added to to the maven repository myself. The download is available from the website of sun.</p>
<p><a href="http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/download.jsp">http://java.sun.com/javase/technologies/core/mntr-mgmt/javamanagement/download.jsp﻿</a></p>
<p>I used the <em>JMX Remote API 1.0.1_04 Reference Implementation﻿</em>, you will need the <strong>jmxremote_optional.jar</strong>. You can use the serviceUrl to connect from jconsole. Because we now use jmxmp, you have to tell jconsole to use jmxremote_optional.jar. Easiest way is to use the endorsed.dirs property. Start jconsole using the following command from the directory that contains the jmxremote_optional.jar:</p>
<p><em>jconsole &#8216;-J-Djava.endorsed.dirs=.&#8217;﻿</em></p>
<p>Let us move on to creating a groovy client</p>
<h2>Creating a groovy jmx client</h2>
<p>Groovy makes it very easy to connect to a remote jmx service. All you need is the service url and a bit of knowledge of the beans that are exposed. The following lines of code show all you need from the groovy side:</p>
<pre>
<pre class="brush: groovy; title: ; notranslate">
import javax.management.remote.JMXServiceURL
import javax.management.remote.JMXConnectorFactory as JmxFactory

def serverUrl = 'service:jmx:jmxmp://localhost:9998/'
def server = JmxFactory.connect(new JMXServiceURL(serverUrl)).MBeanServerConnection
def serviceMonitor = new GroovyMBean(server,'nl.gridshore.monitoring.springannotation:name=contactServiceMonitorSpring,type=ContactServiceMonitorSpring')

println &quot;${serviceMonitor.AmountOfContacts}&quot;
</pre>
</pre>
<p>The serviceUrl is the same as exposed by the spring configuration. Another important part is the domain, the name and the type of the bean to connect to. The result is a new GroovyMBean that acts as a proxy to the exposed MBean. Now you can just ask for the exposed attributes like <strong>AmountdOfContacts</strong>.</p>
<p>You could run this code as a groovy script. Spring comes with support for groovy. You can use groovy beans as real objects in your spring configuration. That way you can easily create jmx clients that you can expose through a web interface or something like that. Easiest way to do this is by implementing an interface that you can use to inject the groovy bean into another bean. The following line shows the spring configuration for a groovy bean.</p>
<pre>    &lt;lang:groovy id="jmxInfo"
                 script-source="file:///absolute/path/to/src/nl/gridshore/monitoring/groovy/JmxInfo.groovy"/&gt;
</pre>
<p>Of course you need to put groovy on your classpath. Check the <a href="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/dynamic-language.html#dynamic-language-beans-groovy">spring documentation</a> to find out more about groovy support. The following code block shows the complete source code for the groovy class.</p>
<pre>
<pre class="brush: groovy; title: ; notranslate">
package nl.gridshore.monitoring.groovy

import javax.management.remote.JMXServiceURL
import javax.management.remote.JMXConnectorFactory as JmxFactory

class JmxInfo implements Info {
    public Map obtainParams() {
        Map params = new HashMap()
        def serverUrl = 'service:jmx:jmxmp://localhost:9998/'
        def server = JmxFactory.connect(new JMXServiceURL(serverUrl)).MBeanServerConnection
        def serviceMonitor = new GroovyMBean(server,'nl.gridshore.monitoring.springannotation:name=contactServiceMonitorSpring,type=ContactServiceMonitorSpring')

println &quot;${serviceMonitor.AmountOfContacts}&quot;

params.put(&quot;amountOfContacts&quot;,serviceMonitor.AmountOfContacts)
        return params
    }
}
</pre>
</pre>
<p>Last part is to actually use the bean. Therefore I have created a very small runner with the main method as shown below.</p>
<pre>
<pre class="brush: java; title: ; notranslate">
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(&quot;nl/gridshore/monitoring/springannotation/spring-config.xml&quot;);
        ContactService service = context.getBean(ContactService.class);

        service.addContact(new Contact(20, &quot;not me&quot;));

        Info jmxInfo = (Info) context.getBean(&quot;jmxInfo&quot;);

        System.out.println(&quot;amount of contacts : &quot; + jmxInfo.obtainParams().get(&quot;amountOfContacts&quot;));
    }
</pre>
</pre>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F06%2F20%2Fexposing-jmx-through-jmxmp-and-reading-the-jmx-data-with-groovy%2F&amp;title=Exposing%20jmx%20through%20jmxmp%20and%20reading%20the%20jmx%20data%20with%20groovy&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/06/20/exposing-jmx-through-jmxmp-and-reading-the-jmx-data-with-groovy/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Use Grails and Axon to create a CQRS application (part II)</title>
		<link>http://www.gridshore.nl/2010/04/16/use-grails-and-axon-to-create-a-cqrs-application-part-ii/</link>
		<comments>http://www.gridshore.nl/2010/04/16/use-grails-and-axon-to-create-a-cqrs-application-part-ii/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 18:58:48 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[axon]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1036</guid>
		<description><![CDATA[<p>In this post we focus on getting the task based user interface. We have the basic building blocks in the application, but the screens are a bit stupid. How many applications would you create where you have to manually copy the identifier of a contact to an address when you want to register an [...]]]></description>
			<content:encoded><![CDATA[<p>In this post we focus on getting the task based user interface. We have the basic building blocks in the application, but the screens are a bit stupid. How many applications would you create where you have to manually copy the identifier of a contact to an address when you want to register an address for this contact. Well in the current version of the application this is what you really have to do.</p>
<p>What are the tasks that we focus on right now:</p>
<ul>
<li>Create a new contact</li>
<li>Remove a contact</li>
<li>Change the name of a contact</li>
<li>Register an address of a certain type for a specific contact</li>
<li>Remove an address from a contact</li>
</ul>
<p>But before we step into creating the front-end, we install some plugins that I discussed in previous posts.</p>
<p><span id="more-1036"></span><br />
<h2>Plugins</h2>
<ul>
<li>Db-util &#8211; mainly used for testing</li>
<li>Navigation &#8211; change the templates as well as add navigation stuff to the controller</li>
</ul>
<h2>Get our grails hands dirty</h2>
<h3>Task driven &#8211; Create a new contact, remove a contact, change name of a contact</h3>
<p>Time to start working on the tasks. The first is a basic one: Create a new contact. This is one that comes out of the box, but we now have different navigation and I only want to show the fields that can actually be entered. For a contact that is only the name.</p>
<p>When creating new views I like to generate the views and start from the result. I took the list view first, removed the navigation part and shuffled the columns.</p>
<p>We move on to the create.gsp and the edit.gsp. Again we remove the input fields for items we do not need. In this case this is purely the identifier field. Of course I also remove the navigation. After testing the create screen, now without the identifier field I found out we need to change the constraints of the Contact object. We have to add nullable is true.</p>
<p>Let us move on to a more interesting task</p>
<h3>Register an address of a certain type for a specific contact</h3>
<p>At the moment we use the AddressEntryController to have a look at the addresses. This is about to change. Now we are going to show the available addresses in the contact details screen. This is also the screen where we present the tasks to remove an address and to register a new one.</p>
<p>We start with creating the button to add an address. We reuse the add button as provided by grails. There is a difference, the add button usually is presented in the top bar, we however want it in the bottom bar. Therefore we must add a class to the stylesheet and the following button to the bottom button bar:</p>
<pre class="brush: xml; title: ; notranslate">
&lt;span class=&quot;button&quot;&gt;
  &lt;g:actionSubmit class=&quot;add&quot; action=&quot;registerAddress&quot;
      value=&quot;${message(code: 'orderEntry.button.registerAddress.label', default: 'Register Address')}&quot;/&gt;
&lt;/span&gt;
</pre>
<p>Another part of the show Contact page we need to change is the part where we actually show the addresses of the contact. I use the generated code for the list.gsp of address entries. I remove the pagination part, but other than that it is the same. Except for one column. We do want to be able to delete addresses. Therefore I have added an image with the a link to the delete action. This link with an image is shown in the next line of code.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;g:link action=&quot;deleteAddress&quot; id=&quot;${addressEntryInstance.id}&quot;&gt;
    &amp;ltimg src=&quot;${resource(dir:'images/skin',file:'database_delete.png')}&quot; alt=&quot;delete&quot;&gt;
&lt;/g:link&gt;
</pre>
<p>Check out the way to create the link, just define the action and pass it an id. That is enough to be wired to the actual action method on the controller. I also like the way to create a link to an image. The resource method is used to point to a directory and the actual file. No need to think about web context url or things like that.</p>
<p>The final screen we need is the registerAddress form. It is mostly a copy of the edit.gsp of the address entry. I also do not want the contact name and contact identifier to be editable. Finally I changed the action of the form into saveAddress.</p>
<p>The final thing I want to have a look at is the groovy code of the controllers. The following code block shows all three methods that are important with respect to the addresses. The code is pretty straightforward. </p>
<pre class="brush: groovy; title: ; notranslate">
    def registerAddress = {
        def contactEntryInstance = ContactEntry.get(params.id)
        def addressEntryInstance = new AddressEntry();
        addressEntryInstance.contactIdentifier = contactEntryInstance.identifier
        addressEntryInstance.contactName = contactEntryInstance.name
        [addressEntryInstance: addressEntryInstance]
    }

    def saveAddress = {
        def addressEntryInstance = new AddressEntry(params)
        if (addressEntryInstance.validate()) {
            def foundContact = ContactEntry.findByIdentifier(addressEntryInstance.contactIdentifier)
            contactCommandHandlerService.registerAddress(
                    addressEntryInstance.addressType,
                    addressEntryInstance.contactIdentifier,
                    addressEntryInstance.streetAndNumber,
                    addressEntryInstance.zipCode,
                    addressEntryInstance.city)
            flash.message = &quot;${message(code: 'default.created.message', args: [message(code: 'addressEntry.label', default: 'AddressEntry'), addressEntryInstance.city])}&quot;
            redirect(action: &quot;show&quot;, params:[id:foundContact.id])
        }
        else {
            render(view: &quot;registerAddress&quot;, model: [addressEntryInstance: addressEntryInstance])
        }
    }

    def deleteAddress = {
        def addressEntryInstance = AddressEntry.get(params.id)
        if (addressEntryInstance) {
            contactCommandHandlerService.removeAddress(addressEntryInstance.addressType, addressEntryInstance.contactIdentifier)
        }
        def foundContact = ContactEntry.findByIdentifier(addressEntryInstance.contactIdentifier)
        redirect(action: &quot;show&quot;, id: foundContact.id)
    }
</pre>
<p>Again a lot of copy paste from the generated controller. But here we use the contactCommandHandlerService to create the commands that are send back to the server. In all three methods we use the query datasource to obtain the contact data. As you can see, we do not store anything in the query database. That is all handled by the commands and events. Than in the event listener we receive the domain events and update the query database. The following and last code block gives you the action that handles the AddressDeletedEvent.</p>
<pre class="brush: groovy; title: ; notranslate">
    private void doHandle(AddressRemovedEvent event) {
        ContactEntry foundContact = ContactEntry.findByIdentifier(event.aggregateIdentifier.toString())
        AddressEntry foundAddress = AddressEntry.findByAddressTypeAndContactIdentifier(event.addressType,foundContact.identifier)
        if (foundAddress) {
            foundAddress.delete()
        }
    }
</pre>
<p>Oke because I actually forgot to implement this correct at first, the listener for ContactDeletedEvent. I forgot to remove the addresses for the contact. We have a table with contacts and a table that combines the contact information with the address information. Therefore we have to do two delete actions. </p>
<pre class="brush: groovy; title: ; notranslate">
    private void doHandle(ContactDeletedEvent event) {
        ContactEntry foundContact = ContactEntry.findByIdentifier(event.aggregateIdentifier.toString())
        List&lt;AddressEntry&gt; foundAddresses = AddressEntry.findAllByContactName(foundContact.name)

        foundContact.delete()

        foundAddresses.each {address -&gt;
            address.delete()
        }
    }
</pre>
<p>The following image gives you an idea about the screen.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-04-16-at-20.38.13.png" alt="Screen shot 2010-04-16 at 20.38.13.png" border="0" width="627" height="591" /></div>
<p>That is it for now, in my next and final blogpost about this example I will show the advantage of having these simple screen oriented  tables.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F04%2F16%2Fuse-grails-and-axon-to-create-a-cqrs-application-part-ii%2F&amp;title=Use%20Grails%20and%20Axon%20to%20create%20a%20CQRS%20application%20%28part%20II%29&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/04/16/use-grails-and-axon-to-create-a-cqrs-application-part-ii/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Use Grails and Axon to create a CQRS application (part I)</title>
		<link>http://www.gridshore.nl/2010/04/08/use-grails-and-axon-to-create-a-cqrs-application-part-i/</link>
		<comments>http://www.gridshore.nl/2010/04/08/use-grails-and-axon-to-create-a-cqrs-application-part-i/#comments</comments>
		<pubDate>Thu, 08 Apr 2010 22:02:49 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[Axon Framework]]></category>
		<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[axon]]></category>
		<category><![CDATA[cqrs]]></category>
		<category><![CDATA[grails]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1025</guid>
		<description><![CDATA[<p>Allard has been working on a new framework to make it easier to create a CQRS application. CQRS is short for Command Query Responsibility Segregation. An architecture that separates data sources for storing state and querying data. The query datasource should be easy to use when creating screens. The framework Allard created is the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/axon_logo.png" alt="axon_logo.png" border="0" width="55" height="55" align="left" />Allard has been working on a new framework to make it easier to create a CQRS application. CQRS is short for Command Query Responsibility Segregation. An architecture that separates data sources for storing state and querying data. The query datasource should be easy to use when creating screens. The framework Allard created is the <a href="http://www.axonframework.org/">Axon Framework</a>. This framework makes it a lot easier to use commands, events, event sourcing. If these terms are not known to you, I suggest you start reading the reference manual that comes with axon.</p>
<p><img src="http://www.gridshore.nl/wp-content/uploads/grailslogo.png" alt="grailslogo.png" border="0" width="163" height="43" align="right" />What does <a href="http://www.grails.org/">grails</a> do in this picture. Isn&#8217;t grails about rapid application creation? Well, yes. It is a good platform to rapidly create web applications using the groovy language and still be able to use existing libraries. Personally I really like the Gorm library of grails. I think that gorm would be an excellent choice to wrap the query datasource. Of course the gsp technology and the groovy language are nice to have when working with the web applications as well.</p>
<p>In this blog post I&#8217;ll discuss the integration between grails and axon. How can we create an application with grails that makes use of Axon to implement CQRS. I&#8217;ll discuss the way to create commands and send these to axon. I&#8217;ll also discuss responding to events coming from axon. First I have to show some aspects of a grails project that you need to know before you can use Axon. I&#8217;ll try to take you with me when I take the steps to create a good integration between Axon and Grails.</p>
<p><span id="more-1025"></span><br />
<h2>Sources</h2>
<p>The sample I am using is the same sample that is provided by axon with a flex client. The AddressBook is used to show the different possibilities of axon and a client. You can create contacts, and register addresses of a certain type for contacts. You can register home, work and holiday addresses.</p>
<p>You can find the sources of the sample at github:</p>
<pre>
<a href="http://github.com/jettro/axon-addressbook-grails">http://github.com/jettro/axon-addressbook-grails</a>
</pre>
<h2>Configure grails to use Axon</h2>
<p>Grails has a pretty elegant way to configure libraries to be used by the project. You can make grails look for libraries in remote maven repositories as well as your local repository. I need to enable the local repository since I am working with a SNAPSHOT version of axon at the moment of writing.</p>
<p>Each normal grails project contains a folder grails-app/conf. In this folder is a file called BuildConfig.groovy. This file contains the build configuration, you did not see that one coming did you? In this file there is a closure called <em>grails.project.dependency.resolution</em>. Within this closure you can configure the repositories and the dependencies. As I said before you need to uncomment the mavenLocal() and add the following two lines to the dependencies.</p>
<pre class="brush: groovy; title: ; notranslate">
compile 'org.axonframework:axon-core:0.5-SNAPSHOT'
runtime 'com.thoughtworks.xstream:xstream:1.3.1'
</pre>
<p>I did not get the grails project to work in a way that SNAPSHOT dependencies are updated. So if I compile a new version of axon, I manually delete the library in the grails cache. The libraries are stored in the ivy cache on your computer. In my case the jars are in the folder:</p>
<pre>
&lt;user_home>/.ivy2/cache/org.axonframework/axon-core/jars/axon-core-0.5-SNAPSHOT.jar
</pre>
<h2>Structure of the project</h2>
<p>If you create a normal grails application you usually stick to the conventional project setup. Within the grails-app folder you have folders for domain classes, controllers, services, and others. </p>
<h3>The domain model</h3>
<p>When creating a CQRS application the domain becomes a different beast. It is the domain that commands act upon and the events are generated by the domain. For now let us call the domain from CQRS perspective the core-domain and the grails domain classes the query domain. The query domain resides in the normal grails location. Each grails project also contains a src folder with the groovy and java classes. This is where we will store the core domain.</p>
<p>A very important thing to stick in your brain is that the controllers must not use the standard way of grails to save domain objects. If you would do that, you only update the query database and no commands are created and send to the Axon backend.</p>
<h3>Grails services and axon commands</h3>
<p>We interact with axon by making use of command objects. To make this easy from the grails perspective we create a service class around the command creation. This makes it easier to create a transactional scope and to have just one location where we actually send data to axon. This service is more like a proxy to the Axon command bus.</p>
<h3>Grails controllers</h3>
<p>The controllers are normal grails controllers, they make use of services to send data to the backend and they use gorm to query the data.</p>
<h3>Axon event listeners</h3>
<p>The event listeners are used to receive updates about the core domain and reflect this in the query domain. The listeners make extensive use of gorm to update data in the query domain.</p>
<p>The following image gives you an idea about the directory layout of the project.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-04-06-at-18.48.39.png" alt="Screen shot 2010-04-06 at 18.48.39.png" border="0" width="331" height="554" /></div>
<h2>Scaffolding</h2>
<p>One of the nice options of grails to create applications very fast is to use scaffolding. When using axon this is still possible, but only to do the first steps very fast. I recommend creating your own views and controllers when you know what you want and you need to create better useable screens. You cannot use the scaffolding controllers. They would only use the query domain. We need to call the services from the controllers. I do generate the controllers and then adjust them to my needs.</p>
<p>To get an idea what I reused from the generated controllers, let us have a look at the changes I made to the generated controller methods. For now I did not change views, so they are still using the scaffolding versions. Beware that this is not a final solution. To give you an idea, registering an address for a contact means that you have to manually copy the uuid of the contact to the create new address screen. Of course I will change this as well, but that will be the topic of a next blog post.</p>
<p>As a rule of thumb, all methods that actually change data need to be altered.</p>
<pre class="brush: groovy; title: ; notranslate">
def save = {
    def contactEntryInstance = new ContactEntry(params)
    if (contactEntryInstance.validate()) {
        def uuid = contactCommandHandlerService.createContact(contactEntryInstance.name)
        def foundContact = ContactEntry.findByIdentifier(uuid)

        flash.message = &quot;${message(code: 'default.created.message', args: [message(code: 'contactEntry.label', default: 'ContactEntry'), foundContact.name])}&quot;
        redirect(action: &quot;show&quot;, id: foundContact.id)
    }
    else {
        render(view: &quot;create&quot;, model: [contactEntryInstance: contactEntryInstance])
    }
}
</pre>
<p>Line 4 show that we use the service instead of the query domain object. In line 5 we do use the query domain object to find the created contact.</p>
<h2>Configuring the event and command bus using grails and spring</h2>
<p>Grails uses a lot of spring udner the hood. But they also give you a very easy way to use spring yourself as well. Grails comes with a special domain specific language for configuring spring. You can find the file <em>resources.groovy</em> in the grails-app/conf/spring folder. In this file we configure the event bus, the command bus, the event listener and the command handlers. The following code block shows the beans, it should be straightforward and not to hard to understand.</p>
<pre class="brush: groovy; title: ; notranslate">
beans = {
    contactRepository(ContactRepository) {
        eventBus = ref(&quot;eventBus&quot;)
        eventStore = ref(&quot;eventStore&quot;)
    }

    contactEventListener(ContactEventListener, ref(&quot;eventBus&quot;))

    createContactCommandHandler(CreateContactCommandHandler, ref(&quot;contactRepository&quot;), ref(&quot;commandBus&quot;))
    updateContactCommandHandler(UpdateContactCommandHandler, ref(&quot;contactRepository&quot;), ref(&quot;commandBus&quot;))
    removeContactCommandHandler(RemoveContactCommandHandler, ref(&quot;contactRepository&quot;), ref(&quot;commandBus&quot;))
    registerAddressCommandHandler(RegisterAddressCommandHandler, ref(&quot;contactRepository&quot;), ref(&quot;commandBus&quot;))

    // axon beans
    commandBus(SimpleCommandBus)

    eventBus(SimpleEventBus)

    eventStore(FileSystemEventStore, ref(&quot;xstreamSerializer&quot;)) {
        baseDir = &quot;file:/Users/jcoenradie/temp/axonrepo&quot;
    }

    xstreamSerializer(XStreamEventSerializer)
}
</pre>
<p>Creating a bean is easy, some of the beans are direct axon classes. The contactRepository, contactEventListener and all the command handlers are not. These are groovy classes that reside in the src directory.</p>
<h2>Axon components in groovy</h2>
<p>I am not going to write extensively about Axon. The website from Axon does a much better job. I do want to mention the most important components and show some of the groovy code to make it work.</p>
<h3>Sending data using commands</h3>
<p>The data send is in the command objects. The commandBus is used to dispatch the commands. Each command must have a registered command handler. Axon provided a special mechanism to use annotations to register handlers. For now I register the handlers manually. Let us have a look at the handler for contact creation. The spring configuration already shows that the handlers use the contactRepository as well as the commandBus.</p>
<pre class="brush: groovy; title: ; notranslate">
class CreateContactCommandHandler implements CommandHandler&lt;CreateContactCommand&gt; {
    ContactRepository contactRepository

    def CreateContactCommandHandler(contactRepository, commandBus) {
        this.contactRepository = contactRepository;
        commandBus.subscribe(CreateContactCommand.class, this)
    }

    Object handle(CreateContactCommand command) {
        ContactAggregate contact = new ContactAggregate(command.newContactName)
        contactRepository.save contact
        return contact.identifier.toString()
    }
}
</pre>
<p>As you can see we need to implement the interface <em>CommandHandler</em>. In the constructor we subscribe the handler with the command bus. Now focus on the handle method. We create the contact aggregate and store it in the repository by calling the save method.</p>
<h3>Core domain</h3>
<p>Now the contact is created, but we also must update our query database. To understand what happens there, we must have a look at the core domain class. The following code block shows the constructor and that it applies an event for a contact being created.</p>
<pre class="brush: groovy; title: ; notranslate">
    ContactAggregate(String name) {
        apply(new ContactCreatedEvent(name))
    }
</pre>
<h3>Event listener</h3>
<p>Now that we have the events, we want to listen for them and update our query database. When creating the event listener, we need to provide the eventBus. In the constructor of the listener we register the listener with the eventBus. The handle method receives the events. In this method we check if we support the provided event. If we support it, we call one of the available doHandle methods that make use of overloading to determine the right method. The following code block shows the handle method and two of the doHandle methods.</p>
<pre class="brush: groovy; title: ; notranslate">
void handle(Event event) {
    println &quot;Contact event listener recevied an event : ${event.class.simpleName}&quot;
    if (event.class in [ContactCreatedEvent, ContactNameChangedEvent, ContactDeletedEvent, AddressAddedEvent]) {
        doHandle(event)
    } else {
        println &quot;Event not supported&quot;
    }
}

private void doHandle(ContactCreatedEvent event) {
    def contact = new ContactEntry(name: event.name, identifier: event.aggregateIdentifier.toString())
    contact.save()
}

private void doHandle(ContactNameChangedEvent event) {
    ContactEntry foundContact = ContactEntry.findByIdentifier(event.aggregateIdentifier.toString())
    foundContact.name = event.newName
    foundContact.save()
}
</pre>
<p>The ContactEntry is the query domain object. See how we query for an existing contact and how we store the new or updated contact in the query database.</p>
<h2>Summary</h2>
<p>That is about it for now. I have showed you some basic Axon components in groovy. I introduced you to the concept of a state datastore and a query datastore. Next to that I also told you about the commands. I did not tell you anything about the datastore used for storing the state. The sample makes use of the file based event sourcing datastore. Check the Axon documentation to find out more.</p>
<p>In the following blog posts I will improve the sample by making better screens and controllers. i will also talk more about the axon options. Try to use annotations to see if that makes the event listeners and the command handlers easier to understan.</p>
<p>Hope to see yo back.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F04%2F08%2Fuse-grails-and-axon-to-create-a-cqrs-application-part-i%2F&amp;title=Use%20Grails%20and%20Axon%20to%20create%20a%20CQRS%20application%20%28part%20I%29&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/04/08/use-grails-and-axon-to-create-a-cqrs-application-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Doing more with groovy</title>
		<link>http://www.gridshore.nl/2010/04/05/doing-more-with-groovy/</link>
		<comments>http://www.gridshore.nl/2010/04/05/doing-more-with-groovy/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 18:19:09 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[gradle]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[grape]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=1021</guid>
		<description><![CDATA[<p>I have big plans with groovy. After playing around with grails and doing some groovy scripting I was sure. I want more groovy. To be able to do more with groovy, I needed to learn more about groovy. One way to do this is to start reading and experimenting. This blog post discusses a [...]]]></description>
			<content:encoded><![CDATA[<p>I have big plans with groovy. After playing around with grails and doing some groovy scripting I was sure. I want more groovy. To be able to do more with groovy, I needed to learn more about groovy. One way to do this is to start reading and experimenting. This blog post discusses a few experiments as well as some of the learning sources.</p>
<p><span id="more-1021"></span>
<p>The best learning source for me consists of a number of manning books:</p>
<ul>
<li><a href="http://www.manning.com/gsmith/">Grails in Action</a></li>
<li><a href="http://www.manning.com/koenig2/">Groovy in Action (2nd edition)</a></li>
</ul>
<p>The first thing I did was creating some scripts, I mainly copied some sources from others. I also wrote a blog post about the groovy goodness:</p>
<p><a href="http://www.gridshore.nl/2009/11/20/analyzing-beet-results-with-groovy/">http://www.gridshore.nl/2009/11/20/analyzing-beet-results-with-groovy/</a></p>
<p>Again I was amazed by the way groovy is used to obtain a webpage and print the contents of the page. The following code block shows the script.</p>
<pre class="brush: groovy; title: ; notranslate">
#!/usr/bin/env groovy
def NEW_LINE = System.getProperty(&quot;line.separator&quot;)
def address = &quot;http://www.applenieuws.nl/?feed=rss&quot;
def urlInfo = address.toURL()
println &quot;URL: ${address}${NEW_LINE}&quot;
println &quot;URL Text: ${urlInfo.text}${NEW_LINE}&quot;
println &quot;Host/Port: ${urlInfo.host}/${urlInfo.port}${NEW_LINE}&quot;
println &quot;Protocol: ${urlInfo.protocol}${NEW_LINE}&quot;
println &quot;User Info: ${urlInfo.userInfo}${NEW_LINE}&quot;
println &quot;File: ${urlInfo.file}${NEW_LINE}&quot;
</pre>
<p>But since you are reading this I guess you are already interested in groovy. This post is not for experts in groovy. It is more focussed on people trying to find out if groovy is going to help them work more effectively or just for the fun of it.</p>
<h2>Integration</h2>
<p>I love the integration of groovy and java. You can implement a java interface with groovy. You can call a groovy class from java code. One of the things you are able to do is use spring annotations like @Autowired and @Component in groovy. The following code block shows a listener that can function within an Axon application to receive events. Nice stuff isn&#8217;t it?</p>
<pre class="brush: groovy; title: ; notranslate">
@Component
class GroovyAddressListener implements org.axonframework.core.eventhandler.EventListener {

  @Autowired
  GroovyAddressListener(SimpleEventBus eventBus) {
    eventBus.subscribe this
  }

  void handle(Event event) {
    if (event instanceof AddressRegisteredEvent) {
      println &quot;a new address in city ${event.address.getCity()} is received.&quot;
    }
  }
}
</pre>
<p>If you are not familiar with the Axon Framework, check the website <a href="http://www.axonframework.org">www.axonframework.org</a>. I am also planning a blog post around a sample I am creating with a tight integration of Axon and Grails.</p>
<p>Due to the easy integration of groovy and java, people that like groovy create wrappers around existing java libraries to make them better useable. On of those examples is the <a href="http://groovy.codehaus.org/modules/http-builder/">HttpBuilder project</a>. This is a project that wraps the apache http client.</p>
<h2>Building groovy</h2>
<h3>Using maven</h3>
<p>What is with software that it needs to be build. In java land we have maven. Nowadays (maven 3), maven is even powered by groovy. If you want to integrate groovy with java, a maven build seems very logical. There is a good maven plugin for building groovy. Checkout the following page to learn about the maven configuration.</p>
<p><a href="http://btilford.blogspot.com/2010/02/groovy-170-and-gmaven-12-multi-module.html">http://btilford.blogspot.com/2010/02/groovy-170-and-gmaven-12-multi-module.html</a></p>
<p>If you want to compile groovy classes into java classes and use them in your own application, you need to add the groovy library to your classpath. The groovy maven plugin itself is easy to configure. The following code block shows an example that makes use of the groovy maven plugin.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;dependencies&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.codehaus.gmaven.runtime&lt;/groupId&gt;
        &lt;artifactId&gt;gmaven-runtime-1.7&lt;/artifactId&gt;
        &lt;version&gt;1.2&lt;/version&gt;
    &lt;/dependency&gt;
    &lt;dependency&gt;
        &lt;groupId&gt;org.codehaus.groovy&lt;/groupId&gt;
        &lt;artifactId&gt;groovy-all&lt;/artifactId&gt;
        &lt;version&gt;1.7.0&lt;/version&gt;
    &lt;/dependency&gt;
&lt;dependencies&gt;
&lt;build&gt;
    &lt;plugins&gt;
        &lt;plugin&gt;
            &lt;groupId&gt;org.codehaus.gmaven&lt;/groupId&gt;
            &lt;artifactId&gt;gmaven-plugin&lt;/artifactId&gt;
            &lt;executions&gt;
                &lt;execution&gt;
                    &lt;goals&gt;
                        &lt;goal&gt;generateStubs&lt;/goal&gt;
                        &lt;goal&gt;generateTestStubs&lt;/goal&gt;
                        &lt;goal&gt;compile&lt;/goal&gt;
                        &lt;goal&gt;testCompile&lt;/goal&gt;
                    &lt;/goals&gt;
                    &lt;configuration&gt;
                        &lt;providerSelection&gt;1.7&lt;/providerSelection&gt;
                    &lt;/configuration&gt;
                &lt;/execution&gt;
            &lt;/executions&gt;
        &lt;/plugin&gt;
    &lt;/plugins&gt;
&lt;/build&gt;
</pre>
<h3>Using grails</h3>
<p>Cannot get easier than this, just create a project and use the grails commands. Grails also makes it very easy to add libraries to the project. These libraries can be used in the normal grails classes: domain, controller, service. But you can also use them in your own groovy classes. I use this extensively in the grails/axon integration sample.</p>
<p>In your grails project go to the directory <em>grails-app/conf</em>. There you can find the BuildConfig.groovy. Within this file you can find the dependencies. The following code block gives you an example to include the axon framework as a compile time dependency and xstream as a runtime dependency. To be able to use this you have to uncomment the <em>mavenLocal()</em> in de dependencies part of the same file.</p>
<pre class="brush: groovy; title: ; notranslate">
  dependencies {
    compile 'org.axonframework:axon-core:0.5-SNAPSHOT'
    runtime 'com.thoughtworks.xstream:xstream:1.3.1'
  }
</pre>
<p>Of course you could obtain libraries from other maven repositories, but since we use the snapshot that is not available in a repository we use the local maven repository.</p>
<p>The complete dependency model of grails is pretty extensive and a bit to much to discuss in detail.</p>
<h3>Using Gradle</h3>
<p>If you are only doing groovy, maven might not be the best choice. Even if you are combining java and groovy some people say maven is not the right choice. I think it is a matter of taste although I do think maven is pretty verbose. An alternative in groovy landscape is <a href="http://www.gradle.org/">Gradle</a>. Gradle uses convention over configuration. It needs less lines of code than ant (without custom libraries) and gives more freedom than maven. Maybe the best about grails is that it does not use xml, but it uses groovy instead.</p>
<p>Peter Ledbrook is doing a good job in using gradle to build grails projects. Read his blog post : <a href="http://www.cacoethes.co.uk/blog/groovyandgrails/building-a-grails-project-with-gradle">http://www.cacoethes.co.uk/blog/groovyandgrails/building-a-grails-project-with-gradle</a>. Personally I do think this is one step to far. For me the grails build system is good enough. I also had a lot of tooling problems when combining gradle and grails in intellij. I did not get the classpath like I wanted to. Using the mechanism as described in the grails part of build works for me. I do think they borrowed some good ideas (dependency management) from gradle.</p>
<h3>Grapes</h3>
<p>The last tool you can use when running groovy I would like to mention is <a href="http://groovy.codehaus.org/Grapes+and+grab()">Grapes</a>. I like the idea for dependency management in scripts. There is a very easy way to add libraries to your classpath by using the grab mechanism. I like the example as published on the page about the <a href="http://groovy.codehaus.org/HTTP+Builder">groovy Http builder</a>. I am not going to reprint the example here. It all has to do with the grab annotation. The following line only shows the grab command.</p>
<pre>
@Grab(group='org.codehaus.groovy.modules.http-builder', module='http-builder', version='0.5.0-RC2' )
</pre>
<p>So even in a command line script you can now use libraries managed by Grapes.</p>
<p>That is it for now, more to follow the next months.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F04%2F05%2Fdoing-more-with-groovy%2F&amp;title=Doing%20more%20with%20groovy&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/04/05/doing-more-with-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Still doing grails</title>
		<link>http://www.gridshore.nl/2010/01/10/still-doing-grails/</link>
		<comments>http://www.gridshore.nl/2010/01/10/still-doing-grails/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 11:07:31 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[grails-ui]]></category>
		<category><![CDATA[rss]]></category>
		<category><![CDATA[searchable]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=984</guid>
		<description><![CDATA[<p></p> <p>This is the third post in a series of post about grails. In this series I am describing an application I am creating with grails. It is a scheduling application for scheduling people on projects. You can find the previous posts here:</p> http://www.gridshore.nl/2009/12/20/starting-with-grails/ http://www.gridshore.nl/2010/01/04/continuing-with-grails/ <p>In this post I will discuss the following topics:</p> [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/F0720E8F-2336-4FEE-BB96-7F8FA9B9FD9C.jpg" alt="F0720E8F-2336-4FEE-BB96-7F8FA9B9FD9C.jpg" border="0" width="134" height="117" align="right" /></p>
<p>This is the third post in a series of post about grails. In this series I am describing an application I am creating with grails. It is a scheduling application for scheduling people on projects. You can find the previous posts here:</p>
<ul>
<li><a href="http://www.gridshore.nl/2009/12/20/starting-with-grails/">http://www.gridshore.nl/2009/12/20/starting-with-grails/</a></li>
<li><a href="http://www.gridshore.nl/2010/01/04/continuing-with-grails/">http://www.gridshore.nl/2010/01/04/continuing-with-grails/</a></li>
</ul>
<p>In this post I will discuss the following topics:</p>
<ul>
<li>Creating meeting notes using the grails-ui rich text editor</li>
<li>Create a search using the searchable plugin on the meeting notes</li>
<li>Introducing rss to subscribe to new meeting notes</li>
</ul>
<p><span id="more-984"></span><br />
<h2>Meeting notes</h2>
<h3>Create the basics</h3>
<p>For the meeting notes we want a large text field that can contain html to make it look better. We start of with the domain object. We give it three fields: a weekNr a User and the notes. The notes field must become a Text field in the database and a textarea on the screen. To accomplish this, we add a mapping element with the following contents as well as the constraints to make it an html textarea element. (Yes I know this feels strange)</p>
<pre class="brush: groovy; title: ; notranslate">
class MeetingNotes {
    int weekNr
    User user
    String notes
    static constraints = {
        notes(blank:false, widget:&quot;textarea&quot;)
    }
    static mapping = {
        notes type:&quot;text&quot;
    }
}
</pre>
<p>Next step is the controller, for now we add the scoffold property and configuration to add it to the navigation. The next code block shows the first implementation.</p>
<pre class="brush: groovy; title: ; notranslate">
class MeetingNotesController {
    def scaffold = true

    static navigation = [
            group: 'tabs',
            order: 110,
            subItems: [
                    [group: 'tabs', action: 'create']
            ]
    ]
}
</pre>
<p>The create screen now looks like this:</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-01-09-at-17.16.59.png" alt="Screen shot 2010-01-09 at 17.16.59.png" border="0" width="500" height="490" /></div>
<h3>Use the rich text editor</h3>
<p>In include the rich text editor, we generate the views and make changes to those. Than we change the create.jsp in views/meetingnotes. We start by removing the navigation. Than we add the following line to the head element.</p>
<pre>
&lt;gui:resources components="richEditor"/&gt;
</pre>
<p>Then we just need to make a small change to the gsp. Look for the line with <em>g:textArea</em>. We replace this input item with the following line.</p>
<pre>
&lt;gui:richEditor id='notes' value='add your weekly notes here ....'/&gt;
</pre>
<p>This results in the following screen:</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-01-09-at-18.01.22.png" alt="Screen shot 2010-01-09 at 18.01.22.png" border="0" width="500" height="490" /></div>
<p>The same changes need to be made to the edit.gsp. I also removed the navigation from the other gsp&#8217;s. Time to move on, now we are going to include the searchable plugin and make the weekly meeting notes searchable.</p>
<h2>The searchable plugin</h2>
<p>Let us start with the basics and install the plugin, configure the MeetingNotes domain class to be searchable, and look at the generated search screen. You can find these steps as well in the <a href="http://www.grails.org/Searchable+Plugin+-+Quick+start">quick start</a> from the plugin documentation.</p>
<pre>
grails install-plugin searchable
</pre>
<p>Now the hard part to make our MeetingNotes searchable, we have to add the following line to the MeetingNotes domain class.</p>
<pre>
static searchable = true
</pre>
<p>For real, that is it. Now you can browse to the controller that serves the search.</p>
<p>I have created three items that all contain data, the following screen shows the standard search controller. Only two items will be returned if I look for the project name cqrs4j</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-01-10-at-09.59.29.png" alt="Screen shot 2010-01-10 at 09.59.29.png" border="0" width="500" height="490" /></div>
<p>That is all nice, but it does not really integrate with our site. Therefore we want to make a controller that does the search thing and an input box beneath the header menu.</p>
<p>First I add a line to the UrlMappings that maps the /search request to the SearchableController that comes out of the box. Check the file UrlMappings.groovy in the conf folder.</p>
<pre>
"/search" (controller:"searchable")
</pre>
<p>Now we will override the view of that comes with the plugin and make it look more like our own. This page, <a href="http://www.grails.org/Searchable+Plugin+-+SearchableController+and+view">Controller and view</a>, describes how you can do that. I copied the index.gsp from the path ${user.home}/.grails/1.2.0/projects/MyScheduling/plugins/searchable-0.5.5/grails-app/views/searchable/index.gsp to the same location in my own application. Then I alter that index.gsp, add the template, remove some styling and I have a better looking page. I also copied the form into the main.gsp layout so we have a search box on each page. The following screendump shows the result.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-01-10-at-10.49.38.png" alt="Screen shot 2010-01-10 at 10.49.38.png" border="0" width="500" height="488" /></div>
<p>There you have it, basic search implemented in our own application. Looking really integrated.</p>
<p>There is topic that I also want to mention, this is suggestions. You know them from google and more advanced search solutions. You know what, we have an advanced search now as well. We just have to configure that we want to use suggestions. With this option configured, the results page shows a link to try the search again with suggestions. As an example try to search for <em>holday</em>, you get no results, try the suggestions and you get the following screen.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-01-10-at-11.02.28.png" alt="Screen shot 2010-01-10 at 11.02.28.png" border="0" width="500" height="488" /></div>
<p>To do this, we change the searchable part of the MeetingNotes into the following lines:</p>
<pre class="brush: groovy; title: ; notranslate">
    static searchable = {
        spellCheck &quot;include&quot;
    }
</pre>
<p>The search plugin has a lot of options and functionality. I urge you to have a look at the <a href="http://www.grails.org/plugin/searchable">plugin page</a>.</p>
<h2>Rss feed</h2>
<p>A very often method used to be informed for new items is rss. I want to create a feed for all meeting notes. That way people get notified when a new Meeting Note is created. To create the feed, I use the <a href="http://www.grails.org/plugin/feeds">feeds plugin</a>.</p>
<p>Again it all starts with the installation of the plugin. The plugin makes use of the framework Rome. So if you are familiar with that, this should not be to hard. Not that it is hard if you do not have the knowledge.</p>
<pre>
grails install-plugin feeds
</pre>
<p>Now adding the feed consists of two parts. The first part is to add a feed method to the MeetingNotes controller. The second part is two add the special html tag, which is done using a grails tag.</p>
<pre>
&lt;feed:meta kind="rss" version="2.0" controller="meetingNotes" action="feed"/&gt;
</pre>
<pre class="brush: groovy; title: ; notranslate">
    def feed = {
        render(feedType:&quot;rss&quot;, feedVersion:&quot;2.0&quot;) {
            title = &quot;Meeting Notes feed&quot;
            link = &quot;${grailsApplication.config.grails.serverURL}/meetingNotes/feed&quot;
            description = &quot;All meeting notes that have been written per week&quot;
            MeetingNotes.list().each() { note -&gt;
                entry(&quot;weekNr : ${note.weekNr}&quot;) {
                    link = &quot;${grailsApplication.config.grails.serverURL}/meetingNotes/show/${note.id}&quot;
                    &quot;Meeting notes for week number ${note.weekNr} by ${note.user.userRealName}&quot; // return the content
                }
            }
        }
    }
</pre>
<p>The code is so easy I hardly need to explain anything. One thing that had a problem at the moment is hard wiring the name of the server to get the feed from. The only trick I want to point out is the way to construct the link (line 4 and 8). We use the special mechanism to read parameters from the config that can be environment specific. The <em>grails.serverURL parameter</em> is by default configured in the Config.groovy configuration file.</p>
<p>In safari I now have the following result.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-01-10-at-12.00.01.png" alt="Screen shot 2010-01-10 at 12.00.01.png" border="0" width="500" height="426" /></div>
<p>That is it for this post. I am still amazed by how easy things are using grails. Most of the time I spend on getting the ui done. In the next post I will not introduce new plugin, but I will focus on getting the solutions better. Add validation, better configured access control, internationalization. Those kind of topics.</p>
<p>Hope to see you back.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F01%2F10%2Fstill-doing-grails%2F&amp;title=Still%20doing%20grails&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/01/10/still-doing-grails/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Continuing with grails</title>
		<link>http://www.gridshore.nl/2010/01/04/continuing-with-grails/</link>
		<comments>http://www.gridshore.nl/2010/01/04/continuing-with-grails/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 16:26:00 +0000</pubDate>
		<dc:creator>jettro</dc:creator>
				<category><![CDATA[groovy and grails]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[grails]]></category>

		<guid isPermaLink="false">http://www.gridshore.nl/?p=975</guid>
		<description><![CDATA[<p> <p>In my previous post Starting with grails, I wrote a long story about creating a new application with grails. I introduced some plugins and gave some hints and tips about working with grails from a starter perspective. As I move on, I will write down other things I have done.</p> <p>Some of the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.gridshore.nl/wp-content/uploads/F0720E8F-2336-4FEE-BB96-7F8FA9B9FD9C.jpg" alt="F0720E8F-2336-4FEE-BB96-7F8FA9B9FD9C.jpg" border="0" width="134" height="117" align="right" />
<p>In my previous post <a href="http://www.gridshore.nl/2009/12/20/starting-with-grails/">Starting with grails</a>, I wrote a long story about creating a new application with grails. I introduced some plugins and gave some hints and tips about working with grails from a starter perspective. As I move on, I will write down other things I have done.</p>
<p>Some of the things you can find in this post are:</p>
<ul>
<li>Using <a href="http://developer.yahoo.com/yui/grids/">yahoo ui grid</a> for laying out the page</li>
<li>Creating a second navigation menu</li>
<li>Mail integration for the contact form</li>
<li>Implement access control, so only known users can use the application.</li>
</ul>
<p><span id="more-975"></span><br />
<h2>Yahoo Grid</h2>
<p>Laying out a page is not easy. Especially not when you want to facilitate resizing of all browsers. Why would you want to develop stylesheets yourself if you can get a good one for free. I decided to use yahoo grids to layout the base components of my pages. It fits very well with sitemesh and of course grails.</p>
<p>If you want to learn more about what yahoo grid is, check the following page. I personally like the <a href="http://yuiblog.com/assets/pdf/cheatsheets/css.pdf">cheatsheet</a> they provided a lot.</p>
<p>Yahoo grids is all about stylesheets, you can link to the stylesheets located at yahoo servers. To do that add the following line to the main template. You can find the main template in grails-app/views/layouts/main.gsp</p>
<pre>
&lt;link rel="stylesheet" type="text/css" href="http://yui.yahooapis.com/2.8.0r4/build/reset-fonts-grids/reset-fonts-grids.css/"&gt;
</pre>
<p>Than you need to think about the layout of your page. I want a page that uses the maximum space. In the header I want a logo and the navigation. The body consists of two columns, one for the main content and the other for messages, special actions using ajax controls, and other things I can think of.</p>
<p>The main layout items are in the maain.gsp that I mentioned before. The body element is split into two elements, one for the actual content using the sitemesh g:layoutBody. The other contains the flash message and flash error message. For these classes I included some styling in the web-app/css/main.css.</p>
<h2>Adding a second menu</h2>
<p>I also want a menu with items like about and contact. So we go back to the navigation plugin. Now I have create a new menu group called sitemenu. For now there are two controllers adding items to this menu, the Contact and About controller. Now we need to change the style of this menu, we make it float right and change some of the styling. To do this, we add the following lines to the main.css mentioned earlier.</p>
<pre class="brush: css; title: ; notranslate">
#sitemenu .navigation li a { background-color: #fff }
#sitemenu .navigation li.navigation_active a { background-color: #fff; color:#555; text-decoration:underline}
#sitemenu .navigation li.navigation_active a:hover { background-color: #fff;}
#sitemenu .navigation li a:hover { background-color: #999; }
#sitemenu .navigation li a { color: #555; }
#sitemenu .navigation li a:hover { color: #555; text-decoration:underline}
#sitemenu .navigation li { border: 1px solid #fff; background-color: #fff }
</pre>
<p>The next code block shows the changed main.gsp, for now only the part containing the header</p>
<pre class="brush: xml; title: ; notranslate">
&lt;div id=&quot;doc3&quot;&gt;
  &lt;div id=&quot;hd&quot;&gt;
    &lt;div id=&quot;sitemenu&quot;&gt;
      &lt;nav:render group=&quot;sitemenu&quot;/&gt;
    &lt;/div&gt;
    &lt;div id=&quot;grailsLogo&quot; class=&quot;logo&quot;&gt;&lt;a href=&quot;http://grails.org&quot;&gt;&lt;img src=&quot;${resource(dir: 'images', file: 'grails_logo.png')}&quot; alt=&quot;Grails&quot; border=&quot;0&quot;/&gt;&lt;/a&gt;&lt;/div&gt;
    &lt;div id=&quot;menu&quot;&gt;
      &lt;nav:render group=&quot;tabs&quot;/&gt;
      &lt;nav:renderSubItems group=&quot;tabs&quot;/&gt;
    &lt;/div&gt;
  &lt;/div&gt;
  &lt;div id=&quot;bd&quot;&gt;
  &lt;/div&gt;
  &lt;div id=&quot;ft&quot;&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>That is step one in creating a better looking application. The following screendump gives you an idea where we are right now.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2009-12-25-at-11.38.06.png" alt="Screen shot 2009-12-25 at 11.38.06.png" border="0" width="869" height="662" /></div>
<p>Next up is the create scheduling items screen.</p>
<h2>Improving form layout of create scheduling items screen</h2>
<p>Let me state up front, this is not easy. I am not the king in stylesheets, so don&#8217;t take this as the best example. I had a hard time limiting the length of the autocomplete boxes. I ended up limiting the div surrounding the input box. For the date picker I had a simular problem. By default position elements left and top are not zero. Also a padding is not nice in this form. Therefore I added a style block into the html. Not ideal, you would want to have this in a central place, but I do not know how to do this. If someone has suggestions, please place a comment to this post.</p>
<p>The following screendump shows what it looks like right now with one of the date pickers popped open.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2009-12-25-at-12.25.14.png" alt="Screen shot 2009-12-25 at 12.25.14.png" border="0" width="870" height="771" /></div>
<h2>Adding logo</h2>
<p>The grails logo is nice, but not what you want to have in your application. Changing it is very easy. Just open the main.gsp in the views/layout folder. Create a logo and probably a favicon.ico and put them in the web-app/images folder. Find the link in the header of the template with the shortcut icon. If you named the ico file the same you do not have to change a thing. For the logo you need to find the div with the id grailslogo. See how the function resources is used to create the src of the img tag.</p>
<p>If you do not know how to create an ico file, check this website: <a href="http://www.favicon.cc/">favicon.cc</a></p>
<h2>Mail integration</h2>
<p>The contact form can be used to send a mail to responsible users of the system. To be able to send the mail, we are going to use the mail plugin. Installing it is easy with the command:</p>
<pre>
grails install-plugin mail
</pre>
<p>Configuration of the plugin is done in the Config.groovy. You can set the mail.host and the default.from properties. The mail service is injected in the Controllers and can be injected in the services by declaring a mailService property. You can send messages inline by providing a closure with the properties. Another mechanism is by using a template or a view. When sending the mail from a service you do not have the current request. Then you can still use the views, do provide the absolute paths if you use the service to generate the mail. It is also possible to take the template from a plugin, check the <a href="http://www.grails.org/plugin/mail">page of the mail plugin</a>.</p>
<p>In my example I am using the controller to send a mail and the template for an html mail. I also use a trick with system properties to prevent my password to be send to GIT. Let us focus on the configuration first. The following code block shows the configuration of mail using a gmail account. Check the System.getProperty usage for obtaining the userid and the password</p>
<pre class="brush: groovy; title: ; notranslate">
grails {
    mail {
        host = &quot;smtp.gmail.com&quot;
        port = 465
        username = System.getProperty(&quot;gmail.userid&quot;) + &quot;@gmail.com&quot;
        password = System.getProperty(&quot;gmail.password&quot;)
        props = [&quot;mail.smtp.auth&quot;:&quot;true&quot;,
                 &quot;mail.smtp.socketFactory.port&quot;:&quot;465&quot;,
                 &quot;mail.smtp.socketFactory.class&quot;:&quot;javax.net.ssl.SSLSocketFactory&quot;,
                 &quot;mail.smtp.socketFactory.fallback&quot;:&quot;false&quot;]
    }
}
</pre>
<p>In the contact/index.gsp I created a form with a few fields. The submit is send to the mail method of the ContactController. Like I said, the mailService is available to all controllers. The following code block shows how to send the mail.</p>
<pre class="brush: groovy; title: ; notranslate">
    def mail = {
        if (params.yourname) {
            sendMail {
                to &quot;jettro@gridshore.nl&quot;
                subject &quot;Contact Form&quot;
                html g.render(template: &quot;contactMailTemplate&quot;,
                        model:[remark:params.remark,yourname:params.yourname,yourmail:params.yourmail])
            }
            flash.message = &quot;Thank you for your remark, will get back to you if desired!&quot;
        } else {
            flash.error = &quot;Could not send a message, no name!&quot;
        }
        redirect (controller:&quot;contact&quot;)
    }
</pre>
<p>Check the way to make an html mail using a template and model parameters. More examples are available at the plugins page. We use a template to generate the mail. Easy stuff or not? Remember from that grails introduction that you need to prepend a template with an &#8220;_&#8221;, so we create contact/_contactMailTemplate.gsp. The following code block shows this file.</p>
<pre class="brush: xml; title: ; notranslate">
&lt;%@ page contentType=&quot;text/html&quot; %&gt;
&lt;html&gt;
&lt;head&gt;
  &lt;title&gt;Welcome Aboard&lt;/title&gt;
  &lt;style type=&quot;text/css&quot;&gt;
  body {
    font-family: &quot;Trebuchet MS&quot;
  }
  &lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;h1&gt;Howdy!&lt;/h1&gt;
&lt;p&gt;
  We have a remark from : &lt;strong&gt;${yourname}&lt;/strong&gt; with &lt;strong&gt;${yourmail}&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
  ${remark}
&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>Of course this is not the end of the line, we need to add form validation, maybe a better confirmation screen. You name it, but that is not making the mail integration harder. It will be the same.</p>
<h2>Access control</h2>
<p>There are multiple plugins to do authentication/authorization or access control. I have a history with the spring security project, therefore I will use the <a href="http://grails.org/plugin/acegi">acegi or spring security plugin</a>. I do have to warn you that this is not the easiest plugin available. But security is not easy. The plugin comes with some nice shortcuts to create the required classes. I am not going to be very thorough in my description of the plugin, since it is still kind of a beginners blog post.</p>
<p>Some things you should know about the security plugin:</p>
<ul>
<li>You can use a map, spring xml configurtation as well as annotations to configure security</li>
<li>You need three domain classes: User, Role and RequestMap</li>
<li>You can secure url patterns using the admin screens of your application.</li>
</ul>
<p>Now let us start securing our application. First install the plugin. Then we generate the domain classes.</p>
<pre>
grails install-plugin acegi
grails create-auth-domains nl.gridshore.scheduling.User nl.gridshore.scheduling.Role nl.gridshore.scheduling.Requestmap
</pre>
<p>Now we start the application and nothing really changed since we have not secured anything yet. Next up is securing the creating of new Persons. This should only be possible by a user with admin rights. For now we are going to create three roles, the viewer, the admin and the sysadmin.</p>
<p>To be able to add roles, we need to add the Role controller. We also need the Requestmap controller. We already had the user controller.</p>
<p>Now you can use the following urls to add roles and Requestmap items. I have added some code to the bootstrap class. I did have a problem with the Requestmap items, they were not updated. I had to restart the container to make them actually work. During development you cannot recreate the database each time without loosing the items. Therefore you really need the Bootstrapper. The following lines of code create the roles as well as the Requestmap items.</p>
<pre class="brush: groovy; title: ; notranslate">
def roleAdmin = new Role(authority:&quot;ROLE_ADMIN&quot;,description:&quot;admin&quot;)
roleAdmin.save()
def roleSysAdmin = new Role(authority:&quot;ROLE_SYSADMIN&quot;,description:&quot;sysadmin&quot;)
roleSysAdmin.save()

def securePerson = new Requestmap(url:&quot;/person/**&quot;,configAttribute:&quot;ROLE_ADMIN&quot;)
securePerson.save()
def secureProject = new Requestmap(url:&quot;/project/**&quot;,configAttribute:&quot;ROLE_ADMIN&quot;)
secureProject.save()
</pre>
<p>When adding a new user I came to the conclusion that the defautl scaffolding screens do not work appropriately. Therefore I create the screens and controller of the User and other security related classes using the special script.</p>
<pre>
grails generate-manager
</pre>
<p>Now everything works fine, I removed the navigation from the generated screens and the create user screen looks like the following image. Check the way the roles can be added to a user. Good stuff. My final steps are creating an admin user and a sysadmin user and securing the user, requestmap and role screens as well. That is all pretty straightforward.</p>
<div style="text-align:center;"><img src="http://www.gridshore.nl/wp-content/uploads/Screen-shot-2010-01-04-at-17.19.01.png" alt="Screen shot 2010-01-04 at 17.19.01.png" border="0" width="860" height="714" /></div>
<h2>Final remarks</h2>
<p>We covered some big topics. Made the application look better. Implemented security using the spring security plugin. We also made a contact form using the mail plugin. In the next blogpost I will write about the search plugin and some optimizations to the current code base and maybe google charts.</p>
<p>If you have comments, tips, improvements feel free to contact me.</p>
<div class='dd_post_share'><div class='dd_buttons'><div class='dd_button'><iframe src='http://widgets.dzone.com/links/widgets/zoneit.html?url=http%3A%2F%2Fwww.gridshore.nl%2F2010%2F01%2F04%2Fcontinuing-with-grails%2F&amp;title=Continuing%20with%20grails&amp;t=2' height='25' width='155' frameborder='0' scrolling='no'></iframe></div></div><div style='clear:both'></div></div><!-- Social Buttons Generated by Digg Digg plugin v4.5.3.4, 
    Author : Yong Mook Kim
    Website : http://www.diggdigg2u.com -->]]></content:encoded>
			<wfw:commentRss>http://www.gridshore.nl/2010/01/04/continuing-with-grails/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

