Groovy vs. Jelly

780 views
Skip to first unread message

Jacqueline Taing

unread,
Sep 9, 2015, 5:41:00 PM9/9/15
to Jenkins Developers
Hi,

I am fairly new to plugin development and I would like to understand when someone would use jelly vs. groovy script for the UI.  I am seeing some plugins with jelly but some that use groovy.  When would you use one over the other?

Thanks,
-jacqui

Kanstantsin Shautsou

unread,
Sep 9, 2015, 5:44:42 PM9/9/15
to Jenkins Developers
Well, if you are new in jenkins, then i can suggest using jelly. When you know how UI constructs you will understand where Groovy wins. But for new comers groovy will be very difficult as it not documented at all for some controls.

Stephen Connolly

unread,
Sep 9, 2015, 6:20:20 PM9/9/15
to jenkin...@googlegroups.com
Use jelly always. It is closer to the html. It is more obvious what the effects will be. It is faster.

The only reason to use groovy view is if you want partial support for IDE completion of expressions (it's only partial mind, as the IDE will not be able to get full contextual type info)

Any time I find a view performance issue it is usually a groovy view and reworking as jelly usually yields a simpler file with better performance.

But that is my personal experience and I've been writing jelly views since 2006... The groovy fanboys have not been able to convince me to switch yet.

(I would switch to handlebars as a templating engine, some day soon I'll bite the bullet and implement support for handlebars as a view rendering engine in stapler)
--
You received this message because you are subscribed to the Google Groups "Jenkins Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/37090e7c-5188-4c94-ab57-1c20dfcad0a4%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--
Sent from my phone

Kanstantsin Shautsou

unread,
Sep 9, 2015, 7:35:06 PM9/9/15
to jenkin...@googlegroups.com
Jelly like xml has overhead, that’s why workflow/build flow/gradle produces DSLs. Groovy code is clean and has less tags, supported by IDE and allows setting breakpoints for debug. Also it provides more control under page internals (that is also penalty in conjunction with lack of docs).
I never had performance issues. As i understand both is runtime compilable. Stephen please provide some performance example if you hit it. I think nowadays it shouldn’t have such issues.

You received this message because you are subscribed to a topic in the Google Groups "Jenkins Developers" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/jenkinsci-dev/n4Xw9pq2fl8/unsubscribe.
To unsubscribe from this group and all its topics, send an email to jenkinsci-de...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/jenkinsci-dev/CA%2BnPnMxJe74ZSFeoSN%2BChVbY8n3-r4N2A4suR4uzsAjOcM1V_A%40mail.gmail.com.

Stephen Connolly

unread,
Sep 10, 2015, 4:41:38 AM9/10/15
to jenkin...@googlegroups.com
On 10 September 2015 at 00:35, Kanstantsin Shautsou <kanstan...@gmail.com> wrote:
Jelly like xml has overhead, that’s why workflow/build flow/gradle produces DSLs. Groovy code is clean and has less tags, supported by IDE and allows setting breakpoints for debug. Also it provides more control under page internals (that is also penalty in conjunction with lack of docs).
I never had performance issues. As i understand both is runtime compilable. Stephen please provide some performance example if you hit it. I think nowadays it shouldn’t have such issues.

As I understand it, all the template engines get routed through the jelly engine anyway because the main page is a .jelly page.

You might get comparable performance if the page starts as a groovy view and layout.jelly (plus any included files) were switched to layout.groovy but as you start in the jelly rendering engine the groovy views have to be mapped to XML for injection into the jelly view that is <st:include>ing your groovy view.

For most cases where the view is rendered once or twice in the page, groovy is not a major block. But once the view is being rendered 1000's of times I have found that you need to switch to jelly.

BUT performance aside, the critical issue for me is debugging the resulting markup.

When you use the groovy view it can be great for specifying complex logic, e.g. let's take an example view:


package hudson.model.View;

t=namespace(lib.JenkinsTagLib)
st=namespace("jelly:stapler")

if (items.isEmpty()) {
    if (app.items.size() != 0) {
        set("views",my.owner.views);
        set("currentView",my);
        include(my.owner.viewsTabBar, "viewTabs");
    }
    include(my,"noJob.jelly");
} else {
    t.projectView(jobs: items, showViewTabs: true, columnExtensions: my.columns, indenter: my.indenter, itemGroup: my.owner.itemGroup) {
        set("views",my.owner.views);
        set("currentView",my);
        if (my.owner.class == hudson.model.MyViewsProperty.class) {
            include(my.owner?.myViewsTabBar, "myViewTabs");
        } else {
            include(my.owner.viewsTabBar,"viewTabs");
        }
    }
}

How would this look in jelly?

<j:jelly xmlns:j="jelly:core" xmlns:st="jelly:stapler" xmlns:t="/lib/hudson">
  <j:choose>
    <j:when test="${items.empty}">
      <j:if test="${app.items.size() != 0"}">
        <j:set var="views" value="${it.owner.views}"/>
        <j:set var="currentView" value="${it}"/>
        <st:include it="${it.owner.viewsTabBar}" page="viewTabs.jelly"/>
      </j:if>
      <st:include page="noJob.jelly"/>
    </j:when>
    <j:otherwise>
      <j:set var="views" value="${it.owner.views}"/>
      <j:set var="currentView" value="${it}"/>
      <t:projectView jobs="${items}" showViewTabs="true" columnExtensions="${it.columns}" indenter="${it.indenter}" itemGroup="${it.owner.itemGroup}">
        <j:choose>
          <!-- this is really the reason why there was a switch to groovy view as EL will not give the Class -->
          <j:when test="${it.owner.class.name == 'hudson.model.MyViewsProperty'}">
            <j:include it="${it.owner.myViewsTabBar}" page="myViewTabs.jelly"/> 
          </j:when>
          <j:otherwise>
            <j:include it="${it.owner.viewsTabBar}" page="viewTabs.jelly"/> 
          </j:otherwise>
        </j:choose>
      </t:projectView>
    </j:otherwise>
  </j:choose>
</j:jelly>

More typing, and there is a restriction from the Jelly EL being unable to instantiate static classes so we need to test against a class name (though perhaps a more correct test would be ${it.owner.myViewsTabBar!=null} as that allows for extension of the MyViewsProperty type)

But here is the question for you, where do you actually get IDE expansion help with the groovy view?

The IDE does not know the type of `my` so command completion on `my.` will just give you all possible options for any type... well that was helpful... NOT (I say a draw comparing groovy views with jelly views as all possible options is no better than no command completion... what we really want is the stapler plugin for IntelliJ to provide a custom language for the Jelly EL so that you get completion therein - and a stapler specific plugin might well be possible to infer the type of `it` in the root of a page at least)

OK, what about the `t.pro` giving command completion for `t.projectView`... well I get that exact same equivalent completion for `<t:pro` in the jelly files using the IntelliJ plugin (I say a draw comparing the two)

OK, what about debugging the resulting HTML? With the jelly view it follows the structure of HTML. If I need to inject a HTML tag and control exactly what the tag looks like, I just type it in exactly. With the groovy view, I am a layer of abstraction away. (I say the jelly views win on this one)

So the result I see is that:

* Jelly wins on performance (but I am willing to concede that if you maybe converted *everything* to groovy that might not be the case)

* Jelly wins on debugging resulting HTML (though might require a bit of exposure to XSLT to fully appreciate)

* Jelly wins on interaction with web designers (they can grök the jelly files more easily than the groovy views)

* Jelly draws on taglib completion (at least for my IDE of choice)

* Jelly draws on EL completion

* Groovy might have a very slight edge over Jelly EL in terms of technical capabilities invoking static methods

I choose Jelly every time for all of the above reasons.

-Stephen


Robert Sandell

unread,
Sep 10, 2015, 5:35:24 AM9/10/15
to jenkin...@googlegroups.com
I hope Jacqueline didn't expect a flame war ;)

As Kanstantsin and Stephen points out is that Jelly is better if you are a beginner because there is better documentation, more examples to draw from and the syntax itself is closer to html, so often simpler to debug with an ocular inspection. And the groovy views has their quirks that you sort of need to learn over time what they are.
I usually think of jelly as if ANT and JSP had a child with all the power and quirks of those engines combined :)

What Stephen missed though in his debug defence is that you can actually debug a groovy view, as in put a breakpoint on the line and step through it as it gets executed and inspect variables etc. although you won't see the resulting html until after the view is fully executed.
And the code completion is simply fixed by starting your script with MyBuildStep myStep = my; and you'll get your code completion in full effect.

For me it mostly comes down to taste. I normally go for groovy views because I feel the code gets cleaner, especially if you need a bit more fancy logic and static class access, and that you can step through that logic in a debugger if that logic doesn't work as expected.

/B


For more options, visit https://groups.google.com/d/optout.



--
Robert Sandell
Software Engineer
CloudBees Inc.

Jesse Glick

unread,
Sep 10, 2015, 1:08:54 PM9/10/15
to Jenkins Dev
I generally use Jelly views by default, but switch to Groovy if the
view really needs some complex logic in it: something beyond accessing
public properties of Java objects and doing simple if-then tests.

Really I would prefer a different view engine altogether, based on
`src/main/java/**/*.java` logic + static prototype
`src/main/resources/**/*.html`, but that is a topic for another day…
Reply all
Reply to author
Forward
0 new messages