X

Geertjan's Blog

  • February 13, 2009

Running Groovy on the NetBeans Platform

Geertjan Wielenga
Product Manager
Here's a Groovy POJO:

package org.my.app
public class DemoPojo {
def foo


}

And here's my ModuleInstall class (which is a NetBeans module's lifecycle manager), which uses its restored() method to instantiate the POJO, set the variable, and then print out the variable. Oh, by the way, the class below is, just like the above, a Groovy class. The thing to notice is that I defined no getter/setter in the POJO above, because Groovy simply assumes I have them, and that there are no semi-colons at the end of the statements at all (thanks again Groovy).

package org.my.app
import org.openide.modules.ModuleInstall as MI
public class Installer extends MI {
@Override
public void restored() {
for(int i = 0; i < 10; i++) {
DemoPojo dp = new DemoPojo()
dp.setFoo(i)
println("Number: " + dp.getFoo())
}
}
}

Also, the "println" statement comes from Groovy, without my needing to import the class. Look also at the abbreviation for my imported class, which I can then refer to in that way in my class signature (and anywhere else). In fact, I could use any Groovy constructs at all now.

So the above two are in a module. The ModuleInstall class is registered in the Manifest, just like any other ModuleInstall class, because after compilation the Groovy class becomes a Java class. At that point, there's no difference anymore.

To make all of the above possible, add the following to your module's build.xml file:

<taskdef name="groovyc"
classpath="ext/groovy-all.jar"
classname="org.codehaus.groovy.ant.Groovyc"/>
<target name="netbeans-extra">
<groovyc srcdir="${src.dir}" destdir="${build.classes.dir}">
<classpath refid="cp"/>
</groovyc>
<jarwithmoduleattributes jarfile="${cluster}/${module.jar}"
compress="${build.package.compress}" index="${build.package.index}"
manifest="${manifest.mf}" stamp="${cluster}/.lastModified">
<fileset dir="${build.classes.dir}"/>
</jarwithmoduleattributes>
</target>

So, after the Groovy compiler does its thing, the module's JAR is recreated, using the output from the Groovy compiler. Note that, as indicated above, you need a folder in your module named "ext", containing "groovy-all.jar". You also need to put your module in a suite and set a dependency on a library wrapper module that contains "groovy-all.jar".

Here's the Projects view on my module, isn't it cool to see only Groovy classes there?

Then you've got everything you need to run Groovy on the NetBeans Platform. Now excuse me while I go and create some file templates for Groovy versions of TopComponents, Actions, and so on...

Join the discussion

Comments ( 17 )
  • Jesse Glick Friday, February 13, 2009

    Unfortunately Groovy for Platform development becomes less appealing with NB 7.0 because groovyc does not seem to support JSR 269 - or at least gmaven-plugin does not support it, and nothing on the Groovy site indicates that it is even planned. Which means that any objects you want to register declaratively must either be written in Java or registered the old way in the XML layer.


  • Geertjan Friday, February 13, 2009

    Well, what's so wrong with using the XML layer? If that's the only downside, then that's not so bad at all. The real downside is joint compilation between Java and Groovy. My approach above assumes that everything is Groovy classes. Well, I don't see what's wrong with that. But, add one Java class and this solution fails.


  • Sven Reimers Saturday, February 14, 2009

    So what about doing the same using jython? Anyone any experience?


  • Geertjan Saturday, February 14, 2009

    Good question. All you need is an Ant target like the one I show above for Groovy. That's all it would (should) take.


  • Paul King Sunday, February 15, 2009

    Jesse, where is a good sample of registering an object declaratively using Java?


  • Geertjan Wielenga Sunday, February 15, 2009
  • Paul King Sunday, February 15, 2009

    Re: Only Groovy files ...

    Just added "&lt;javac includes="\*.java"/&gt;" inside the groovyc task as well a Doubler Java class and changed restored() method in Installer

    5.times { int i ->

    int j = Doubler.twice(i)

    def dp = new DemoPojo(foo:j)

    println "Number: " + dp.foo

    }

    Seemed to work fine unless Netbeans was doing something special and compiling Doubler under the covers.


  • Geertjan Wielenga Sunday, February 15, 2009

    Awesome!!! Going to try that right away.


  • Geertjan Wielenga Sunday, February 15, 2009

    Yup, your example works for me. The Ant target needs to be tweaked exactly as you have it. Java and Groovy integration on the NetBeans Platform. How cool is that.


  • Geertjan Wielenga Sunday, February 15, 2009

    Re: annotations and Groovy files ...

    See this screenshot, which is quite interesting:

    http://blogs.sun.com/geertjan/resource/groovy-warning-sprovider.png


  • Paul King Sunday, February 15, 2009

    The error message is partially obscuring the next line but it looks as if the next line might be an inner class which isn't supported until Groovy 1.7 (there are usually better ways, e.g. closures, to do inner classes in Groovy). Perhaps the example needs some restructuring.

    Groovy doesn't have explicit JSR 269 support but given that it calls javac under the covers for joint compilation (gmaven I am less clear on) perhaps there is some stuff that can be easily made to (already does?) work.


  • Paul King Tuesday, February 17, 2009

    Using a Groovy installer class and a restore() method like:

    Lookup.default.lookupAll(DemoInterface).each {

    di -> println "Hello from Groovy: " + di.name

    }

    seems to allows hooking into JSR269 services without issues. At the moment you would still need to write the actual service in Java but it seems to happily all sit together using the previous mod to the build file for enacting the joint compiler.


  • Jesse Glick Tuesday, February 17, 2009

    The screenshot is off base. You can indeed annotate Groovy classes - I tried - and you can even read runtime annotations using reflection. And of course you can look up services from Groovy code. What you cannot do, as Paul King just said, is write the service in Groovy: the annotation will be accepted by groovyc but there is no META-INF/services/org.demoservice.DemoInterface file generated as a result.

    Since more and more NetBeans SPIs are being migrated to the use of annotations for their registration, Groovy cannot be a full replacement for Java in such modules - unless you manually create old-style XML layer entries, which is also becoming more difficult to do as more advanced lazy loading strategies are implemented.

    It would be great if Groovy's compiler could support JSR 269. While the JSR of course does not define a source language exactly like Groovy, in practice most of javax.lang.model.\*\* would fit Groovy pretty well (since it is designed to compile into more or less "natural" JVM classes). Indeed, if mixed compilation is accomplished simply by generating \*.java from Groovy sources, as the Maven plugin seems to do, then it would seem straightforward to run annotation processors, though mapping Filer messages back to original \*.groovy sources could be tricky.


  • Paul King Tuesday, February 17, 2009

    @Jesse: yes, that summaries it well. No promises, but there is now an issue to track this in Groovy's Jira:

    http://jira.codehaus.org/browse/GROOVY-3361

    If you can think of any suggestions for getting the ball rolling or good standalone examples that can act as a driver, please feel free to add comments to the issue.


  • anonymous Saturday, February 28, 2009

    Great, i searched a long time for this. Maybe someone can update this open issue now.

    http://www.netbeans.org/issues/show_bug.cgi?id=129812


  • Sam Griffith Friday, July 31, 2009

    Hello Geertjan,

    I was wondering if you could maybe explain this section of the instructions more.

    "So, after the Groovy compiler does its thing, the module's JAR is recreated, using the output from the Groovy compiler. Note that, as indicated above, you need a folder in your module named "ext", containing "groovy-all.jar". You also need to put your module in a suite and set a dependency on a library wrapper module that contains "groovy-all.jar"."

    If you have a groovy-all module that has the 'groovy-all.jar' in it and you have the other module 'Demo' that is dependent on the'groovy-all' module, then why do you have to add groovy-all.jar to your 'Demo' module?

    Seems like the Demo module should find the jar file because of the dependency? The only other thing I can think of is that you need the jar locally in 'Demo' for compile time resolution and then the module 'groovy-all' is used at run-time. But that doesn't seem to make sense at all either.

    Thanks for you time to explain a bit more. I've got it working by doing what you suggest above in 6.7, but was wondering about why the jar file for groovy is needed in both modules.

    Thanks!


  • Artur Friday, September 16, 2016

    This post is very outdated, im trying to do it with netbeans 8.1 but isn´t working. Can someone help?


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

Integrated Cloud Applications & Platform Services