Hello World with ColdFusion and Spring

Firstly, what is Spring? Spring is a Java based ‘dependency injection’ framework, which is a complicated name for something that simply ‘helps objects to talk to each other’ in a well designed way. Spring is the framework that was the basis for the popular ColdFusion dependency injection framework, ColdSpring.

Learn more about dependency injection in ColdFusion

Visit the ColdSpring site

Visit the Spring site

So why use Spring? Typically you would not need to, but using Spring in a ColdFusion application is only applicable when you want to develop larger aspects of your application in Java rather than CFML. This may be useful, for example, if you were to develop your business logic layer in Java and use CFML for your views.

Using CFEclipse

For this demo code I am using Eclipse/CFEclipse and have created a project called springdemo.

All of the directory and file references below are relative to the root of the project.

Preparing our project structure

Let’s create a few directories to hold all of the files we’ll need.

First create the directories for the Java code

  • /java – Root of our Java code
  • /java/src – Java source files
  • /java/build – Compiled java class files
  • /java/dist – Compiled java class files packaged into a ‘jar’ file

Then a directory for the CFML code

  • /web – CFML code goes here

For this example, the directory /web is the web root of the application. For example, you can set up a local URL http://springdemo.localhost/ which points to this folder.

And lastly, a directory to hold some java libraries that we will download

  • /lib – Java libraries go here

Download everything we need

Download Spring

Download the Latest GA Release, which at the time of this writing is spring-framework-2.5.6.SEC01.zip

http://www.springsource.com/download/community

Unzip the file and place the spring directory into the /lib folder.

/lib/spring-framework-2.5.6.SEC01

Download Commons Logging

The Commons Logging library is required by Spring.

Download the binary zip file, which at the time of this writing is commons-logging-1.1.1-bin.zip

http://commons.apache.org/downloads/download_logging.cgi

Unzip the file and place the commons logging directory into the /lib folder:

/lib/commons-logging-1.1.1

Download JavaLoader

We will use the JavaLoader to load the classes we need rather than needing to configure them in the ColdFusion administrator.

Download JavaLoader, which at the time of this writing is javaloader_v0.6.zip

http://javaloader.riaforge.org/

Unzip the javaloader zip file and place the javaloader directory into the /web directory:

/web/javaloader

Create a simple Java class

First, let’s create a simple Java class that will provide our ‘hello world’ message. Create this GreetingService.java file in the directory:

/java/src/com/greeting/

package com.greeting;
 
public class GreetingService {
 
	// Private greeting variable
 
	private String greeting = "";
 
	// Constructor, similar to init() on CFCs
 
	public GreetingService(String greeting) {
		this.greeting = greeting;
	}
 
	// Returns the greeting
 
	public String sayGreeting() {
		return greeting;
	}
 
}

Compiling our Java class

There are a number of ways we can compile this code, but I am using Eclipse’s built in Java and Ant scripting. I have created the a build.xml file in the project’s root directory:

/build.xml

<project name="SpringDemo" default="dist" basedir=".">
 
	<description>
		Simple example of Spring and ColdFusion integration
	</description>
 
	<!-- set global properties for this build -->
	<property name="src" location="./java/src" />
	<property name="build" location="./java/build" />
	<property name="dist"  location="./java/dist" />
 
	<target name="init">
		<!-- Create the build directory structure used by compile -->
		<mkdir dir="${build}"/>
	</target>
 
	<target name="compile" depends="init" description="Compile the source">
		<!-- Compile the java code from ${src} into ${build} -->
		<javac srcdir="${src}" destdir="${build}" />
	</target>
 
	<target name="dist" depends="compile" description="Generate the distribution">
		<!-- Create the distribution directory -->
		<mkdir dir="${dist}/lib"/>
		<!-- Put everything in ${build} into the greeting.jar file -->
		<jar jarfile="${dist}/lib/greeting.jar" basedir="${build}"/>
	</target>
 
	<target name="clean" description="clean up" >
		<!-- Delete the ${build} and ${dist} directory trees -->
		<delete dir="${build}"/>
		<delete dir="${dist}"/>
	</target>
 
</project>

To execute this script

  1. Right click on the build.xml file
  2. Select ‘Run As’
  3. Select ’1 Ant Build’

This should produce output in the Eclipse console similar to:

Buildfile: C:\DATA\workspace\springdemo\build.xml
init:
compile:
dist:
BUILD SUCCESSFUL
Total time: 265 milliseconds

This will have also:

1) Compiled the java code and placed the compiled files into the /java/build directory

2) Converted the compiled code into a ‘jar’ file and placed it in at /java/lib/greeting.jar

Creating the Spring configuration file

Spring uses an XML file to define all of the objects it manages. Let’s create a simple /web/beans.xml file that defines our GreetingService object:

<?xml version="1.0" encoding="UTF-8"?>
<beans
	xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
	http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">
 
	<bean id="greetingService" class="com.greeting.GreetingService">
		<constructor-arg>
			<value>Hello World!</value>
		</constructor-arg>
	</bean>
 
</beans>

This file defines our single GreetingService object and passes the string ‘Hello World!’ to the constructor.

Bringing it all together

At this point we have:

  1. the Spring (and required Commons Logging) library available,
  2. the JavaLoader available,
  3. our custom GreetingService object,
  4. our Spring definition file.

Create a /web/index.cfm file to test our code in:

First, load our three ‘jar’ files using the JavaLoader. The JavaLoader only needs to be created once, so just create it the first time the code is run:

<cfif structKeyExists(url,"reload") or not structKeyExists(server,"javaloader")>
	<cfscript>
		paths = arrayNew(1);
		paths[1] = expandPath("../lib/spring-framework-2.5.6.SEC01/dist/spring.jar");
		paths[2] = expandPath("../lib/commons-logging-1.1.1/commons-logging-1.1.1.jar");
		paths[3] = expandPath("../java/dist/lib/greeting.jar");
		server.javaloader = createObject("component", "javaloader.JavaLoader").init(paths);
	</cfscript>
</cfif>

We place the JavaLoader into the server scope so it never times out which minimises the effect of a small memory leak in the underlying Java class loader that occurs each time the loader is created.

Next, we can create the Spring factory. We’ll store the factory in the application scope and only create it if it does not already exist:

<cfif structKeyExists(url,"reload") or not structKeyExists(application,"factory")>
	<cfscript>
 
	// Create the main Spring factory object
 
	factory = server.javaloader.create("org.springframework.context.support.FileSystemXmlApplicationContext").init();
 
	// Advise Spring of the classes that have been loaded by the JavaLoader
 
	factory.setClassLoader( server.javaloader.getURLClassLoader() );
 
	// Advise Spring of the location of our Spring config file
 
	factory.setConfigLocation( expandPath("beans.xml") );
 
	// Load the config file and prepare our objects
 
	factory.refresh();
 
	// Store Spring in the application scope ready for use
 
	application.factory = factory;
 
	</cfscript>
</cfif>

Lastly, we can get our GreetingService out of Spring’s factory and ask it to display its greeting.

<cfscript>
	greetingService = application.factory.getBean("greetingService");
</cfscript>
 
<cfoutput>
	#greetingService.sayGreeting()#
</cfoutput>

Hello World

When you execute this code, you should see the message defined in the beans.xml file:

Hello World!

Feedback

I’ve looked around for code on how to get CF and Spring to work together and have not have much luck with find specific examples, so I’m posting what I have. If you have some experience in integrating CF with Java and Spring then I’d love to get some feedback or recommendations on what I’ve posted.

Thanks!

This entry was posted in ColdFusion and tagged , , . Bookmark the permalink. Both comments and trackbacks are currently closed.

20 Comments

  1. Posted November 3, 2009 at 2:26 pm | Permalink

    There is a stack more that can be done with Spring and Javaloader, be sure to check out the documentation and examples in the downloads.
    http://www.compoundtheory.com/javaloader/docs/#_ColdFusion_Spring_Integration_42221130791396544

  2. Posted November 3, 2009 at 3:44 pm | Permalink

    Thanks, Mark.

  3. Posted November 3, 2009 at 3:48 pm | Permalink

    Oh, and I forgot to mention, if you want to talk to a good crew of people about Java & CF integration, you can’t go past the JavaLoader-Dev Google Group:
    http://groups.google.com/group/javaloader-dev

    Okay, i’ll stop plugging my stuff now ;o)

  4. Posted November 3, 2009 at 4:10 pm | Permalink

    Thanks, joined!

  5. Joe
    Posted December 16, 2009 at 5:14 pm | Permalink

    Haha, good one guys!

  6. mark
    Posted December 16, 2009 at 5:16 pm | Permalink

    Wow, all of that work, for "Hello World!"

  7. Neil Middleton
    Posted December 16, 2009 at 5:16 pm | Permalink

    Insane

  8. Posted December 16, 2009 at 5:23 pm | Permalink

    Wow. That is a lot of stuff just to say "Hello World".

  9. Thomas
    Posted December 16, 2009 at 11:37 pm | Permalink

    The same with sinatra:

    require ‘rubygems’
    require ‘sinatra’
    get ‘/hi’ do
    "Hello World!"
    end

    hmm, does anybody find a difference?

  10. Posted December 17, 2009 at 12:52 am | Permalink

    Thanks Thomas, Sinatra certainly looks impressive and I look forward to learning a bit more about it. For everyone reading, the purpose of this entry is really about connecting to Spring managed Java classes from within CFML, and not really about the display of Hello World. The Hello World aspect is just a light way to present the material.

  11. Posted February 12, 2010 at 7:13 pm | Permalink

    Kevin, this is an OUTSTANDING post. You have explained, in this simple and concise tutorial, how to hook up ColdFusion and Spring, with the help of Mark Mandel’s JavaLoader CFC library, which opens the tremendous possibilities of server-based processing using Java. Ya, Ruby can spit out a hello world with less lines of code, but that really has nothing to do with your entry. Again, a great post for a coldfusioner like myself of 10 years, who are seeking simple explanations of how to hook up ColdFusion (the ultimate "language") with the rest of the world’s languages and frameworks. Keep rollin’.

  12. shiva sankara rao
    Posted March 11, 2010 at 4:22 am | Permalink

    This is very good example for beginner .
    Thanks, because it helps more to understand spring

  13. Hussein Grant
    Posted March 25, 2010 at 9:31 pm | Permalink

    This is a great post! I’m finding myself using java and ColdFusion quite often. Any good programmer Knowledgeable enough in both disciplines would be crazy to not leverage the two at some point.

  14. Zarko Susnjar
    Posted April 8, 2010 at 4:29 am | Permalink

    Great tutorial! Even if you don’t use dependency injection, I find it even more useful as Java>Javaloader>CFML how-to.

  15. Aristides
    Posted September 13, 2010 at 9:12 pm | Permalink

    Hi, how can I run this on tomcat 6.0?

  16. Posted September 14, 2010 at 1:37 am | Permalink

    Hi Aristides, perhaps you can give some more details on what you are trying to do? If you have ColdFusion running under TomCat then this should all work for you.

  17. Posted September 14, 2010 at 5:05 pm | Permalink

    I am new using coldfusion, but i am java developer that need to use some services writing using spring framework to get data from database.

    So I am not sure is this the correct deployment on tomcat, the coldfusion sendme this error.
    Variable APPLICATION is undefined.
    for more info I take some screenshots of the code and class

    screen2
    screen0

  18. Posted September 14, 2010 at 11:23 pm | Permalink

    Hi Aristides, sound like you might need to create an Application.cfc file which sits in your web root directory.

    In ColdFusion version 9 you can use something like this:

    component {
    	this.name = "CFSpring";
    }
    

    In ColdFusion version 8 and earlier you can use this:

    <cfcomponent output="false">
    	<cfset this.name = "CFSpring">
    </cfcomponent>
    
  19. Posted September 15, 2010 at 4:25 pm | Permalink

    Oh thanks for the help !!!
    and also I have to change this line
    factory.setConfigLocation( expandPath(“beans.xml”) );
    for this one;
    factory.setConfigLocation( “../webapps/cfusion/springdemo/beans.xml” );
    I don’t why but the parameter was bad sended.

    thanks for the post, help me really much.

  20. Guillermo
    Posted March 27, 2011 at 10:09 pm | Permalink

    First this tutorial works great.

    I have an issue though in regards to setting the scope on a bean. I am trying to set it to the ‘request’ scope. I keep getting “No Scope registered for scope ‘request’” Now I found the fix at this URL http://static.springsource.org/spring/docs/2.5.x/reference/beans.html
    3.4.4.1. Initial web configuration

    I change the File
    C:\JRun4\servers\dev3\cfusion.ear\cfusion.war\WEB-INF\web.xml is valid.
    (Adobe CF9)

    I then change to use AOP in the beans definition in web.xml

    all to no avail I keep getting the No Scope registered for scope ‘request’
    I think It might be that the listener change cannot find the jar but not sure what to change it to so it finds it.
    listener-class
    org.springframework.web.context.request.RequestContextListener
    /listener-class

    Any help would be appreciated I am going out of my mind.