Archive for the Category 'spring'

An updated Grails Spring MVC Plugin

Tuesday, December 18th, 2012

The springmvc plugin was one of the first that I wrote. At the time it wasn’t possible to create controllers in Java, so the plugin added the feature as a way to migrate existing controllers from traditional Spring applications, or to use Java if Groovy performance is an issue. But direct support for annotated controllers was added in Grails 1.2 so that made the plugin redundant.

But I found when describing this feature for the Spring chapter of Programming Grails that all URLs end up with a .dispatch suffix. This has a workaround since you can re-map the URLs in UrlMappings.groovy but it’s not DRY since it has to be done for each URL. I saw this question on Stack Overflow and thought it’d be good to update the plugin since it allows the flexibility of using any URL suffix.

So I updated the plugin to work with Grails 2.0 and higher. See the plugin documentation for installation and configuration information. We’ll get the issues that the plugin addresses fixed in Grails, but that won’t happen until 2.3, so use this until then. You can download a sample application here.

For information on the history of the plugin, see the original post and the plugin announcement.

Autodiscovery of JPA-annotated domain classes in Grails

Wednesday, October 24th, 2012

There are some issues to be fixed with the support for adding JPA annotations (for example @Entity) to Groovy classes in grails-app/domain in 2.0. This is due to the changes made to adding most GORM methods to the domain class bytecode with AST transformations instead of adding them to the metaclass at runtime with metaprogramming. There is a workaround – put the classes in src/groovy (or write them in Java and put them in src/java).

This adds a maintenance headache though because by being in grails-app/domain the classes are automatically discovered, but there’s no scanning of src/groovy or src/java for annotated classes so they must be explicitly listed in grails-app/conf/hibernate/hibernate.cfg.xml. We do support something similar with the ability to annotate Groovy and Java classes with Spring bean annotations like @Component and there is an optional property grails.spring.bean.packages in Config.groovy that can contain one or more packages names to search. We configure a Spring scanner that looks for annotated classes and automatically registers them as beans. So that’s what we need for JPA-annotated src/groovy and src/java classes.

It turns out that there is a Spring class that does this, org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean. It extends the standard SessionFactory factory bean class org.springframework.orm.hibernate3.LocalSessionFactoryBean and adds support for an explicit list of class names to use and also a list of packages to scan. Unfortunately the Grails factory bean class org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean also extends LocalSessionFactoryBean so if you configure your application to use AnnotationSessionFactoryBean you’ll lose a lot of important functionality from ConfigurableLocalSessionFactoryBean. So here’s a subclass of ConfigurableLocalSessionFactoryBean that borrows the useful annotation support from AnnotationSessionFactoryBean and can be used in a Grails application:

package com.burtbeckwith.grails.jpa;

import java.io.IOException;

import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.MappedSuperclass;

import org.codehaus.groovy.grails.orm.hibernate.ConfigurableLocalSessionFactoryBean;
import org.codehaus.groovy.grails.orm.hibernate.cfg.GrailsAnnotationConfiguration;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.cfg.Configuration;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternUtils;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.ClassUtils;

/**
 * Based on org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean.
 * @author Burt Beckwith
 */
public class AnnotationConfigurableLocalSessionFactoryBean extends ConfigurableLocalSessionFactoryBean implements ResourceLoaderAware {

   private static final String RESOURCE_PATTERN = "/**/*.class";

   private Class<?>[] annotatedClasses;
   private String[] annotatedPackages;
   private String[] packagesToScan;

   private TypeFilter[] entityTypeFilters = new TypeFilter[] {
         new AnnotationTypeFilter(Entity.class, false),
         new AnnotationTypeFilter(Embeddable.class, false),
         new AnnotationTypeFilter(MappedSuperclass.class, false),
         new AnnotationTypeFilter(org.hibernate.annotations.Entity.class, false)};

   private ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

   public AnnotationConfigurableLocalSessionFactoryBean() {
      setConfigurationClass(GrailsAnnotationConfiguration.class);
   }

   public void setAnnotatedClasses(Class<?>[] annotatedClasses) {
      this.annotatedClasses = annotatedClasses;
   }

   public void setAnnotatedPackages(String[] annotatedPackages) {
      this.annotatedPackages = annotatedPackages;
   }

   public void setPackagesToScan(String[] packagesToScan) {
      this.packagesToScan = packagesToScan;
   }

   public void setEntityTypeFilters(TypeFilter[] entityTypeFilters) {
      this.entityTypeFilters = entityTypeFilters;
   }

   public void setResourceLoader(ResourceLoader resourceLoader) {
      this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
   }

   @Override
   protected void postProcessMappings(Configuration config) throws HibernateException {
      GrailsAnnotationConfiguration annConfig = (GrailsAnnotationConfiguration)config;
      if (annotatedClasses != null) {
         for (Class<?> annotatedClass : annotatedClasses) {
            annConfig.addAnnotatedClass(annotatedClass);
         }
      }
      if (annotatedPackages != null) {
         for (String annotatedPackage : annotatedPackages) {
            annConfig.addPackage(annotatedPackage);
         }
      }
      scanPackages(annConfig);
   }

   protected void scanPackages(GrailsAnnotationConfiguration config) {
      if (packagesToScan == null) {
         return;
      }

      try {
         for (String pkg : packagesToScan) {
            logger.debug("Scanning package '" + pkg + "'");
            String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
                  ClassUtils.convertClassNameToResourcePath(pkg) + RESOURCE_PATTERN;
            Resource[] resources = resourcePatternResolver.getResources(pattern);
            MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
            for (Resource resource : resources) {
               if (resource.isReadable()) {
                  MetadataReader reader = readerFactory.getMetadataReader(resource);
                  String className = reader.getClassMetadata().getClassName();
                  if (matchesFilter(reader, readerFactory)) {
                     config.addAnnotatedClass(resourcePatternResolver.getClassLoader().loadClass(className));
                     logger.debug("Adding annotated class '" + className + "'");
                  }
               }
            }
         }
      }
      catch (IOException ex) {
         throw new MappingException("Failed to scan classpath for unlisted classes", ex);
      }
      catch (ClassNotFoundException ex) {
         throw new MappingException("Failed to load annotated classes from classpath", ex);
      }
   }

   private boolean matchesFilter(MetadataReader reader, MetadataReaderFactory readerFactory) throws IOException {
      if (entityTypeFilters != null) {
         for (TypeFilter filter : entityTypeFilters) {
            if (filter.match(reader, readerFactory)) {
               return true;
            }
         }
      }
      return false;
   }
}

You can replace the Grails SessionFactory bean in your application’s grails-app/conf/spring/resources.groovy by using the same name as the one Grails registers:

import com.burtbeckwith.grails.jpa.AnnotationConfigurableLocalSessionFactoryBean

beans = {
   sessionFactory(AnnotationConfigurableLocalSessionFactoryBean) { bean ->
      bean.parent = 'abstractSessionFactoryBeanConfig'
      packagesToScan = ['com.mycompany.myapp.entity']
   }
}

Here I’ve listed one package name in the packagesToScan property but you can list as many as you want. You can also explicitly list classes with the annotatedClasses property. Note that this is for the “default” DataSource; if you’re using multiple datasources you will need to do this for each one.

So this means we can define this class in src/groovy/com/mycompany/myapp/entity/Person.groovy:

package com.mycompany.myapp.entity

import javax.persistence.Column
import javax.persistence.Entity
import javax.persistence.GeneratedValue
import javax.persistence.Id
import javax.persistence.Version

@Entity
class Person {

   @Id @GeneratedValue
   Long id

   @Version
   @Column(nullable=false)
   Long version

   @Column(name='first', nullable=false)
   String firstName

   @Column(name='last', nullable=false)
   String lastName

   @Column(nullable=true)
   String initial

   @Column(nullable=false, unique=true, length=200)
   String email
}

It will be detected as a domain class and if you run the schema-export script the table DDL will be there in target/ddl.sql.


There are a few issues to be aware of however, mostly around constraints. You can’t define a constraints or mapping block in the class – they will be ignored. The mappings that you would have added just need to go in the annotations. For example I have overridden the default names for the firstName and lastName properties in the example above. But nullable=true is the default for JPA and it’s the opposite in Grails – properties are required by default. So while the annotations will affect the database schema, Grails doesn’t use the constraints from the annotations and you will get a validation error for this class if you fail to provide a value for the initial property.

You can address this by creating a constraints file in src/java; see the docs for more details. So in this case I would create src/java/com/mycompany/myapp/entity/PersonConstraints.groovy with a non-static constraints property, e.g.

constraints = {
   initial(nullable: true)
   email unique: true, length: 200)
}

This way the Grails constraints and the database constraints are in sync; without this I would be able to create an instance of the domain class that has an email with more than 200 characters and it would validate, but cause a database constraint exception when inserting the row.

This also has the benefit of letting you use the Grails constraints that don’t correspond to a JPA constraint such as email and blank.

Accessing the GrailsApplication and ApplicationContext from domain classes without holders

Saturday, November 12th, 2011

The various holder classes in Grails (ApplicationHolder, ConfigurationHolder, etc.) are now deprecated and the plan was to remove them at some point since static variables cause problems. One example is deploying multiple Grails applications with the --nojars option, using jar files in the server’s shared classpath. If a class with a static field is loaded by the shared classloader, its value is shared by all callers. Kaboom.

We’re working on a fix but it doesn’t look like it’ll be ready for 2.0 final, so it’s still best to avoid their use. In practice this isn’t really that much of a problem since you can use dependency injection to inject the GrailsApplication into any artifact (controllers, services, Quartz jobs, etc.) with def grailsApplication. From there you can get the configuration (grailsApplication.config) and the ApplicationContext (grailsApplication.mainContext). From there you can get any Spring bean, including the ServletContext (registered as the "servletContext" bean).

Dependency injection isn’t an option for regular classes in src/groovy or src/java, but they don’t exist in isolation. They have to be called from somewhere, and that’s most likely going to be an artifact that can use dependency injection. So instead of auto-injecting into your Groovy class, just pass the application, config, or context (or specific beans) to the class when you call it.

I described a way to add a getGrailsApplication method (both static and instance) to the MetaClass of your domain classes in an answer to this StackOverflow question, and it’s still a good option. One caveat – adding a getFoo instance method allows you to call it like it’s a property (thing.foo) but that doesn’t work with static methods. You have to use the getter syntax: Thing.getFoo().

But it turns out this is all possible in 2.0 without changes. There’s a new getDomainClass instance method in domain classes (it returns the GrailsDomainClass artifact API class), and from there you can access the GrailsApplication with its getGrailsApplication method. So if you need access to the configuration, GrailsApplication, or ApplicationContext from a static method, you can reach everything from a new instance of your domain class:

class Book {
   ...
   static someMethod() {
      def grailsApplication = new Book().domainClass.grailsApplication
      def ctx = grailsApplication.mainContext
      def config = grailsApplication.config
      def fooService = ctx.fooService
      ...
   }
}

Grails App-Info plugin

Saturday, July 17th, 2010

Update July 5, 2012: See this blog post for an updated test app and support for Grails 2.0+.

I released a new Grails plugin today, app-info. This plugin exposes a lot of internal information for a Grails application. Most of the code for this plugin dates back a long time and was originally mostly JSPs that I would copy into whatever application I was working on to give myself a view into what’s going on. Over time as I started using Spring and Hibernate I added more pages to display that information, and it now also shows information about Grails too.
(more…)

SpringOne/2GX

Saturday, October 24th, 2009

I got back from Spring One/2GX in New Orleans a couple of days ago and wanted to write up some thoughts about what a great time it was. This was my first SpringOne – my first attempt at getting sent by my employer didn’t go so well and I didn’t go to the Groovy/Grails Experience in Reston, VA in 2008. But earlier this year I noticed Guillaume Laforge’s tweet announcing the presentation request page so I submitted 5 Grails proposals, and luckily 4 were selected.

I got into New Orleans around 1:30 on Monday and took a cab to the hotel. When I checked in the clerk smiled and told me I’d been upgraded to a very nice room. She wasn’t kidding, it was huge. As a geek all I need is a bed and a shower (and of course wifi and power for the laptop) but it was cool that the organizers got the speakers such nice rooms.

I went to registration to get my speaker badge and schedule and met Dave Klein, the first of many famous GR8 folks that I met this week. After that I went out wandering and ended up on Bourbon St. Even at 3pm on a Monday it was pretty wild, lots of people and great music. Later on was dinner and then Rod Johnson’s keynote. Of course the highlight for us Grails folks was Graeme’s demo of STS 2.2 with Grails support. After the keynote a bunch of us went to Bourbon St. and had some beers.


My first session of the conference was my Clustering a Grails Application for Scalability and Availability talk. They’d assigned talks to the various rooms based on expected attendance but based on responses from the attendee questionnaire they moved some talks and mine got moved to a larger room, so there was a little confusion there. I’d given an earlier version of this talk at the Boston Grails meetup so it was a good one to do first. It went pretty well and the audience asked lots of great questions. Unfortunately although I discussed two Quartz bugs that need to be fixed, I only fixed one, so the demo crashed with an error that wasn’t very obvious, so I wasn’t able to get that fixed. Of course 5 minutes after the talk I realized what I’d forgotten.

Next up was Hamlet D’Arcy’s Groovy Compiler Metaprogramming and AST Transformations. AST transforms are a powerful addition to Groovy but it’s a complex topic and Hamlet did a great job explaining the concepts. The AST viewer that he wrote is pretty slick. I’ve got a couple of potential uses for ASTs that I’ll be trying out in the next few weeks.

After lunch was my UI Performance – Maximizing Page Load Efficiency talk. This one surprised me. I’m not a UI guy, but I am a performance nut and I’m psyched about what the UI Performance plugin provides to Grails applications. But I was concerned about running under for this talk since this isn’t really an area of expertise for me. However we had a great interactive discussion with lots of great audience questions and this talk was ironically probably the best of the four that I did.

After that was Andy Clement’s Eclipse Groovy Tooling. I’m a hardcore Eclipse user and had been using the v1 Eclipse Groovy plugin. The work that Andy Clement and Andrew Eisenberg have done with the v2 plugin has been fantastic. I’m subscribed to the
eclipse-plugin-user and eclipse-plugin-dev mailing lists so I’m aware of a lot of what’s happened along the way but it was great to hear the stories and challenges from the source.

The last session of the day was Ken Sipe’s Grails and the JVM Memory Management. I’m comfortable with garbage collection and the various heap generations so I didn’t get much out of the first part of Ken’s talk but the demos of VisualVM and BTrace were great. It’s always good to add new tools to the toolkit and these look great.

I got Thai takeout for dinner and skipped Adrian Colyer’s technical keynote to do prep for the next day’s talk but went to the Grails BOF. It was a lively discussion with Graeme and Jeff – you can listen to a recording that Colin Harrington tweeted here.


The first talk Wednesday was Andres Almiray’s Flying with Griffon. I’m a big fan of Griffon, having done a bunch of Swing development. Pretty much everything I do currently is web-based but I’m looking for an excuse to write a desktop app in Griffon and after seeing Andres’ talk I’m even more psyched. The highlight of the talk was finding out that the slick presentation that he’d switched to from his PowerPoint slides was actually a Griffon app: Griffon Talk. btw – I highly recommend Griffon in Action – it’s available in Manning’s early access program and is already packed with great information.

Next was Matt Taylor’s GrailsUI Primer. Being a bad UI developer I need good tools for UI work and GrailsUI is very good. Matt also suggested that it’d be good to integrate GrailsUI with the UI Performance plugin, so that should be interesting.

After lunch was my Advanced GORM – Performance, Customization and Monitoring talk. When I did an earlier version of this talk at the Boston Grails meetup it ran long and I didn’t get to the demo of the graphics and monitoring part, so I rushed this one a bit. But overall the audience seemed to find the content interesting. I even had some people offer to help making the monitoring stuff into a plugin – please email me if you were one of them.

Next was my one Spring talk, Chris Richardson’s Running Java and Grails applications on the Amazon Elastic Compute Cloud. I’ll be working on a project that will deploy to EC2 so this is useful info, but to be honest I was more than a little distracted since they had just announced that STS 2.2 was released so I spent a lot of the talk trying that out.

The final talk of the day was Paul King’s Groovy and Concurrency talk. This was an interesting discussion of the various options for multithreading in Groovy, from Ant’s parallel task to various wrappers of the java.util.concurrent classes like Jetlang and GPars, and the new Fork/Join stuff that’ll be in Java 7.

That night I had dinner with Calen and Chelle from Orange and Bronze. I’ll be working on an outsourcing project with them and they had a booth at the conference, so it was a good opportunity to talk with them in person. The restaurant was at the other end of the French Quarter so we had plenty of time to talk – if the rest of the company is like Calen and Chelle we’ll be in good hands.


I did some prep work for the next day’s Demystifying Spring Security in Grails talk and got to bed reasonably early, but for some reason didn’t set an alarm. Luckily a friend who noticed that I wasn’t available on IM called me at 8am so I at least had 1/2 hour to take a shower and get ready. I didn’t have any caffeine or breakfast and was pretty annoyed at myself for nearly screwing up in a major way, but like the rest of the talks I got plenty of great questions and participation from the audience so except for yet another partially failed demo things went well.

I had another celebrity sighting on the way to the talk: Luke Taylor, who’s currently doing most of the work on Spring Security now that Ben Alex is working on Roo. We talked briefly about the breaking changes in Spring Security 3 that are prompting me to write a new plugin (this will be a great opportunity to start from scratch and also modularize the plugin btw) and he offered to answer questions, so I’ll definitely be taking him up on that offer. Later I ran into Luke and Ben in the hotel coffee shop when I was finally able to get caught up on caffeine and I talked to Ben about Roo – he’s clearly excited about the enthusiasm that people have shown for Roo so far. I doubt I’ll do much with Roo since I’ve spent so much time working with Grails, but I can see how Java developers who like the idea of Convention over Configuration but aren’t ready to make the leap to the dynamic language-based Grails would find Roo attractive.

I was going to go to Ramnivas Laddad’s AOP talk next, but I needed to check out and hadn’t had a chance to pack since I’d overslept, so I did that and spent some time catching up on email. I got a takeout falafel wrap from a funky little Middle Eastern place near the hotel and spent some time working on parallelizing Grails integration tests (inspired by a thread on the Grails user mailing list and Paul King’s talk). It’s mostly finished; once I get it working I’ll post the code and a writeup – it should help speed up test time on multicore machines.

My last talk of the conference was Scott Vlaminck’s AOP in Grails. I had heard about Scott’s Circuit Breaker Plugin but didn’t read enough about it to see how it’d be useful. So I was glad I went to the talk – this plugin is a great idea. We have a Log4j SMTP appender configured on a project and on two occasions recently have generated over 2000 error emails in under an hour, so a circuit breaker would have come in very handy there. Most of the time in Grails we can just use MOP for before/around/after advice, but “real” AOP is necessary when Java is calling Java since there isn’t a hook for MOP.


So it was a fantastic 3 1/2 days. It was cool to meet so many people that I had previously only known online, both the big names in the Groovy/Grails/Griffon communities but also developers, plugin authors, and other users and fans of the GR8 stack.

I’ll be posting the presentations and sample apps for the talks that I did when I get a chance so people can try them out and hopefully take advantage of some of the code.

I’m definitely psyched for next year, and I’m also looking forward to the next GR8 event, the Groovy & Grails Exchange in London in December. After that I’ll be headed to the Philippines in January to work with Orange and Bronze and speak at a Spring and Grails conference that they’re sponsoring, so it’ll be an interesting few months.

Grails “Lite” on Google AppEngine

Monday, April 13th, 2009

This week Google announced Java support for AppEngine. I had signed up when they originally announced Python support, hoping to use it as an excuse to learn Python, but never did anything with it, mostly because I’ve been spending so much time with Grails. So when they announced Java support I immediately signed up and was approved in about an hour.

Guillaume Laforge blogged about Groovy support – they’d worked with Google to ensure compatibility and released v1.6.1 with the required fixes. Of course with Groovy support, lots of people were asking if Grails would work. Unfortunately it looks like it’ll take some work for that. So far it looks like there are problems with threads, XPathFactory, and SiteMesh, and of course GORM will have to be enhanced to work with the AppEngine datastore.

Lots of work is being done to get frameworks working in AppEngine. Shay Banon updated Compass and posted a screencast demonstrating its usage. Thomas Mueller updated H2 database, so in-memory JDBC is possible, and he’s planning on writing a JDBC driver wrapping the datastore API which would make porting apps a lot more straightforward. In addition work is being done to make Tapestry, Struts, JSF, and other frameworks compatible.

The SDK supports both JPA and JDO, but JDO is currently much better documented. I have no experience with JDO so I started playing with the “jdoexamples” demo project that ships with the SDK. Like most of the examples it uses Servlets and JSPs, which after using SpringMVC and Grails seemed painfully dated. And the database code is very repetitive with lots of boilerplate. So I thought I’d play with using Groovy to add Grails-like functionality to reduce some of the clutter. This also gave me an excuse to use the new MVC features in Spring 2.5, especially the annotation support.


I reworked the jdoexamples project as a Spring MVC application, along with a bunch of Groovy MetaClass magic. There’s no BeanBuilder or resources.groovy/resources.xml; instead the “core” applicationContext.xml includes two other context files, one that’s auto-generated during the Ant “war” target containing services, and one that is application-specific in src/java/applicationContext_user.xml.

The domain classes aren’t changed much except that they take advantage of being written in Groovy, and static inner classes were reworked as top-level classes since Groovy doesn’t support inner classes. The “Utils” classes were reworked as Services. The Servlets were reworked as Controllers, and all of the scriptlets in the JSPs were moved to the controllers or reworked using JSTL tags. I didn’t improve the UI (it’s pretty sparse) since I was more focused on the code and not the look and feel.

The code expects a directory structure similar to a Grails project: domain classes in grails-app/domain, services in grails-app/services, controllers in grails-app/controllers, Java source in src/java, and Groovy helper classes in src/groovy:

In addition there’s the framework classes (in src/framework, there’s no separate library for these) and core applicationContext.xml, some application-specific config files in src/java (which will end up in WEB-INF/classes), application jars in lib, web content in war, web config files in war/WEB-INF, JSPs in war/WEB-INF/jsp, and Groovlets in war/WEB-INF/groovy (these aren’t auto-discovered, they need to be manually registered in web.xml as Servlets).

During the build, a file is generated (WEB-INF/artifacts.config) containing the names of the domain, controller, and service classes; this way the framework code knows which MOP methods to add when the app starts up.

The added domain class MetaClass methods are:

  • save
  • get
  • delete
  • findAll
  • withTransaction
  • withPersistenceManager (to execute code with access to the PersistenceManager)
  • isJdoPersistent, isJdoDeleted, isJdoDetached, isJdoDirty, isJdoNew, isJdoTransactional, getJdoTransactionalObjectId, getJdoVersion, getJdoObjectId, and jdoMakeDirty corresponding to the JDOHelper methods isPersistent, isDeleted, isDetached, isDirty, isNew, isTransactional, getTransactionalObjectId, getVersion, getObjectId, and makeDirty

Controllers have these attributes added to their MetaClass:

  • params (with Request attributes like in Grails)
  • session
  • request
  • response
  • servletContext

These attributes provide controllers access to the standard servlet classes but they aren’t as useful as in Grails since the approach taken is to use the newer MVC features in Spring 2.5 like declaring typed (auto-converted) parameters using annotations in controller methods. But they’re available in case they’re needed.

All artifacts have a Commons Logging “log” (wrapping a java.util.Logger) wired up, although for some reason this doesn’t work in Services. The only thing I can think of is that it’s because they’re Spring beans, but that shouldn’t matter since they’re not proxied.

Controllers are singletons. I appreciate the convenience of having stateful per-instance (prototype scope) Controllers in Grails but I tend not to take advantage of that and prefer the more traditional stateless singleton scope approach.

There are no Spring samples in the downloadable SDK demos, but after I’d written most of the demo app code I saw on the mailing list that the autoshoppe demo had been checked into the trunk (along with a few others). I should have expected that Spring would have a JdoTemplate – I’ll need to rework some of the code to use that since I reinvented a few wheels.

There’s a lot of missing functionality. No taglibs, scripts, converters, or GSPs. Also no SiteMesh, no BeanBuilder, and obviously no plugins 🙂 But it mostly works and definitely makes Spring/AppEngine development easier.

In addition I was thinking that I’d integrate Compass, plus it shouldn’t be much work to add Spring Security – it should only need a JDO-based UserDetailsService implementation.


You can download the sample code here and view it in action here.

Note that to use Ant to build the app, you need to copy groovy-all-1.6.1.jar to $ANT_HOME/lib. You also need a build.properties with an “appengine.sdk” property pointing to the root directory of your AppEngine SDK directory (to load the shared Ant targets). And you’ll need to change the app name (“bb-grails-lite”) in build.xml, web.xml, and appengine-web.xml. You’ll also need to change the Controller package name in spring-servlet.xml from com.burtbeckwith.gae.guestbook.controller to whatever your Controller package is.

There are two issues with the online demo. One is that the “friends” demo displays an error page – there are error messages in the console logs complaining about a missing index (this works fine locally). The other is that the “addressbook” demo mostly works, but it doesn’t save the state or phoneNumber fields correctly. This means that you can’t search by state, only by last name, and it displays the state value instead of the phoneNumber value. As you can see from the screenshot of the admin console, it thinks that there’s a metaClass field instead of state, and isn’t aware of phoneNumber at all. This seems highly likely to be due to Groovy, but it’ll have to be investigated. If the domain classes can’t be written in Groovy, there’s a lot of lost functionality without being able to use MOP.

Spring Bean Aliases in Grails

Tuesday, January 06th, 2009

I was looking at the source code of a Spring application recently and saw an applicationContext.xml element that I hadn’t seen before: <alias>. It turns out this has been around for quite a while, since v1.2 (2005). It sure would have been convenient several months ago.

My first Grails app was a Live Chat app for tech support. I used Comet, so I needed to access Grails beans from Java classes. I did this by having my Services implement an interface, and used that as the type for the Spring bean dependency injection.

But the problem with that was that in Grails you don’t get to choose the bean names of artifacts – there’s a strict convention, so a Service named ChatService is registered as chatService. But the convention I’ve always used is to name my interface ChatService and name the implementation class ChatServiceImpl. But then the Spring bean name would be chatServiceImpl.

In a regular Spring app I’d implicitly alias when I added the bean element to the applicationContext.xml file, e.g.

<bean id='chatService' class='com.foo.bar.ChatServiceImpl' />

So instead I chose an option that I really dislike – I named the interface IChatService and the Grails Service ChatService.

But with the <alias> tag, I should be able to do what I want – name the interface ChatService and the Grails Service ChatServiceImpl, and add

<alias name='chatServiceImpl' alias='chatService' />

to resources.xml. The original bean name will still be there, but I can use the more natural bean name for dependency injection.

This doesn’t cause an error, but it doesn’t work either. I spent some time in a debugger and the alias is registered, but the application context that’s available when the app is running is different from the one that the alias was added to.

But it turns out that you can add programatically add aliases at any time, so I added the alias call to BootStrap.groovy:

class BootStrap {

  def grailsApplication

  def init = { servletContext ->
    grailsApplication.mainContext.registerAlias('chatServiceImpl', 'chatService')
  }

  def destroy = {}
}

and now I can use the chatService alias as the bean name.


I noticed though that since aliases are stored in a Map and not directly in the bean registry, that ctx.getBeanDefinitionNames() only returns ‘real’ bean names and no aliases. But it turns out that it’s pretty simple to get all bean names and aliases:

def allNames = [] as Set
ctx.beanDefinitionNames.each { name ->
    allNames << name
    ctx.getAliases(name).each { alias -> allNames << alias }
}

Wow – SpringSource Bought G2One

Tuesday, November 11th, 2008

Apparently The Register broke the embargo and published an early article about the aquisition, which was noticed by a user on the mailing list.

This is great news for Groovy and Grails. Sun is becoming less and less relevant and unable to monetize the Java family, and is focusing way more on JRuby and Python than Groovy, which is the “official” Java scripting language. So it’s great that they’ll have the resources of Spring, Inc. behind them. Apparently they’ll be putting a lot of effort into improving the Eclipse plugin – woot!

I guess this explains a lot about why Graeme didn’t seem very concerned about Spring’s new maintenance policy.

Some links – the SpringSource page and announcement, Graeme’s blog post, Guillaume’s blog post, and Rod’s blog post.

A Grails Plugin for Spring MVC Controllers

Sunday, September 07th, 2008

I wrote earlier about using Spring MVC controllers in a Grails app. I was looking at that again since I thought it might be useful as a plugin. Unfortunately although it did work at the time, I ended up having to do a lot more work to get it going. I guess some things changed in intermediate Grails releases, and I didn’t save the code. But anyway, it’s working now 🙂

Installation

To use it in your app, install like any plugin:

grails install-plugin springmvc

The install script will create a web-app/WEB-INF/jsp folder if it doesn’t exist, and copy the sample error.jsp there if it doesn’t exist. It also creates an empty web-app/WEB-INF/SpringMVC-servlet.xml – the file has to exist but all beans are defined by the plugin or in the app’s resources.groovy and/or resources.xml.

Configuration

There are a few configuration options available – all are optional. They’re defined in a springmvc block in Config.groovy:

Name Default Value Description
urlSuffix ‘action’, i.e. *.action the URL pattern for Spring MVC controller URLs
exceptionMappings none Map with exception class names as keys and JSP names as values
defaultErrorView ‘error’, i.e. web-app/WEB-INF/jsp/error.jsp the default error page if there’s no corresponding mapping for the exception class
interceptors none bean names of HandlerInterceptors to apply to Spring MVC URLs

So a configuration block that defines a single interceptor, uses *.action for URLs, and defines a default error JSP and two exeption-specific exception mappings (note that the values for urlSuffix and defaultErrorView are redundant since they’re the default values) would be:

springmvc {
   interceptors = ['loggingInterceptor']
   exceptionMappings = ['java.io.IOException': 'ioexception']
   exceptionMappings = ['com.myapp.MyException': 'myex']
   defaultErrorView = 'error'
   urlSuffix = 'action'
}

Application Beans

Unlike in Grails, there’s no automatic URL mapping. To connect a controller to a URL you define a Spring bean (in resources.groovy or resources.xml) whose name is the url and the bean class is the controller, e.g.:

   '/test.action'(com.burtbeckwith.mvctest.controller.TestController) {
      cacheSeconds = 0
      bookService = ref('bookService')
   }

This will map http://localhost:8080/yourapp/test.action to TestController. Setting cacheSeconds to 0 instructs Spring to send headers to disable caching. And ‘bookService’ is a dependency injection for BookService to access Book domain instances. The controller returns ‘books’ as it’s view name – this is prefixed by ‘/WEB-INF/jsp/’ and suffixed by ‘.jsp’ to define the JSP that will render the response (i.e. ‘/WEB-INF/jsp/books.jsp’).

You can also define HandlerInterceptors in resources.groovy. They should extend HandlerInterceptorAdapter or implement HandlerInterceptor directly. Add their bean names to the ‘interceptors’ list and Spring MVC requests will be intercepted. Note that these interceptors are in addition to the standard Hibernate OSIV interceptor and a locale change interceptor.

For example:

   loggingInterceptor(com.burtbeckwith.mvctest.interceptor.LoggingInterceptor)

Sample App

You can download a sample app here. It’s pretty simple – it has a single domain class, and a single Grails controller and a Spring MVC controller (to test that both work in the same app). There’s a Grails service to access domain instances that implements a Java interface so it’s callable by the MVC controller. There’s also a sample interceptor (it just logs requests) and a sample JSP 2.0 tag file, date.tag.

The app creates six books in Bootstrap – you can see the data by going to http://localhost:8080/mvctest/test.action. Go to http://localhost:8080/mvctest/regular to access a regular Grails controller.

A Grails Plugin for Multiple DataSources

Thursday, September 04th, 2008

There have been a few requests on the Grails user mailing list about using multiple data sources in a Grails app, i.e. some domain classes use one data source and database and others use another. Grails doesn’t directly support this – there’s only one DataSource and one SessionFactory, and all domain classes use them. But it turns out it’s not that difficult to support this (and it doesn’t involve too many ugly hacks …)


There are some implications of the approach I took. This doesn’t provide XA transactions, 2PC, etc. It’s just a partitioning of classes between two or more datasources. The way it works is to run after the HibernateGrailsPlugin and DomainClassPlugin have done their work. Then it uses a configuration defined in grails-app/conf/Datasources.groovy and creates one or more extra DataSource, SessionFactory, TransactionManager, etc. and re-runs the HibernateGrailsPlugin‘s doWithDynamicMethods closure for the appropriate subset of domain classes. This way when you call a magic GORM method (e.g. list(), get(), findByNameAndDate(), etc.) it will use the correct underlying datasource. Any domain class not defined as using a secondary datasource will use the ‘core’ datasource defined in DataSource.groovy.

Another issue is that all domain classes stay defined in the core datasource/SessionFactory – the existing behavior isn’t changed, other than redefining the metaclass methods to use another datasource. The only effect of this is that if you use dsCreate = ‘create-drop’ or ‘create’ or ‘update’ for the core datasource, all tables will be created in the core database even though some won’t be used.

Datasources DSL

The DSL used in Datasources.groovy is very similar to the format of DataSource.groovy. One difference is that the ‘hibernate’ section is inside the ‘datasource’ section, and there are a few extra attributes.

Name Type Required Description
name String yes datasource name, used as a Spring bean suffix, e.g. ‘ds2’
readOnly boolean no, defaults to false if true, the datasource and corresponding transactional services will be read-only
driverClassName String yes same as in DataSource
url String yes same as in DataSource
username String no same as in DataSource
password String no same as in DataSource
dbCreate String yes same as in DataSource
dialect String or Class yes (no autodetect) same as in DataSource
jndiName String no same as in DataSource
pooled boolean no, defaults to false same as in DataSource
loggingSql boolean no, defaults to false same as in DataSource
logSql boolean no, defaults to false same as in DataSource
environments List<String> no, defaults to [‘development’, ‘test’, ‘production’] list of environments this DataSource should be active in
domainClasses List<String> or List<Class> yes the domain classes that should use this DataSource
services List<String> no short names of the services that should use this DataSource (same as Spring bean without ‘Service’, e.g. ‘user’ for UserService)

See the sample app (link below) for a usage example.

OpenSessionInView

An OpenSessionInViewInterceptor is defined for each datasource, so the features that it provides are available to all domain classes. For example you can load a domain instance and set a property, and it will be detected as dirty and pushed to the database. Also, lazy loaded collections will load since there’s an active session available.

Further, if you save, create, load, etc. domain instances from multiple datasources in one controller method, all will work fine.

Transactional Services

By default, any service defined as transactional will use the core datasource. If you want a service to use a specific datasource, add its name to the ‘services’ attribute for a datasource definition. If there’s no one datasource for a particular service, you can still define programmatic transactions using withTransaction on any domain class for the appropriate datasource for each method or code block.

HibernateTemplate

I can’t think of non-contrived reasons to do so, but it’s possible to use a domain class in two or more datasources. The problem here is that the metaclass methods will end up mapped to the last declared datasource, so there’s no way to use GORM for the other datasource(s). However you can use Spring’s HibernateTemplate yourself – it has a lot of the functionality of GORM (GORM uses it under the hood). You can use the convenience method DatasourcesUtils.newHibernateTemplate(String dsName) to create a HibernateTemplate configured with the SessionFactory for the named datasource.

Usage

You might want to use this plugin even if you have only one database. Since you can define a datasource as being read-only and point read-only domain classes at it, your prevent yourself from accidentally creating, deleting, or updating instances.

I’ve created a basic (and rather contrived) test application. It has three datasources and five domain classes:

  • Country, State
  • Library, Book
  • Visit

Country and State are just lookup tables, so they use a read-only datasource. Visit has a weak foreign key to Library, but this is not enforced since they’re stored in two databases. It’s the responsibility of the application to ensure that the library id for each visit is valid. This is to simulate having a second database for auditing.

To test the app:

If you want to manually manage the tables in each database instead of letting Hibernate do it for you, you can use the schema-export script from here to capture the DDL for all the tables. Then you can execute the DDL statements for each database separately.


The plugin is in the Grails repository, so to use it just run “grails install-plugin datasources”. You can download the test application here.

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