alexcuesta

My tech blog

Archive for the ‘Groovy/Grails’ Category

Handling form errors on Grails

leave a comment »

I have not found clear information about how to deal with form errors on Grails so I made my own investigation.

How to deal with form field errors

We need to bear in mind that each field might have more than one error.

E.g.: Imagine a age field and we enter “abcde”. Having the right constraints, we’d display two error messages: “maximum 3 digits”, “only numbers please”.

In order to do this, Grails provide the following tags: renderErrors, hasErrors and eachError. This is well explained in the user guide.

How to print the list of messages using different formats

What if I don’t want to use the standard as=”list” which generates output?

This is an example of how to print error messages in a paragraph separated by<br/>

<g:hasErrors bean="${customer}" field="email">
      <p>
            <g:eachError bean="${customer}" field="email">
                  <g:message error="${it}" /><br/>
            </g:eachError>
      </p>
</g:hasErrors>

How to print global errors

I could not find a better way of doing this than through the standard Spring Errors interface:

Having a customer bean, in the controller:

customer.errors.reject("registration.data.access.error")
error()

And in the view:

<g:each var="error" in="${customer.errors.globalErrors}">
	<g:message error="${error}" />
</g:each>

Written by alexcuesta

February 22, 2011 at 3:51 pm

Posted in Groovy/Grails

Grails 1.3.6 & JNDI on Tomcat

with 3 comments

We’ve been struggling for a couple of days to configure grails to pick up JNDI resources using the embedded tomcat plugin (run-app). After some googling I found an article which solved my problem. At least for now. You will find the link to the article at the end of this post. For completeness, I’ve added a few comments in this blog post + the steps for how to get this working.

Before we start. Some notes about Tomcat and JNDI.

Tomcat support a number of different JNDI resource types (normally configured in Tomcat’s context xml file).

These are:

<Environment>
<Resource>
<ResourceLink>
<Transaction>

On a side note, also Jetty support at least the first three resource types but additional configuration is needed which is beyond the scope of this post.

The <Environment> type is mainly used to configure environmental properties within an application while <Resource> and <ResourceLink> types link to external resources such as JDBC, JMS or LDAP. I won’t elaborate on <Transaction> since I’m unfamiliar with this type.

When it comes to configuring the embedded tomcat plugin (1.2-M2) with JNDI it took a little while to get this right.

If you are only using <Resource> types you won’t have any problems \:) The problem you will encounter is with applications using the <Environment> type. As of version 1.2-M2 the tomcat plugin doesn’t support <Environment> JNDI types. On the other hand, the Jetty plugin support both of them. The very quick solution is to switch to Jetty obviously. Hopefully next version of the tomcat plugin will have better JNDI support. In the meantime we have to fall back on the following hack.

There is an easy way to get the Tomcat plugin to accept other types of JNDI resources and this is what the following article is about [http://6by9.wordpress.com/2010/12/10/grails-1-3-5-tomcat-plugin-and-jndi-environment-variables/]

I’ve also provided the steps here but please read the article before following the steps below.

Do the following:

  • Locate the following file TomcatServer.groovy. Mine was located under:C:\Documents and Settings\alejandro.cuesta\.grails\1.3.6\projects\trace\plugins\tomcat-1.3.6\src\groovy\org\grails\tomcat
  • Replace the private preStart() method with the following methods

private preStart() {
  eventListener?.event("ConfigureTomcat", [tomcat])
  def jndiEntries = grailsConfig?.grails?.naming?.entries

  if(jndiEntries instanceof Map) {
    def envs = jndiEntries.remove('environments')
    if (envs instanceof Map) {
      envs.each { name, cfg ->
        if (cfg) {
          addEnvironment(name, cfg)
        }
      }
    }
    def ress = jndiEntries.remove('resources')
    if (ress instanceof Map) {
      ress.each { name, cfg ->
        if (cfg) {
          addResource(name, cfg)
        }
      }
    }
    jndiEntries.each { name, cfg ->
      if(cfg) {
        addResource(name, cfg)
      }
    }
  }
}

private addEnvironment(name, envCfg) {
  if (!envCfg["type"]) {
    throw new IllegalArgumentException("Must supply a environment type for JNDI configuration")
  }
  def env = loadInstance('org.apache.catalina.deploy.ContextEnvironment')
  env.name = name
  env.type = envCfg.type
  env.description = envCfg.description
  env.override = envCfg.override as boolean
  env.value = envCfg.value

  context.namingResources.addEnvironment env
}

private addResource(name, resCfg) {
  if (!resCfg["type"]) {
    throw new IllegalArgumentException("Must supply a resource type for JNDI configuration")
  }
  def res = loadInstance('org.apache.catalina.deploy.ContextResource')
  res.name = name
  res.auth = resCfg.remove("auth")
  res.scope = resCfg.remove("scope")
  res.type = resCfg.remove("type")
  res.description = resCfg.remove("description")
  // now it's only the custom properties left in the Map...
  resCfg.each {key, value ->
    res.setProperty (key, value)
  }

  context.namingResources.addResource res
}
  • The tomcat plugin has now been configured to also read environment resource types
  • You should now be able to define your resources in Config.groovy. Such as
grails.naming.entries = [

  "resources" : [

    "jms/bananas": [
      type: "org.apache.activemq.command.ActiveMQTopic",
      description: "Fruit salad",
      factory: "org.apache.activemq.jndi.JNDIReferenceFactory",
      physicalName: "bananas"
    ]
  ],

  "environments" : [
    "/app/config/db.mysql.username": [
      type: "java.lang.String",
      value: "MYUSERNAME",
      override: "true"
    ],

    "/app/config/db.mysql.password": [
      type: "java.lang.String",
      value: "MYPASSWORD",
      override: "true"
    ]
  ]

]

Written by alexcuesta

February 12, 2011 at 6:54 pm

Posted in Groovy/Grails

Using snapshots stored in your maven repository with Grails

leave a comment »

In my current project, we are developing a core domain library to be shared across different web applications of different companies. We are also developing the new website of one of those companies in Grails. Therefore, we need to declare a Grails dependency on the core domain library which is stored on a Maven repository.

Grails, by default, uses Ant to build the project and Ivy to resolve dependencies. Using maven as a repository is very easy: you only need to declare it on the “BuildConfig.groovy” file.

The problem is that this simple approach does not pick up changes on snapshots. The way I solved this was using “useOrigin true” in the same file.

Here you have the BuildConfig.groovy file:

grails.project.dependency.resolution = {

	useOrigin true

	...

	repositories {
		...
        mavenLocal()
        mavenCentral()
		...
	}
	...
}

Written by alexcuesta

January 26, 2011 at 5:06 pm

Posted in Groovy/Grails

Gradle on Grails

with 10 comments

I am taking my first steps on grails on a real project after playing around with it for a while.

The first problem I came across was: how to deal with dependencies? In my project, we have some dependencies on libraries stored in our internal maven repository.

You have three options here:

  1. Use Ivy which comes out-of-the-box in Grails. Ivy is just a dependency manager for ant. I have never used it and looks old-fashioned,  so I went to the next step.
  2. Mavenize your project.
  3. Use gradle, which is the latest cool builder. A mix of Ant and Maven with the power of the Groovy language.

As I said, I ignored Ivy.

My first successful attempt was Maven. It is quite easy following the steps in the documentation.

Anyway, I really wanted to use Gradle because it looks really easy to read, so I gave it a go. My starting point was this article by Peter Ledbrook but it was confusing because the build script contains errors. So after reading the comments, I went to the grails-gradle-plugin project instead.

After a couple of hours, I ended up with this solution:

  1. Create an empty folder for your project
  2. Go to root of your new project folder and store the build.gradle script  below.
  3. Run ‘gradle init’ to create the grails layout
  4. Use the normal grails commands using the “grails-” prefix.
    $ gradle grails-run-app

This is the build.gradle script

buildscript {
    repositories {
        mavenCentral()
        mavenRepo urls: "http://repository.jboss.org/maven2/"
    }

    dependencies {
        classpath "org.grails:grails-gradle-plugin:1.0",
                      "org.grails:grails-bootstrap:1.3.6"
    }
}

apply plugin: "grails"

version = '1.0-SNAPSHOT'

// this is your local maven repository
def localMavenRepository = new File( System.getProperty("user.home" ), ".m2/repository" ).toURL().toString()

repositories {
    mavenCentral()
    mavenRepo urls: "http://repository.jboss.org/maven2/"
	mavenRepo urls: "http://download.java.net/maven/2/"
	mavenRepo name:'localMavenRepo', urls: localMavenRepository
}

configurations {
    compile.exclude module: "xml-apis"
}

dependencies {
    compile "org.grails:grails-crud:1.3.6",
               "org.grails:grails-gorm:1.3.6"

    runtime "org.slf4j:slf4j-log4j12:1.5.5",
	      "hsqldb:hsqldb:1.8.0.5",
	      "jstl:jstl:1.1.2"

}

You may need to add or remove dependencies. This depends on your project.

Hope this saves you some time.

UPDATE 4 JAN 2011

The example above was done using gradle 0.9. The new version 0.9.1 supports mavenLocal() so you can remove the localMavenRepository definition and replace the last mavenRepo with mavenLocal()

Written by alexcuesta

December 21, 2010 at 2:27 pm

Posted in Groovy/Grails

Groovy & Grails eXchange 2010

leave a comment »

I’ve just come from the Groovy & Grails eXchange 2010. I am not an expert on Groovy or Grails but I must admit that I have learned lots of things and I can’t wait to start using this technology on my next project.

My highlights of these two days of talks:

  • I really loved Tomas Lin‘s talk about Geb. This is just a web testing framework based on Spock using a groovy DSL based on the JQuery language. In other words, bye bye WebDriver’s findElementBy and welcome JQuery selectors. It uses the Page Object pattern so tests are organized better. This also comes as a Grails plugin.
  • I loved the talk by the guys from Sky.com who developed the whole site in Grails after comparing the productivity between two teams implementing the same features in two weeks. Groovy represents 95% of their code whereas 5% is Java. They test absolutely everything: unit testing and lots of functional testing to guarantee releases every week. They even test deployments!
  • Gradle is becoming the next building tool. I really like it. It seems to be easy to use because it is just a combination of Ant and Maven with the power of Groovy.
  • From Graeme Rocher‘s keynote:
    • DB reverse engineering to create domain classes from a database schema.
    • Database migration
    • New GORM implementations for nosql databases: mongodb, redis, gemfire…
    • A demo of Spring insight, a tc server profiling tool. Very cool but JavaMelody looks better and independent from tc Server.
  • From Laforge’s keynote I liked:
  • Plugins for almost everything!

Written by alexcuesta

December 17, 2010 at 8:48 pm

Posted in Groovy/Grails