Monday, October 22, 2007

Grails Exchange

Last month I did a talk on behalf of the Java Web User Group (JavaWUG) at the Grails Exchange. Unfortunately, I did not go to the full conference but it was nice to pop in and attend a couple of the evening sessions, do my bit, and join in for a beer and chat aftewards.

The thrust of my talk was on embedding Grails into Java applications. Grails is a full-stack framework, which aims to solve an overlapping set of problems to Impala. I feel lured towards Groovy, but every time I get put off by my perception that Groovy is too slow. I'm not talking about execution speed, more compile speed.

Anyway, there could be a nice synergy with Impala and Grails - Impala for a standard Spring-based back end, and Grails for the front end. That's certainly a part of the reason for my interest in embedding Grails in a typical Java application.

Impala, of course, works out of the box with Spring MVC, but it would be great to get integration going with other frameworks. One of the key requirements for a web framework integration with Impala is that the web application is itself dynamically reloadable. Of course, you could integrate Impala with any statically reloading web application, but it seems a bit pointless having dynamically reloadable back-end functionality while still having to restart the application every time you want to make a change to one of your presentation classes. Grails seems to fit the dynamic reloadable requirement quite well. However, unpicking it's functionality so that you can reuse it outside of the Grails environment is not trivial.

Here's some code which goes part of the way to achieving this task.


public static void main(String[] args) throws IOException {
MetaClassRegistry registry = GroovySystem.getMetaClassRegistry();

if (!(registry.getMetaClassCreationHandler()
instanceof ExpandoMetaClassCreationHandle))
registry.setMetaClassCreationHandle(new ExpandoMetaClassCreationHandle());

FileSystemXmlApplicationContext cpc =
new FileSystemXmlApplicationContext("web-app/WEB-INF/grails-context.xml");
DefaultRuntimeSpringConfiguration springConfig =
new DefaultRuntimeSpringConfiguration(cpc);

GrailsApplication application = (GrailsApplication) cpc.getBean("grailsApplication");
application.registerArtefactHandler(new ControllerArtefactHandler());
application.registerArtefactHandler(new TagLibArtefactHandler());
application.registerArtefactHandler(new DomainClassArtefactHandler());

application.getConfig().put("plugin.includes", "filter, controllers, taglib");

DefaultGrailsPluginManager pluginManager =
new DefaultGrailsPluginManager(new Class[] {}, application);

WebApplicationContext context = springConfig.getUnrefreshedApplicationContext();
pluginManager.setParentApplicationContext(context);
pluginManager.loadPlugins();

pluginManager.doPostProcessing(context);
pluginManager.doRuntimeConfiguration(springConfig);
pluginManager.setApplicationContext(context);
pluginManager.doDynamicMethods();

WebApplicationContext ctx = springConfig.getApplicationContext();

System.out.println(Arrays.toString(ctx.getBeanDefinitionNames()));
}


Note that this code will fire up Grails, load its web-specific plugins. The trick now is to get the rest of the environment working, so that a full Grails web application can slot neatly into Impala's environment. Something I'll be trying in the next few weeks.

No comments: