Jelly Overview

Jelly is an XML based scripting engine. The basic idea is that XML elements can be bound to a Java Tag which is a Java bean that performs some function. Here's an example action

public class FooTag extends TagSupport {    
    private int count;
    public void setCount(int count) {
        this.count = count;
    }
    public void doTag(XMLOutput output) throws Exception {
        for ( int i = 0; i < count; i++ ) {
            // evaluate body
            getBody().run( context, output );
        }
    }
}

Then in a Jelly script this tag could be used as follows:-

<f:foo count="123">
    something...
</f:foo>

Jelly is totally extendable via custom actions (in a similar way to JSP custom tags) as well as cleanly integrating with scripting languages such as Jexl, Velocity, pnuts, beanshell and via BSF (Bean Scripting Framework) languages like JavaScript & JPython

Also notice that Jelly uses an XMLOutput class which extends SAX ContentHandler to output XML events. This makes Jelly ideal for XML content generation, SOAP scripting or dynamic web site generation. A single Jelly tag can produce, consume, filter or transform XML events. This leads to a powerful XML pipeline engine similar in some ways to Cocoon.

Background

It seems quite common these days to define custom XML languages to perform some kind of processing. Here are a few examples

  • Ant
  • XSLT
  • XML Pipeline language
  • JSTL and JSP custom tags
  • Latka, AntEater & other similar XML based unit testing frameworks
  • commons-workflow

So the motivation behind Jelly was to create a simple XML based processing engine that could be extended to support various custom actions. A fully qualified XML element name can be mapped to a Java Bean (or DynaBean), the attributes map to bean properties, once the bean is constructed and the properties set it is executed via the Tag interfaces doTag() method. So custom actions can perform all kinds of processing from lower level looping, conditional logic and expression evaluations to higher level actions like post processing their bodies, making a HTTP, SOAP or JMS call, querying SQL databases etc.

Comparisons

To try give you a better feel for what Jelly is, we'll compare and contrast Jelly with other scripting engines and templating technologies.

Jelly versus JSP

Similarities

  • Jelly uses the concept of custom tag libraries from JSP and follows many of the lessons learnt from the JSTL (JSP Standard Tag Library). Indeed JSTL could be implemented in Jelly.

Differences

  • Jelly has no dependency on Servlets or JSP so Jelly can be run from the command line, inside Ant, inside an applet or anywhere that Java code can be ran.
  • Jelly tags are much simpler to write and use than JSP tags. Because JSP must support scriptlets due to backwards compatibility issues, they are implemented 'inside out' with 3 different interfaces (Tag, BodyTag, IterationTag) to implement based on the kind of tag you are writing, together with a fairly complex set of event-based methods that are called by the page container. Jelly tags are very easy - just derive from TagSupport and implement the doTag() method. Really simple!
  • Jelly is XML native both as the format of the scripts and the output format, so its ideal for work with XML and XML based applications and web services
  • Jelly tags can parse and compile their bodies for more optimal performance and easier validation. So a tag can ignore whitespace, iterate over its body, transform its body at compile time etc. So a Jelly tag can be a simple macro, preprocessing its body at compile time, such as to build smart HTML forms or to make SOAP macros etc.

Jelly versus Velocity

Velocity could actually be used inside Jelly via custom tags which support Velocity expressions, directives and scripts. However here's a head to head comparison anyways.

Similarities

  • Jelly allows Java objects to be manipulated in a Java-like manner just like Velocity.
  • Jelly could have a surface syntax that looks similar to Velocity. i.e. someone could make a parser of Jelly that had a look-and-feel of Velocity for common directives and expressions.

Differences

  • Jelly provides an extensible tag mechanism to provide more powerful scripting such as by supporting JSTL, XML, XPath, XSLT, SQL or SOAP service scripting. In essence, Jelly uses XML tags to denote 'directives'.
  • Jelly has integrated support for other scripting languages such as JavaScript, NetRexx, Jython etc.

Jelly versus Ant

Ant is a truly awesome build system which has always resisted 'scripting'. Jelly has never tried to be a build system but instead has just focussed on 'scripting'. However Jelly is a lot like Ant in many ways.

The two can work hand in hand together very nicely. Jelly could be thought of as a scripting plugin for Ant. Jelly can be called from inside Ant as an Ant Task, then the Jelly script can script other Ant tasks, access Ant properties and use all other Jelly tags such as for logic, looping, working with beans, XPath, SQL etc.

Similarities

  • Both use an XML format for the script with an expression language like ${foo.bar}
  • XML elements are mapped to a Java object, so its easy to extend both Ant and Jelly with simple Java code.

Differences

  • Jelly has full support for pluggable expression languages. The default expression language is a superset of the one used in JSP, JSTL and JSF which supports conditional expressions, navigating bean properties, and working with Maps, Collections, Lists, arrays etc. Jexl is the current implementation which adds some Velocity-like enhancements like method calls on beans etc. Jelly supports other expression and scripting languages like Velocity, beanshell, JavaScript, Jython, pnuts, BSF etc in separate tag libraries
  • Jelly has native XML support. Jelly can parse XML and process it using XPath expressions (via the JSTL tags). Also Jelly supports a declarative model of processing XML (via the JSL tags) which is similar to XSLT but can use Jelly tags, beans and Ant tasks inside the XML template in a similar way to DVSL.
  • Jelly has a much more powerful collaboration mechanism for passing information between tags/tasks. In Jelly variables can be any object plus variable scopes can be nested to allow nested scripts to work together neatly. A tag/task can be customized with beans as well as being able to consume, emit, filter and transform XML. So Jelly tags can be configured from and can collaborate with beans and XML.
  • Jelly supports dynamic tags. Tags can be defined in Jelly script to avoid repetitive typing such as to wrap up most of the complexity of making a SOAP call. So Jelly has an integrated tag based macro facility.
  • Jelly uses XML namespaces to allow lots of different tag libraries to work together seamlessly in the same XML document. This means you can mix and match Ant tasks with JSTL and Jelly tag libraries. All can use their own expression languages, so one script could mix and match the expression languages from Ant and JSTL as well as XPath and Jython.
  • There is a clear difference of emphasis. Ant is a build system, Jelly is a scripting engine.

Possible uses for Jelly

Jelly has various possible uses. Here's a few to think about

  • An additional tool for Ant users to provide more flexible Ant scripting. Indeed Jelly is already used in Maven to provide a more flexible build system while still preserving existing investment in Ant tasks.
  • HTTP, JMS, SOAP, XML and SQL based unit testing framework similar to Latka and AntEater
  • SOAP scripting or XML processing engine
  • XML or page templating system, possibly a Generator for Cocoon
  • Alternative (very lightweight) implementation of JSTL that can be run from Ant to generate static content
  • A workflow, EAI or integration, maybe integrated into commons-workflow
  • Code generation system, maybe an enhanced scripting engine for XDoclet