Skip navigation
All Places > Alfresco Content Services (ECM) > Blog > 2010 > August

Alfresco and Groovy, Baby!

Posted by pmonks2 Aug 19, 2010
For quite a few years now I've been a fan of scripted languages that run on the JVM, initially experimenting with the venerable BeanShell, then tinkering with Javascript (via Rhino), JRuby and finally discovering Groovy in late 2007.  A significant advantage that Groovy has over most of those other languages (with the possible exception of BeanShell), is that it is basically a superset of Java, so most valid Java code is also valid Groovy code and can therefore be executed by the Groovy 'interpreter'1 without requiring compilation, packaging or deployment - three things that significantly drag down one's productivity with 'real' Java.

To that end I decided to see if there was a way to implement Alfresco Web Scripts using Groovy, ideally in the hope of gaining access to the powerful Alfresco Java APIs with all of the productivity benefits of working in a scripting-like interpreted environment.

It turns out that the Spring Framework (a central part of Alfresco) moved in this direction some time ago, with support for what they refer to as dynamic-language-backed beans.  Given that a Java backed Web Script is little more than a Spring bean plus a descriptor and some view templates, initially it seemed like Groovy backed Web Scripts might be possible in Alfresco already, merely by adding the Groovy runtime JAR to the Alfresco classpath and then configuring a Java-backed Web Script with a dynamic-language-backed Spring bean.

Oh behave!

Unfortunately this approach ran into one small snag: Alfresco requires that Java Web Script beans have a 'parent' of 'webscript', as follows:

<bean id=''



<constructor-arg index='0' ref='ServiceRegistry' />


but Spring doesn't allow dynamic-language-backed beans to have a 'parent' clause.

It's freedom baby, yeah!

There are several ways to work around this issue, but the simplest was to implement a 'proxy' Web Script bean in Java that simply delegates to another Spring bean, which itself could be a dynamic-language-backed Spring bean implemented in any of the dynamic languages Spring supports.

This class ends up looking something like (imports and comments removed in the interest of brevity):

public class DelegatingWebScript

extends DeclarativeWebScript


private final DynamicDeclarativeWebScript dynamicWebScript;

public DelegatingWebScript(final DynamicDeclarativeWebScript dynamicWebScript)


this.dynamicWebScript = dynamicWebScript;



protected Map executeImpl(WebScriptRequest request, Status status, Cache cache)


return(dynamicWebScript.execute(request, status, cache));



While DynamicDeclarativeWebScript looks something like:

public interface DynamicDeclarativeWebScript


Map execute(WebScriptRequest request, Status status, Cache cache);


This Java interface defines the API the Groovy code needs to implement in order for the DelegatingWebScript to be able to delegate to it correctly when the Web Script is invoked.

The net effect of all this is that a Web Script can now be implemented in Groovy (or any of the dynamic languages Spring supports for beans), by implementing the DynamicDeclarativeWebScript interface in a Groovy class, declaring a Spring bean with the script file containing that Groovy class and then configuring a new DelegatingWebScript instance with that dynamic bean.  This may sound complicated, but as you can see in this example, is pretty straightforward:

<lang:groovy id='groovy.myWebScript'



<lang:property name='serviceRegistry' ref='ServiceRegistry' />


<bean id='webscript.groovy.myWebScript'



<constructor-arg index='0' ref='groovy.myWebScript' />


While a little more work than I'd expected, this approach meets all of my goals of being able to write Groovy backed Web Scripts, and in the interests of sharing I've put the code up on the Alfresco forge Google Code.

I demand the sum... ...OF 1 MILLION DOLLARS!

But wait - there's more! Not content with simply providing a framework for developing custom Web Scripts in Groovy, I decided to test out this framework by implementing a 'Groovy Shell' Web Script.  The idea here is that rather than having to develop and register a new Groovy Web Script each and every time I want to tinker with some Groovy code, instead the Web Script would receive the Groovy code as a parameter and execute whatever is passed to it.

Before we go any further, I should mention one very important thing: this opens up a massive script-injection-attack hole in Alfresco, and as a result this Web Script should NOT be used in any environment where data loss (or worse!) is unacceptable!! It is trivial to upload a script that does extremely nasty things to the machine hosting Alfresco (including, but by no means limited to, formatting all drives attached to the system) so please be extremely cautious about where this Web Script gets deployed!

Getting back on track, I accomplished this using Groovy's GroovyShell class to evaluate a form POSTed parameter to the Web Script as Groovy code (this is conceptually identical to Javascript's 'eval' function, hence the warning about injection attacks).  Effectively we have a Groovy-backed Web Script that interprets an input parameter as Groovy code, and then goes ahead and dynamically executes it!  It's turtles all the way down!

The code also transforms the output of the script into JSON format, since there are existing Java libraries for transforming arbitrary object graphs (as would be returned by an arbitrary Groovy script) into JSON format.

Here's a screenshot showing the end result:

[caption id='attachment_274' align='aligncenter' width='500' caption='Alfresco Groovy Shell - Vanilla Groovy Script']Alfresco Groovy Shell[/caption]

The more observant reader will have noticed the notes in the top right corner, particularly the note referring to a 'serviceRegistry' object.  Before evaluating the script, the Web Script injects the all important Alfresco ServiceRegistry object into the execution context of the script, in a Groovy variable called 'serviceRegistry'.  The reason for doing so is obvious - this allows the script to interrogate and manipulate the Alfresco repository:

[caption id='attachment_276' align='aligncenter' width='500' caption='Alfresco Groovy Shell - Groovy Script that Interrogates the Alfresco Repository']Alfresco Groovy Shell[/caption]

Sharks with lasers strapped to their heads!

Now if you look carefully at this script, you'll notice that it (mostly) looks like Java, and this is where the value of this Groovy Shell Web Script starts to become apparent: because most valid Java code is also valid Groovy code, you can use this Web Script to prototype Java code that interacts with the Alfresco repository, without going through the usual Java rigmarole of compiling, packaging, deploying and restarting!

I recently conducted an in-depth custom code review for an Alfresco customer who had used Java extensively, and this Web Script was a godsend - not only did I eliminate the drudgery of compiling, packaging and deploying the customer's custom code (not to mention restarting Alfresco each time), I also completely avoided the time consuming (and, let's be honest, painful) task of trying to reverse engineer their build toolchain so that I could build the code in my environment.  This alone was worth the price of admission, but coupled with the rapid turnaround on changes (the mythical 'edit / test / edit / test' cycle), I was able to diagnose their issues in a much shorter time than would otherwise have been possible.


As always I'm keen to hear of your experiences with this project should you choose to use it, and am keen to have others join me in maintaining and enhancing the code (which is surprisingly little, once all's said and done).

Technically Groovy does not have an interpreter; rather it compiles source scripts into JVM bytecode on demand.  The net effect for the developer however is the same - the developer doesn't have to build, package or deploy their code prior to execution - a serious productivity boost.


Apparently there has been some confusion over the various product names and the version numbering that has been used by Alfresco in the past (see a sample below).

[caption id='attachment_62' align='aligncenter' width='500' caption='Alfresco Product Names']Alfresco Product Names[/caption]

Now what makes perfect sense to us at Alfresco does not always mean the same thing to the Alfresco Community. For example while we knew that ‘Alfresco Enterprise Edition 3.2r’ meant that it would support ‘Records Management’ this was not immediately obvious to others. And when we released Alfresco Community Edition 3.3g (the g meant that it included a technology preview of the Google Docs integration), people asked what happened to versions a, b, c, d, e and f!

So to make it simpler we are adopting the following numbering convention...

Alfresco Community

The Alfresco Community product is freely available to download and use. Future versions of Alfresco Community will be identified by the following numbering scheme:

Alfresco Community Major.Minor.Build


  • Major - Number used to identify major releases in functionality (examples 3.0, 4.0, 5.0 etc.)

  • Minor - Number used to identify minor releases (example 3.1, 3.2, 3.3 etc.). There will be multiple minor releases for each major release

  • Build - Builds that are publicly released will be identified by a letter (example 3.4.a, 3.4.b, 3.4.c etc.)

The addition of a build letter will enable Alfresco to release multiple incremental builds for each minor version. These could be to provide a more stable version, or to include a technology pre-view. Each of these will be incremental (starting with a) so should allow people to easily understand which is the latest version.

Alfresco Enterprise

The Alfresco Enterprise product is provided to subscription customers. It has some enterprise extensions and goes through a more extensive QA process. Future versions of Alfresco Enterprise will be identified by the following numbering scheme:

Alfresco Enterprise Major.Minor.ServicePack.HotFix


  • Major - Number used to identify major releases in functionality (examples 3.0, 4.0, 5.0 etc.)

  • Minor - Number used to identify minor releases (example 3.1, 3.2, 3.3 etc.). There will be multiple minor releases for each major release

  • ServicePack - Number to identify the service pack included (examples 3.3.1, 3.3.2, 3.3.3, etc.)

  • HotFix - Number to identify which hot fix is included (examples

As Alfresco Enterprise goes through its development cycle, various pre-view (alpha, beta) releases will be made available to customers. These will be identified with the full pre-view name (Example 3.3.alpha or 3.3.beta). This should stop any confusion about 3.3.a being an alpha version.


The next release has been code named ‘Cheetah’ and will be released as 3.4. So expect to see Alfresco Community 3.4.a and Alfresco Enterprise 3.4.0 released over the next few months.

You can check the roadmap to see what will be delivered as part of Cheetah and Swift.

Filter Blog

By date: By tag: