Geertjan's Blog

  • November 22, 2007

Direct vs. Precompiled Mode in Groovy

Geertjan Wielenga
Product Manager
Groovy can be used in two modes, Dierk König et al, in "Groovy In Action" tell us, on page 19:

  • Direct mode. Code is "directly executed, without producing any executable files".

  • Precompiled mode. The second way, which involves taking the code and "compiling it to Java bytecode and running it as regular Java application code within a Java Virtual Machine (JVM)".

Importantly, notes the book: "Both ways execute Groovy inside a JVM eventually, and both ways compile the Groovy code to Java bytecode. The major difference is when that compilation occurs and whether the resulting classes are used in memory or stored on disk".

I'm stating the above things so explicitly because of the implications this has for the Groovy plugin on the Plugin Portal. If, for example, I run Groovy script that looks as follows, there is no need to compile the code explicitly. It simply works, because here we are making use of direct mode:

Here (i.e., in the pic below), however, the situation is different. Here we are dealing with a closure. When we run this by simply right-clicking in the editor and choose Run, as done above, nothing appears in the Output window, because we are using direct mode, while we should be using precompiled mode:

To use precompiled mode, we basically need to set up a Groovy harness within our Java application. Parts of this are already supported by the Groovy plugin. Parts are not and need to be done manually. I've been doing them manually all along, but will automate the following steps in the next version of the plugin. Here I'm just writing them down so you know what you need to do to run scripts such as the above. (I'm also doing this as a reminder to myself of what I need to do to automate this next time I work on the plugin.)

  1. We need to use groovyc to compile the script. (Joint compiler is something I haven't even begun to look at yet.) However, everything you need for groovyc is already provided by the plugin. Start by creating a new application after installing the plugin. (Only Java applications supported currently, though possible in others, not explicitly supported.)

  2. Now, right-click the Libraries node and choose Add Library. Choose Groovy and then click Add Library and then (a snapshot build of) Groovy 1.1 RC 2 is added to the Libraries node. That library includes groovyc. Now we need an Ant script that will call it.

  3. Right-click the application's project node and choose Properties. Note there is a new panel, called "Groovy", provided by the plugin. In it, click the checkbox that says "Ant Task for Compiling Groovy". Then click OK.

  4. Now switch to the Files window. In the nbproject folder, you will find an Ant script called groovy-compile-impl.xml. Open it. Notice that it will compile to a folder called "groovy". Create that folder in the Files window. (That will automatically be done for you in the next version of this plugin.) Notice also that the Ant script refers to a library (the snapshot library that you added to the project earlier). The script says that the library is in dist/lib. Currently it isn't there.

  5. Build the project. Now, back in the Files window, you have dist/lib containing the Groovy snapshot build.

  6. The earlier step where we generated the Ant script did more than just generating the Ant script. It also hooked it up in such a way that, when you right-click the build.xml, you can choose the "groovyc" target. (The next version of the plugin will hook that target to the project's Compile target, so that those two work together. Or the joint compiler will somehow be included.) You can now choose that "groovyc" target. Since we have no Groovy scripts, nothing is compiled, but at least you can see that it is now possible.

  7. Now go back to the Projects window. Right-click the Libraries node and add the "groovy" folder to the Libraries node. We need to do this to let the (currently non-existent) compiled Groovy classes be available to code completion in our Java source files.

  8. Now add a Groovy script, but in a Java class format, i.e., with a package declaration, class declaration, and method declaration:

    package javaaplication36;
    class newScript {

    public static void main(String[] args) {
    def x = 1
    3.times {
    println x++

  9. Next, run the groovyc target. The groovy folder, visible in your Libraries node, now shows the compiled class, as well as a class for the closure:

  10. And now you can call the main method above from your Java class:


    It has to be done this way, because currently one can't run the Groovy script (except in direct mode) and there is no right-click Run action on compiled Java classes. (That would be a very nice thing to have.)

  11. When you run the application, you now get the expected results, i.e., via the closure in the Groovy script (or, in fact, via the compiled Java class):

The moral of this story is that if you try to run a Groovy script using the plugin, and nothing appears in the Output window (or wherever it should appear), the reason probably is that you need to be making use of precompiled mode. The above is the current way of setting that up. It might seem slightly cumbersome, and currently it is unnecessarily cumbersome, because the plugin could take care of more things than it does right now (i.e., creating the 'groovy' folder, adding it to the Libraries node, and hooking the Ant groovyc target to the general build process), none of which would be hard to do. Also, I will include samples in the next version, i.e., samples that have the correct folder structure and so on already defined, so that you can look at how it should be done. Anyway, until those parts are automated, now at least you know what you need to do in these cases.

Note, again, that the above procedure only applies if you are using Groovy's precompiled mode. Otherwise, simply right-click in the editor and choose "Run". The Groovy script is then directly executed without producing executable files.

Join the discussion

Comments ( 8 )
  • guest Thursday, November 22, 2007


    Running a groovy script via groovy.bat does not require pre-compiling.

    Moreover groovy shall be able to compile scripts on the fly.

    I try this with the old coyote plugin.

  • Marcus Thursday, November 22, 2007

    Yes, I agree. This runs fine on the console

    groovy -e '3.times { print "$it " }'

    So why should I have to create that boiler plate code?

    And: how does the groovyConsole work? Isn't that 'direct' as its best?


  • Victor Thursday, November 22, 2007

    Geertjan, thanks for your Groovy article series, great to see there's a Groovy life on Sun... erm, NetBeans side :P Really, it's great.

    Nevertheless, I'm not sure I understand why shouldn't the small script in your second screenshot run without being compiled, e.g.:

    groovy -e "def x = 1; 3.times { println x++ }"

  • Victor Thursday, November 22, 2007

    Heh, Marcus was two minutes faster ;)

  • Geertjan Thursday, November 22, 2007

    Well, Marcus and Victor, and, I don't know why exactly. I don't know the "why" but I do know that the above is true. Try it for yourself. I would like to know the reason, maybe something with classloaders, but I don't understand why one type of Groovy script works in direct mode while another doesn't. Closures can definitely not be run by the Groovy plugin in direct mode.

  • Ranganath.S Thursday, November 22, 2007

    hi geertjan,

    Is this plugin same as wht Martin Adamek is doin? if not why two versions of same plugin?

  • Geertjan Thursday, November 22, 2007

    Not same plugin, Ranganath. I will blog about it today. However, here his plugin is described, and he gives you the answer to your question: http://martin.adamek.sk/

  • Schummy Wednesday, December 5, 2007

    Seems in step 5, the groovyc jar cannot be moved to the dist/lib, I have to manually copy it there to make it work.

Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.