JVM Language Integration

 
Aug 12, 2010

By Barney Boisvert (www.barneyb.com)

In 2002, Macromedia released CFMX, a port of ColdFusion to the JVM (from it's prior C++ codebase). In the eyes of most CFML developers, this was largely irrelevant. However, this change turned every CFML developer into a JVM developer. For free.

What does it mean to be a JVM developer? First, it does not mean you're a Java developer. There's a fundamental difference: Java is a programming language, while the JVM (with its JRE) is a runtime environment. By the time the JVM gets hold of your code, there's no way to tell what language it was written in.

JVM, JRE, JSR, etc.

The JVM is the Java Virtual Machine, which is the platform-specific virtual machine responsible for executing Java bytecode (which itself is platform-neutral). The JRE is the Java Runtime Environment, which is comprised of the JVM plus the core Java class libraries (collections, graphics, crypto, etc.). All bytecode runs on the JVM, but your code doesn't have to leverage the whole JRE. For example, if you don't care for the JRE's Collections classes, Apache Jakarta provides alternate implementations. If you don't like the built-in windowing toolkit, you can use SWT from Eclipse.

JSR or Java Specification Request is the way the Java community specifies new functionality for the Java Platform as part of the Java Community Process. Each JSR has a unique identifying integer (e.g., JSR-170 or JSR-223). More information about specific JSRs and the process as a whole can be found at http://jcp.org/en/jsr/overview.

It does mean that you can write your code in any language that runs on the JVM, and it'll all seamlessly work together. I'm not talking about using CFML in a JEE development flow (that beastly write-compile-restart-refresh cycle). I'm talking about keeping your existing CFML workflow (write-refresh), but not being constrained to CFML.

The cornerstone of this is JSR-223, which specifies an implementation- and language-neutral way of integrating scripting languages (such as JavaScript) into applications running on the JVM. In simpler terms, if you have code running on the JVM, you can seamlessly jump over to code written in another language, and then bounce back to the original code. You already do this with CFSCRIPT blocks, or SQL within CFQUERY blocks. But now you can do it with Groovy, JavaScript, Ruby, or Python.

The JSR-223 integration is a set of interfaces that the scripting language must implement, along with a registry mechanism for registering your scripting language with the JRE it is available to. In most cases you need only place the language JAR onto your classpath and you can use it via the javax.script.ScriptEngineManager class. But that gets kind of hairy if you're doing it all over the place.

Enter CFGroovy

Several years ago, I created the CFGroovy framework to hide the nitty-gritty bits so I could easily use Groovy within my CFML. I almost immediately generalized the tag to work with any JSR-223 language, and made it publicly available so you can skip all that nitty-gritty too, regardless of whether you want to use Groovy or not. Let's see it in action, shall we?

First, here's a very simple example of CFSCRIPT within CFML:

<cfset variables.myArray = ["hello"]>
<cfscript>
arrayAppend(variables.myArray, "world");
</cfscript>
<cfoutput>#arrayToList(variables.myArray)#</cfoutput>

The output of this little snippet would be "hello,world". If we simply replace ColdFusion's CFSCRIPT tag with CFGroovy's <g:script> tag, we can use JavaScript instead of CFSCRIPT:

<cfset variables.myArray = ["hello"] >
<g:script lang="js">
variables.get("myArray").add("world")
</g:script>
<cfoutput>#arrayToList(variables.myArray)#</cfoutput>

The CFML is identical; only the "inner" language has changed. Here's one more version, this time with Groovy:

<cfset variables.myArray = ["hello"] >
<g:script>
variables.myArray += "world"
</g:script>
<cfoutput>#arrayToList(variables.myArray)#</cfoutput>

The first thing you should notice is that we're using the normal CFML 'variables' scope within the script, regardless of what language it is. The same thing goes for any of the other scopes: application, cgi, cluster, etc. The syntax to dereference the scopes is language-specific, of course, but they're the same CFML scopes you already know and love.

Why Mix Languages?

Every language has a different set of strengths and weaknesses. CFML is great for templating, but it's not so hot when it comes to manipulating complex data structures or interfacing with Java APIs. JavaScript has familiar syntax and very useful functional constructs, but it has a bit of a mismatch between its concept of objects and arrays and the ones that the JRE provides. Groovy, in my opinion, hits the sweet spot: its syntax is familiar enough for CFML developers to easily grasp, and it provides augmented access to the entire JRE in a dynamic and non-ceremonious language.

These are just three languages, of course. JSR-223 supports at least 35 languages, including pretty much all the big-name languages on the web. Which ones are best for you is something only you can answer. But as it's so simple to get started, there's no reason not to try two or three and see what you like. Maybe you already know PHP and so Quercus (Caucho's PHP implementation) is a good fit. Perhaps you want to mix some Rails code in and so JRuby is what you want.

I'm certainly not going to suggest using PHP in place of CFML, but PHP is one of many languages available for the JVM with a massive developer base. That breadth of developers means a lot of code that you can leverage in your CFML apps if you're willing to cross the language boundary. Maybe you're taking over a WordPress site and need to replicate some piece of custom functionality and it's easier to just leave it as PHP. My personal favorite is stealing Java snippets and running them unchanged as Groovy scriptlets. This is especially helpful when integrating some third-part Java API, because you can just grab their sample code and run it — no compiler, no container restarts, nothing.

As a JVM developer, you owe it to yourself to check out the languages available for the JVM. There are a lot of choices, and every one of them is both better and worse than CFML. The art is to use each language for its strengths, thereby never using a language where it's not well suited. Fortunately with today's modern JVMs, that is a very accessible reality.

A note on JVM vs. JRE: the JVM actually executes Java bytecode, which is what every compiled JVM language ends up as. The JRE is the JVM plus the core class libraries (collections, graphics, crypto, etc.) available to Java. Java code is written against the core libraries and executed on the JVM. CFML and Groovy are implemented atop the JRE core libraries. Scala, as a counterpoint, provides its own collection classes in addition to the JRE-provided ones, and Jython even replaces the implementation of numbers. This is one reason CFML and Groovy play nicely together, but using Scala and Jython together could be more problematic.


Barney Boisvert is a Senior Application Developer for Mentor Graphics Corp in Wilsonville, OR. He has been developing CFML, Java, and Groovy applications for over 10 years, ranging from ecommerce to crisis communication management to business intelligence. A strong proponent of open source, he has produced several frameworks and packages for CFML developers, as well as contributing to existing projects (including Fusebox, ColdSpring, Hibernate, Groovy, and Prototype). His blog on various technical topics can be found at http://www.barneyb.com. In his spare time he can usually be found on some mountain road — precariously balanced on two wheels — or eating something delicious.



Add a Comment
(If you subscribe, any new posts to this thread will be sent to your email address.)
  
Privacy | FAQ | Site Map | About | Guidelines | Contact | Advertising | What is ColdFusion?
House of Fusion | ColdFusion Jobs | Blog of Fusion | AHP Hosting