Archive for December, 2010

Customizing GORM with a Configuration Subclass

Tuesday, December 28th, 2010

GORM mappings let you configure pretty much anything you need in your Grails applications, but occasionally there are more obscure tweaks that aren’t directly supported, and in this case a custom Configuration class is often the solution.

By default Grails uses an instance of GrailsAnnotationConfiguration and the standard approach is to subclass that to retain its functionality and override the secondPassCompile() method.

As an example, let’s look at what is required to specify the foreign key name between two related domain classes. This is inspired by this mailing list question but is also a personal pet peeve since I always name foreign keys in traditional Hibernate apps (using annotations or hbm.xml files). FK_USER_COUNTRY is a lot more useful than FK183C3385A9B72.

One restriction is that you need to code the class in Java – a Groovy class won’t compile due to method visibility issues.

Create this class (with an appropriate name and package for your application) in src/java:

package com.yourcompany.yourapp;

import java.util.Collection;
import java.util.Iterator;

import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.MappingException;
import org.hibernate.mapping.ForeignKey;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.RootClass;

public class MyConfiguration extends GrailsAnnotationConfiguration {

   private static final long serialVersionUID = 1;

   private boolean _alreadyProcessed;

   @SuppressWarnings({"unchecked", "rawtypes"})
   @Override
   protected void secondPassCompile() throws MappingException {
      super.secondPassCompile();

      if (_alreadyProcessed) {
         return;
      }

      for (PersistentClass pc : (Collection<PersistentClass>)classes.values()) {
         if (pc instanceof RootClass) {
            RootClass root = (RootClass)pc;
            if ("com.yourcompany.yourapp.User".equals(root.getClassName())) {
               for (Iterator iter = root.getTable().getForeignKeyIterator();
                       iter.hasNext();) {
                  ForeignKey fk = (ForeignKey)iter.next();
                  fk.setName("FK_USER_COUNTRY");
               }
            }
         }
      }

      _alreadyProcessed = true;
   }
}

This is a very simplistic example and everything is hard-coded. A real example would check that the foreign key exists, that it’s the correct one, etc., or might be more sophisticated and automatically rename all foreign keys using the FK_ prefix and using the table names of the two related tables.

This won’t be automatically used, but you just need to set the configClass property in grails-app/conf/DataSource.groovy:

dataSource {
   pooled = true
   driverClassName = '...'
   username = '...'
   password = '...'
   configClass = 'com.yourcompany.yourapp.MyConfiguration'
}

For other examples of using this approach, see these posts in the Nabble archive:

This Week in Grails (2010-51)

Saturday, December 25th, 2010

Update: Check out the traducción al español

Update #2: Check out the Portugese translation

Update #3: Check out the Chinese translation: Grails每周观察

Happy (belated) Festivus to you all.

A few notes first. I missed an item last week, Peter Ledbrook’s writeup of the cool stuff he’s working on at beta.grails.org. Also, if you want to keep up with these “This Week in Grails” posts you can access them directly via their category link or in an RSS reader with the feed for just these posts.

Miscellaneous Items

Plugins

There were 8 new plugins released:

There were also several updated plugins:

  • ajaxflow version 0.1.10. Enables Ajaxified Webflows
  • cache-headers version 1.1.3. Improve application performance with browser caching
  • chargify version 1.0. Integration with http://chargify.com/
  • greenmail version 1.2.2. Support for email testing with GreenMail
  • grom version 0.2.1. Sends notifications on Windows, Linux, and Mac
  • jquery-validation-ui version 1.0.1. Client Side Validation without writing JavaScript
  • maven-publisher version 0.7.4. Publish Grails projects and plugins to local and remote Maven repositories
  • multi-tenant-spring-security version 0.2.0. Integrates the multi-tenant plugin with the spring-security-core plugin
  • ofchart version 0.6.2. Open Flash Chart Plugin
  • resources version 1.0-RC1b. Improved handling for static resources (JS, CSS, images, etc.)
  • routing version 1.1.0. Integration with Camel
  • routing-jms version 1.1.0. JMS/ActiveMQ support for the routing plugin
  • springcache version 1.3. Caches Spring bean methods and page fragments generated by Grails controllers
  • zk version 1.0.1. Adds ZK Ajax framework (www.zkoss.org) support to Grails applications
  • zk-ee version 1.0.1. Enterprise Addons for the ZK plugin

Interesting Tweets

Jobs

Using the H2 Database Console in Grails

Sunday, December 19th, 2010

We’ve switched the in-memory development database in Grails from HSQLDB to H2 for 1.4 and one of the cool features this provides is a web-based database console. It’s available as a standalone app runnable from the commandline, but it’s also easy to wire up in web.xml so it runs in-process.

Most of the time you’ll probably use it to access data in your development environment, but the console is not limited to H2 databases – it will work with any database that you have a JDBC driver for.

This is already implemented in 1.4; by default in development you can access it by opening http://localhost:8080/appname/dbconsole. The URL is configurable and you can enable or disable it per-environment. But there are only a couple of steps required to enable this in pre-1.4 applications.

Required changes

You’ll need the H2 JDBC driver and the best way to get that is with BuildConfig.groovy. Add a dependency for H2 in the dependencies block and enable the Maven central repo by adding mavenCentral() to the repositories block:

grails.project.class.dir = 'target/classes'
grails.project.test.class.dir = 'target/test-classes'
grails.project.test.reports.dir = 'target/test-reports'

grails.project.dependency.resolution = {

   inherits 'global'

   log 'warn'

   repositories {
      grailsPlugins()
      grailsHome()
      grailsCentral()

      mavenCentral()
   }

   dependencies {
      runtime('com.h2database:h2:1.3.146') {
         transitive = false
      }
   }
}

You’ll also need to edit web.xml to register the servlet. If you haven’t already, run

grails install-templates

and edit src/templates/war/web.xml and add this servlet and servlet-mapping:

<servlet>
   <servlet-name>H2Console</servlet-name>
   <servlet-class>org.h2.server.web.WebServlet</servlet-class>
   <load-on-startup>1</load-on-startup>
   <init-param>
      <param-name>-webAllowOthers</param-name>
      <param-value>true</param-value>
   </init-param>
</servlet>

<servlet-mapping>
   <servlet-name>H2Console</servlet-name>
   <url-pattern>/dbconsole/*</url-pattern>
</servlet-mapping>

Use whatever url-pattern you want, e.g. you might want to change it to <url-pattern>/admin/dbconsole/*</url-pattern> to make it easier to secure with a wildcard rule saying that /admin/** requires ROLE_ADMIN.

Alternate approach

One downside to this approach is that there’s no way to disable the console per-environment since you’re hard-coding the change in web.xml. So be sure to guard access to this URL, e.g. with a security plugin. As an alternative, you can insert the servlet and servlet-mapping tags into web.xml programmatically.

To do this, create (or edit if you already have one) scripts/_Events.groovy and add this:

import grails.util.Environment

eventWebXmlEnd = { String filename ->

   if (Environment.current != Environment.DEVELOPMENT) {
      return
   }

   String consoleServlet = '''

   <servlet>
      <servlet-name>H2Console</servlet-name>
      <servlet-class>org.h2.server.web.WebServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
      <init-param>
         <param-name>-webAllowOthers</param-name>
         <param-value>true</param-value>
      </init-param>
   </servlet>'''

   String consoleServletMapping = '''

   <servlet-mapping>
      <servlet-name>H2Console</servlet-name>
      <url-pattern>/dbconsole/*</url-pattern>
   </servlet-mapping>'''

   def insertAfterTag = { String original, String endTag, String addition ->
      int index = original.indexOf(endTag)
      original.substring(0, index + endTag.length()) +
            addition + original.substring(index + endTag.length())
   }

   String xml = webXmlFile.text
   xml = insertAfterTag(xml, '</servlet>', consoleServlet)
   xml = insertAfterTag(xml, '</servlet-mapping>', consoleServletMapping)

   webXmlFile.withWriter { it.write xml }
}

This checks if the environment is development and adds the tags at the correct location, then rewrites the file with the updates.

If you go with this approach, there’s no need to make any changes in the web.xml template since you’ll be making all of your changes programmatically.

This Week in Grails (2010-50)

Friday, December 17th, 2010

Update: Check out the traducción al español

Update #2: Check out the Chinese translation: Grails每周观察

Last week’s post was rather popular so I’ll try to make this a regular thing. To re-cap, this series of posts will contain Grails and Groovy related items that I come across each week and want to bring more attention to.

Groovy & Grails Exchange

The big item of the week was the 2010 Groovy & Grails Exchange at Skills Matter in London. I went last year and it was a blast. They were uploading videos of talks shortly after the speakers finished, so you can view them online now – go to the conference page and click on the ‘View the podcast here…’ links. You can also check out the Flickr photostream

They’ve already announced the 2011 conference too – only £75 until January 31st.

Miscellaneous Items

  • Grails 1.3.6 release

    • We released v1.3.6 of Grails this week. Lots of fixes and enhancements (over 100 issues closed). You’ll also notice that the distribution downloads a lot faster now that we’re using Amazon S3
  • Groovy 1.7.6 and 1.8-beta-3 releases

    • Groovy 1.7.6 and Beta 3 of 1.8 were released. We’ll be using 1.8 in Grails 1.4 so it’ll be cool to have the new features and performance enhancements available for Grails apps.
  • GR8 Conference Europe 2011

    • GR8 Conference 2011 has been announced and will be May 17th-19th in Copenhagen.
  • http://hashable.com/

  • STS/Insight Screencast

    • Check out this screencast showing how to use Insight with STS to see performance and profiling information for a Grails application
  • inconsequential NoSQL project

    • The inconsequential project has added a lot of new providers and subprojects since the last time I checked it out
  • More large-scale Grails usage

    • I wish I could talk about this email from one of our sales managers: “we met with a team that is looking to re-write hundreds of internal applications in Grails”. Great to see Grails being used by big companies.
  • GSP tag autocompletion

    • STS will be smarter about providing taglib autocompletion and usage information in v2.5.2 (out soon) if developers add javadoc information – all of the Grails tags have been updated, and plugin developers should do the same
  • Can you make a large application with Groovy and Grails?

    • Yes you can :)
  • Updated reference doc search widget

    • I just noticed that the search widget at http://grails.org/doc/latest/ now auto-hides. That’s convenient since before it would obscure in-document searches when using CTRL-F.

I forgot to mention an item last week, the new Google Groups discussion list Grails Startup Support Group created by Warner Onstine. Lots of information for developers working on (or interested in working on) a Grails-based startup.

Plugins

There were 5 new plugins released:

  • local-storage version 0.1. Provides a simple tag-based wrapper around the HTML5 local storage mechanism.
  • riak version 1.0.0.M1. GORM for the Riak NoSQL datastore
  • routing version 1.0.1. Replacement for the abandoned Camel plugin
  • routing-jms version 1.0.1. ActiveMQ JMS support for the routing plugin
  • elasticsearch version 0.13.0-a. Adds support for the http://www.elasticsearch.com/ RESTful search engine

In addition there were three new plugins released that aren’t (yet) available using the standard install-plugin mechanism:

There were also several updated plugins:

  • blueprint version 1.0.1. Provides Blueprint CSS framework resource files and tags
  • dojo version 1.4.3.5. Adds the Dojo javascript toolkit
  • geb version 0.5.1. The functional testing plugin that all the cool kids are using
  • infinispan version 0.3.7. Adds support for the JBoss Infinispan distributed cache
  • jquery version 1.4.4. jQuery javascript toolkit
  • jquery-ui version 1.8.7. jQuery javascript toolkit UI widgets and tools
  • multi-tenant-ehcache version 1.0.1. Ehcache Support for the Multi Tenant plugin
  • rendering version 0.4. Render GSPs as PDFs, JPEGs, GIFs and PNGs
  • resources version 1.0-RC1. Static resource handling
  • spock version 0.5. The unit testing framework that all the cool kids are using
  • ulc version 0.3.2. Provides access to the Canoo UltraLightClient (ULC) RIA kit
  • weceem version 1.0-M1. Grails-based content management system (CMS)
  • zipped-resources version 1.0-RC1. GZips javascript and CSS

Interesting Tweets

Jobs

Stuff I’m working on

Now that 1.3.6 is finished I’ve started merging the Datasources plugin into Grails core for 1.4. It’s mostly finished except for a few more tests and documentation. I’m looking into adding JTA and 2PC support but that might have to wait until 2.0.

I had almost finished the Database Migrations plugin before switching gears to work on 1.3.6 fixes, so that should hopefully be finished this week.

If you’re interested in using closed-source plugins using compiled classes then you should check out the Binary Artifacts plugin I released this week (blog post here). I’m curious about how people might use it and of course am interested in suggestions for enhancements, so let me know if you’re using it.

Grails Binary Artifacts Plugin

Monday, December 13th, 2010

Last week at the Boston Grails Meetup we were talking about the state of Grails plugins (the plugin collective, certified plugins, etc.) and the idea of binary plugins came up. This has been discussed as a way to deploy closed-source plugins – with the current approach the plugin zip file contains all of the source code and the plugin descriptor, and there’s no way to use compiled classes as controllers, services, etc. I suppose it’s because of the work I did with the Dynamic Controller plugin (used by the App Info plugin) and the dynamic domain class stuff that I worked on (which is used in the Dynamic Domain Class plugin) but this stuck in my head and I ended up spending most of last weekend working on a plugin for this and finished it up this weekend.

The approach I took is to write a plugin (binary-artifacts) that proxies your plugin(s) which contain compiled classes instead of source code. Grails has some fixed rules about what it means for a class to be an artifact of a specific type, so these needed to be worked around, but there really aren’t any hacks here. For example a service must be under the grails-app/services folder and the name must end in Service, and controllers, taglibs, filters, have similar rules. Domain classes have no name restrictions but must be under grails-app/domain.

Instead of using these conventions, artifacts are configured with a properties file which must be named <appname>-binaryartifacts.properties and be in the classpath (so it’s best to put it in grails-app/conf or src/java).

Plugin descriptor

The plugin descriptor is created by the create-plugin script and contains several plugin properties (version, grailsVersion, author, title, etc.) and six closures (all optional) that are called either at startup during a particular initialization phase (doWithWebDescriptor, doWithSpring, doWithDynamicMethods, and doWithApplicationContext) or when the configuration or a watched resource is modified in dev mode (onChange and onConfigChange).

When using binary artifacts you still specify the property values the traditional way and can implement any of the six closures inline, but you can instead register a plugin ‘stub’ that’s called at each phase. This is a Groovy class containing any or all of the six supported closures. It will be instantiated and each closure called with the appropriate delegate set, so you can put Spring bean creation, metaclass enhancements, etc. in a compiled Groovy class. Register the class name in the properties file using the stub key.

Be sure to register a dependency on this plugin in your plugin descriptor, e.g.

def dependsOn = ['binaryArtifacts': '1.0 > *']

Codecs

Codecs can be written in Groovy or Java and must follow the standard naming convention. Code them just like you do traditional codecs, but put the source under src/groovy or src/java and register the comma-delimited class names in the properties file using the codecs key.

Controllers

Controllers must be written in Groovy (since they’re implemented with Closures) and must follow the standard naming convention. Code them just like you do traditional controllers, but put the source under src/groovy and register the comma-delimited class names in the properties file using the controllers key.

Domain classes

Domain classes must be written in Groovy (to support the mapping and constraints closures). Code them just like you do traditional domain classes, but put the source under src/groovy and register the comma-delimited class names in the properties file using the domainClasses key.

Filters

Filters must be written in Groovy (since they’re implemented with Closures) but you can use whatever class names you want. Code them just like you do traditional filter classes, but put the source under src/groovy and register the comma-delimited class names in the properties file using the filters key.

Services

Services can be written in Groovy or Java (but if you’re doing database work with GORM classes it’ll be a lot more convenient to use Groovy) but you can use whatever class names you want. Code them just like you do traditional services, but put the source under src/groovy or src/java and register the comma-delimited class names in the properties file using the services key.

In addition you have flexibility with the Spring bean name that the service is registered under. Traditionally FooService is registered as fooService but using this plugin you can use whatever valid name you want. Register the class name and Spring bean name using the classname:beanname syntax in the properties file.

Taglibs

Taglibs must be written in Groovy (since they’re implemented with Closures) but you can use whatever class names you want. Code them just like you do traditional taglib classes, but put the source under src/groovy and register the comma-delimited class names in the properties file using the taglibs key.

Scripts

Scripts are still implemented as Gant scripts under the scripts folder, but you can delegate the execution of a target to a compiled class. Include the plugin’s _RunBinaryScript.groovy script and do whatever initialization you need (e.g. using depends()) and call runBinaryScript(classname). The specified class will be instantiated and must have a closure named executeClosure. The closure’s delegate will be configured from the calling script’s delegate and invoked.

GSPs

GSP support isn’t 100% complete since compiled GSPs aren’t supported in Grails in run-app. This means that you can either keep your GSPs under the grails-app/views folder and ship the source, or compile them (this is handled by the plugin) but then they’ll only work when deployed in a war.

Code them just like you do traditional GSPs, and put the source wherever you want. If you want them to work in run-app mode keep them under grails-app/views, but if you’re precompiling then you can put them elsewhere and configure the location using the com.burtbeckwith.binaryartifacts.gspFolder config option in Config.groovy

You don’t register individual GSPs in the properties file; instead the GSP precompilation script creates a properties file that is specified. The script will be named <appname>-gsp-views.properties and you specify that name under the gspPropertyFile.

package-binary-plugin

Instead of running package-plugin like with a traditional plugin, you must use package-binary-plugin instead. The script doesn't take any arguments, and it compiles your code (and GSPs if configured) and configures the required properties file, and zips the plugin in the same format as a tradtional plugin. If you unpack the zip file you'll notice that the compiled classes are kept in a jar file in the lib folder.

Configuration

There are only two configuration options that control plugin behavior and they're both for GSPs. Both are set in Config.groovy. The first is com.burtbeckwith.binaryartifacts.gspFolder and it allows you to override the default location of your GSPs (grails-app/views). The other is com.burtbeckwith.binaryartifacts.compileGsp which can be used to disable precompilation of GSPs (defaults to true).


You can download a sample plugin that demonstrates the process. It has two domain classes, two services (one in Groovy and one in Java), a codec (in Java, although Groovy works too), a controller and two GSPs, a filters class, and a script. The plugin stub registers a context and session listener in web.xml and adds a bark method to String's metaclass.

Package the plugin by calling grails package-binary-plugin (or use the included build.xml) and install it the usual way, e.g. grails install-plugin /path/to/grails-binary-artifacts-test-0.1.zip.

This Week in Grails

Friday, December 10th, 2010

Update: Check out the Chinese translation

I tend to see a lot of Grails and Groovy related items in my RSS reader, a couple of Twitter keyword searches, the Grails User mailing list, and miscellaneous other places, so I thought it’d be good to aggregate some of the useful and/or interesting items that I find each week to hopefully give them a little more visibility.

I also wrote a small Groovy script to find the most recent plugin releases and updates since they don’t always get announced.

Miscellaneous Items

  • Upcoming Grails 1.3.6 release

    • The 1.3.6 release should be next week once testing is finished. There are lots of fixes and improvements in this release – check out the partially-finished release notes. The code is very stable at this point so you’d help us out a lot by installing the latest build from our CI server and testing it with your application and letting us know if there are any issues.
  • Ted Naleid’s run-script

    • We had a request to add this cool script to the Grails core scripts and that will be released in 1.3.6. It makes it easy to run a Groovy script that access your domain classes, services, Spring beans, etc.
  • MinuteProject 4 Grails

    • This is an interesting reverse engineering project that supports Grails and several other frameworks. I haven’t looked at it extensively yet but it looks like it does a lot of what my Database reverse engineering plugin does but also generates a scaffolded user interface.
  • Updated Grails logging configuration documentation

    • Peter Ledbrook added a bunch of information to the logging configuration section of the Grails user manual and published a draft here
  • GroovyTestCase uses java.util.logging.Logger

    • Integration tests typically extend GroovyTestCase which has a protected log variable. Unfortunately it turns out that this is is a java.util.logging.Logger but Grails uses Log4j, and this can cause logging statements to seem to disappear and cause confusion when running tests.
  • Testing Closures in Groovy

    • This is an interesting post by Scott Vlaminck using a tracking delegate to help with testing Closures.
  • SAP SDN Blog Reader for iPad, iPhone and Android devices

    • Blog post about using Grails to write a mobile feed reader application
  • Grails 400 Retail Site

    • Developing a Grails e-commerce site using a DB2/400 database on an iSeries/AS400 box
  • QuickHit is hiring

    • QuickHit is hiring a Grails lead developer in Foxboro, MA. They run a popular Grails-based site that hosts realtime football games using Flash.
  • Updated STS Integration docs

  • Mystery Grails site launch

    • Unfortunately I can’t share any details about this one, but a large web site went live this week with their site updated to be entirely Grails-based. It looks great and performance is fantastic. Hopefully more information will be forthcoming once they officially announce the update.
  • Speaking of large sites using Grails …

    • Check out the SpringSource Case Studies page – it turns out that they had a bunch of Groovy and Grails related case studies that I hadn’t seen before.

Plugins

There were four new plugins released:

  • ajaxflow version 0.1.8. Enables ajaxified webflows
  • error-pages-fix version 0.2. Workaround for GRAILS-6992
    until Grails 1.4 is released
  • full-calendar version 0.1.4. Adds support for the FullCalendar jQuery plugin
  • twitter-checker version 0.1. Monitors Twitter for events including new followers and unfollows in your account, new RTs of you made by other users, and new mentions to you made by other users

There were also several updated plugins:

  • activiti version 5.0. Integrates the Activiti BPM Suite and workflow system
  • autobase version 0.10.0. This abandoned plugin has been picked up by new developers
  • cassandra version 0.7.0.20101207. Provides access to Cassandra (not a GORM layer).
  • dojo version 1.4.3.4. Adds the Dojo javascript toolkit.
  • fsm version 0.6.4. Adds Finite State Machine behaviors to domain classes.
  • gorm-mongodb version 0.5.4. Adds a GORM wrapper for MongoDB.
  • jasper version 1.1.6.3. Enables use of JasperReports.
  • localizations version 1.4.1. Stores I18N messages in the database.
  • remoting version 1.2. Exposes Grails services over RMI, Hessian, Burlap, and Spring’s HttpInvoker protocols
  • spreedly version 0.1.2. Provides access to the Spreedly online payment service API
  • ulc version 0.3.1. Provides access to the Canoo UltraLightClient (ULC) RIA kit

In addition, I wanted to draw particular attention to one plugin update, the 1.0 release of the console plugin. This is one of my favorite plugins and I released an updated version yesterday and wrote up some notes here.

Updated Grails Console Plugin

Friday, December 10th, 2010

I’ve released an update to the Grails Console Plugin, version 1.0.1 (there was a bug affecting Grails 1.1 in the 1.0 release). The original authors (Siegfried Puchbauer and Mingfai Ma) aren’t working on it anymore and allowed me to do a release with some changes I had made.

I had been using a modified version of the plugin for a while and finally got around to contributing the changes back. The version I was using was storing the Groovy shell in the user’s HTTP session but this caused problems when clustering since it’s not serializable. This had been fixed in a more recent release however, so the changes I ended up making were mostly cosmetic.

I reworked the GSP, controller and service to be more modular, and split out the Javascript from the GSP into a .js file. In addition I upgraded CodeMirror to the latest version, and switched from Prototype to jQuery (and removed unreleased YUI-based code and other unused files). To customize the console view you can copy the plugin’s GSP (grails-app/views/console/index.gsp) to your application and it’ll be used instead.


Having a console like this available in a running Grails application is very useful. Since it’s running in the same process as your Grails app, it has access to GORM domain classes, services, and everything else in your application. So doing a quick database query, calling a service method or just testing some code is possible without restarting the application or running the standard Swing-based console.

It’s even useful in production, although since this is a very dangerous feature to have in a live web site it’s important to restrict access to it. My preference would be the Spring Security Core plugin since you can restrict it by role (e.g. ROLE_ADMIN) but also by IP address.

I wrote a while back about using a similar console to patch a bug in a running server.

If you have any questions or suggestions send a note to the Grails User mailing list, and report bugs in JIRA under the Grails-Console component.

Creative Commons License
This work is licensed under a Creative Commons Attribution 3.0 License.