The Alfresco API at your fingertips!!



What is it?

The GroovyRunner allows you to run arbitrary Groovy scripts with full acces to the Alfresco Java API in the Alfresco repository. It is a great tool for testing, analysis, maintenance, setup and repair. We have been using it for years and it has become our Alfresco repository "swiss army knife". If you are familiar with the Alfresco Java API, you will feel at home here :) All services are available exactly as they are in the Java API. We have added some helpers to make things easier, but ultimately with access to the full API you will never get stuck.

You can find the sources on github

Getting started


Simply put alfresco-groovy-runner.jar in tomcat/webapps/alfresco/WEB-INF/lib or tomcat/shared/lib and restart Alfresco.

Running a script

You can run a script from a webpage by opening http://[hostname]:[port]/alfresco/service/open_t/groovyrunner
you can also run a GroovyRunner script from the commandline using curl, or by using

Either way, enter a simple script:
Date d = new Date()
println d
println d.getClass().getName()
This will result in the following output:
Tue Jul 14 15:10:14 CEST 2015
That's just standard Groovy. if you haven't used Groovy before, see

Alfresco API

Now for the Alfresco API.

Let's get hold of a nodeRef:
NodeRef nodeRef=findNode("app:dictionary/app:email_templates/cm:invite/cm:invite-email.html.ftl")
println nodeRef
println nodeRef.getClass().getName()
Results in:

We have access to ALL Spring beans, this includes all API services, for example the nodeService:
println nodeService.getProperties(nodeRef)

We can do all the usual API stuff like that.
But we have also made that a lot easier. The NodeRef class has been extended using a Groovy MetaClass so it has extra virtual properties and methods.
For example, all properties from the cm: namespace map to their short names:
println nodeRef.title

Properties from other namespaces are mapped to prefix_name (as a colon is not allowed in a Groovy property name):
println nodeRef.sys_locale

If we want to modify a node, it is good practice to wrap the actions in a transaction:
// Let's find Guest home

def testNode
// We can wrap code in a transaction by using withTransaction { }
withTransaction {
    testNode.title="My test node"
println testNode.aspects

Read more in the reference guide.