Vita Rara: A Life Uncommon

Groovy Works 0.1 Release


Categories: | | |

Groovy Works has been the benefactor of a lot of development this past week. With upgrades for better class caching, better utilization of the GroovyClassLoader, and integration with Groovy-1.1-beta-3-SNAPSHOT and Spring 2.

Google Code Project and SVN Access

I have moved Groovy Works to Google Code. To get the latest release please see the download section on Google.

Quick Start Directions

  • Download the current release from Google Code.
  • Unzip it in a directory: tar xfzv groovyworks-0.1.tar_.gz
  • Change directory to the groovyworks-core directory: cd groovyworks-core
  • Install the Groovy Works artifact with Maven: mvn install
  • Change directory to the sample application: cd ../example-app
  • Run the application with the Jetty plugin: mvn jetty:run
  • Point your browser at http://localhost:8080/groovyworks/

To use the plugin in your Struts projects you'll need to remove the standard Struts Spring plugin. Groovy Works provides all of the functionality of the existing Spring plugin.

Changes

  • Caching of action classes is now working.
  • To configure an action in the struts.xml specify the name as a '.' separated fully qualified class name ending in .groovy. (ie: com.mydomain.actions.MyAction.groovy)

Internally the plugin uses the GroovyClassLoader.loadClass() method to instantiate Class objects now. This is different than 0.1-SNAPSHOT which was creating InputStreams and parsing the results into a Class instance. The new methodology allows the GroovyClassLoader to handle caching and dynamic recompilation if the source file changes.

Integrating Ajax into my current application really brought the lack of class caching to a head. Every Ajax request resulted in recompilation of the action class. With multiple requests being made with the change of one control on the page caching became a serious requirement.

Spring Integration

Groovy Works support auto-wire by name of action dependencies by default. Your service beans can be implemented in Groovy or in Java. If you implement your actions in Groovy you can use Spring scripting support to allow for dynamic recompilation. Your Groovy service beans, DAO, etc. can participate in Spring managed transactions, proxying, AOP, etc.

Future Directions

I have worked for the past week to get Groovy Works working with Groovy-1.1-beta-3-SNAPSHOT (see below). Moving Groovy Works to Groovy 1.1 will allow the usage of annotations and generics. The exciting feature being annotations. This will allow Groovy Works action to support convention over configuration and allow for annotation of results on actions. I plan on integrating the following over the next few weeks:

  • A Dispatcher and Dynamic Configuration Manager: Allow usage of convention to map URLs to Groovy action classes. (ie: http://www.mydomain.com/myContext/setttings/displayProfile.action would automatically map to settings.DisplayProfileAction.groovy) I will also be adding support for Ajax actions by convention.
  • Results Annotations: I think once we have the default mapper using Groovy actions we should be able to annotate the actions with result annotations and obviate the need to add actions to the struts.xml file completely. I'd also like to be able to add results and change results as needed without reloading the application.
  • More Efficient Groovy Class Caching: I'm planning on borrowing an idea from the Spring guys in having a GroovyClassLoader per Groovy action definition. This would allow us to simply dereference the class loader when the source file changes allowing the PermGen space for that class loader to be garbage collected. This is used in JRuby currently also. This would keep the memory foot print small as you develop your actions and do quick iterations without reloading the server. Currently after a certain number of recompilations of an action the server tends to bog down due to lack of memory and unfreeable resources created by left over class objects, at least I think that's what is slowing it down.

That's it for the short term. In the medium term, prior to my training session at ApacheCon in November I'd like to get basic scaffolding working. More on that later.

Groovy 1.1-beta-2 Support

Previously I tried updgrading Groovy Works to Groovy 1.1-beta-1 without success. I personally use service beans and DAO's that are implemented in Groovy and wired using Spring. Between Groovy 1.0 and 1.1-beta-1 Groovy's support for JDK style dynamic proxies was broken. This causes an IllegalArgumentException to be thrown every time a Groovy action called a Spring managed Groovy service bean. This was caused by Spring's wrapping of the service beans in a JDK style dynamic proxy. (cf: Groovy dev list discussion, Spring Forum Thread)

This issue became a show stopper to moving Groovy Works forward so I dug into it. Took about a week to completely wrap my head around the issue and craft a solution. (cf: Groovy JIRA for the patch) (NB: This isn't necessary unless you want to use Groovy Works with a Groovy 1.1 beta release, or you want to try the latest groovyworks-0.2-SNAPSHOT out of SVN.)

Thanks for your hard work.

I have tried it, and it works well. Thanks!