CF Groovy

Those of you who remember CF Rhino will recognize the name for my latest little project. I whipped up a small proof-of-concept integration for Groovy into CF apps tonight while playing with some classloading issues within Groovy itself.

Groovy has a number of advantages for this type of integration of JavaScript, the biggest one being that Groovy IS Java, and carries Java's semantics almost perfectly. So unlike with Rhino, no major conversions are needed moving in and out of Groovy, which makes things enormously easier. CF still brings it's special blend of "insane" to the party, but it works quite well overall. Definitely has more real-world potential than CF Rhino ever did.

CF Groovy is not a whole framework like CF Rhino was, it's really just a proof of concept for integrating the two together and sharing resources. You can get the demo (which includes the engine via svn:externals) from Subversion at https://ssl.barneyb.com/svn/barneyb/cfgroovy/trunk/demo/. Just check it out to a directory named 'cfgroovy' in your webroot, drop the groovy JAR from the 'groovyEngine' subdirectory into your /WEB-INF/lib folder, and you should be done.  You can see it in action at the demo page, though without source to browse, it's not very interesting.

Also, unlike CF Rhino, there's no dependencies on the internals of ColdFusion (the Adobe product). To do some of the bridging to JavaScript, I had to invoke internal APIs of ColdFusion, so it wouldn't run on BlueDragon, Railo, etc. I built CF Groovy with Open BlueDragon and Railo 3 on Tomcat simply because I didn't have a CFML runtime on my box, and CF is like 400MB while oBD is 11MB and Railo is 25MB.

Unfortunately, all three runtimes have bugs that prevent them from working as expected.

Railo was the worst: it has some recursion issue with the JEE.include() call. It also doesn't seem to implement java.util.Map with it's struct implementation, and throws on missing keys rather than returning null.

Open BlueDragon initializes ResultSets from manually assembled queries (and possibly "real" queries) with the row pointer pointed at the first row, rather than before the first row as the spec says it should be.

ColdFusion doesn't create java.util.Date objects with the createDate built in, so trying to call ResultSet.getDate() throws a ClassCastException. Using ResultSet.getObject() and letting the ducks work their magic fixes this issue. It's also 15-35 times larger than the others.

Except for the download size issue, I've got conditionals to cover all the cases in the app, so it should be checkout and run on all three platforms. I haven't tested NA BD, CF7-, or Railo 2. I don't know why they wouldn't work, though, since I'm just doing standard Java stuff. I'm not doing any version conditionals, only platform ones, just in case.

5 responses to “CF Groovy”

  1. Dan Roberts

    Very cool. Is this something that, given some more work, you plan to use for real projects?

  2. Streit Michael

    hi barneyb

    you are absolutly right, a railo struct does not extends java.util.Map.
    that's because railo's struct is optimized for the railo enviroment, it neeeds no interpetation, like a map in cfmx needs.
    why you access a struct via reflection (struct.get(key)) instead of native cf access (struct[key]), every refection access is 1000 times slower than a native access! reflection access on coldfusion object is always the worst decision.

    on java level railo can't be 100% similar to cfmx, only cfmx can this.

    what is exactly the problems with include?

    greetings michael

  3. Comparators in CF with Groovy at BarneyBlog

    [...] wanting to create little ad hoc Java classes in my CF apps in a common occurrence for me.  With my CF Groovy project, it's both possible and very easy.  No Java, no compiling, no classloading [...]