Creating a Hybrid ColdFusion – Java Project in Eclipse

Sunday, May 23, 2010

On more than one occasion recently I’ve wanted to incorporate Java libraries into ColdFusion applications. You can do this in your CFML, but it usually involves the following:

  1. CFML code littered with createObject(“java”,”whatever.Whatever”);
  2. Zero content assist for the Java objects
  3. Optionally, Putting jar files in your CF installation’s lib directories and deploying those to all servers (dev, test, staging, prod) and developer machines

1 and 2 are the worst problems because 3 is solved with Mark Mandel’s javaloader (more on that later).

Ideally, I’d be able to write Java code in Java source files, compile it and test it in Eclipse, and fairly seamlessly use it in my CFML… in the same project. In this post, I’ll show you how to set it up in ColdFusion Builder. Note that these same steps apply to CFEclipse as well. In a follow-up post, I’ll show a more real-world example

Create your CFML project

  1. In CFBuilder or CFEclipse, either create a new project or use an existing one.
  2. Create a directory named “java”
    1. under there, create “src”, “bin”, and “lib” directories
    2. Download javaloader from Mark’s site, and drag the “javaloader” directory into the root of your project (or put it in your webroot)
    3. If you put it into your project, add this to your Application.cfc: this.mappings["/javaloader"] = getDirectoryFromPath(getCurrentTemplatePath());

By now, your project should look something like this:


Apply the Java Nature

  1. Close the project: right click – “Close Project”
  2. From the file system, open the project’s “.project” file in a text editor
  3. In the “<natures>” element, add this: <nature>org.eclipse.jdt.core.javanature</nature>
  4. In the “<buildSpec>” element, add the following:


Back in Eclipse, open the project (right click -- “Open Project”). Once you do that, it’s going to look very strange… something like this:



Configure the Java Build Path

Your project now looks funky because it’s treating everything as a Java source folder. Let’s fix that.

  1. On the project, right click, select “Build Path”, then “Configure Build Path”
  2. In the “Source” tab, remove any entries
  3. In the same tab, select “Add Folder” and navigate to your project’s “java/src” folder
  4. Down at the bottom, in “Default output folder” text field, browse to your project’s “java/bin” directory

Now, your project should look something like this:


That’s better.


Create a simple Java file

Note in that screenshot above that you have “java/src” with a package decorator… that’s where you’ll be working. Ignore the “java” directory that you see in that screenshot… we don’t care about it for now.

  1. In the “java/src” directory, right click, select “New – Package”. Name it “hello”.
  2. In that (now empty) package, right click, select “New – Java Class”. Name it “Hello”
  3. This will open a new in a java editor. Let’s create a simple “echo” method. For now, just use a “main” method to drive it in Eclipse… we don’t need to get fancy with unit tests just yet:

package hello;

public class Hello {
        public String echo(String input){
                return "Hello. You said: " + input;
        public static void main(String[] args) {
                Hello h = new Hello();

If all goes well, you should be able to run this file and see output in the console. To run it, select “” in the Project Explorer and hit the green “Play” button in the toolbar, or right click in and select “run as – java application”, or hit “Alt-Shift-X, J"

Use it in your CFML

To use it in your CFML, you’ll want to use javaloader. Conceptually, you simply tell javaloader where your compiled classes are, where any additional .jar files live, and then use it to create objects. Here’s what it looks like in practice. For demo purposes, I just created a file in my project root; thus, all paths you see in here are relative to that file in the root.

<!--- set up javaloader --->
<cfset binDir = expandPath("java/bin")>
<cfset libDir = expandPath("java/lib")>
<cfset jars = directoryList(libDir)>
<cfset arrayAppend(jars,binDir)>
<cfset loader = createObject("component","javaloader.JavaLoader").init(jars)>

<!--- run it --->

<h2>Echo example</h2>
<cfset hello = loader.create("hello.Hello")>

If you’ve done everything right, when you run this in your browser you should see the expected output. If you go back into your java file, make a change, and hit refresh in the browser, the  changes you made should be reflected.

Final Thoughts

For years, folk have praised the ability to integrate Java into CFML. However, the workflow has always been complicated and the tooling nonexistent. CFMLers who’ve worked for years without content assist on their own Components most likely have no idea just how powerful an ally their IDE can be. So we suffer, typing “whatever = createObject(“java”, “some.Java”); whatever.NowWhatWasThatMethodAgain(AndWhatWereThoseArgumentsAgain)”, not realizing that if we were writing our java in a “real” editor, you’d get all the richness the IDE can offer. In other words, most CFMLers don’t know what they’re missing when they have to incorporate java into their projects.

I am not saying that when you create Java objects in your CFML code that you’re going to get content assist; rather, what I’m saying is that if you have more than a few lines of Java code in your CFML, then perhaps it’s best to put that code into its own Java sources – inside the same project, as I’ve described above – and simplify the work you have to do with Java without sacrificing workflow and deployment speed.

It also opens up some other nice possibilities: If you’ve a Groovy fan, or have a problem that would be better suited for Groovy – yes… even if the thing you want to do is simply more enjoyable in that language --- then you could do very similar steps to turn your CFML project into a hybrid Groovy project. Create your Whatever.g sources, and use Barney Boivert’s excellent CFGroovy to run your Groovy sources.

If you need to write some java of your own, and you need to incorporate it into your CFML projects, then this IDE setup can help you.

Coming soon: a real-world example.


Mark Mandel said...

That's interesting! I never thought of adding the Java nature.

The way I do it, is I will create a seperate Java project in my workspace, and then do a linked source folder pointing to where my Java source is in my ColdFusion project.

I guess because I do that, I tend to then let JavaLoader (1.0) compile my source code for me at run time, as the .class files are in a seperate Java project, but since you have your compiled classes right there, that makes perfect sense as well!

Very cool stuff!

qasimrasheed said...

Awesome, never knew that is was possible to add another nature to a project. This will definitely make life easier by maintaining both language code together.

Thanks a bunch