Download NetBeans!

20071122 Thursday November 22, 2007

Direct vs. Precompiled Mode in Groovy

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:

    newScript.main(args);

    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.

Nov 22 2007, 04:52:47 AM PST Permalink